Exceptional handling for PS/2 scan code set 2
changed names which does not comply to C spec.(underscore prefix names)
This commit is contained in:
		
							parent
							
								
									a28a2a6a5e
								
							
						
					
					
						commit
						23c686ad46
					
				| @ -17,7 +17,7 @@ | ||||
| // Convert physical keyboard layout to matrix array.
 | ||||
| // This is a macro to define keymap easily in keyboard layout form.
 | ||||
| #define KEYMAP( \ | ||||
|     K76,  K05,K06,K04,K0C, K03,K0B,K83,K0A, K01,K09,K78,K07, KFE,K7E,KFF,      KB7,KBF,KDE, \ | ||||
|     K76,  K05,K06,K04,K0C, K03,K0B,K83,K0A, K01,K09,K78,K07, KFC,K7E,KFE,      KB7,KBF,KDE, \ | ||||
|     K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD,  K77,KCA,K7C,K7B, \ | ||||
|     K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA,  K6C,K75,K7D,     \ | ||||
|     K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,    K5A,               K6B,K73,K74,K79, \ | ||||
| @ -55,7 +55,7 @@ | ||||
|     { KB_NO,    KB_NO,    KB_NO,    KB_NO,    KB_NO,    KB_NO,    KB_NO,    KB_NO    }, \ | ||||
|     { KB_NO,    KB_##KE9, KB_NO,    KB_##KEB, KB_##KEC, KB_NO,    KB_NO,    KB_NO    }, \ | ||||
|     { KB_##KF0, KB_##KF1, KB_##KF2, KB_NO,    KB_##KF4, KB_##KF5, KB_NO,    KB_NO    }, \ | ||||
|     { KB_NO,    KB_NO,    KB_##KFA, KB_NO,    KB_NO,    KB_##KFD, KB_##KFE, KB_##KFF }, \ | ||||
|     { KB_NO,    KB_NO,    KB_##KFA, KB_NO,    KB_##KFC, KB_##KFD, KB_##KFE, KB_NO    }, \ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -161,7 +161,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||||
|     ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F8,  F10, F11, F12, BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS, | ||||
|     TAB, NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, NO,  NO,  NO,  BSLS,     DEL, END, PGDN,    P7,  P8,  P9, | ||||
|     CAPS,NO,  NO,  NO,  NO,  NO,  LEFT,DOWN,UP,  RGHT,NO,  NO,       ENT,                         P4,  P5,  P6,  PPLS, | ||||
|     LSFT,VOLD,VOLU,MUTE,NO,  NO,  HOME,PGUP,PGDN,END, FN1,           RSFT,          UP,           P1,  P2,  P3, | ||||
|     LSFT,VOLD,VOLU,MUTE,NO,  NO,  HOME,PGDN,PGUP,END, FN1,           RSFT,          UP,           P1,  P2,  P3, | ||||
|     LCTL,LGUI,LALT,          SPC,                     RALT,RGUI,APP, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PENT | ||||
|     ), | ||||
| }; | ||||
|  | ||||
							
								
								
									
										266
									
								
								ps2_usb/matrix.c
									
									
									
									
									
								
							
							
						
						
									
										266
									
								
								ps2_usb/matrix.c
									
									
									
									
									
								
							| @ -29,40 +29,39 @@ | ||||
|  *      8bit | ||||
|  *    --------- | ||||
|  *  0|         | | ||||
|  *  :|   XX    | 00-7F for normal codes | ||||
|  *  :|   XX    | 00-7F for normal codes(without E0-prefix) | ||||
|  *  f|_________| | ||||
|  * 10|         | | ||||
|  *  :|  E0 XX  | 80-FF for E0-prefix codes(use (XX|0x80) as code) | ||||
|  * 1f|         | | ||||
|  *    --------- | ||||
|  * exceptions: | ||||
|  * 0x83: F8(normal code placed beyond 0x7F) | ||||
|  * 0xFE: PrintScreen | ||||
|  * 0xFF: Puause/Break | ||||
|  * 83:    F8[0x83](normal codes but > 0x7F) | ||||
|  * FC:    PrintScreen[E0 7C or 84] | ||||
|  * FE:    Puause | ||||
|  */ | ||||
| #define _PRINT_SCREEN   (0xFE) | ||||
| #define _PAUSE_BREAK    (0xFF) | ||||
| #define _ROW(code)      (code>>3) | ||||
| #define _COL(code)      (code&0x07) | ||||
| #define F8             (0x83) | ||||
| #define PRINT_SCREEN   (0xFC) | ||||
| #define PAUSE          (0xFE) | ||||
| #define ROW(code)      (code>>3) | ||||
| #define COL(code)      (code&0x07) | ||||
| 
 | ||||
| static bool _matrix_is_modified = false; | ||||
| static bool is_modified = false; | ||||
| 
 | ||||
| // matrix state buffer(1:on, 0:off)
 | ||||
| #if (MATRIX_COLS <= 8) | ||||
| static uint8_t *matrix; | ||||
| static uint8_t _matrix0[MATRIX_ROWS]; | ||||
| static uint8_t matrix[MATRIX_ROWS]; | ||||
| #else | ||||
| static uint16_t *matrix; | ||||
| static uint16_t _matrix0[MATRIX_ROWS]; | ||||
| static uint16_t matrix[MATRIX_ROWS]; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef MATRIX_HAS_GHOST | ||||
| static bool matrix_has_ghost_in_row(uint8_t row); | ||||
| #endif | ||||
| static void _matrix_make(uint8_t code); | ||||
| static void _matrix_break(uint8_t code); | ||||
| static void _ps2_reset(void); | ||||
| static void _ps2_set_leds(uint8_t leds); | ||||
| static void matrix_make(uint8_t code); | ||||
| static void matrix_break(uint8_t code); | ||||
| static void ps2_reset(void); | ||||
| static void ps2_set_leds(uint8_t leds); | ||||
| 
 | ||||
| 
 | ||||
| inline | ||||
| @ -82,38 +81,96 @@ void matrix_init(void) | ||||
|     print_enable = true; | ||||
|     ps2_host_init(); | ||||
| 
 | ||||
|     _ps2_reset(); | ||||
|     ps2_reset(); | ||||
| 
 | ||||
|     // flush LEDs
 | ||||
|     _ps2_set_leds(1<<PS2_LED_NUM_LOCK); | ||||
|     ps2_set_leds(1<<PS2_LED_NUM_LOCK); | ||||
|     _delay_ms(100); | ||||
|     _ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK); | ||||
|     ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK); | ||||
|     _delay_ms(100); | ||||
|     _ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK|1<<PS2_LED_SCROLL_LOCK); | ||||
|     ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK|1<<PS2_LED_SCROLL_LOCK); | ||||
|     _delay_ms(300); | ||||
|     _ps2_set_leds(0x00); | ||||
|     ps2_set_leds(0x00); | ||||
|      | ||||
|     // initialize matrix state: all keys off
 | ||||
