aboutsummaryrefslogtreecommitdiff
path: root/ps2_usb/matrix.c
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2011-12-05 02:53:15 +0900
committertmk <nobody@nowhere>2011-12-05 16:14:45 +0900
commit3f9de37310f670e6289738c628747e6787d42b22 (patch)
treeb4e7ab8df3cb59ba388cd60f7c8a698a4e9ce08e /ps2_usb/matrix.c
parent6284b147c23aa32a9e65138b1eb8ee908ece4941 (diff)
downloadqmk_firmware-3f9de37310f670e6289738c628747e6787d42b22.tar.gz
qmk_firmware-3f9de37310f670e6289738c628747e6787d42b22.zip
Added ISO/JIS keyboard support.
Diffstat (limited to 'ps2_usb/matrix.c')
-rw-r--r--ps2_usb/matrix.c184
1 files changed, 88 insertions, 96 deletions
diff --git a/ps2_usb/matrix.c b/ps2_usb/matrix.c
index 1aac3f866..4187ea060 100644
--- a/ps2_usb/matrix.c
+++ b/ps2_usb/matrix.c
@@ -15,9 +15,6 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18/*
19 * scan matrix
20 */
21#include <stdint.h> 18#include <stdint.h>
22#include <stdbool.h> 19#include <stdbool.h>
23#include <avr/io.h> 20#include <avr/io.h>
@@ -29,53 +26,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29#include "matrix.h" 26#include "matrix.h"
30 27
31 28
32#if (MATRIX_COLS > 16) 29static void matrix_make(uint8_t code);
33# error "MATRIX_COLS must not exceed 16" 30static void matrix_break(uint8_t code);
34#endif 31#ifdef MATRIX_HAS_GHOST
35#if (MATRIX_ROWS > 255) 32static bool matrix_has_ghost_in_row(uint8_t row);
36# error "MATRIX_ROWS must not exceed 255"
37#endif 33#endif
38 34
39 35
40/* 36/*
41 * Matrix usage: 37 * Matrix Array usage:
42 * "PS/2 Scan Codes Set 2" is assigned to 256(32x8)cells matrix. 38 * 'Scan Code Set 2' is assigned into 256(32x8)cell matrix.
43 * Hmm, It is very sparse and not efficient :( 39 * Hmm, it is very sparse and not efficient :(
40 *
41 * Notes:
42 * Both 'Hanguel/English'(F1) and 'Hanja'(F2) collide with 'Delete'(E0 71) and 'Down'(E0 72).
43 * These two Korean keys need exceptional handling and are not supported for now. Sorry.
44 * 44 *
45 * 8bit 45 * 8bit wide
46 * --------- 46 * +---------+
47 * 0| | 47 * 0| |
48 * :| XX | 00-7F for normal codes(without E0-prefix) 48 * :| XX | 00-7F for normal codes(without E0-prefix)
49 * f|_________| 49 * f|_________|
50 * 10| | 50 * 10| |
51 * :| E0 XX | 80-FF for E0-prefix codes(use (XX|0x80) as code) 51 * :| E0 YY | 80-FF for E0-prefixed codes
52 * 1f| | 52 * 1f| | (<YY>|0x80) is used as matrix position.
53 * --------- 53 * +---------+
54 * exceptions: 54 *
55 * 83: F8[0x83](normal codes but > 0x7F) 55 * Exceptions:
56 * FC: PrintScreen[E0 7C or 84] 56 * 0x83: F7(0x83) This is a normal code but beyond 0x7F.
57 * FE: Puause 57 * 0xFC: PrintScreen
58 * 0xFE: Pause
58 */ 59 */
59#define F8 (0x83) 60static uint8_t matrix[MATRIX_ROWS];
60#define PRINT_SCREEN (0xFC)
61#define PAUSE (0xFE)
62#define ROW(code) (code>>3) 61#define ROW(code) (code>>3)
63#define COL(code) (code&0x07) 62#define COL(code) (code&0x07)
64 63
65static bool is_modified = false; 64// matrix positions for exceptional keys
66 65#define F7 (0x83)
67// matrix state buffer(1:on, 0:off) 66#define PRINT_SCREEN (0xFC)
68#if (MATRIX_COLS <= 8) 67#define PAUSE (0xFE)
69static uint8_t matrix[MATRIX_ROWS];
70#else
71static uint16_t matrix[MATRIX_ROWS];
72#endif
73 68
74#ifdef MATRIX_HAS_GHOST 69static bool is_modified = false;
75static bool matrix_has_ghost_in_row(uint8_t row);
76#endif
77static void matrix_make(uint8_t code);
78static void matrix_break(uint8_t code);
79 70
80 71
81inline 72inline
@@ -107,13 +98,13 @@ void matrix_init(void)
107 * The scan code for these keys are varied or prefix/postfix'd 98 * The scan code for these keys are varied or prefix/postfix'd
108 * depending on modifier key state. 99 * depending on modifier key state.
109 * 100 *
110 * References: 101 * Keyboard Scan Code Specification:
111 * http://www.microsoft.com/whdc/archive/scancode.mspx 102 * http://www.microsoft.com/whdc/archive/scancode.mspx
112 * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc 103 * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
113 * 104 *
114 * 105 *
115 * Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left: 106 * 1) Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left
116 * Num Lock: off 107 * a) when Num Lock is off
117 * modifiers | make | break 108 * modifiers | make | break
118 * ----------+---------------------------+---------------------- 109 * ----------+---------------------------+----------------------
119 * Ohter | <make> | <break> 110 * Ohter | <make> | <break>
@@ -121,16 +112,16 @@ void matrix_init(void)
121 * RShift | E0 F0 59 <make> | <break> E0 59 112 * RShift | E0 F0 59 <make> | <break> E0 59
122 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 113 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
123 * 114 *
124 * Num Lock: on 115 * b) when Num Lock is on
125 * modifiers | make | break 116 * modifiers | make | break
126 * ----------+---------------------------+---------------------- 117 * ----------+---------------------------+----------------------
127 * Other | E0 12 <make> | <break> E0 F0 12 118 * Other | E0 12 <make> | <break> E0 F0 12
128 * Shift'd | <make> | <break> 119 * Shift'd | <make> | <break>
129 * 120 *
130 * Handling: ignore these prefix/postfix codes 121 * Handling: These prefix/postfix codes are ignored.
131 * 122 *
132 * 123 *
133 * Keypad-/: 124 * 2) Keypad /
134 * modifiers | make | break 125 * modifiers | make | break
135 * ----------+---------------------------+---------------------- 126 * ----------+---------------------------+----------------------
136 * Ohter | <make> | <break> 127 * Ohter | <make> | <break>
@@ -138,12 +129,10 @@ void matrix_init(void)
138 * RShift | E0 F0 59 <make> | <break> E0 59 129 * RShift | E0 F0 59 <make> | <break> E0 59
139 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 130 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
140 * 131 *
141 * Handling: ignore these prefix/postfix codes 132 * Handling: These prefix/postfix codes are ignored.
142 * 133 *
143 * 134 *
144 * PrintScreen: 135 * 3) PrintScreen
145 * With hoding down modifiers, the scan code is sent as following:
146 *
147 * modifiers | make | break 136 * modifiers | make | break
148 * ----------+--------------+----------------------------------- 137 * ----------+--------------+-----------------------------------
149 * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12 138 * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12
@@ -151,29 +140,30 @@ void matrix_init(void)
151 * Control'd | E0 7C | E0 F0 7C 140 * Control'd | E0 7C | E0 F0 7C
152 * Alt'd | 84 | F0 84 141 * Alt'd | 84 | F0 84
153 * 142 *
154 * Handling: ignore prefix/postfix codes and treat both scan code 143 * Handling: These prefix/postfix codes are ignored, and both scan codes
155 * E0 7C and 84 as PrintScreen. 144 * 'E0 7C' and 84 are seen as PrintScreen.
156 *
157 * Pause:
158 * With hoding down modifiers, the scan code is sent as following:
159 * 145 *
146 * 4) Pause
160 * modifiers | make(no break code) 147 * modifiers | make(no break code)
161 * ----------+-------------------------------------------------- 148 * ----------+--------------------------------------------------
162 * no mods | E1 14 77 E1 F0 14 F0 77 149 * Other | E1 14 77 E1 F0 14 F0 77
163 * Control'd | E0 7E E0 F0 7E 150 * Control'd | E0 7E E0 F0 7E
164 * 151 *
165 * Handling: treat these two code sequence as Pause 152 * Handling: Both code sequences are treated as a whole.
153 * And we need a ad hoc 'pseudo break code' hack to get the key off
154 * because it has no break code.
166 * 155 *
167 */ 156 */
168uint8_t matrix_scan(void) 157uint8_t matrix_scan(void)
169{ 158{
170 159
160 // scan code reading states
171 static enum { 161 static enum {
172 INIT, 162 INIT,
173 F0, 163 F0,
174 E0, 164 E0,
175 E0_F0, 165 E0_F0,
176 // states for Pause/Break 166 // Pause
177 E1, 167 E1,
178 E1_14, 168 E1_14,
179 E1_14_77, 169 E1_14_77,
@@ -181,12 +171,16 @@ uint8_t matrix_scan(void)
181 E1_14_77_E1_F0, 171 E1_14_77_E1_F0,
182 E1_14_77_E1_F0_14, 172 E1_14_77_E1_F0_14,
183 E1_14_77_E1_F0_14_F0, 173 E1_14_77_E1_F0_14_F0,
174 // Control'd Pause
175 E0_7E,
176 E0_7E_E0,
177 E0_7E_E0_F0,
184 } state = INIT; 178 } state = INIT;
185 179
186 180
187 is_modified = false; 181 is_modified = false;
188 182
189 // Pause/Break off(PS/2 has no break for this key) 183 // 'pseudo break code' hack
190 if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { 184 if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
191 matrix_break(PAUSE); 185 matrix_break(PAUSE);
192 } 186 }
@@ -196,20 +190,20 @@ uint8_t matrix_scan(void)
196 switch (state) { 190 switch (state) {
197 case INIT: 191 case INIT:
198 switch (code) { 192 switch (code) {
199 case 0xE0: // 2byte make 193 case 0xE0:
200 state = E0; 194 state = E0;
201 break; 195 break;
202 case 0xF0: // break code 196 case 0xF0:
203 state = F0; 197 state = F0;
204 break; 198 break;
205 case 0xE1: // Pause/Break 199 case 0xE1:
206 state = E1; 200 state = E1;
207 break; 201 break;
208 case 0x83: // F8 202 case 0x83: // F7
209 matrix_make(F8); 203 matrix_make(F7);
210 state = INIT; 204 state = INIT;
211 break; 205 break;
212 case 0x84: // PrintScreen 206 case 0x84: // Alt'd PrintScreen
213 matrix_make(PRINT_SCREEN); 207 matrix_make(PRINT_SCREEN);
214 state = INIT; 208 state = INIT;
215 break; 209 break;
@@ -222,21 +216,19 @@ uint8_t matrix_scan(void)
222 state = INIT; 216 state = INIT;
223 } 217 }
224 break; 218 break;
225 case E0: 219 case E0: // E0-Prefixed
226 switch (code) { 220 switch (code) {
227 case 0x12: // postfix/postfix code for exceptional keys 221 case 0x12: // to be ignored
228 case 0x59: // postfix/postfix code for exceptional keys 222 case 0x59: // to be ignored
229 // ignore
230 state = INIT; 223 state = INIT;
231 break; 224 break;
232 case 0x7E: // former part of Control-Pause[E0 7E E0 F0 7E] 225 case 0x7E: // Control'd Pause
233 matrix_make(PAUSE); 226 state = E0_7E;
234 state = INIT;
235 break; 227 break;
236 case 0xF0: // E0 break 228 case 0xF0:
237 state = E0_F0; 229 state = E0_F0;
238 break; 230 break;
239 default: // E0 make 231 default:
240 if (code < 0x80) { 232 if (code < 0x80) {
241 matrix_make(code|0x80); 233 matrix_make(code|0x80);
242 } else { 234 } else {
@@ -245,13 +237,13 @@ uint8_t matrix_scan(void)
245 state = INIT; 237 state = INIT;
246 } 238 }
247 break; 239 break;
248 case F0: 240 case F0: // Break code
249 switch (code) { 241 switch (code) {
250 case 0x83: 242 case 0x83: // F7
251 matrix_break(F8); 243 matrix_break(F7);
252 state = INIT; 244 state = INIT;
253 break; 245 break;
254 case 0x84: 246 case 0x84: // Alt'd PrintScreen
255 matrix_break(PRINT_SCREEN); 247 matrix_break(PRINT_SCREEN);
256 state = INIT; 248 state = INIT;
257 break; 249 break;
@@ -264,12 +256,10 @@ uint8_t matrix_scan(void)
264 state = INIT; 256 state = INIT;
265 } 257 }
266 break; 258 break;
267 case E0_F0: // E0 break 259 case E0_F0: // Break code of E0-prefixed
268 switch (code) { 260 switch (code) {
269 case 0x12: // postfix/postfix code for exceptional keys 261 case 0x12: // to be ignored
270 case 0x59: // postfix/postfix code for exceptional keys 262 case 0x59: // to be ignored
271 case 0x7E: // latter part of Control-Pause[E0 7E E0 F0 7E]
272 // ignore
273 state = INIT; 263 state = INIT;
274 break; 264 break;
275 default: 265 default:
@@ -281,7 +271,7 @@ uint8_t matrix_scan(void)
281 state = INIT; 271 state = INIT;
282 } 272 }
283 break; 273 break;
284 /* Pause */ 274 // following are states of Pause
285 case E1: 275 case E1:
286 switch (code) { 276 switch (code) {
287 case 0x14: 277 case 0x14:
@@ -346,6 +336,24 @@ uint8_t matrix_scan(void)
346 state = INIT; 336 state = INIT;
347 } 337 }
348 break; 338 break;
339 // Following are states of Control'd Pause
340 case E0_7E:
341 if (code == 0xE0)
342 state = E0_7E_E0;
343 else
344 state = INIT;
345 break;
346 case E0_7E_E0:
347 if (code == 0xF0)
348 state = E0_7E_E0_F0;
349 else
350 state = INIT;
351 break;
352 case E0_7E_E0_F0:
353 if (code == 0x7E)
354 matrix_make(PAUSE);
355 state = INIT;
356 break;
349 default: 357 default:
350 state = INIT; 358 state = INIT;
351 } 359 }
@@ -378,29 +386,17 @@ bool matrix_is_on(uint8_t row, uint8_t col)
378} 386}
379 387
380inline 388inline
381#if (MATRIX_COLS <= 8)
382uint8_t matrix_get_row(uint8_t row) 389uint8_t matrix_get_row(uint8_t row)
383#else
384uint16_t matrix_get_row(uint8_t row)
385#endif
386{ 390{
387 return matrix[row]; 391 return matrix[row];
388} 392}
389 393
390void matrix_print(void) 394void matrix_print(void)
391{ 395{
392#if (MATRIX_COLS <= 8)
393 print("\nr/c 01234567\n"); 396 print("\nr/c 01234567\n");
394#else
395 print("\nr/c 0123456789ABCDEF\n");
396#endif
397 for (uint8_t row = 0; row < matrix_rows(); row++) { 397 for (uint8_t row = 0; row < matrix_rows(); row++) {
398 phex(row); print(": "); 398 phex(row); print(": ");
399#if (MATRIX_COLS <= 8)
400 pbin_reverse(matrix_get_row(row)); 399 pbin_reverse(matrix_get_row(row));
401#else
402 pbin_reverse16(matrix_get_row(row));
403#endif
404#ifdef MATRIX_HAS_GHOST 400#ifdef MATRIX_HAS_GHOST
405 if (matrix_has_ghost_in_row(row)) { 401 if (matrix_has_ghost_in_row(row)) {
406 print(" <ghost"); 402 print(" <ghost");
@@ -414,11 +410,7 @@ uint8_t matrix_key_count(void)
414{ 410{
415 uint8_t count = 0; 411 uint8_t count = 0;
416 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 412 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
417#if (MATRIX_COLS <= 8)
418 count += bitpop(matrix[i]); 413 count += bitpop(matrix[i]);
419#else
420 count += bitpop16(matrix[i]);
421#endif
422 } 414 }
423 return count; 415 return count;
424} 416}