]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/xt_usb/matrix.c
xt_usb: Change debug print
[max/tmk_keyboard.git] / 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 // matrix positions for exceptional keys
37 #define PRINT_SCREEN   (0x7C)
38 #define PAUSE          (0x7D)
39
40
41 void matrix_init(void)
42 {
43     debug_enable = true;
44     xt_host_init();
45
46     // initialize matrix state: all keys off
47     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
48
49     return;
50 }
51
52 static uint8_t move_codes(uint8_t code) {
53     switch(code) {
54         case 0x10:
55             code += 0x5E;
56             break;
57         case 0x19:
58             code += 0x41;
59             break;
60         case 0x1C:
61         case 0x1D:
62             code += 0x38;
63             break;
64         case 0x20:
65         case 0x21:
66         case 0x22:
67         case 0x24:
68             code += 0x40;
69             break;
70         case 0x2E:
71         case 0x30:
72         case 0x32:
73             code += 0x44;
74             break;
75         case 0x35:
76         case 0x38:
77             code += 0x21;
78             break;
79         case 0x47:
80         case 0x48:
81         case 0x49:
82         case 0x4B:
83         case 0x4D:
84         case 0x4F:
85         case 0x50:
86         case 0x51:
87         case 0x52:
88         case 0x53:
89             code += 0x28;
90             break;
91     }
92     return code;
93 }
94
95 uint8_t matrix_scan(void)
96 {
97
98     // scan code reading states
99     static enum {
100         INIT,
101         E0,
102         E0_2A,
103         E0_2A_E0,
104         E0_B7,
105         E0_B7_E0,
106
107         // print screen
108         E1,
109         E1_1D,
110         E1_1D_45,
111         E1_1D_45_E1,
112         E1_1D_45_E1_9D,
113         // pause
114     } state = INIT;
115
116
117     // 'pseudo break code' hack
118     if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
119         matrix_break(PAUSE);
120     }
121
122     uint8_t code = xt_host_recv();
123     if (code) xprintf("%02X ", code);
124     switch (state) {
125         case INIT:
126             switch (code) {
127                 case 0xE0:
128                     state = E0;
129                     break;
130                 case 0xE1:
131                     state = E1;
132                     break;
133                 default:    // normal key make
134                     if (code < 0x80 && code != 0x00) {
135                         matrix_make(code);
136                     } else if (code > 0x80 && code < 0xFF && code != 0x00) {
137                         matrix_break(code - 0x80);
138                     }
139                     state = INIT;
140             }
141             break;
142         case E0:    // E0-Prefixed
143             switch (code) { //move these codes to unused places on the matrix
144                 case 0x2A:
145                     state = E0_2A;
146                     break;
147                 case 0xB7:
148                     state = E0_B7;
149                     break;
150                 default:
151                     if (code < 0x80 && code != 0x00) {
152                         matrix_make(move_codes(code));
153                     } else if (code > 0x80 && code < 0xFF && code != 0x00) {
154                         matrix_break(move_codes(code - 0x80));
155                     }
156                     state = INIT;
157             }
158             break;
159         case E0_2A:
160             if(code == 0xE0)
161                 state = E0_2A_E0;
162             else
163                 state = INIT;
164             break;
165         case E0_2A_E0:
166             if(code == 0x37)
167                 matrix_make(PRINT_SCREEN);
168             else
169                 state = INIT;
170             break;
171         case E0_B7:
172             if(code == 0xE0)
173                 state = E0_B7;
174             else
175                 state = INIT;
176             break;
177         case E0_B7_E0:
178           if(code == 0xAA)
179               matrix_break(PRINT_SCREEN);
180           else
181               state = INIT;
182           break;
183         case E1:
184             if (code == 0x1D)
185                 state = E1_1D;
186             else
187                 state = INIT;
188             break;
189         case E1_1D:
190             if(code == 0x45)
191                 state = E1_1D_45;
192             else
193                 state = INIT;
194             break;
195         case E1_1D_45:
196             if(code == 0xE1)
197                 state = E1_1D_45_E1;
198             else
199                 state = INIT;
200             break;
201         case E1_1D_45_E1:
202             if(code == 0x9D)
203                 state = E1_1D_45_E1_9D;
204             else
205                 state = INIT;
206             break;
207         case E1_1D_45_E1_9D:
208             if(code == 0xC5)
209                 matrix_make(PAUSE);
210             else
211                 state = INIT;
212             break;
213         default:
214             state = INIT;
215     }
216     return 1;
217 }
218
219 inline
220 uint8_t matrix_get_row(uint8_t row)
221 {
222     return matrix[row];
223 }
224
225 inline
226 static void matrix_make(uint8_t code)
227 {
228     if (!matrix_is_on(ROW(code), COL(code))) {
229         matrix[ROW(code)] |= 1<<COL(code);
230     }
231 }
232
233 inline
234 static void matrix_break(uint8_t code)
235 {
236     if (matrix_is_on(ROW(code), COL(code))) {
237         matrix[ROW(code)] &= ~(1<<COL(code));
238     }
239 }
240
241 void matrix_clear(void)
242 {
243     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
244 }