|     for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00; | ||||
|     matrix = _matrix0; | ||||
|     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; | ||||
| 
 | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * PS/2 Scan Code Set 2: Exceptional Handling | ||||
|  * | ||||
|  * There are several keys to be handled exceptionally. | ||||
|  * The scan code for these keys are varied or prefix/postfix'd | ||||
|  * depending on modifier key state. | ||||
|  * | ||||
|  * References: | ||||
|  *     http://www.microsoft.com/whdc/archive/scancode.mspx
 | ||||
|  *     http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
 | ||||
|  * | ||||
|  * | ||||
|  * Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left: | ||||
|  *     Num Lock: off | ||||
|  *     modifiers | make                      | break | ||||
|  *     ----------+---------------------------+---------------------- | ||||
|  *     Ohter     |                    <make> | <break> | ||||
|  *     LShift    | E0 F0 12           <make> | <break>  E0 12 | ||||
|  *     RShift    | E0 F0 59           <make> | <break>  E0 59 | ||||
|  *     L+RShift  | E0 F0 12  E0 F0 59 <make> | <break>  E0 59 E0 12 | ||||
|  * | ||||
|  *     Num Lock: on | ||||
|  *     modifiers | make                      | break | ||||
|  *     ----------+---------------------------+---------------------- | ||||
|  *     Other     | E0 12              <make> | <break>  E0 F0 12 | ||||
|  *     Shift'd   |                    <make> | <break> | ||||
|  * | ||||
|  *     Handling: ignore these prefix/postfix codes | ||||
|  * | ||||
|  * | ||||
|  * Keypad-/: | ||||
|  *     modifiers | make                      | break | ||||
|  *     ----------+---------------------------+---------------------- | ||||
|  *     Ohter     |                    <make> | <break> | ||||
|  *     LShift    | E0 F0 12           <make> | <break>  E0 12 | ||||
|  *     RShift    | E0 F0 59           <make> | <break>  E0 59 | ||||
|  *     L+RShift  | E0 F0 12  E0 F0 59 <make> | <break>  E0 59 E0 12 | ||||
|  * | ||||
|  *     Handling: ignore these prefix/postfix codes | ||||
|  * | ||||
|  * | ||||
|  * PrintScreen: | ||||
|  *     With hoding down modifiers, the scan code is sent as following: | ||||
|  * | ||||
|  *     modifiers | make         | break | ||||
|  *     ----------+--------------+----------------------------------- | ||||
|  *     Other     | E0 12  E0 7C | E0 F0 7C  E0 F0 12 | ||||
|  *     Shift'd   |        E0 7C | E0 F0 7C | ||||
|  *     Control'd |        E0 7C | E0 F0 7C | ||||
|  *     Alt'd     |           84 | F0 84 | ||||
|  * | ||||
|  *     Handling: ignore prefix/postfix codes and treat both scan code | ||||
|  *               E0 7C and 84 as PrintScreen. | ||||
|  * | ||||
|  * Pause: | ||||
|  *     With hoding down modifiers, the scan code is sent as following: | ||||
|  * | ||||
|  *     modifiers | make(no break code) | ||||
|  *     ----------+-------------------------------------------------- | ||||
|  *     no mods   | E1 14 77 E1 F0 14 F0 77 | ||||
|  *     Control'd | E0 7E E0 F0 7E | ||||
|  * | ||||
|  *     Handling: treat these two code sequence as Pause | ||||
|  * | ||||
|  */ | ||||
| uint8_t matrix_scan(void) | ||||
| { | ||||
| 
 | ||||
|     static enum { | ||||
|         INIT, | ||||
|         BREAK, | ||||
|         F0, | ||||
|         E0, | ||||
|         E0_F0, | ||||
|         // states for PrintScreen
 | ||||
|         E0_12, | ||||
|         E0_12_E0, | ||||
|         E0_F0_7C, | ||||
|         E0_F0_7C_E0, | ||||
|         E0_F0_7C_E0_F0, | ||||
|         // states for Pause/Break
 | ||||
|         E1, | ||||
|         E1_14, | ||||
| @ -125,15 +182,16 @@ uint8_t matrix_scan(void) | ||||
|     } state = INIT; | ||||
| 
 | ||||
| 
 | ||||
|     _matrix_is_modified = false; | ||||
|     is_modified = false; | ||||
| 
 | ||||
|     // Pause/Break off(PS/2 has no break for this key)
 | ||||
|     if (matrix_is_on(_ROW(_PAUSE_BREAK), _COL(_PAUSE_BREAK))) { | ||||
|         _matrix_break(_PAUSE_BREAK); | ||||
|     if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { | ||||
|         matrix_break(PAUSE); | ||||
|     } | ||||
| 
 | ||||
|     uint8_t code; | ||||
|     while ((code = ps2_host_recv())) { | ||||
| debug_hex(code); debug(" "); | ||||
|         switch (state) { | ||||
|             case INIT: | ||||
|                 switch (code) { | ||||
| @ -141,113 +199,88 @@ uint8_t matrix_scan(void) | ||||
|                         state = E0; | ||||
|                         break; | ||||
|                     case 0xF0:  // break code
 | ||||
|                         state = BREAK; | ||||
|                         state = F0; | ||||
|                         break; | ||||
|                     case 0xE1:  // Pause/Break
 | ||||
|                         state = E1; | ||||
|                         break; | ||||
|                     case 0x83:  // F8
 | ||||
|                         matrix_make(F8); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     case 0x84:  // PrintScreen
 | ||||
|                         matrix_make(PRINT_SCREEN); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     default:    // normal key make
 | ||||
|                         if (code < 0x80) { | ||||
|                             _matrix_make(code); | ||||
|                             matrix_make(code); | ||||
|                         } else { | ||||
|                             debug("ps/2 unknow code: "); debug_hex(code); debug("\n"); | ||||
|                             debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n"); | ||||
|                         } | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             case E0: | ||||
|                 switch (code) { | ||||
|                     case 0x12:  // PrintScreen(make)
 | ||||
|                         state = E0_12; | ||||
|                         break; | ||||
|                     case 0x7C:  // PrintScreen(typematic)
 | ||||
|                     case 0x12:  // postfix/postfix code for exceptional keys
 | ||||
|                     case 0x59:  // postfix/postfix code for exceptional keys
 | ||||
|                         // ignore
 | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     case 0x7E:  // former part of Control-Pause[E0 7E  E0 F0 7E]
 | ||||
|                         matrix_make(PAUSE); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     case 0xF0:  // E0 break
 | ||||
|                         state = E0_F0; | ||||
|                         break; | ||||
|                     default:    // E0 make
 | ||||
|                         if (code < 0x80) { | ||||
|                             _matrix_make(code|0x80); | ||||
|                             matrix_make(code|0x80); | ||||
|                         } else { | ||||
|                             debug("ps/2 unknow code: "); debug_hex(code); debug("\n"); | ||||
|                             debug("unexpected scan code at E0: "); debug_hex(code); debug("\n"); | ||||
|                         } | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             case BREAK: | ||||
|                 if (code < 0x80) { | ||||
|                     _matrix_break(code); | ||||
|                 } else { | ||||
|                     debug("ps/2 unknow code: "); debug_hex(code); debug("\n"); | ||||
|             case F0: | ||||
|                 switch (code) { | ||||
|                     case 0x83: | ||||
|                         matrix_break(F8); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     case 0x84: | ||||
|                         matrix_break(PRINT_SCREEN); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     default: | ||||
|                     if (code < 0x80) { | ||||
|                         matrix_break(code); | ||||
|                     } else { | ||||
|                         debug("unexpected scan code at F0: "); debug_hex(code); debug("\n"); | ||||
|                     } | ||||
|                     state = INIT; | ||||
|                 } | ||||
|                 state = INIT; | ||||
|                 break; | ||||
|             case E0_F0: // E0 break
 | ||||
|                 switch (code) { | ||||
|                     case 0x7C: | ||||
|                         state = E0_F0_7C; | ||||
|                     case 0x12:  // postfix/postfix code for exceptional keys
 | ||||
|                     case 0x59:  // postfix/postfix code for exceptional keys
 | ||||
|                     case 0x7E:  // latter part of Control-Pause[E0 7E  E0 F0 7E]
 | ||||
|                         // ignore
 | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     default: | ||||
|                         if (code < 0x80) { | ||||
|                             _matrix_break(code|0x80); | ||||
|                             matrix_break(code|0x80); | ||||
|                         } else { | ||||
|                             debug("ps/2 unknow code: "); debug_hex(code); debug("\n"); | ||||
|                             debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n"); | ||||
|                         } | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             /* PrintScreen(make) */ | ||||
|             case E0_12: | ||||
|                 switch (code) { | ||||
|                     case 0xE0: | ||||
|                         state = E0_12_E0; | ||||
|                         break; | ||||
|                     default: | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             case E0_12_E0: | ||||
|                 switch (code) { | ||||
|                     case 0x7C: | ||||
|                         _matrix_make(_PRINT_SCREEN); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     default: | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             /* PrintScreen(break) */ | ||||
|             case E0_F0_7C: | ||||
|                 switch (code) { | ||||
|                     case 0xE0: | ||||
|                         state = E0_F0_7C_E0; | ||||
|                         break; | ||||
|                     default: | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             case E0_F0_7C_E0: | ||||
|                 switch (code) { | ||||
|                     case 0xF0: | ||||
|                         state = E0_F0_7C_E0_F0; | ||||
|                         break; | ||||
|                     default: | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             case E0_F0_7C_E0_F0: | ||||
|                 switch (code) { | ||||
|                     case 0x12: | ||||
|                         _matrix_break(_PRINT_SCREEN); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     default: | ||||
|                         state = INIT; | ||||
|                 } | ||||
|                 break; | ||||
|             /* Pause/Break */ | ||||
|             /* Pause */ | ||||
|             case E1: | ||||
|                 switch (code) { | ||||
|                     case 0x14: | ||||
| @ -305,7 +338,7 @@ uint8_t matrix_scan(void) | ||||
|             case E1_14_77_E1_F0_14_F0: | ||||
|                 switch (code) { | ||||
|                     case 0x77: | ||||
|                         _matrix_make(_PAUSE_BREAK); | ||||
|                         matrix_make(PAUSE); | ||||
|                         state = INIT; | ||||
|                         break; | ||||
|                     default: | ||||
| @ -317,6 +350,7 @@ uint8_t matrix_scan(void) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // handle LED indicators
 | ||||
|     static uint8_t prev_leds = 0; | ||||
|     if (prev_leds != usb_keyboard_leds) { | ||||
|         uint8_t leds = 0; | ||||
| @ -327,7 +361,7 @@ uint8_t matrix_scan(void) | ||||
|         if (usb_keyboard_leds&(1<<USB_LED_CAPS_LOCK)) | ||||
|             leds |= (1<<PS2_LED_CAPS_LOCK); | ||||
| 
 | ||||
|         _ps2_set_leds(leds); | ||||
|         ps2_set_leds(leds); | ||||
|         prev_leds = usb_keyboard_leds; | ||||
|     } | ||||
| 
 | ||||
| @ -336,7 +370,7 @@ uint8_t matrix_scan(void) | ||||
| 
 | ||||
| bool matrix_is_modified(void) | ||||
| { | ||||
|     return _matrix_is_modified; | ||||
|     return is_modified; | ||||
| } | ||||
| 
 | ||||
| inline | ||||
| @ -422,24 +456,24 @@ static bool matrix_has_ghost_in_row(uint8_t row) | ||||
| 
 | ||||
| 
 | ||||
| inline | ||||
| static void _matrix_make(uint8_t code) | ||||
| static void matrix_make(uint8_t code) | ||||
| { | ||||
|     if (!matrix_is_on(_ROW(code), _COL(code))) { | ||||
|         matrix[_ROW(code)] |= 1<<_COL(code); | ||||
|         _matrix_is_modified = true; | ||||
|     if (!matrix_is_on(ROW(code), COL(code))) { | ||||
|         matrix[ROW(code)] |= 1<<COL(code); | ||||
|         is_modified = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline | ||||
| static void _matrix_break(uint8_t code) | ||||
| static void matrix_break(uint8_t code) | ||||
| { | ||||
|     if (matrix_is_on(_ROW(code), _COL(code))) { | ||||
|         matrix[_ROW(code)] &= ~(1<<_COL(code)); | ||||
|         _matrix_is_modified = true; | ||||
|     if (matrix_is_on(ROW(code), COL(code))) { | ||||
|         matrix[ROW(code)] &= ~(1<<COL(code)); | ||||
|         is_modified = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void _ps2_reset(void) | ||||
| static void ps2_reset(void) | ||||
| { | ||||
|     ps2_host_send(0xFF); | ||||
|     ps2_host_recv(); // 0xFA
 | ||||
| @ -447,7 +481,7 @@ static void _ps2_reset(void) | ||||
|     _delay_ms(1000); | ||||
| } | ||||
| 
 | ||||
| static void _ps2_set_leds(uint8_t leds) | ||||
| static void ps2_set_leds(uint8_t leds) | ||||
| { | ||||
|         ps2_host_send(0xED); | ||||
|         ps2_host_recv();        // 0xFA
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user