aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ps2_usb/keymap.c6
-rw-r--r--ps2_usb/matrix.c260
2 files changed, 150 insertions, 116 deletions
diff --git a/ps2_usb/keymap.c b/ps2_usb/keymap.c
index f38784d1f..47db18bfa 100644
--- a/ps2_usb/keymap.c
+++ b/ps2_usb/keymap.c
@@ -17,7 +17,7 @@
17// Convert physical keyboard layout to matrix array. 17// Convert physical keyboard layout to matrix array.
18// This is a macro to define keymap easily in keyboard layout form. 18// This is a macro to define keymap easily in keyboard layout form.
19#define KEYMAP( \ 19#define KEYMAP( \
20 K76, K05,K06,K04,K0C, K03,K0B,K83,K0A, K01,K09,K78,K07, KFE,K7E,KFF, KB7,KBF,KDE, \ 20 K76, K05,K06,K04,K0C, K03,K0B,K83,K0A, K01,K09,K78,K07, KFC,K7E,KFE, KB7,KBF,KDE, \
21 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ 21 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
22 K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \ 22 K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
23 K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \ 23 K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
@@ -55,7 +55,7 @@
55 { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \ 55 { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
56 { KB_NO, KB_##KE9, KB_NO, KB_##KEB, KB_##KEC, KB_NO, KB_NO, KB_NO }, \ 56 { KB_NO, KB_##KE9, KB_NO, KB_##KEB, KB_##KEC, KB_NO, KB_NO, KB_NO }, \
57 { KB_##KF0, KB_##KF1, KB_##KF2, KB_NO, KB_##KF4, KB_##KF5, KB_NO, KB_NO }, \ 57 { KB_##KF0, KB_##KF1, KB_##KF2, KB_NO, KB_##KF4, KB_##KF5, KB_NO, KB_NO }, \
58 { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_NO, KB_##KFD, KB_##KFE, KB_##KFF }, \ 58 { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_##KFC, KB_##KFD, KB_##KFE, KB_NO }, \
59} 59}
60 60
61 61
@@ -161,7 +161,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
161 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, 161 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
162 TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9, 162 TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
163 CAPS,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS, 163 CAPS,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS,
164 LSFT,VOLD,VOLU,MUTE,NO, NO, HOME,PGUP,PGDN,END, FN1, RSFT, UP, P1, P2, P3, 164 LSFT,VOLD,VOLU,MUTE,NO, NO, HOME,PGDN,PGUP,END, FN1, RSFT, UP, P1, P2, P3,
165 LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT 165 LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
166 ), 166 ),
167}; 167};
diff --git a/ps2_usb/matrix.c b/ps2_usb/matrix.c
index 366568d68..aaf89719e 100644
--- a/ps2_usb/matrix.c
+++ b/ps2_usb/matrix.c
@@ -29,40 +29,39 @@
29 * 8bit 29 * 8bit
30 * --------- 30 * ---------
31 * 0| | 31 * 0| |
32 * :| XX | 00-7F for normal codes 32 * :| XX | 00-7F for normal codes(without E0-prefix)
33 * f|_________| 33 * f|_________|
34 * 10| | 34 * 10| |
35 * :| E0 XX | 80-FF for E0-prefix codes(use (XX|0x80) as code) 35 * :| E0 XX | 80-FF for E0-prefix codes(use (XX|0x80) as code)
36 * 1f| | 36 * 1f| |
37 * --------- 37 * ---------
38 * exceptions: 38 * exceptions:
39 * 0x83: F8(normal code placed beyond 0x7F) 39 * 83: F8[0x83](normal codes but > 0x7F)
40 * 0xFE: PrintScreen 40 * FC: PrintScreen[E0 7C or 84]
41 * 0xFF: Puause/Break 41 * FE: Puause
42 */ 42 */
43#define _PRINT_SCREEN (0xFE) 43#define F8 (0x83)
44#define _PAUSE_BREAK (0xFF) 44#define PRINT_SCREEN (0xFC)
45#define _ROW(code) (code>>3) 45#define PAUSE (0xFE)
46#define _COL(code) (code&0x07) 46#define ROW(code) (code>>3)
47#define COL(code) (code&0x07)
47 48
48static bool _matrix_is_modified = false; 49static bool is_modified = false;
49 50
50// matrix state buffer(1:on, 0:off) 51// matrix state buffer(1:on, 0:off)
51#if (MATRIX_COLS <= 8) 52#if (MATRIX_COLS <= 8)
52static uint8_t *matrix; 53static uint8_t matrix[MATRIX_ROWS];
53static uint8_t _matrix0[MATRIX_ROWS];
54#else 54#else
55static uint16_t *matrix; 55static uint16_t matrix[MATRIX_ROWS];
56static uint16_t _matrix0[MATRIX_ROWS];
57#endif 56#endif
58 57
59#ifdef MATRIX_HAS_GHOST 58#ifdef MATRIX_HAS_GHOST
60static bool matrix_has_ghost_in_row(uint8_t row); 59static bool matrix_has_ghost_in_row(uint8_t row);
61#endif 60#endif
62static void _matrix_make(uint8_t code); 61static void matrix_make(uint8_t code);
63static void _matrix_break(uint8_t code); 62static void matrix_break(uint8_t code);
64static void _ps2_reset(void); 63static void ps2_reset(void);
65static void _ps2_set_leds(uint8_t leds); 64static void ps2_set_leds(uint8_t leds);
66 65
67 66
68inline 67inline
@@ -82,38 +81,96 @@ void matrix_init(void)
82 print_enable = true; 81 print_enable = true;
83 ps2_host_init(); 82 ps2_host_init();
84 83
85 _ps2_reset(); 84 ps2_reset();
86 85
87 // flush LEDs 86 // flush LEDs
88 _ps2_set_leds(1<<PS2_LED_NUM_LOCK); 87 ps2_set_leds(1<<PS2_LED_NUM_LOCK);
89 _delay_ms(100); 88 _delay_ms(100);
90 _ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK); 89 ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK);
91 _delay_ms(100); 90 _delay_ms(100);
92 _ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK|1<<PS2_LED_SCROLL_LOCK); 91 ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK|1<<PS2_LED_SCROLL_LOCK);
93 _delay_ms(300); 92 _delay_ms(300);
94 _ps2_set_leds(0x00); 93 ps2_set_leds(0x00);
95 94
96 // initialize matrix state: all keys off 95 // initialize matrix state: all keys off
97 for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00; 96 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
98 matrix = _matrix0;
99 97
100 return; 98 return;
101} 99}
102 100
101/*
102 * PS/2 Scan Code Set 2: Exceptional Handling
103 *
104 * There are several keys to be handled exceptionally.
105 * The scan code for these keys are varied or prefix/postfix'd
106 * depending on modifier key state.
107 *
108 * References:
109 * http://www.microsoft.com/whdc/archive/scancode.mspx
110 * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
111 *
112 *
113 * Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left:
114 * Num Lock: off
115 * modifiers | make | break
116 * ----------+---------------------------+----------------------
117 * Ohter | <make> | <break>
118 * LShift | E0 F0 12 <make> | <break> E0 12
119 * RShift | E0 F0 59 <make> | <break> E0 59
120 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
121 *
122 * Num Lock: on
123 * modifiers | make | break
124 * ----------+---------------------------+----------------------
125 * Other | E0 12 <make> | <break> E0 F0 12
126 * Shift'd | <make> | <break>
127 *
128 * Handling: ignore these prefix/postfix codes
129 *
130 *
131 * Keypad-/:
132 * modifiers | make | break
133 * ----------+---------------------------+----------------------
134 * Ohter | <make> | <break>
135 * LShift | E0 F0 12 <make> | <break> E0 12
136 * RShift | E0 F0 59 <make> | <break> E0 59
137 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
138 *
139 * Handling: ignore these prefix/postfix codes
140 *
141 *
142 * PrintScreen:
143 * With hoding down modifiers, the scan code is sent as following:
144 *
145 * modifiers | make | break
146 * ----------+--------------+-----------------------------------
147 * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12
148 * Shift'd | E0 7C | E0 F0 7C
149 * Control'd | E0 7C | E0 F0 7C
150 * Alt'd | 84 | F0 84
151 *
152 * Handling: ignore prefix/postfix codes and treat both scan code
153 * E0 7C and 84 as PrintScreen.
154 *
155 * Pause:
156 * With hoding down modifiers, the scan code is sent as following:
157 *
158 * modifiers | make(no break code)
159 * ----------+--------------------------------------------------
160 * no mods | E1 14 77 E1 F0 14 F0 77
161 * Control'd | E0 7E E0 F0 7E
162 *
163 * Handling: treat these two code sequence as Pause
164 *
165 */
103uint8_t matrix_scan(void) 166uint8_t matrix_scan(void)
104{ 167{
105 168
106 static enum { 169 static enum {
107 INIT, 170 INIT,
108 BREAK, 171 F0,
109 E0, 172 E0,
110 E0_F0, 173 E0_F0,
111 // states for PrintScreen
112 E0_12,
113 E0_12_E0,
114 E0_F0_7C,
115 E0_F0_7C_E0,
116 E0_F0_7C_E0_F0,
117 // states for Pause/Break 174 // states for Pause/Break
118 E1, 175 E1,
119 E1_14, 176 E1_14,
@@ -125,15 +182,16 @@ uint8_t matrix_scan(void)
125 } state = INIT; 182 } state = INIT;
126 183
127 184
128 _matrix_is_modified = false; 185 is_modified = false;
129 186
130 // Pause/Break off(PS/2 has no break for this key) 187 // Pause/Break off(PS/2 has no break for this key)
131 if (matrix_is_on(_ROW(_PAUSE_BREAK), _COL(_PAUSE_BREAK))) { 188 if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
132 _matrix_break(_PAUSE_BREAK); 189 matrix_break(PAUSE);
133 } 190 }
134 191
135 uint8_t code; 192 uint8_t code;
136 while ((code = ps2_host_recv())) { 193 while ((code = ps2_host_recv())) {
194debug_hex(code); debug(" ");
137 switch (state) { 195 switch (state) {
138 case INIT: 196 case INIT:
139 switch (code) { 197 switch (code) {
@@ -141,113 +199,88 @@ uint8_t matrix_scan(void)
141 state = E0; 199 state = E0;
142 break; 200 break;
143 case 0xF0: // break code 201 case 0xF0: // break code
144 state = BREAK; 202 state = F0;
145 break; 203 break;
146 case 0xE1: // Pause/Break 204 case 0xE1: // Pause/Break
147 state = E1; 205 state = E1;
148 break; 206 break;
207 case 0x83: // F8
208 matrix_make(F8);
209 state = INIT;
210 break;
211 case 0x84: // PrintScreen
212 matrix_make(PRINT_SCREEN);
213 state = INIT;
214 break;
149 default: // normal key make 215 default: // normal key make
150 if (code < 0x80) { 216 if (code < 0x80) {
151 _matrix_make(code); 217 matrix_make(code);
152 } else { 218 } else {
153 debug("ps/2 unknow code: "); debug_hex(code); debug("\n"); 219 debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n");
154 } 220 }
155 state = INIT; 221 state = INIT;
156 } 222 }
157 break; 223 break;
158 case E0: 224 case E0:
159 switch (code) { 225 switch (code) {
160 case 0x12: // PrintScreen(make) 226 case 0x12: // postfix/postfix code for exceptional keys
161 state = E0_12; 227 case 0x59: // postfix/postfix code for exceptional keys
162 break;
163 case 0x7C: // PrintScreen(typematic)
164 // ignore 228 // ignore
165 state = INIT; 229 state = INIT;
166 break; 230 break;
231 case 0x7E: // former part of Control-Pause[E0 7E E0 F0 7E]
232 matrix_make(PAUSE);
233 state = INIT;
234 break;
167 case 0xF0: // E0 break 235 case 0xF0: // E0 break
168 state = E0_F0; 236 state = E0_F0;
169 break; 237 break;
170 default: // E0 make 238 default: // E0 make
171 if (code < 0x80) { 239 if (code < 0x80) {
172 _matrix_make(code|0x80); 240 matrix_make(code|0x80);
173 } else {
174 debug("ps/2 unknow code: "); debug_hex(code); debug("\n");
175 }
176 state = INIT;
177 }
178 break;
179 case BREAK:
180 if (code < 0x80) {
181 _matrix_break(code);
182 } else {
183 debug("ps/2 unknow code: "); debug_hex(code); debug("\n");
184 }
185 state = INIT;
186 break;
187 case E0_F0: // E0 break
188 switch (code) {
189 case 0x7C:
190 state = E0_F0_7C;
191 break;
192 default:
193 if (code < 0x80) {
194 _matrix_break(code|0x80);
195 } else { 241 } else {
196 debug("ps/2 unknow code: "); debug_hex(code); debug("\n"); 242 debug("unexpected scan code at E0: "); debug_hex(code); debug("\n");
197 } 243 }
198 state = INIT; 244 state = INIT;
199 } 245 }
200 break; 246 break;
201 /* PrintScreen(make) */ 247 case F0:
202 case E0_12:
203 switch (code) { 248 switch (code) {
204 case 0xE0: 249 case 0x83:
205 state = E0_12_E0; 250 matrix_break(F8);
206 break;
207 default:
208 state = INIT;
209 }
210 break;
211 case E0_12_E0:
212 switch (code) {
213 case 0x7C:
214 _matrix_make(_PRINT_SCREEN);
215 state = INIT; 251 state = INIT;
216 break; 252 break;
217 default: 253 case 0x84:
254 matrix_break(PRINT_SCREEN);
218 state = INIT; 255 state = INIT;
219 }
220 break;
221 /* PrintScreen(break) */
222 case E0_F0_7C:
223 switch (code) {
224 case 0xE0:
225 state = E0_F0_7C_E0;
226 break; 256 break;
227 default: 257 default:
228 state = INIT; 258 if (code < 0x80) {
259 matrix_break(code);
260 } else {
261 debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
262 }
263 state = INIT;
229 } 264 }
230 break; 265 break;
231 case E0_F0_7C_E0: 266 case E0_F0: // E0 break
232 switch (code) {
233 case 0xF0:
234 state = E0_F0_7C_E0_F0;
235 break;
236 default:
237 state = INIT;
238 }
239 break;
240 case E0_F0_7C_E0_F0:
241 switch (code) { 267 switch (code) {
242 case 0x12: 268 case 0x12: // postfix/postfix code for exceptional keys
243 _matrix_break(_PRINT_SCREEN); 269 case 0x59: // postfix/postfix code for exceptional keys
270 case 0x7E: // latter part of Control-Pause[E0 7E E0 F0 7E]
271 // ignore
244 state = INIT; 272 state = INIT;
245 break; 273 break;
246 default: 274 default:
275 if (code < 0x80) {
276 matrix_break(code|0x80);
277 } else {
278 debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n");
279 }
247 state = INIT; 280 state = INIT;
248 } 281 }
249 break; 282 break;
250 /* Pause/Break */ 283 /* Pause */
251 case E1: 284 case E1:
252 switch (code) { 285 switch (code) {
253 case 0x14: 286 case 0x14:
@@ -305,7 +338,7 @@ uint8_t matrix_scan(void)
305 case E1_14_77_E1_F0_14_F0: 338 case E1_14_77_E1_F0_14_F0:
306 switch (code) { 339 switch (code) {
307 case 0x77: 340 case 0x77:
308 _matrix_make(_PAUSE_BREAK); 341 matrix_make(PAUSE);
309 state = INIT; 342 state = INIT;
310 break; 343 break;
311 default: 344 default:
@@ -317,6 +350,7 @@ uint8_t matrix_scan(void)
317 } 350 }
318 } 351 }
319 352
353 // handle LED indicators
320 static uint8_t prev_leds = 0; 354 static uint8_t prev_leds = 0;
321 if (prev_leds != usb_keyboard_leds) { 355 if (prev_leds != usb_keyboard_leds) {
322 uint8_t leds = 0; 356 uint8_t leds = 0;
@@ -327,7 +361,7 @@ uint8_t matrix_scan(void)
327 if (usb_keyboard_leds&(1<<USB_LED_CAPS_LOCK)) 361 if (usb_keyboard_leds&(1<<USB_LED_CAPS_LOCK))
328 leds |= (1<<PS2_LED_CAPS_LOCK); 362 leds |= (1<<PS2_LED_CAPS_LOCK);
329 363
330 _ps2_set_leds(leds); 364 ps2_set_leds(leds);
331 prev_leds = usb_keyboard_leds; 365 prev_leds = usb_keyboard_leds;
332 } 366 }
333 367
@@ -336,7 +370,7 @@ uint8_t matrix_scan(void)
336 370
337bool matrix_is_modified(void) 371bool matrix_is_modified(void)
338{ 372{
339 return _matrix_is_modified; 373 return is_modified;
340} 374}
341 375
342inline 376inline
@@ -422,24 +456,24 @@ static bool matrix_has_ghost_in_row(uint8_t row)
422 456
423 457
424inline 458inline
425static void _matrix_make(uint8_t code) 459static void matrix_make(uint8_t code)
426{ 460{
427 if (!matrix_is_on(_ROW(code), _COL(code))) { 461 if (!matrix_is_on(ROW(code), COL(code))) {
428 matrix[_ROW(code)] |= 1<<_COL(code); 462 matrix[ROW(code)] |= 1<<COL(code);
429 _matrix_is_modified = true; 463 is_modified = true;
430 } 464 }
431} 465}
432 466
433inline 467inline
434static void _matrix_break(uint8_t code) 468static void matrix_break(uint8_t code)
435{ 469{
436 if (matrix_is_on(_ROW(code), _COL(code))) { 470 if (matrix_is_on(ROW(code), COL(code))) {
437 matrix[_ROW(code)] &= ~(1<<_COL(code)); 471 matrix[ROW(code)] &= ~(1<<COL(code));
438 _matrix_is_modified = true; 472 is_modified = true;
439 } 473 }
440} 474}
441 475
442static void _ps2_reset(void) 476static void ps2_reset(void)
443{ 477{
444 ps2_host_send(0xFF); 478 ps2_host_send(0xFF);
445 ps2_host_recv(); // 0xFA 479 ps2_host_recv(); // 0xFA
@@ -447,7 +481,7 @@ static void _ps2_reset(void)
447 _delay_ms(1000); 481 _delay_ms(1000);
448} 482}
449 483
450static void _ps2_set_leds(uint8_t leds) 484static void ps2_set_leds(uint8_t leds)
451{ 485{
452 ps2_host_send(0xED); 486 ps2_host_send(0xED);
453 ps2_host_recv(); // 0xFA 487 ps2_host_recv(); // 0xFA