00001 #include <stdio.h>
00002 #include <string.h>
00003
00004 #include <aversive/wait.h>
00005 #include <aversive/list.h>
00006 #include <uart.h>
00007
00008
00009 LIST_TYPEDEF(fifo_t, char, 32);
00010 volatile fifo_t my_fifo;
00011
00012 #define SCANCODE_MAX_SIZE 8
00013
00014 #define SCANCODE_BREAK 1
00015 #define SCANCODE_EXTENDED 2
00016 #define SCANCODE_HAS_NO_BREAK 4
00017
00018 struct scancode {
00019 uint8_t buf[SCANCODE_MAX_SIZE];
00020 uint8_t size;
00021 uint8_t idx;
00022 uint8_t flags;
00023 };
00024
00025 char tab[] = {
00026
00027 0,
00028 0,
00029 0,
00030 0,
00031 0,
00032 0,
00033 0,
00034 0,
00035 0,
00036 0,
00037 0,
00038 0,
00039 0,
00040 0,
00041 'E',
00042 0,
00043
00044
00045 0,
00046 0,
00047 0,
00048 0,
00049 0,
00050 'Q',
00051 '1',
00052 0,
00053 0,
00054 0,
00055 'Z',
00056 'S',
00057 'A',
00058 'W',
00059 '2',
00060 0,
00061
00062
00063 0,
00064 'C',
00065 'X',
00066 'D',
00067 'E',
00068 '4',
00069 '3',
00070 0,
00071 0,
00072 0,
00073 'V',
00074 'F',
00075 'T',
00076 'R',
00077 '5',
00078 0,
00079
00080
00081 0,
00082 'N',
00083 'B',
00084 'H',
00085 'G',
00086 'Y',
00087 '6',
00088 0,
00089 0,
00090 0,
00091 'M',
00092 'J',
00093 'U',
00094 '7',
00095 '8',
00096 0,
00097
00098
00099 0,
00100 '<',
00101 'K',
00102 'I',
00103 'O',
00104 '0',
00105 '9',
00106 0,
00107 0,
00108 '>',
00109 '?',
00110 'L',
00111 ':',
00112 'P',
00113 '-',
00114 0,
00115
00116
00117 0,
00118 0,
00119 '"',
00120 0,
00121 '[',
00122 'a',
00123 0,
00124 0,
00125 0,
00126 0,
00127 0,
00128 ']',
00129 0,
00130 '\\',
00131 0,
00132 0,
00133
00134
00135 0,
00136 0,
00137 0,
00138 0,
00139 0,
00140 0,
00141 0,
00142 0,
00143 0,
00144 '1',
00145 0,
00146 '4',
00147 '7',
00148 0,
00149 0,
00150 0,
00151
00152
00153 '0',
00154 0,
00155 '2',
00156 '5',
00157 '6',
00158 '8',
00159 0,
00160 0,
00161 0,
00162 '+',
00163 '3',
00164 '-',
00165 '*',
00166 '9',
00167 0,
00168 0,
00169
00170
00171 0,
00172 0,
00173 0,
00174 0,
00175 0,
00176
00177 #define SCANCODE_EXTENDED_LIST "\x11\x14\x4A\x5A\x69\x6B\x6C\x70\x71\x72\x74\x75\x7A\x7C\x7D"
00178 #define SCANCODE_EXTENDED_LIST_SIZE 15
00179 #define SCANCODE_EXTENDED_LIST_OFFSET 0x85
00180
00181 0,
00182 0,
00183 0,
00184 0,
00185 0,
00186 0,
00187 0,
00188 0,
00189 0,
00190 0,
00191 0,
00192
00193
00194 0,
00195 0,
00196 0,
00197 0,
00198
00199
00200
00201
00202
00203 #define SCANCODE_VAL_PAUSE "\xE1\x14\x77\xE1\xF0\x14\xF0\x77"
00204 #define SCANCODE_VAL_PAUSE_SIZE 8
00205 #define SCANCODE_VAL_PAUSE_OFFSET 0
00206
00207 #define SCANCODE_VAL_PRTSCR_BREAK "\xE0\xF0\x12\xE0\xF0\x7C"
00208 #define SCANCODE_VAL_PRTSCR_BREAK_SIZE 6
00209 #define SCANCODE_VAL_PRTSCR_BREAK_OFFSET 1
00210
00211 #define SCANCODE_VAL_CTRL_PAUSE "\xE0\x7E\xE0\xF0\x7E"
00212 #define SCANCODE_VAL_CTRL_PAUSE_SIZE 5
00213 #define SCANCODE_VAL_CTRL_PAUSE_OFFSET 2
00214
00215 #define SCANCODE_VAL_SHIFT_SLASH "\xE0\xF0\x12\xE0\x4A"
00216 #define SCANCODE_VAL_SHIFT_SLASH_SIZE 5
00217 #define SCANCODE_VAL_SHIFT_SLASH_OFFSET 3
00218
00219 #define SCANCODE_VAL_SHIFT_SLASH_BREAK "\xE0\xF0\x4A\xE0\x12"
00220 #define SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE 5
00221 #define SCANCODE_VAL_SHIFT_SLASH_BREAK_OFFSET 3
00222
00223 #define SCANCODE_VAL_PRTSCR "\xE0\x12\xE0\x7C"
00224 #define SCANCODE_VAL_PRTSCR_SIZE 4
00225 #define SCANCODE_VAL_PRTSCR_OFFSET 1
00226
00227
00228 0,
00229 0,
00230 0,
00231 0,
00232 0,
00233 };
00234
00235 char * scancode_extended_list = SCANCODE_EXTENDED_LIST;
00236
00237
00238
00239
00240 int8_t get_scancode(struct scancode *s)
00241 {
00242 char * p;
00243
00244 s->flags = 0;
00245 s->size = LIST_TO_ARRAY(my_fifo, s->buf, SCANCODE_MAX_SIZE);
00246 printf("%d\n", s->size);
00247
00248 if (!s->size)
00249 return -1;
00250
00251
00252 if (s->size >= SCANCODE_VAL_PAUSE_SIZE &&
00253 !memcmp(SCANCODE_VAL_PAUSE, s->buf, SCANCODE_VAL_PAUSE_SIZE)) {
00254 s->flags |= (SCANCODE_EXTENDED | SCANCODE_HAS_NO_BREAK);
00255 s->size = SCANCODE_VAL_PAUSE_SIZE;
00256 s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_PAUSE_OFFSET;
00257 return 0;
00258 }
00259
00260
00261
00262 if (s->buf[0] == 0xE0 && s->size >= 2) {
00263 s->flags |= SCANCODE_EXTENDED;
00264
00265
00266 if (s->size >= SCANCODE_VAL_PRTSCR_BREAK_SIZE &&
00267 !memcmp(SCANCODE_VAL_PRTSCR_BREAK, s->buf, SCANCODE_VAL_PRTSCR_BREAK_SIZE)) {
00268 s->flags |= SCANCODE_BREAK;
00269 s->size = SCANCODE_VAL_PRTSCR_BREAK_SIZE;
00270 s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_PRTSCR_BREAK_OFFSET;
00271 return 0;
00272 }
00273
00274
00275 if (s->size >= SCANCODE_VAL_CTRL_PAUSE_SIZE &&
00276 !memcmp(SCANCODE_VAL_CTRL_PAUSE, s->buf, SCANCODE_VAL_CTRL_PAUSE_SIZE)) {
00277 s->flags |= SCANCODE_HAS_NO_BREAK;
00278 s->size = SCANCODE_VAL_CTRL_PAUSE_SIZE;
00279 s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_CTRL_PAUSE_OFFSET;
00280 return 0;
00281 }
00282
00283
00284 if (s->size >= SCANCODE_VAL_SHIFT_SLASH_SIZE &&
00285 !memcmp(SCANCODE_VAL_SHIFT_SLASH, s->buf, SCANCODE_VAL_SHIFT_SLASH_SIZE)) {
00286 s->size = SCANCODE_VAL_SHIFT_SLASH_SIZE;
00287 s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_SHIFT_SLASH_OFFSET;
00288 return 0;
00289 }
00290
00291
00292 if (s->size >= SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE &&
00293 !memcmp(SCANCODE_VAL_SHIFT_SLASH_BREAK, s->buf, SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE)) {
00294 s->flags |= SCANCODE_BREAK;
00295 s->size = SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE;
00296 s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_SHIFT_SLASH_BREAK_OFFSET;
00297 return 0;
00298 }
00299
00300
00301 if (s->size >= SCANCODE_VAL_PRTSCR_SIZE &&
00302 !memcmp(SCANCODE_VAL_PRTSCR, s->buf, SCANCODE_VAL_PRTSCR_SIZE)) {
00303 s->size = SCANCODE_VAL_PRTSCR_SIZE;
00304 s->idx = SCANCODE_EXTENDED_LIST_OFFSET +SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_PRTSCR_OFFSET;
00305 return 0;
00306 }
00307
00308
00309 if (s->size >= 3 && s->buf[1] == 0xF0) {
00310 s->flags |= SCANCODE_BREAK;
00311 s->size = 3;
00312 p = strchr(scancode_extended_list, s->buf[2]);
00313 if (!p)
00314 return -1;
00315 s->idx = (p - scancode_extended_list) + SCANCODE_EXTENDED_LIST_OFFSET;
00316 return 0;
00317 }
00318
00319
00320 s->size = 2;
00321 p = strchr(scancode_extended_list, s->buf[2]);
00322 if (!p)
00323 return -1;
00324 s->idx = (p - scancode_extended_list) + SCANCODE_EXTENDED_LIST_OFFSET;
00325 return 0;
00326 }
00327
00328
00329 if (s->buf[0] == 0xF0) {
00330 s->flags |= SCANCODE_BREAK;
00331 s->size = 2;
00332 s->idx = s->buf[1];
00333 if (s->idx >= SCANCODE_EXTENDED_LIST_OFFSET)
00334 return -1;
00335 return 0;
00336 }
00337
00338
00339 s->idx = s->buf[0];
00340 if (s->idx >= SCANCODE_EXTENDED_LIST_OFFSET)
00341 return -1;
00342
00343 s->size = 1;
00344 return 0;
00345 }
00346
00347 void print_scancode(struct scancode *s)
00348 {
00349 uint8_t i;
00350 printf("[ ");
00351 for (i=0 ; i<s->size ; i++)
00352 printf("%.2x ", s->buf[i]);
00353 printf("] '%c' ", tab[s->idx]);
00354 if (s->flags & SCANCODE_BREAK)
00355 printf("BREAK ");
00356 if (s->flags & SCANCODE_EXTENDED)
00357 printf("EXTENDED ");
00358 if (s->flags & SCANCODE_HAS_NO_BREAK)
00359 printf("HAS_NO_BREAK ");
00360 printf("idx=%d\r\n", s->idx);
00361 }
00362
00363 int main(void)
00364 {
00365 struct scancode s;
00366 char c;
00367
00368 LIST_INIT(my_fifo, 0);
00369
00370 LIST_PUSH_END(my_fifo, 0x35);
00371 LIST_PUSH_END(my_fifo, 0xF0);
00372 LIST_PUSH_END(my_fifo, 0x35);
00373
00374 LIST_PUSH_END(my_fifo, 0xE1);
00375 LIST_PUSH_END(my_fifo, 0x14);
00376 LIST_PUSH_END(my_fifo, 0x77);
00377 LIST_PUSH_END(my_fifo, 0xE1);
00378 LIST_PUSH_END(my_fifo, 0xF0);
00379 LIST_PUSH_END(my_fifo, 0x14);
00380 LIST_PUSH_END(my_fifo, 0xF0);
00381 LIST_PUSH_END(my_fifo, 0x77);
00382
00383 LIST_PUSH_END(my_fifo, 0xE0);
00384 LIST_PUSH_END(my_fifo, 0xF0);
00385 LIST_PUSH_END(my_fifo, 0x12);
00386 LIST_PUSH_END(my_fifo, 0xE0);
00387 LIST_PUSH_END(my_fifo, 0x4A);
00388
00389 LIST_PUSH_END(my_fifo, 0xE0);
00390 LIST_PUSH_END(my_fifo, 0xF0);
00391 LIST_PUSH_END(my_fifo, 0x11);
00392
00393
00394
00395 while(get_scancode(&s) >= 0) {
00396 print_scancode(&s);
00397 while(s.size--)
00398 LIST_PULL_START(my_fifo, &c);
00399 }
00400
00401 return 0;
00402 }