]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/converter/xt_usb/matrix.c
Usbasploader bootloader option addition (#6304)
[qmk_firmware.git] / keyboards / converter / xt_usb / matrix.c
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
29 static void matrix_make(uint8_t code);
30 static void matrix_break(uint8_t code);
31
32 static uint8_t matrix[MATRIX_ROWS];
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
54 void matrix_init(void)
55 {
56     debug_enable = true;
57     xt_host_init();
58
59     // initialize matrix state: all keys off
60     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
61
62     matrix_init_quantum();
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 keyobard 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 {
101     static enum {
102         INIT,
103         E0,
104         // Pause: E1 1D 45, E1 9D C5
105         E1,
106         E1_1D,
107         E1_9D,
108     } state = INIT;
109
110     uint8_t code = xt_host_recv();
111     if (!code) return 0;
112     xprintf("%02X ", code);
113     switch (state) {
114         case INIT:
115             switch (code) {
116                 case 0xE0:
117                     state = E0;
118                     break;
119                 case 0xE1:
120                     state = E1;
121                     break;
122                 default:
123                     if (code < 0x80)
124                         matrix_make(code);
125                     else
126                         matrix_break(code & 0x7F);
127                     break;
128             }
129             break;
130         case E0:
131             switch (code) {
132                 case 0x2A:
133                 case 0xAA:
134                 case 0x36:
135                 case 0xB6:
136                     //ignore fake shift
137                     state = INIT;
138                     break;
139                 default:
140                     if (code < 0x80)
141                         matrix_make(move_e0code(code));
142                     else
143                         matrix_break(move_e0code(code & 0x7F));
144                     state = INIT;
145                     break;
146             }
147             break;
148         case E1:
149             switch (code) {
150                 case 0x1D:
151                     state = E1_1D;
152                     break;
153                 case 0x9D:
154                     state = E1_9D;
155                     break;
156                 default:
157                     state = INIT;
158                     break;
159             }
160             break;
161         case E1_1D:
162             switch (code) {
163                 case 0x45:
164                     matrix_make(0x55);
165                     break;
166                 default:
167                     state = INIT;
168                     break;
169             }
170             break;
171         case E1_9D:
172             switch (code) {
173                 case 0x45:
174                     matrix_break(0x55);
175                     break;
176                 default:
177                     state = INIT;
178                     break;
179             }
180             break;
181         default:
182             state = INIT;
183     }
184     matrix_scan_quantum();
185     return 1;
186 }
187
188 inline
189 uint8_t matrix_get_row(uint8_t row)
190 {
191     return matrix[row];
192 }
193
194 inline
195 static void matrix_make(uint8_t code)
196 {
197     if (!matrix_is_on(ROW(code), COL(code))) {
198         matrix[ROW(code)] |= 1<<COL(code);
199     }
200 }
201
202 inline
203 static void matrix_break(uint8_t code)
204 {
205     if (matrix_is_on(ROW(code), COL(code))) {
206         matrix[ROW(code)] &= ~(1<<COL(code));
207     }
208 }
209
210 void matrix_clear(void)
211 {
212     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
213 }
214
215 bool matrix_is_on(uint8_t row, uint8_t col)
216 {
217     return (matrix_get_row(row) & (1<<col));
218 }
219
220 #if (MATRIX_COLS <= 8)
221 #    define print_matrix_header()  print("\nr/c 01234567\n")
222 #    define print_matrix_row(row)  print_bin_reverse8(matrix_get_row(row))
223 #elif (MATRIX_COLS <= 16)
224 #    define print_matrix_header()  print("\nr/c 0123456789ABCDEF\n")
225 #    define print_matrix_row(row)  print_bin_reverse16(matrix_get_row(row))
226 #elif (MATRIX_COLS <= 32)
227 #    define print_matrix_header()  print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
228 #    define print_matrix_row(row)  print_bin_reverse32(matrix_get_row(row))
229 #endif
230
231 void matrix_print(void)
232 {
233     print_matrix_header();
234
235     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
236         phex(row); print(": ");
237         print_matrix_row(row);
238         print("\n");
239     }
240 }
241
242 /*
243 XT Scancodes
244 ============
245 - http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
246 - https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
247
248 01-53: Normal codes used in original XT keyboard
249 54-7F: Not used in original XT keyboard
250
251         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
252     50  -   -   -   -   *   *   x   x   x   x   *   *   *   o   o   o
253     60  *   *   *   *   x   x   x   x   x   x   x   x   x   x   x   *
254     70  x   *   *   x   *   *   x   *   *   x   *   x   *   x   x   *
255
256 -: codes existed in original XT keyboard
257 *: E0-escaped codes converted into unused code area(internal use in TMK)
258 x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
259 o: reserved
260
261 Usage in TMK:
262
263     00  (reserved) DO NOT USE
264     54  PrintScr*
265     55  Pause*
266     56  Euro2
267     57  F11
268     58  F12
269     59  Keypad =
270     5A  LGUI*
271     5B  RGUI*
272     5C  APP*
273     5D  (reserved)
274     5E  (reserved)
275     5F  (reserved)
276     60  cursor*
277     61  cursor*
278     62  cursor*
279     63  cursor*
280     64  F13
281     65  F14
282     66  F15
283     67  F16
284     68  F17
285     69  F18
286     6A  F19
287     6B  F20
288     6C  F21
289     6D  F22
290     6E  F23
291     6F  Keypad Enter*
292     70  KANA
293     71  nav*
294     72  nav*
295     73  RO
296     74  nav*
297     75  nav*
298     76  F24
299     77  nav*
300     78  nav*
301     79  HENKAN
302     7A  RCTL*
303     7B  MUHENKAN
304     7C  RALT*
305     7D  JPY
306     7E  Keypad ,
307     7F  Keypad / *
308
309 */