Skip to content

Commit 12c509b

Browse files
committed
pre-3.0: support keyboards with NKRO
1 parent 45c72f8 commit 12c509b

File tree

3 files changed

+126
-136
lines changed

3 files changed

+126
-136
lines changed

src/ps2kbd.c

Lines changed: 99 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,25 @@
2525

2626
#include "tusb.h"
2727
#include "ps2pico.h"
28-
#include "atphy.pio.h"
28+
#include "ps2phy.pio.h"
2929
#include "bsp/board_api.h"
3030
#include "pico/util/queue.h"
3131

3232
bool kb_enabled = true;
33-
bool locked = false;
34-
35-
u8 leds;
36-
u8 modifiers;
37-
u8 sent = 0;
38-
u8 packet[9];
39-
u8 last_rx = 0;
40-
u8 last_tx = 0;
41-
u8 repeat = 0;
42-
u32 repeat_us = 91743;
43-
u16 delay_ms = 500;
44-
45-
queue_t packets;
46-
alarm_id_t repeater;
47-
extern s8 set_led;
33+
bool phy_locked = false;
34+
extern s8 kb_set_led;
35+
36+
u8 kb_modifiers = 0;
37+
u8 kb_repeat_key = 0;
38+
u16 kb_delay_ms = 500;
39+
u32 kb_repeat_us = 91743;
40+
alarm_id_t kb_repeater;
41+
42+
u8 phy_last_rx = 0;
43+
u8 phy_last_tx = 0;
44+
u8 phy_sent = 0;
45+
u8 phy_packet[9];
46+
queue_t phy_packets;
4847

