diff options
| author | tmk <nobody@nowhere> | 2011-01-25 00:53:49 +0900 | 
|---|---|---|
| committer | tmk <nobody@nowhere> | 2011-01-25 00:53:49 +0900 | 
| commit | 23c686ad46d325d054b83734cc8e89c4fb5e2572 (patch) | |
| tree | 6fd728d5d3be92746f0ddc60cfa8d5e8e701ceab | |
| parent | a28a2a6a5e74e0b6761ecdfdbfaaf56980429819 (diff) | |
Exceptional handling for PS/2 scan code set 2
changed names which does not comply to C spec.(underscore prefix names)
| -rw-r--r-- | ps2_usb/keymap.c | 6 | ||||
| -rw-r--r-- | ps2_usb/matrix.c | 260 | 
2 files changed, 150 insertions, 116 deletions
| diff --git a/ps2_usb/keymap.c b/ps2_usb/keymap.c index f38784d1f5..47db18bfa1 100644 --- a/ps2_usb/keymap.c +++ b/ps2_usb/keymap.c @@ -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      ),  }; diff --git a/ps2_usb/matrix.c b/ps2_usb/matrix.c index 366568d681..aaf89719ef 100644 --- a/ps2_usb/matrix.c +++ b/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); -                        } else { -                            debug("ps/2 unknow code: "); 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"); -                } -                state = INIT; -                break; -            case E0_F0: // E0 break -                switch (code) { -                    case 0x7C: -                        state = E0_F0_7C; -                        break; -                    default: -                        if (code < 0x80) { -                            _matrix_break(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; -            /* PrintScreen(make) */ -            case E0_12: +            case F0:                  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); +                    case 0x83: +                        matrix_break(F8);                          state = INIT;                          break; -                    default: +                    case 0x84: +                        matrix_break(PRINT_SCREEN);                          state = INIT; -                } -                break; -            /* PrintScreen(break) */ -            case E0_F0_7C: -                switch (code) { -                    case 0xE0: -                        state = E0_F0_7C_E0;                          break;                      default: -                        state = INIT; +                    if (code < 0x80) { +                        matrix_break(code); +                    } else { +                        debug("unexpected scan code at F0: "); debug_hex(code); debug("\n"); +                    } +                    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: +            case E0_F0: // E0 break                  switch (code) { -                    case 0x12: -                        _matrix_break(_PRINT_SCREEN); +                    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); +                        } else { +                            debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n"); +                        }                          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 | 
