timer: fix function definitions for uC having several output compare
[aversive.git] / projects / example1 / main.c
1 #include <stdio.h>
2 #include <string.h>
3
4 #include <aversive/wait.h>
5 #include <aversive/list.h>
6 #include <uart.h>
7
8
9 LIST_TYPEDEF(fifo_t, char, 32);
10 volatile fifo_t my_fifo;
11
12 #define SCANCODE_MAX_SIZE 8
13
14 #define SCANCODE_BREAK        1 /* break code */
15 #define SCANCODE_EXTENDED     2 /* is extended */
16 #define SCANCODE_HAS_NO_BREAK 4 /* no associated break code */
17
18 struct scancode {
19         uint8_t buf[SCANCODE_MAX_SIZE];
20         uint8_t size;
21         uint8_t idx;
22         uint8_t flags;
23 };
24
25 char tab[] = {
26         /***** 0x00 */
27         0,  
28         0,  /* F9 */
29         0,  
30         0,  /* F5 */
31         0,  /* F3 */
32         0,  /* F1 */
33         0,  /* F2 */
34         0,  /* F12 */
35         0, 
36         0,  /* F10 */
37         0,  /* F8 */
38         0,  /* F6 */
39         0,  /* F4 */
40         0,  /* TAB */
41         'E',  /* E */
42         0, 
43
44         /***** 0x10 */
45         0, 
46         0,  /* AltL */
47         0,  /* ShiftL */
48         0, 
49         0,  /* CtrlL */
50         'Q',  /* Q */
51         '1',  /* 1 */
52         0, 
53         0, 
54         0, 
55         'Z',  /* Z */
56         'S',  /* S */
57         'A',  /* A */
58         'W',  /* W */
59         '2',  /* 2 */
60         0, 
61
62         /***** 0x20 */
63         0, 
64         'C',  /* C */
65         'X',  /* X */
66         'D',  /* D */
67         'E',  /* E */
68         '4',  /* 4 */
69         '3',  /* 3 */
70         0, 
71         0, 
72         0,  /* Space */
73         'V',  /* V */
74         'F',  /* F */
75         'T',  /* T */
76         'R',  /* R */
77         '5',  /* 5 */
78         0, 
79
80         /***** 0x30 */
81         0, 
82         'N',  /* N */
83         'B',  /* B */
84         'H',  /* H */
85         'G',  /* G */
86         'Y',  /* Y */
87         '6',  /* 6 */
88         0, 
89         0, 
90         0, 
91         'M',  /* M */
92         'J',  /* J */
93         'U',  /* U */
94         '7',  /* 7 */
95         '8',  /* 8 */
96         0, 
97
98         /***** 0x40 */
99         0, 
100         '<',  /* < */
101         'K',  /* K */
102         'I',  /* I */
103         'O',  /* O */
104         '0',  /* 0 */
105         '9',  /* 9 */
106         0, 
107         0, 
108         '>',  /* > */
109         '?',  /* ? */
110         'L',  /* L */
111         ':',  /* : */
112         'P',  /* P */
113         '-',  /* - */
114         0, 
115
116         /***** 0x50 */
117         0, 
118         0, 
119         '"',  /* " */
120         0, 
121         '[',  /* [ */
122         'a',  /* a */
123         0, 
124         0, 
125         0,  /* CapsLk */
126         0,  /* ShiftR */
127         0,  /* EnterL */
128         ']',  /* ] */
129         0, 
130         '\\',  /* \\ */
131         0, 
132         0, 
133
134         /***** 0x60 */
135         0, 
136         0,  /* Macro */
137         0, 
138         0, 
139         0, 
140         0, 
141         0,  /* BS */
142         0, 
143         0, 
144         '1',  /* 1 */
145         0, 
146         '4',  /* 4 */
147         '7',  /* 7 */
148         0, 
149         0, 
150         0, 
151
152         /***** 0x70 */
153         '0',  /* 0 */
154         0,  /* Del */
155         '2',  /* 2 */
156         '5',  /* 5 */
157         '6',  /* 6 */
158         '8',  /* 8 */
159         0,  /* Esc */
160         0,  /* NumLk */
161         0,  /* F11 */
162         '+',  /* + */
163         '3',  /* 3 */
164         '-',  /* - */
165         '*',  /* * */
166         '9',  /* 9 */
167         0,  /* ScrLk */
168         0, 
169
170         /***** 0x80 */
171         0, 
172         0, 
173         0, 
174         0,  /* F7 */
175         0,  /* Alt-PRTSC */
176
177 #define SCANCODE_EXTENDED_LIST               "\x11\x14\x4A\x5A\x69\x6B\x6C\x70\x71\x72\x74\x75\x7A\x7C\x7D"
178 #define SCANCODE_EXTENDED_LIST_SIZE          15
179 #define SCANCODE_EXTENDED_LIST_OFFSET        0x85
180
181         0, /* 0x0E11 AltR */
182         0, /* 0x0E14 CtrlR */
183         0, /* 0x0E4A / */
184         0, /* 0x0E5A Enter */
185         0, /* 0x0E69 End */
186         0, /* 0x0E6B Left */
187         0, /* 0x0E6C Home */
188         0, /* 0x0E70 Insert */
189         0, /* 0x0E71 Delete */
190         0, /* 0x0E72 Down */
191         0, /* 0x0E74 Right */
192
193         /***** 0x90 */
194         0, /* 0x0E75 Up */
195         0, /* 0x0E7A Pgdn */
196         0, /* 0x0E7C Ctrl-Prtscr */
197         0, /* 0x0E7D Pgup */
198
199
200
201         /* Exceptions */
202
203 #define SCANCODE_VAL_PAUSE                    "\xE1\x14\x77\xE1\xF0\x14\xF0\x77"
204 #define SCANCODE_VAL_PAUSE_SIZE               8
205 #define SCANCODE_VAL_PAUSE_OFFSET             0
206
207 #define SCANCODE_VAL_PRTSCR_BREAK             "\xE0\xF0\x12\xE0\xF0\x7C"
208 #define SCANCODE_VAL_PRTSCR_BREAK_SIZE        6
209 #define SCANCODE_VAL_PRTSCR_BREAK_OFFSET      1
210
211 #define SCANCODE_VAL_CTRL_PAUSE               "\xE0\x7E\xE0\xF0\x7E"
212 #define SCANCODE_VAL_CTRL_PAUSE_SIZE          5
213 #define SCANCODE_VAL_CTRL_PAUSE_OFFSET        2
214
215 #define SCANCODE_VAL_SHIFT_SLASH              "\xE0\xF0\x12\xE0\x4A"
216 #define SCANCODE_VAL_SHIFT_SLASH_SIZE         5
217 #define SCANCODE_VAL_SHIFT_SLASH_OFFSET       3
218
219 #define SCANCODE_VAL_SHIFT_SLASH_BREAK        "\xE0\xF0\x4A\xE0\x12"
220 #define SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE   5
221 #define SCANCODE_VAL_SHIFT_SLASH_BREAK_OFFSET 3
222
223 #define SCANCODE_VAL_PRTSCR                   "\xE0\x12\xE0\x7C"
224 #define SCANCODE_VAL_PRTSCR_SIZE              4
225 #define SCANCODE_VAL_PRTSCR_OFFSET            1
226
227
228         0, /* E11477E1F014F077 PAUSE */
229         0, /* E012E07C PRTSCR */
230         0, /* E07EE0F07E CTRL_PAUSE */
231         0, /* E0F012E04A SHIFT_SLASH */
232         0, /* E012E07C */
233 };
234
235 char * scancode_extended_list = SCANCODE_EXTENDED_LIST;
236
237
238
239
240 int8_t get_scancode(struct scancode *s)
241 {
242         char * p;
243
244         s->flags = 0;
245         s->size = LIST_TO_ARRAY(my_fifo, s->buf, SCANCODE_MAX_SIZE);
246         printf("%d\n", s->size);
247
248         if (!s->size)
249                 return -1;
250         
251         /* special case for 'pause' */
252         if (s->size >=  SCANCODE_VAL_PAUSE_SIZE && 
253             !memcmp(SCANCODE_VAL_PAUSE, s->buf, SCANCODE_VAL_PAUSE_SIZE)) {
254                 s->flags |= (SCANCODE_EXTENDED | SCANCODE_HAS_NO_BREAK);
255                 s->size = SCANCODE_VAL_PAUSE_SIZE;
256                 s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_PAUSE_OFFSET;
257                 return 0;
258         }
259
260
261         /* extended codes */
262         if (s->buf[0] == 0xE0 && s->size >= 2) {
263                 s->flags |= SCANCODE_EXTENDED;
264                 
265                 /* special case for 'prtscr break' */
266                 if (s->size >=  SCANCODE_VAL_PRTSCR_BREAK_SIZE && 
267                     !memcmp(SCANCODE_VAL_PRTSCR_BREAK, s->buf, SCANCODE_VAL_PRTSCR_BREAK_SIZE)) {
268                         s->flags |= SCANCODE_BREAK;
269                         s->size = SCANCODE_VAL_PRTSCR_BREAK_SIZE;
270                         s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_PRTSCR_BREAK_OFFSET;
271                         return 0;
272                 }
273
274                 /* special case for 'ctrl_pause' */
275                 if (s->size >=  SCANCODE_VAL_CTRL_PAUSE_SIZE && 
276                     !memcmp(SCANCODE_VAL_CTRL_PAUSE, s->buf, SCANCODE_VAL_CTRL_PAUSE_SIZE)) {
277                         s->flags |= SCANCODE_HAS_NO_BREAK;
278                         s->size = SCANCODE_VAL_CTRL_PAUSE_SIZE;
279                         s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_CTRL_PAUSE_OFFSET;
280                         return 0;
281                 }
282
283                 /* special case for 'shift_slash' */
284                 if (s->size >=  SCANCODE_VAL_SHIFT_SLASH_SIZE && 
285                     !memcmp(SCANCODE_VAL_SHIFT_SLASH, s->buf, SCANCODE_VAL_SHIFT_SLASH_SIZE)) {
286                         s->size = SCANCODE_VAL_SHIFT_SLASH_SIZE;
287                         s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_SHIFT_SLASH_OFFSET;
288                         return 0;
289                 }
290
291                 /* special case for 'shift_slash_break' */
292                 if (s->size >=  SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE && 
293                     !memcmp(SCANCODE_VAL_SHIFT_SLASH_BREAK, s->buf, SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE)) {
294                         s->flags |= SCANCODE_BREAK;
295                         s->size = SCANCODE_VAL_SHIFT_SLASH_BREAK_SIZE;
296                         s->idx = SCANCODE_EXTENDED_LIST_OFFSET + SCANCODE_EXTENDED_LIST_SIZE + SCANCODE_VAL_SHIFT_SLASH_BREAK_OFFSET;
297                         return 0;
298                 }
299
300                 /* special case for 'prtscr' */
301                 if (s->size >=  SCANCODE_VAL_PRTSCR_SIZE && 
302                     !memcmp(SCANCODE_VAL_PRTSCR, s->buf, SCANCODE_VAL_PRTSCR_SIZE)) {
303                         s->size = SCANCODE_VAL_PRTSCR_SIZE;
304                         s->idx = SCANCODE_EXTENDED_LIST_OFFSET +SCANCODE_EXTENDED_LIST_SIZE +  SCANCODE_VAL_PRTSCR_OFFSET;
305                         return 0;
306                 }
307
308                 /* break for extended codes */
309                 if (s->size >= 3 && s->buf[1] == 0xF0) {
310                         s->flags |= SCANCODE_BREAK;
311                         s->size = 3;
312                         p = strchr(scancode_extended_list, s->buf[2]);
313                         if (!p)
314                                 return -1;
315                         s->idx = (p - scancode_extended_list) + SCANCODE_EXTENDED_LIST_OFFSET;
316                         return 0;
317                 }
318
319                 /* ext scancode, 2 bytes */
320                 s->size = 2;
321                 p = strchr(scancode_extended_list, s->buf[2]);
322                 if (!p)
323                         return -1;
324                 s->idx = (p - scancode_extended_list) + SCANCODE_EXTENDED_LIST_OFFSET;
325                 return 0;
326         }
327
328         /* break scancode (2 bytes) */
329         if (s->buf[0] == 0xF0) {
330                 s->flags |= SCANCODE_BREAK;
331                 s->size = 2;
332                 s->idx = s->buf[1];
333                 if (s->idx >= SCANCODE_EXTENDED_LIST_OFFSET)
334                         return -1;
335                 return 0;
336         }
337
338         /* simple scancode, 1 byte */
339         s->idx = s->buf[0];
340         if (s->idx >= SCANCODE_EXTENDED_LIST_OFFSET)
341                 return -1;
342
343         s->size = 1;
344         return 0;
345 }
346
347 void print_scancode(struct scancode *s)
348 {
349         uint8_t i;
350         printf("[ ");
351         for (i=0 ; i<s->size ; i++)
352                 printf("%.2x ", s->buf[i]);
353         printf("] '%c' ", tab[s->idx]);
354         if (s->flags & SCANCODE_BREAK)
355                 printf("BREAK ");
356         if (s->flags & SCANCODE_EXTENDED)
357                 printf("EXTENDED ");
358         if (s->flags & SCANCODE_HAS_NO_BREAK)
359                 printf("HAS_NO_BREAK ");
360         printf("idx=%d\r\n", s->idx);
361 }
362
363 int main(void)
364 {
365         struct scancode s;
366         char c;
367
368         LIST_INIT(my_fifo, 0);
369
370         LIST_PUSH_END(my_fifo, 0x35);
371         LIST_PUSH_END(my_fifo, 0xF0);
372         LIST_PUSH_END(my_fifo, 0x35);
373
374         LIST_PUSH_END(my_fifo, 0xE1);
375         LIST_PUSH_END(my_fifo, 0x14);
376         LIST_PUSH_END(my_fifo, 0x77);
377         LIST_PUSH_END(my_fifo, 0xE1);
378         LIST_PUSH_END(my_fifo, 0xF0);
379         LIST_PUSH_END(my_fifo, 0x14);
380         LIST_PUSH_END(my_fifo, 0xF0);
381         LIST_PUSH_END(my_fifo, 0x77);
382
383         LIST_PUSH_END(my_fifo, 0xE0);
384         LIST_PUSH_END(my_fifo, 0xF0);
385         LIST_PUSH_END(my_fifo, 0x12);
386         LIST_PUSH_END(my_fifo, 0xE0);
387         LIST_PUSH_END(my_fifo, 0x4A);
388
389         LIST_PUSH_END(my_fifo, 0xE0);
390         LIST_PUSH_END(my_fifo, 0xF0);
391         LIST_PUSH_END(my_fifo, 0x11);
392
393
394
395         while(get_scancode(&s) >= 0) {
396                 print_scancode(&s);
397                 while(s.size--)
398                         LIST_PULL_START(my_fifo, &c);   
399         }
400         
401         return 0;
402 }