qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

matrix.c (8250B)


      1 /*
      2 Copyright 2011 Jun Wako <wakojun@gmail.com>
      3 Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
      4 
      5 This program is free software: you can redistribute it and/or modify
      6 it under the terms of the GNU General Public License as published by
      7 the Free Software Foundation, either version 2 of the License, or
      8 (at your option) any later version.
      9 
     10 This program is distributed in the hope that it will be useful,
     11 but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 */
     18 
     19 #include <stdint.h>
     20 #include <stdbool.h>
     21 #include "action.h"
     22 #include "print.h"
     23 #include "util.h"
     24 #include "debug.h"
     25 #include "xt.h"
     26 #include "matrix.h"
     27 
     28 static void matrix_make(uint8_t code);
     29 static void matrix_break(uint8_t code);
     30 
     31 static uint8_t matrix[MATRIX_ROWS];
     32 
     33 #define ROW(code) (code >> 3)
     34 #define COL(code) (code & 0x07)
     35 
     36 __attribute__ ((weak))
     37 void matrix_init_kb(void) {
     38     matrix_init_user();
     39 }
     40 
     41 __attribute__ ((weak))
     42 void matrix_scan_kb(void) {
     43     matrix_scan_user();
     44 }
     45 
     46 __attribute__ ((weak))
     47 void matrix_init_user(void) {
     48 }
     49 
     50 __attribute__ ((weak))
     51 void matrix_scan_user(void) { }
     52 
     53 void matrix_init(void) {
     54     debug_enable = true;
     55     xt_host_init();
     56 
     57     // initialize matrix state: all keys off
     58     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
     59         matrix[i] = 0x00;
     60     }
     61 
     62     matrix_init_kb();
     63 }
     64 
     65 // convert E0-escaped codes into unused area
     66 static uint8_t move_e0code(uint8_t code) {
     67     switch(code) {
     68         // Original IBM XT keyboard has these keys
     69         case 0x37: return 0x54; // Print Screen
     70         case 0x46: return 0x55; // Ctrl + Pause
     71         case 0x1C: return 0x6F; // Keypad Enter
     72         case 0x35: return 0x7F; // Keypad /
     73 
     74         // Any XT keyboard with these keys?
     75         // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
     76         // https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
     77         case 0x5B: return 0x5A; // Left  GUI
     78         case 0x5C: return 0x5B; // Right GUI
     79         case 0x5D: return 0x5C; // Application
     80         case 0x5E: return 0x5D; // Power(not used)
     81         case 0x5F: return 0x5E; // Sleep(not used)
     82         case 0x63: return 0x5F; // Wake (not used)
     83         case 0x48: return 0x60; // Up
     84         case 0x4B: return 0x61; // Left
     85         case 0x50: return 0x62; // Down
     86         case 0x4D: return 0x63; // Right
     87         case 0x52: return 0x71; // Insert
     88         case 0x53: return 0x72; // Delete
     89         case 0x47: return 0x74; // Home
     90         case 0x4F: return 0x75; // End
     91         case 0x49: return 0x77; // Home
     92         case 0x51: return 0x78; // End
     93         case 0x1D: return 0x7A; // Right Ctrl
     94         case 0x38: return 0x7C; // Right Alt
     95     }
     96     return 0x00;
     97 }
     98 
     99 uint8_t matrix_scan(void) {
    100     static enum {
    101         XT_STATE_INIT,
    102         XT_STATE_E0,
    103         // Pause: E1 1D 45, E1 9D C5
    104         XT_STATE_E1,
    105         XT_STATE_E1_1D,
    106         XT_STATE_E1_9D,
    107     } state = XT_STATE_INIT;
    108 
    109     uint8_t code = xt_host_recv();
    110 
    111     if (!code) {
    112         return 0;
    113     }
    114 
    115     xprintf("%02X ", code);
    116 
    117     switch (state) {
    118         case XT_STATE_INIT:
    119             switch (code) {
    120                 case 0xE0:
    121                     state = XT_STATE_E0;
    122                     break;
    123                 case 0xE1:
    124                     state = XT_STATE_E1;
    125                     break;
    126                 default:
    127                     if (code < 0x80) {
    128                         matrix_make(code);
    129                     } else {
    130                         matrix_break(code & 0x7F);
    131                     }
    132                     break;
    133             }
    134             break;
    135         case XT_STATE_E0:
    136             switch (code) {
    137                 case 0x2A:
    138                 case 0xAA:
    139                 case 0x36:
    140                 case 0xB6:
    141                     //ignore fake shift
    142                     state = XT_STATE_INIT;
    143                     break;
    144                 default:
    145                     if (code < 0x80) {
    146                         matrix_make(move_e0code(code));
    147                     } else {
    148                         matrix_break(move_e0code(code & 0x7F));
    149                     }
    150                     state = XT_STATE_INIT;
    151                     break;
    152             }
    153             break;
    154         case XT_STATE_E1:
    155             switch (code) {
    156                 case 0x1D:
    157                     state = XT_STATE_E1_1D;
    158                     break;
    159                 case 0x9D:
    160                     state = XT_STATE_E1_9D;
    161                     break;
    162                 default:
    163                     state = XT_STATE_INIT;
    164                     break;
    165             }
    166             break;
    167         case XT_STATE_E1_1D:
    168             switch (code) {
    169                 case 0x45:
    170                     matrix_make(0x55);
    171                     break;
    172                 default:
    173                     state = XT_STATE_INIT;
    174                     break;
    175             }
    176             break;
    177         case XT_STATE_E1_9D:
    178             switch (code) {
    179                 case 0x45:
    180                     matrix_break(0x55);
    181                     break;
    182                 default:
    183                     state = XT_STATE_INIT;
    184                     break;
    185             }
    186             break;
    187         default:
    188             state = XT_STATE_INIT;
    189     }
    190 
    191     matrix_scan_kb();
    192 
    193     return 1;
    194 }
    195 
    196 inline
    197 uint8_t matrix_get_row(uint8_t row) {
    198     return matrix[row];
    199 }
    200 
    201 inline static void matrix_make(uint8_t code) {
    202     if (!matrix_is_on(ROW(code), COL(code))) {
    203         matrix[ROW(code)] |= 1 << COL(code);
    204     }
    205 }
    206 
    207 inline static void matrix_break(uint8_t code) {
    208     if (matrix_is_on(ROW(code), COL(code))) {
    209         matrix[ROW(code)] &= ~(1 << COL(code));
    210     }
    211 }
    212 
    213 void matrix_clear(void) {
    214     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
    215 }
    216 
    217 bool matrix_is_on(uint8_t row, uint8_t col) {
    218     return (matrix_get_row(row) & (1 << col));
    219 }
    220 
    221 #if (MATRIX_COLS <= 8)
    222 #    define print_matrix_header() print("\nr/c 01234567\n")
    223 #    define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
    224 #elif (MATRIX_COLS <= 16)
    225 #    define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
    226 #    define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
    227 #elif (MATRIX_COLS <= 32)
    228 #    define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
    229 #    define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
    230 #endif
    231 
    232 void matrix_print(void) {
    233     print_matrix_header();
    234 
    235     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
    236         print_hex8(row);
    237         print(": ");
    238         print_matrix_row(row);
    239         print("\n");
    240     }
    241 }
    242 
    243 /*
    244 XT Scancodes
    245 ============
    246 - http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
    247 - https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
    248 
    249 01-53: Normal codes used in original XT keyboard
    250 54-7F: Not used in original XT keyboard
    251 
    252 	0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    253     50  -   -   -   -   *   *   x   x   x   x   *   *   *   o   o   o
    254     60  *   *   *   *   x   x   x   x   x   x   x   x   x   x   x   *
    255     70  x   *   *   x   *   *   x   *   *   x   *   x   *   x   x   *
    256 
    257 -: codes existed in original XT keyboard
    258 *: E0-escaped codes converted into unused code area(internal use in TMK)
    259 x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
    260 o: reserved
    261 
    262 Usage in TMK:
    263 
    264     00  (reserved) DO NOT USE
    265     54  PrintScr*
    266     55  Pause*
    267     56  Euro2
    268     57  F11
    269     58  F12
    270     59  Keypad =
    271     5A  LGUI*
    272     5B  RGUI*
    273     5C  APP*
    274     5D  (reserved)
    275     5E  (reserved)
    276     5F  (reserved)
    277     60  cursor*
    278     61  cursor*
    279     62  cursor*
    280     63  cursor*
    281     64  F13
    282     65  F14
    283     66  F15
    284     67  F16
    285     68  F17
    286     69  F18
    287     6A  F19
    288     6B  F20
    289     6C  F21
    290     6D  F22
    291     6E  F23
    292     6F  Keypad Enter*
    293     70  KANA
    294     71  nav*
    295     72  nav*
    296     73  RO
    297     74  nav*
    298     75  nav*
    299     76  F24
    300     77  nav*
    301     78  nav*
    302     79  HENKAN
    303     7A  RCTL*
    304     7B  MUHENKAN
    305     7C  RALT*
    306     7D  JPY
    307     7E  Keypad ,
    308     7F  Keypad / *
    309 
    310 */