-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathhost_teensy_kbd_charmap.h
497 lines (459 loc) · 15.7 KB
/
host_teensy_kbd_charmap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
/*
* This file is part of uLibx.
*
* Copyright (C) 2018 D.Herrendoerfer
*
* uLibx is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* uLibx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with uLibx. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define PS2_TAB 9
#define PS2_ENTER 13
#define PS2_LINEFEED 10
#define PS2_BACKSPACE 8
#define PS2_ESC 27
#define PS2_INSERT 128
#define PS2_DELETE 127
#define PS2_HOME 129
#define PS2_END 156
#define PS2_PAGEUP 25
#define PS2_PAGEDOWN 26
#define PS2_UPARROW 11
#define PS2_LEFTARROW 8
#define PS2_DOWNARROW 12
#define PS2_RIGHTARROW 21
#define PS2_F1 130
#define PS2_F2 131
#define PS2_F3 132
#define PS2_F4 133
#define PS2_F5 134
#define PS2_F6 135
#define PS2_F7 136
#define PS2_F8 137
#define PS2_F9 138
#define PS2_F10 139
#define PS2_F11 140
#define PS2_F12 141
#define PS2_SCROLL 142
#define PS2_TAB_SHIFT 9
#define PS2_ENTER_SHIFT 13
#define PS2_BACKSPACE_SHIFT 157
#define PS2_F1_SHIFT 143
#define PS2_F2_SHIFT 144
#define PS2_F3_SHIFT 145
#define PS2_F4_SHIFT 146
#define PS2_F5_SHIFT 147
#define PS2_F6_SHIFT 148
#define PS2_F7_SHIFT 149
#define PS2_F8_SHIFT 150
#define PS2_F9_SHIFT 151
#define PS2_F10_SHIFT 152
#define PS2_F11_SHIFT 153
#define PS2_F12_SHIFT 154
#define PS2_INVERTED_EXCLAMATION 161 // ¡
#define PS2_CENT_SIGN 162 // ¢
#define PS2_POUND_SIGN 163 // £
#define PS2_CURRENCY_SIGN 164 // ¤
#define PS2_YEN_SIGN 165 // ¥
#define PS2_BROKEN_BAR 166 // ¦
#define PS2_SECTION_SIGN 167 // §
#define PS2_DIAERESIS 168 // ¨
#define PS2_COPYRIGHT_SIGN 169 // ©
#define PS2_FEMININE_ORDINAL 170 // ª
#define PS2_LEFT_DOUBLE_ANGLE_QUOTE 171 // «
#define PS2_NOT_SIGN 172 // ¬
#define PS2_HYPHEN 173
#define PS2_REGISTERED_SIGN 174 // ®
#define PS2_MACRON 175 // ¯
#define PS2_DEGREE_SIGN 176 // °
#define PS2_PLUS_MINUS_SIGN 177 // ±
#define PS2_SUPERSCRIPT_TWO 178 // ²
#define PS2_SUPERSCRIPT_THREE 179 // ³
#define PS2_ACUTE_ACCENT 180 // ´
#define PS2_MICRO_SIGN 181 // µ
#define PS2_PILCROW_SIGN 182 // ¶
#define PS2_MIDDLE_DOT 183 // ·
#define PS2_CEDILLA 184 // ¸
#define PS2_SUPERSCRIPT_ONE 185 // ¹
#define PS2_MASCULINE_ORDINAL 186 // º
#define PS2_RIGHT_DOUBLE_ANGLE_QUOTE 187 // »
#define PS2_FRACTION_ONE_QUARTER 188 // ¼
#define PS2_FRACTION_ONE_HALF 189 // ½
#define PS2_FRACTION_THREE_QUARTERS 190 // ¾
#define PS2_INVERTED_QUESTION MARK 191 // ¿
#define PS2_A_GRAVE 192 // À
#define PS2_A_ACUTE 193 // Á
#define PS2_A_CIRCUMFLEX 194 // Â
#define PS2_A_TILDE 195 // Ã
#define PS2_A_DIAERESIS 196 // Ä
#define PS2_A_RING_ABOVE 197 // Å
#define PS2_AE 198 // Æ
#define PS2_C_CEDILLA 199 // Ç
#define PS2_E_GRAVE 200 // È
#define PS2_E_ACUTE 201 // É
#define PS2_E_CIRCUMFLEX 202 // Ê
#define PS2_E_DIAERESIS 203 // Ë
#define PS2_I_GRAVE 204 // Ì
#define PS2_I_ACUTE 205 // Í
#define PS2_I_CIRCUMFLEX 206 // Î
#define PS2_I_DIAERESIS 207 // Ï
#define PS2_ETH 208 // Ð
#define PS2_N_TILDE 209 // Ñ
#define PS2_O_GRAVE 210 // Ò
#define PS2_O_ACUTE 211 // Ó
#define PS2_O_CIRCUMFLEX 212 // Ô
#define PS2_O_TILDE 213 // Õ
#define PS2_O_DIAERESIS 214 // Ö
#define PS2_MULTIPLICATION 215 // ×
#define PS2_O_STROKE 216 // Ø
#define PS2_U_GRAVE 217 // Ù
#define PS2_U_ACUTE 218 // Ú
#define PS2_U_CIRCUMFLEX 219 // Û
#define PS2_U_DIAERESIS 220 // Ü
#define PS2_Y_ACUTE 221 // Ý
#define PS2_THORN 222 // Þ
#define PS2_SHARP_S 223 // ß
#define PS2_a_GRAVE 224 // à
#define PS2_a_ACUTE 225 // á
#define PS2_a_CIRCUMFLEX 226 // â
#define PS2_a_TILDE 227 // ã
#define PS2_a_DIAERESIS 228 // ä
#define PS2_a_RING_ABOVE 229 // å
#define PS2_ae 230 // æ
#define PS2_c_CEDILLA 231 // ç
#define PS2_e_GRAVE 232 // è
#define PS2_e_ACUTE 233 // é
#define PS2_e_CIRCUMFLEX 234 // ê
#define PS2_e_DIAERESIS 235 // ë
#define PS2_i_GRAVE 236 // ì
#define PS2_i_ACUTE 237 // í
#define PS2_i_CIRCUMFLEX 238 // î
#define PS2_i_DIAERESIS 239 // ï
#define PS2_eth 240 // ð
#define PS2_n_TILDE 241 // ñ
#define PS2_o_GRAVE 242 // ò
#define PS2_o_ACUTE 243 // ó
#define PS2_o_CIRCUMFLEX 244 // ô
#define PS2_o_TILDE 245 // õ
#define PS2_o_DIAERESIS 246 // ö
#define PS2_DIVISION 247 // ÷
#define PS2_o_STROKE 248 // ø
#define PS2_u_GRAVE 249 // ù
#define PS2_u_ACUTE 250 // ú
#define PS2_u_CIRCUMFLEX 251 // û
#define PS2_u_DIAERESIS 252 // ü
#define PS2_y_ACUTE 253 // ý
#define PS2_thorn 254 // þ
#define PS2_y_DIAERESIS 255 // ÿ
#define PS2_KEYMAP_SIZE 136
typedef struct {
uint8_t noshift[PS2_KEYMAP_SIZE];
uint8_t shift[PS2_KEYMAP_SIZE];
uint8_t uses_altgr;
uint8_t altgr[PS2_KEYMAP_SIZE];
} uKbdC_PS2Keymap_t;
static const uKbdC_PS2Keymap_t *keymap=NULL;
// Controls for a single scancode
#define SHIFT 0x01
#define ALT 0x02
#define ALTGR 0x04
#define CTRL 0x08
#define WIN 0x10
// Semi-permanent modifiers
#define SHIFTLOCK 0x01
#define NUM 0x02
static uint8_t uKbdC_state_controls = 0;
static uint8_t uKbdC_mod_controls = 0;
static uint8_t uKbdC_do_break = 0;
static uint8_t uKbdC_do_modify = 0;
static uint8_t uKbdC_buffer[16];
static uint8_t uKbdC_ptr_floor = 0;
static uint8_t uKbdC_ptr_ceil = 0;
// These arrays provide a simple key map, to turn scan codes into ISO8859
// output. If a non-US keyboard is used, these may need to be modified
// for the desired output.
//
static const uKbdC_PS2Keymap_t PS2Keymap_US = {
// without shift
{0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '`', 0,
0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
0, 0, 'z', 's', 'a', 'w', '2', 0,
0, 'c', 'x', 'd', 'e', '4', '3', 0,
0, ' ', 'v', 'f', 't', 'r', '5', 0,
0, 'n', 'b', 'h', 'g', 'y', '6', 0,
0, 0, 'm', 'j', 'u', '7', '8', 0,
0, ',', 'k', 'i', 'o', '0', '9', 0,
0, '.', '/', 'l', ';', 'p', '-', 0,
0, 0, '\'', 0, '[', '=', 0, 0,
0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, ']', 0, '\\', 0, 0,
0, 0, 0, 0, 0, 0, PS2_BACKSPACE, 0,
0, '1', 0, '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
0, 0, 0, PS2_F7 },
// with shift
{0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '~', 0,
0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
0, 0, 'Z', 'S', 'A', 'W', '@', 0,
0, 'C', 'X', 'D', 'E', '$', '#', 0,
0, ' ', 'V', 'F', 'T', 'R', '%', 0,
0, 'N', 'B', 'H', 'G', 'Y', '^', 0,
0, 0, 'M', 'J', 'U', '&', '*', 0,
0, '<', 'K', 'I', 'O', ')', '(', 0,
0, '>', '?', 'L', ':', 'P', '_', 0,
0, 0, '"', 0, '{', '+', 0, 0,
0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '}', 0, '|', 0, 0,
0, 0, 0, 0, 0, 0, PS2_BACKSPACE, 0,
0, '1', 0, '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
0, 0, 0, PS2_F7 },
0
};
static const uKbdC_PS2Keymap_t PS2Keymap_German = {
// without shift
{0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '^', 0,
0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
0, 0, 'y', 's', 'a', 'w', '2', 0,
0, 'c', 'x', 'd', 'e', '4', '3', 0,
0, ' ', 'v', 'f', 't', 'r', '5', 0,
0, 'n', 'b', 'h', 'g', 'z', '6', 0,
0, 0, 'm', 'j', 'u', '7', '8', 0,
0, ',', 'k', 'i', 'o', '0', '9', 0,
0, '.', '-', 'l', PS2_o_DIAERESIS, 'p', PS2_SHARP_S, 0,
0, 0, PS2_a_DIAERESIS, 0, PS2_u_DIAERESIS, '\'', 0, 0,
0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '+', 0, '#', 0, 0,
0, '<', 0, 0, 0, 0, PS2_BACKSPACE, 0,
0, '1', 0, '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
0, 0, 0, PS2_F7 },
// with shift
{0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, PS2_DEGREE_SIGN, 0,
0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
0, 0, 'Y', 'S', 'A', 'W', '"', 0,
0, 'C', 'X', 'D', 'E', '$', PS2_SECTION_SIGN, 0,
0, ' ', 'V', 'F', 'T', 'R', '%', 0,
0, 'N', 'B', 'H', 'G', 'Z', '&', 0,
0, 0, 'M', 'J', 'U', '/', '(', 0,
0, ';', 'K', 'I', 'O', '=', ')', 0,
0, ':', '_', 'L', PS2_O_DIAERESIS, 'P', '?', 0,
0, 0, PS2_A_DIAERESIS, 0, PS2_U_DIAERESIS, '`', 0, 0,
0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '*', 0, '\'', 0, 0,
0, '>', 0, 0, 0, 0, PS2_BACKSPACE, 0,
0, '1', 0, '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
0, 0, 0, PS2_F7 },
1,
// with altgr
{0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, 0, 0,
0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, '@', 0, 0,
0, 0, 0, 0, 0, 0, PS2_SUPERSCRIPT_TWO, 0,
0, 0, 0, 0, PS2_CURRENCY_SIGN, 0, PS2_SUPERSCRIPT_THREE, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, PS2_MICRO_SIGN, 0, 0, '{', '[', 0,
0, 0, 0, 0, 0, '}', ']', 0,
0, 0, 0, 0, 0, 0, '\\', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '~', 0, '#', 0, 0,
0, '|', 0, 0, 0, 0, PS2_BACKSPACE, 0,
0, '1', 0, '4', '7', 0, 0, 0,
'0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
0, 0, 0, PS2_F7 }
};
static inline int8_t uKbdC_num_mod(uint8_t code)
{
switch (code) {
case 0x4A: return('/'); break;
case 0x5A: return(PS2_ENTER); break;
case 0x69: return(PS2_END); break;
case 0x6B: return(PS2_LEFTARROW); break;
case 0x6C: return(PS2_HOME); break;
case 0x70: return(PS2_INSERT); break;
case 0x71: return(PS2_DELETE); break;
case 0x72: return(PS2_DOWNARROW); break;
case 0x74: return(PS2_RIGHTARROW); break;
case 0x75: return(PS2_UPARROW); break;
case 0x7A: return(PS2_PAGEDOWN); break;
case 0x7D: return(PS2_PAGEUP); break;
}
return(0);
}
static inline uint8_t uKbdC_ctrl_mod(uint8_t key)
{
if (key >= 'A' && key <= 'Z')
return(key - 'A' + 1);
else if (key >= 'a' && key <= 'z')
return(key - 'a' + 1);
else if (key == PS2_ENTER)
return(PS2_LINEFEED);
return key;
}
static inline uint8_t uKbdC_state_set(uint8_t code)
{
switch (code) {
case 0x12: uKbdC_state_controls |= SHIFT; return 1; break;
case 0x59: uKbdC_state_controls |= SHIFT; return 1; break;
case 0x11: uKbdC_state_controls |= ALT; return 1; break;
case 0x14: uKbdC_state_controls |= CTRL; return 1; break;
}
return 0;
}
static inline uint8_t uKbdC_mstate_set(uint8_t code)
{
switch (code) {
case 0x11: uKbdC_state_controls |= ALTGR; return 1; break;
case 0x1F: uKbdC_state_controls |= WIN; return 1; break;
}
return 0;
}
static inline uint8_t uKbdC_state_reset(uint8_t code)
{
switch (code) {
case 0x12: uKbdC_state_controls &= ~SHIFT; return 1; break;
case 0x59: uKbdC_state_controls &= ~SHIFT; return 1; break;
case 0x11: uKbdC_state_controls &= ~ALT; return 1; break;
case 0x14: uKbdC_state_controls &= ~CTRL; return 1; break;
}
return 0;
}
static inline uint8_t uKbdC_mstate_reset(uint8_t code)
{
switch (code) {
case 0x11: uKbdC_state_controls &= ~ALTGR; return 1; break;
case 0x1F: uKbdC_state_controls &= ~WIN; return 1; break;
}
return 0;
}
static inline uint8_t uKbdC_mod_set(uint8_t code)
{
switch (code) {
case 0x58:
if (uKbdC_mod_controls & SHIFTLOCK)
uKbdC_mod_controls &= ~SHIFTLOCK;
else
uKbdC_mod_controls |= SHIFTLOCK;
return 1;
break;
case 0x77:
if (uKbdC_mod_controls & NUM)
uKbdC_mod_controls &= ~NUM;
else
uKbdC_mod_controls |= NUM;
return 1;
break;
}
return 0;
}
static uint8_t uKbdC_process_code(uint8_t code, const uKbdC_PS2Keymap_t &map = PS2Keymap_US)
{
uint8_t key = 0;
keymap = ↦
if(code == 0xF0) {
//BREAK
uKbdC_do_break = 1;
return(0);
}
if(code == 0xE0) {
//MODIFY
uKbdC_do_modify = 1;
return(0);
}
if (uKbdC_do_break == 0) {
//MAKE CODES
if (uKbdC_do_modify) {
uKbdC_do_modify = 0;
if (uKbdC_mstate_reset(code))
return(0);
}
else {
if (uKbdC_state_set(code))
return(0);
}
if (uKbdC_mod_set(code))
return(0);
//Lets make keys from codes
if (uKbdC_mod_controls & NUM) {
key = uKbdC_num_mod(code);
if (key) {
uKbdC_buffer[uKbdC_ptr_ceil++] = key;
uKbdC_ptr_ceil = uKbdC_ptr_ceil & 0xF;
return(1);
}
}
if ((uKbdC_state_controls & ALTGR) && keymap->uses_altgr) {
if (code < PS2_KEYMAP_SIZE)
key = pgm_read_byte(keymap->altgr + code);
}
else if (uKbdC_state_controls & SHIFT || uKbdC_mod_controls & SHIFTLOCK) {
if (code < PS2_KEYMAP_SIZE)
key = pgm_read_byte(keymap->shift + code);
}
else {
if (code < PS2_KEYMAP_SIZE)
key = pgm_read_byte(keymap->noshift + code);
}
if (uKbdC_state_controls & CTRL) {
key = uKbdC_ctrl_mod(key);
}
if (key) {
uKbdC_buffer[uKbdC_ptr_ceil++] = key;
uKbdC_ptr_ceil = uKbdC_ptr_ceil & 0xF;
return(1);
}
}
else {
uKbdC_do_break = 0;
if (uKbdC_do_modify) {
uKbdC_do_modify = 0;
if (uKbdC_mstate_reset(code))
return(0);
}
else {
if (uKbdC_state_reset(code))
return(0);
}
if (uKbdC_do_modify) {
}
}
return(0);
}
uint8_t uKbdC_send_scancode(uint8_t code)
{
return uKbdC_process_code(code);
}
uint8_t uKbdC_available()
{
if (uKbdC_ptr_ceil < uKbdC_ptr_floor)
return(32 - uKbdC_ptr_floor + uKbdC_ptr_ceil);
else
return(uKbdC_ptr_ceil - uKbdC_ptr_floor);
}
uint8_t uKbdC_read()
{
uint8_t ret;
if (uKbdC_ptr_ceil != uKbdC_ptr_floor) {
ret = uKbdC_buffer[uKbdC_ptr_floor++];
uKbdC_ptr_floor = uKbdC_ptr_floor & 0xF;
return ret;
}
return(0);
}