]> git.gir.st - tmk_keyboard.git/blob - converter/xt_usb/matrix.c
Merge commit '22b6e15a179031afb7c3534cf7b109b0668b602c'
[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 switch (state) {
124 case INIT:
125 switch (code) {
126 case 0xE0:
127 state = E0;
128 break;
129 case 0xE1:
130 state = E1;
131 break;
132 default: // normal key make
133 if (code < 0x80 && code != 0x00) {
134 xprintf("make: %X\r\n", code);
135 matrix_make(code);
136 } else if (code > 0x80 && code < 0xFF && code != 0x00) {
137 xprintf("break %X\r\n", code);
138 matrix_break(code - 0x80);
139 }
140 state = INIT;
141 }
142 break;
143 case E0: // E0-Prefixed
144 switch (code) { //move these codes to unused places on the matrix
145 case 0x2A:
146 state = E0_2A;
147 break;
148 case 0xB7:
149 state = E0_B7;
150 break;
151 default:
152 if (code < 0x80 && code != 0x00) {
153 matrix_make(move_codes(code));
154 } else if (code > 0x80 && code < 0xFF && code != 0x00) {
155 matrix_break(move_codes(code - 0x80));
156 }
157 state = INIT;
158 }
159 break;
160 case E0_2A:
161 if(code == 0xE0)
162 state = E0_2A_E0;
163 else
164 state = INIT;
165 break;
166 case E0_2A_E0:
167 if(code == 0x37)
168 matrix_make(PRINT_SCREEN);
169 else
170 state = INIT;
171 break;
172 case E0_B7:
173 if(code == 0xE0)
174 state = E0_B7;
175 else
176 state = INIT;
177 break;
178 case E0_B7_E0:
179 if(code == 0xAA)
180 matrix_break(PRINT_SCREEN);
181 else
182 state = INIT;
183 break;
184 case E1:
185 if (code == 0x1D)
186 state = E1_1D;
187 else
188 state = INIT;
189 break;
190 case E1_1D:
191 if(code == 0x45)
192 state = E1_1D_45;
193 else
194 state = INIT;
195 break;
196 case E1_1D_45:
197 if(code == 0xE1)
198 state = E1_1D_45_E1;
199 else
200 state = INIT;
201 break;
202 case E1_1D_45_E1:
203 if(code == 0x9D)
204 state = E1_1D_45_E1_9D;
205 else
206 state = INIT;
207 break;
208 case E1_1D_45_E1_9D:
209 if(code == 0xC5)
210 matrix_make(PAUSE);
211 else
212 state = INIT;
213 break;
214 default:
215 state = INIT;
216 }
217 return 1;
218 }
219
220 inline
221 uint8_t matrix_get_row(uint8_t row)
222 {
223 return matrix[row];
224 }
225
226 inline
227 static void matrix_make(uint8_t code)
228 {
229 if (!matrix_is_on(ROW(code), COL(code))) {
230 matrix[ROW(code)] |= 1<<COL(code);
231 }
232 }
233
234 inline
235 static void matrix_break(uint8_t code)
236 {
237 if (matrix_is_on(ROW(code), COL(code))) {
238 matrix[ROW(code)] &= ~(1<<COL(code));
239 }
240 }
241
242 void matrix_clear(void)
243 {
244 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
245 }
Imprint / Impressum