4948
u8 const led2ps2[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
5049
u8 const mod2ps2[] = { 0x14, 0x12, 0x11, 0x1f, 0x14, 0x59, 0x11, 0x27 };
@@ -58,13 +57,13 @@ u8 const hid2ps2[] = {
5857
0x75, 0x7d, 0x70, 0x71, 0x61, 0x2f, 0x37, 0x0f, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40,
5958
0x48, 0x50, 0x57, 0x5f
6059
};
61-
u32 const repeats[] = {
60+
u32 const kb_repeats[] = {
6261
33333, 37453, 41667, 45872, 48309, 54054, 58480, 62500,
6362
66667, 75188, 83333, 91743, 100000, 108696, 116279, 125000,
6463
133333, 149254, 166667, 181818, 200000, 217391, 232558, 250000,
6564
270270, 303030, 333333, 370370, 400000, 434783, 476190, 500000
6665
};
67-
u16 const delays[] = { 250, 500, 750, 1000 };
66+
u16 const kb_delays[] = { 250, 500, 750, 1000 };
6867

6968
u32 ps2_frame(u8 byte) {
7069
bool parity = 1;
@@ -75,31 +74,29 @@ u32 ps2_frame(u8 byte) {
7574
}
7675

7776
void ps2_send(u8 len) {
78-
packet[0] = len;
79-
80-
/*printf("TX: ");
81-
for(u8 i = 1; i <= packet[0]; i++) {
82-
printf("%02x ", packet[i]);
83-
}
84-
printf("\n");*/
85-
77+
phy_packet[0] = len;
8678
board_led_write(1);
87-
queue_try_add(&packets, &packet);
79+
queue_try_add(&phy_packets, &phy_packet);
8880
}
8981

9082
void kb_set_leds(u8 byte) {
9183
if(byte > 7) byte = 0;
92-
set_led = led2ps2[byte];
84+
kb_set_led = led2ps2[byte];
9385
}
9486

95-
s64 blink_callback() {
87+
s64 reset_callback() {
9688
kb_set_leds(0);
97-
packet[1] = 0xaa;
89+
phy_packet[1] = 0xaa;
9890
ps2_send(1);
91+
kb_enabled = true;
9992
return 0;
10093
}
10194

102-
bool key_is_e0(u8 key) {
95+
bool key_is_modifier(u8 key) {
96+
return key >= HID_KEY_CONTROL_LEFT && key <= HID_KEY_GUI_RIGHT;
97+
}
98+
99+
bool key_is_extended(u8 key) {
103100
return key == HID_KEY_PRINT_SCREEN ||
104101
(key >= HID_KEY_INSERT && key <= HID_KEY_ARROW_UP) ||
105102
key == HID_KEY_KEYPAD_DIVIDE ||
@@ -109,22 +106,25 @@ bool key_is_e0(u8 key) {
109106
(key >= HID_KEY_GUI_LEFT && key != HID_KEY_SHIFT_RIGHT);
110107
}
111108

112-
s64 repeat_callback() {
113-
if(repeat) {
114-
u8 len = 0;
115-
if(key_is_e0(repeat)) packet[++len] = 0xe0;
109+
s64 kb_repeat_callback() {
110+
if(kb_repeat_key) {
111+
if(kb_enabled) {
112+
u8 len = 0;
113+
if(key_is_extended(kb_repeat_key)) phy_packet[++len] = 0xe0;
116114

117-
if(repeat >= HID_KEY_CONTROL_LEFT && repeat <= HID_KEY_GUI_RIGHT) {
118-
packet[++len] = mod2ps2[repeat - HID_KEY_CONTROL_LEFT];
119-
} else {
120-
packet[++len] = hid2ps2[repeat];
115+
if(key_is_modifier(kb_repeat_key)) {
116+
phy_packet[++len] = mod2ps2[kb_repeat_key - HID_KEY_CONTROL_LEFT];
117+
} else {
118+
phy_packet[++len] = hid2ps2[kb_repeat_key];
119+
}
120+
121+
ps2_send(len);
121122
}
122123

123-
ps2_send(len);
124-
return repeat_us;
124+
return kb_repeat_us;
125125
}
126126

127-
repeater = 0;
127+
kb_repeater = 0;
128128
return 0;
129129
}
130130

@@ -135,30 +135,30 @@ void kb_receive(u8 byte, u8 prev_byte) {
135135
break;
136136

137137
case 0xf3: // Set typematic rate and delay
138-
repeat_us = repeats[byte & 0x1f];
139-
delay_ms = delays[(byte & 0x60) >> 5];
138+
kb_repeat_us = kb_repeats[byte & 0x1f];
139+
kb_delay_ms = kb_delays[(byte & 0x60) >> 5];
140140
break;
141141

142142
default:
143143
switch(byte) {
144144
case 0xff: // Reset
145-
kb_enabled = true;
146-
repeat_us = 91743;
147-
delay_ms = 500;
148-
repeat = 0;
145+
kb_enabled = false;
146+
kb_repeat_us = 91743;
147+
kb_delay_ms = 500;
149148
kb_set_leds(KEYBOARD_LED_NUMLOCK | KEYBOARD_LED_CAPSLOCK | KEYBOARD_LED_SCROLLLOCK);
150-
add_alarm_in_ms(500, blink_callback, NULL, false);
149+
add_alarm_in_ms(500, reset_callback, NULL, false);
150+
printf("resetting...\n");
151151
break;
152152

153153
case 0xee: // Echo
154-
packet[1] = 0xee;
154+
phy_packet[1] = 0xee;
155155
ps2_send(1);
156156
return;
157157

158158
case 0xf2: // Identify keyboard
159-
packet[1] = 0xfa;
160-
packet[2] = 0xab;
161-
packet[3] = 0x83;
159+
phy_packet[1] = 0xfa;
160+
phy_packet[2] = 0xab;
161+
phy_packet[3] = 0x83;
162162
ps2_send(3);
163163
return;
164164

@@ -169,25 +169,24 @@ void kb_receive(u8 byte, u8 prev_byte) {
169169
case 0xf5: // Disable scanning, restore default parameters
170170
case 0xf6: // Set default parameters
171171
kb_enabled = byte == 0xf6;
172-
repeat_us = 91743;
173-
delay_ms = 500;
174-
repeat = 0;
172+
kb_repeat_us = 91743;
173+
kb_delay_ms = 500;
175174
kb_set_leds(0);
176175
break;
177176
}
178177
break;
179178
}
180179

181-
packet[1] = 0xfa;
180+
phy_packet[1] = 0xfa;
182181
ps2_send(1);
183182
}
184183

185184
void kb_send_key(u8 key, bool state) {
186185
if(key >= HID_KEY_CONTROL_LEFT && key <= HID_KEY_GUI_RIGHT) {
187186
if(state) {
188-
modifiers = modifiers | (1 << (key - HID_KEY_CONTROL_LEFT));
187+
kb_modifiers = kb_modifiers | (1 << (key - HID_KEY_CONTROL_LEFT));
189188
} else {
190-
modifiers = modifiers & ~(1 << (key - HID_KEY_CONTROL_LEFT));
189+
kb_modifiers = kb_modifiers & ~(1 << (key - HID_KEY_CONTROL_LEFT));
191190
}
192191
} else if(key < HID_KEY_A || key > HID_KEY_F24) {
193192
return;
@@ -202,25 +201,25 @@ void kb_send_key(u8 key, bool state) {
202201
}
203202

204203
if(key == HID_KEY_PAUSE) {
205-
repeat = 0;
204+
kb_repeat_key = 0;
206205

207206
if(state) {
208-
if(modifiers & KEYBOARD_MODIFIER_LEFTCTRL ||
209-
modifiers & KEYBOARD_MODIFIER_RIGHTCTRL) {
210-
packet[++len] = 0xe0;
211-
packet[++len] = 0x7e;
212-
packet[++len] = 0xe0;
213-
packet[++len] = 0xf0;
214-
packet[++len] = 0x7e;
207+
if(kb_modifiers & KEYBOARD_MODIFIER_LEFTCTRL ||
208+
kb_modifiers & KEYBOARD_MODIFIER_RIGHTCTRL) {
209+
phy_packet[++len] = 0xe0;
210+
phy_packet[++len] = 0x7e;
211+
phy_packet[++len] = 0xe0;
212+
phy_packet[++len] = 0xf0;
213+
phy_packet[++len] = 0x7e;
215214
} else {
216-
packet[++len] = 0xe1;
217-
packet[++len] = 0x14;
218-
packet[++len] = 0x77;
219-
packet[++len] = 0xe1;
220-
packet[++len] = 0xf0;
221-
packet[++len] = 0x14;
222-
packet[++len] = 0xf0;
223-
packet[++len] = 0x77;
215+
phy_packet[++len] = 0xe1;
216+
phy_packet[++len] = 0x14;
217+
phy_packet[++len] = 0x77;
218+
phy_packet[++len] = 0xe1;
219+
phy_packet[++len] = 0xf0;
220+
phy_packet[++len] = 0x14;
221+
phy_packet[++len] = 0xf0;
222+
phy_packet[++len] = 0x77;
224223
}
225224

226225
ps2_send(len);
@@ -229,49 +228,48 @@ void kb_send_key(u8 key, bool state) {
229228
return;
230229
}
231230

232-
if(key_is_e0(key)) packet[++len] = 0xe0;
231+
if(key_is_extended(key)) phy_packet[++len] = 0xe0;
233232

234233
if(state) {
235-
repeat = key;
236-
if(repeater) cancel_alarm(repeater);
237-
repeater = add_alarm_in_ms(delay_ms, repeat_callback, NULL, false);
234+
kb_repeat_key = key;
235+
if(kb_repeater) cancel_alarm(kb_repeater);
236+
kb_repeater = add_alarm_in_ms(kb_delay_ms, kb_repeat_callback, NULL, false);
238237
} else {
239-
if(key == repeat) repeat = 0;
240-
packet[++len] = 0xf0;
238+
if(key == kb_repeat_key) kb_repeat_key = 0;
239+
phy_packet[++len] = 0xf0;
241240
}
242241

243242
if(key >= HID_KEY_CONTROL_LEFT && key <= HID_KEY_GUI_RIGHT) {
244-
packet[++len] = mod2ps2[key - HID_KEY_CONTROL_LEFT];
243+
phy_packet[++len] = mod2ps2[key - HID_KEY_CONTROL_LEFT];
245244
} else {
246-
packet[++len] = hid2ps2[key];
245+
phy_packet[++len] = hid2ps2[key];
247246
}
248247

249248
ps2_send(len);
250249
}
251250

252251
void kb_task() {
253252
if(pio_interrupt_get(pio0, 1)) {
254-
if(sent > 0) sent--;
253+
if(phy_sent > 0) phy_sent--;
255254
pio_interrupt_clear(pio0, 1);
256255
}
257256

258-
if(!locked && !queue_is_empty(&packets) && !pio_interrupt_get(pio0, 0)) {
259-
if(queue_try_peek(&packets, &packet)) {
260-
if(sent == packet[0]) {
261-
sent = 0;
262-
queue_try_remove(&packets, &packet);
257+
if(!phy_locked && !queue_is_empty(&phy_packets) && !pio_interrupt_get(pio0, 0)) {
258+
if(queue_try_peek(&phy_packets, &phy_packet)) {
259+
if(phy_sent == phy_packet[0]) {
260+
phy_sent = 0;
261+
queue_try_remove(&phy_packets, &phy_packet);
263262
board_led_write(0);
264263
} else {
265-
sent++;
266-
last_tx = packet[sent];
267-
locked = true;
268-
//printf(" put %02x \n", last_tx);
269-
pio_sm_put(pio0, 0, ps2_frame(last_tx));
264+
phy_sent++;
265+
phy_last_tx = phy_packet[phy_sent];
266+
phy_locked = true;
267+
pio_sm_put(pio0, 0, ps2_frame(phy_last_tx));
270268
}
271269
}
272270
}
273271

274-
if(locked && pio_interrupt_get(pio0, 0)) locked = false;
272+
if(phy_locked && pio_interrupt_get(pio0, 0)) phy_locked = false;
275273

276274
if(!pio_sm_is_rx_fifo_empty(pio0, 1)) {
277275
u32 fifo = pio_sm_get(pio0, 1) >> 23;
@@ -287,22 +285,20 @@ void kb_task() {
287285
}
288286

289287
if((fifo & 0xff) == 0xfe) {
290-
pio_sm_put(pio0, 0, ps2_frame(last_tx));
288+
pio_sm_put(pio0, 0, ps2_frame(phy_last_tx));
291289
return;
292290
}
293291

294-
while(queue_try_remove(&packets, &packet));
295-
sent = 0;
296-
297-
//printf("RX: 0x%02lx\n", fifo & 0xff);
292+
while(queue_try_remove(&phy_packets, &phy_packet));
293+
phy_sent = 0;
298294

299-
kb_receive(fifo, last_rx);
300-
last_rx = fifo;
295+
kb_receive(fifo, phy_last_rx);
296+
phy_last_rx = fifo;
301297
}
302298
}
303299

304300
void kb_init() {
305301
ps2write_program_init(pio0, 0, pio_add_program(pio0, &ps2write_program));
306302
ps2read_program_init(pio0, 1, pio_add_program(pio0, &ps2read_program));
307-
queue_init(&packets, 9, 32);
303+
queue_init(&phy_packets, 9, 32);
308304
}

0 commit comments

Comments
 (0)