Subversion Repositories shark

Rev

Rev 966 | Rev 1034 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
519 mauro 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   Mauro Marinoni      <mauro.marinoni@unipv.it>
13
 *   (see the web pages for full authors list)
14
 *
15
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
16
 *
17
 * http://www.sssup.it
18
 * http://retis.sssup.it
19
 * http://shark.sssup.it
20
 */
21
 
22
//#define __KEYB_DEBUG__
523 mauro 23
#define KEYB_TASK
519 mauro 24
 
25
#include <kernel/kern.h>
26
#include <signal.h>
966 pj 27
#include <hartport/hartport/hartport.h>
519 mauro 28
 
29
#include "../include/drivers/shark_input26.h"
30
#include "../include/drivers/shark_keyb26.h"
31
 
32
/* Devices */
1015 mauro 33
extern int  atkbd_init(int soft);
519 mauro 34
extern int  atkbd_exit(void);
35
 
36
/* Handlers */
37
extern int  kbd_init(void);
38
extern int  kbd_exit(void);
39
 
523 mauro 40
/* Functions */
519 mauro 41
extern int  kbd_enable(void);
42
extern int  kbd_disable(void);
43
extern int  kbd_get(unsigned int *data, BYTE access);
44
extern void kbd_setleds(unsigned int led);
45
extern int  kbd_rate(unsigned int *delay, unsigned int *period);
46
extern void kbd_mksound(unsigned int hz, unsigned int ticks);
47
 
48
/*
49
 * The following tables contains the ascii code corresponding to the
50
 * scan codes, with shift & no shift...
51
 */
52
char keyTable     [TABLE_KEY_SIZE];
53
char keyShiftTable[TABLE_KEY_SIZE];
54
char keyAltGrTable[TABLE_KEY_SIZE];
55
 
56
BYTE useAltGr = FALSE;
57
 
58
/* Status variables */
59
static BYTE shift = FALSE;
60
static BYTE ctrl  = FALSE;
61
static BYTE alt   = FALSE;
62
static BYTE altgr = FALSE;
63
 
64
static BYTE capslock   = FALSE;
65
static BYTE numlock    = TRUE;
66
static BYTE scrolllock = FALSE;
67
 
68
/* Keyboard Flags (if shift, alt or control are pressed...); */
69
static BYTE keyFlag = 0x00;
70
static BYTE status;
71
 
72
/* Keyboard driver currently installed */
73
static int keyb_installed = FALSE;
74
 
75
 
76
#define MAX_KEY_EXC     50
77
 
78
static struct keyexctable
79
{
80
        KEY_EVT evt;
81
        void (*func) (KEY_EVT * k);
82
        unsigned char lock;
83
} keyExcTable[MAX_KEY_EXC];
84
 
85
static int lastExc;
86
 
87
/* Communication port between the extern process & the user     */
88
static PORT pkeyPort, ukeyPort;
89
 
522 mauro 90
#ifdef KEYB_TASK
519 mauro 91
/* keyboard task PID */
92
static PID keybpid;
522 mauro 93
#else
523 mauro 94
static void keyProc(void);
522 mauro 95
#endif
519 mauro 96
 
97
/*
522 mauro 98
 * Start keyProc Task or exec it as function
519 mauro 99
 */
522 mauro 100
void shark_kbd_exec(void)
519 mauro 101
{
522 mauro 102
#ifdef KEYB_TASK
519 mauro 103
        task_activate(keybpid);
522 mauro 104
#else
105
        keyProc();
106
#endif
519 mauro 107
}
108
 
109
/*
110
 * This function get a scan code, return an ascii code and set
111
 * the status vars in order to handle the special keys of the AT keyboard
112
 */
113
WORD scanCode(unsigned int c, int d)
114
{
115
        //printk("scanCode: c (%x) - d (%d)\n", c, d);
116
 
117
        /* KEY_EVT status setting */
749 mauro 118
        status = 1 << d;
519 mauro 119
 
120
        switch (c) {
121
                /* CapsLock pressed*/
122
                case KEY_CPSLOCK:
123
                        if (d == KEY_PRESSED) {
124
                                capslock = capslock ? FALSE : TRUE;
125
                                /* light the caps lock led */
126
                                kbd_setleds(scrolllock + (numlock << 1) + (capslock << 2));
127
                        }
128
                        return 0;
129
                /* NumLock pressed */
130
                case PAD_NUMLOCK:
131
                        if (d == KEY_PRESSED) {
132
                                numlock = numlock ? FALSE : TRUE;
133
                                /* light the num lock led */
134
                                kbd_setleds(scrolllock + (numlock << 1) + (capslock << 2));
135
                        }
136
                        return 0;
137
                /* ScrollLock pressed*/
138
                case EXT_SCRLOCK:
139
                        if (d == KEY_PRESSED) {
140
                                scrolllock = scrolllock ? FALSE : TRUE;
141
                                /* light the scroll lock led */
142
                                kbd_setleds(scrolllock + (numlock << 1) + (capslock << 2));
143
                        }
144
                        return 0;
145
                /* Shift pressed or released */
146
                case KEY_SHL:
147
                        if (d) {
148
                                shift = TRUE;
149
                                if (c == KEY_SHL)
150
                                        keyFlag |= SHFL_BIT;
151
                        } else {
152
                                keyFlag &= (!SHFL_BIT);
153
                                if (!(keyFlag & SHFR_BIT))
154
                                        shift = FALSE;
155
                        }
156
                        return 0;
157
                /* Shift pressed or released */
158
                case KEY_SHR:
159
                        if (d) {
160
                                shift = TRUE;
161
                                if (c == KEY_SHR)
162
                                        keyFlag |= SHFR_BIT;
163
                        } else {
164
                                keyFlag &= (!SHFR_BIT);
165
                                if (!(keyFlag & SHFL_BIT))
166
                                        shift = FALSE;
167
                        }
168
                        return 0;
169
                /* Control pressed or released */
170
                case KEY_CTRLL:
171
                        if (d) {
172
                                ctrl = TRUE;
173
                                keyFlag |= CNTL_BIT;
174
                        } else {
175
                                keyFlag &= (!CNTL_BIT);
176
                                if (!(keyFlag & CNTR_BIT))
177
                                        ctrl = FALSE;
178
                        }
179
                        return 0;
180
                /* Control pressed or released */
181
                case KEY_CTRLR:
182
                        if (d) {
183
                                ctrl = TRUE;
184
                                keyFlag |= CNTR_BIT;
185
                        } else {
186
                                keyFlag &= (!CNTR_BIT);
187
                                if (!(keyFlag & CNTL_BIT))
188
                                        ctrl = FALSE;
189
                        }
190
                        return 0;
191
                /* Alt Left pressed */
192
                case KEY_ALTL:
193
                        if (d) {
194
                                alt = TRUE;
195
                                keyFlag |= ALTL_BIT;
196
                        } else {
197
                                alt = FALSE;
198
                                keyFlag &= (!ALTL_BIT);
199
                        }
200
                        return 0;
201
                /* Alt Right (AltGr) pressed */
202
                case KEY_ALTR:
203
                        if (d) {
204
                                altgr = TRUE;
205
                                keyFlag |= ALTR_BIT;
206
                        } else {
207
                                altgr = FALSE;
208
                                keyFlag &= (!ALTR_BIT);
209
                                if ((!useAltGr) && (!(keyFlag & ALTL_BIT)))
210
                                        alt = FALSE;
211
                        }
212
                        return 0;
213
                /* Delete */
214
                case EXT_DEL:
215
                        return DELETE;
216
                case PAD_DEL:
217
                        if (numlock || shift)
218
                                return 0x18;
219
                        else
220
                                break;
221
                /* Pad Enter */
222
                case PAD_ENT:
223
                        return 0x0d;
224
                /* Pad Add */
225
                case PAD_PLUS:
226
                        return 0x2b;
227
                /* Pad Sub */
228
                case PAD_SUB:
229
                        return 0x2d;
230
                /* Pad Slash */
231
                case PAD_SLH:
232
                        return 0x2f;
233
                /* Numbers & simbols */
234
                case KEY_1: case KEY_2: case KEY_3: case KEY_4: case KEY_5:
235
                case KEY_6: case KEY_7: case KEY_8: case KEY_9: case KEY_0:
236
                case KEY_SUB: case KEY_PLUS: case KEY_BRL: case KEY_BRR:
237
                case KEY_COL: case KEY_API:  case KEY_TIL: case KEY_BSL:
238
                case KEY_LT:  case KEY_GT:   case KEY_SLH:
239
                        /* AlrGR enabled & pressed */
240
                        if (altgr && useAltGr) {
241
                                return keyAltGrTable[c];
242
                        }
243
                        /* Control Shift status */
244
                        if (shift)
245
                                return keyShiftTable[c];
246
                        else
247
                                return keyTable[c];
248
        }
249
 
250
        /* Pad Keys */
251
        if (numlock || shift)
252
                switch (c) {
253
                        case PAD_DEL:
254
                                return 0x18;
255
                        case PAD_INS:
256
                                return 0x30;
257
                        case PAD_END:
258
                                return 0x31;
259
                        case PAD_DOWN:
260
                                return 0x32;
261
                        case PAD_PGDW:
262
                                return 0x33;
263
                        case PAD_RIGHT:
264
                                return 0x34;
265
                        case PAD_5:
266
                                return 0x35;
267
                        case PAD_LEFT:
268
                                return 0x36;
269
                        case PAD_HOME:
270
                                return 0x37;
271
                        case PAD_UP:
272
                                return 0x38;
273
                        case PAD_PGUP:
274
                                return 0x39;
275
                }
276
 
277
        /* Characters keys */
278
        if (((c >= KEY_Q) && (c <= KEY_P)) ||
279
            ((c >= KEY_A) && (c <= KEY_L)) ||
280
            ((c >= KEY_Z) && (c <= KEY_M))) {
281
                /* AlrGR enabled & pressed */
282
                if (altgr && useAltGr) {
283
                        return keyAltGrTable[c];
284
                }
285
                /* Control CapsLock & Shift status */
286
                if (capslock) {
287
                        if (shift)
288
                                return keyTable[c];
289
                        else
290
                                return keyShiftTable[c];
291
                } else {
292
                        if (shift)
293
                                return keyShiftTable[c];
294
                        else
295
                                return keyTable[c];
296
                }
297
        }
298
 
299
        /* Remaining keys */
300
        if (c < TABLE_KEY_SIZE)
301
                /* Left 'low' keys (Esc, BackSpace, Space, ...) */
302
                return keyTable[c];
303
        else
304
                /* Default - Return as keycode */
305
                return (0xff00 | c);
306
}
307
 
522 mauro 308
#ifdef KEYB_TASK
519 mauro 309
TASK keyProc(void)
522 mauro 310
#else
523 mauro 311
static void keyProc(void)
522 mauro 312
#endif
519 mauro 313
{
314
        WORD code;
315
        BYTE found;
316
        KEY_EVT dt;
317
        int i, res;
318
        unsigned int dato;
319
 
522 mauro 320
#ifdef KEYB_TASK
519 mauro 321
        while (1) {
522 mauro 322
#endif
519 mauro 323
                res = kbd_get(&dato, NON_BLOCK);
324
                if (res >= 0) {
325
                        code = scanCode(dato, res);
326
                        if (code != 0) {
327
                                if (code & 0xff00)
328
                                        /* It's a scan code, set the right bit */
329
                                        dt.flag = (keyFlag | SCAN_BIT);
330
                                else
331
                                        /* Simply send the keyFlag status */
332
                                        dt.flag = keyFlag;
333
                                dt.status = status;
334
                                dt.ascii  = (BYTE) (code & 0x00FF);
335
                                dt.scan   = dato;
336
#ifdef __KEYB_DEBUG__
337
                                printk("shark_keyb.c: KEY_EVT ( %2x - %c - %2x - %1d)\n", dt.scan, dt.ascii, dt.flag, dt.status);
338
#endif
339
                                found = FALSE;
340
                                for (i = 0; i < lastExc; i++)
666 mauro 341
                                        if (((keyExcTable[i].evt.flag & ~SCAN_BIT) == (dt.flag & ~SCAN_BIT)) &&
749 mauro 342
                                            ((keyExcTable[i].evt.status & dt.status) != 0)) {
666 mauro 343
                                                if ( ((keyExcTable[i].evt.scan == dt.scan) || (keyExcTable[i].evt.scan == 0)) &&
344
                                                     ((keyExcTable[i].evt.ascii == dt.ascii) || (keyExcTable[i].evt.ascii == 0)) ){
519 mauro 345
#ifdef __KEYB_DEBUG__
666 mauro 346
                                                        printk("shark_keyb.c: Key_Hook ( %2x - %2x - %1d) -> ( %2x - %2x - %1d)\n",
347
                                                               dt.scan, dt.ascii, dt.flag, dt.status,
348
                                                               keyExcTable[i].evt.scan, keyExcTable[i].evt.ascii, keyExcTable[i].evt.flag, keyExcTable[i].evt.status);
519 mauro 349
#endif
666 mauro 350
                                                        keyExcTable[i].func(&dt);
351
                                                        if (keyExcTable[i].lock == TRUE)
352
                                                                found = TRUE;
353
                                                }
523 mauro 354
                                        }
519 mauro 355
                                /* when the port is full, data is lost */
356
                                if (!found)
357
                                        port_send(pkeyPort, (BYTE *) (&dt), NON_BLOCK);
358
                        }
359
                }
522 mauro 360
#ifdef KEYB_TASK
519 mauro 361
                task_endcycle();
362
        }
522 mauro 363
#endif
519 mauro 364
}
365
 
366
/* default function called on ctrl-c */
367
void default_ctrlChandler(KEY_EVT * k) {
368
        set_active_page(0);
369
        set_visual_page(0);
523 mauro 370
        //cputs("Ctrl-C pressed!\n");
927 pj 371
        exit(1);
519 mauro 372
}
373
 
374
/**** Start User Functions ****/
375
 
376
/* Function that returns the ascii code */
377
BYTE keyb_getch(BYTE wait)
378
{
523 mauro 379
        KEY_EVT ev;
519 mauro 380
        BYTE fl;
381
 
523 mauro 382
        fl = port_receive (ukeyPort, &ev, wait);
383
        if (fl) {
384
#ifdef __KEYB_DEBUG__
385
                printk("shark_keyb.c: GetChar ( %2x - %c - %2x - %1d)\n", ev.scan, ev.ascii, ev.flag, ev.status);
386
#endif
826 mauro 387
                if (!isScanCode(&ev) && !isReleased(&ev))
523 mauro 388
                        return (ev.ascii);
389
                else
390
                        return 0;
391
        } else
519 mauro 392
                return 0;
393
}
394
 
395
/*
396
 * Function that returns a structure containing the flags status, the ascii
397
 * code, and the scan code
398
 */
826 mauro 399
int inline keyb_getcode(KEY_EVT * k, BYTE wait)
519 mauro 400
{
401
        return (port_receive (ukeyPort, (BYTE *) (k), wait));
402
}
403
 
404
void keyb_hook(KEY_EVT k, void (*f) (KEY_EVT * k), unsigned char l)
405
{
406
        if (lastExc >= MAX_KEY_EXC)
407
                return;
408
        keyExcTable[lastExc].evt = k;
409
        keyExcTable[lastExc].func = f;
410
        keyExcTable[lastExc++].lock = l;
411
 
412
        return;
413
}
414
 
523 mauro 415
/* This function disable the keyboard */
826 mauro 416
void inline keyb_disable(void)
519 mauro 417
{
418
        kbd_disable();
419
}
420
 
523 mauro 421
/* This function enable the keyboard */
826 mauro 422
void inline keyb_enable(void)
519 mauro 423
{
424
        kbd_enable();
425
}
426
 
523 mauro 427
/**** End User Functions ****/
826 mauro 428
int inline KEYB26_installed(void)
549 mauro 429
{
430
        return keyb_installed;
431
}
519 mauro 432
 
433
int KEYB26_init(KEYB_PARMS *s)
434
{
435
        KEYB_PARMS kparms = BASE_KEYB;
436
        WORD i;
437
        int status = 0;
438
 
522 mauro 439
#ifdef KEYB_TASK
519 mauro 440
        SOFT_TASK_MODEL base_m;
441
        TASK_MODEL *m;
522 mauro 442
#endif
519 mauro 443
 
444
        if (keyb_installed == TRUE) return 0;
445
 
446
        /* if a NULL is passed */
447
        if (s == NULL)
448
                s = &kparms;
449
 
450
        for (i = 0; i < TABLE_KEY_SIZE; i++) {
451
                keyTable[i] = 0;
452
                keyShiftTable[i] = 0;
453
                keyAltGrTable[i] = 0;
454
        }
455
 
456
        /* keymap */
457
        if (s->keymap == (unsigned char)KEYB_DEFAULT) s->keymap = KEYMAP_US;
458
        keyb_set_map(s->keymap);
459
 
523 mauro 460
        pkeyPort = port_create ("KeybPort", sizeof(KEY_EVT), 20, STREAM, WRITE);
519 mauro 461
        if (pkeyPort == -1)
462
                return -2;
523 mauro 463
        ukeyPort = port_connect ("KeybPort", sizeof(KEY_EVT), STREAM, READ);
519 mauro 464
        if (ukeyPort == -1) {
465
                port_delete (pkeyPort);
466
                return -3;
467
        }
468
 
469
        /* remove all key pressed handlers */
470
        lastExc = 0;
471
 
472
        /* and add a ctrl-c handler if requested */
473
        if (s->ctrlcfunc == (void *) KEYB_DEFAULT)
474
                s->ctrlcfunc = (void *) default_ctrlChandler;
475
        if (s->ctrlcfunc != NULL) {
476
                KEY_EVT emerg;
523 mauro 477
                emerg.ascii  = 'c';
478
                emerg.scan   = KEY_C;
479
                emerg.status = KEY_PRESSED;
480
                emerg.flag   = CNTL_BIT;
519 mauro 481
                keyb_hook (emerg, s->ctrlcfunc, TRUE);
523 mauro 482
                emerg.flag   = CNTR_BIT;
519 mauro 483
                keyb_hook (emerg, s->ctrlcfunc, TRUE);
484
        }
485
 
522 mauro 486
#ifdef KEYB_TASK
519 mauro 487
        /* keyb task */
488
        if (s->tm == (TASK_MODEL *) KEYB_DEFAULT) {
489
                soft_task_default_model (base_m);
490
                soft_task_def_wcet (base_m, 2000);
491
                soft_task_def_met (base_m, 800);
492
                soft_task_def_period (base_m, 25000);
493
                soft_task_def_system (base_m);
826 mauro 494
                soft_task_def_nokill (base_m);
519 mauro 495
                soft_task_def_aperiodic (base_m);
496
                m = (TASK_MODEL *) & base_m;
497
        } else
498
                m = s->tm;
499
 
500
#ifdef __KEYB_DEBUG__
501
        //printk(KERN_DEBUG "keyb task: %li %li %li %li\n", (long)s->pclass, (long)APERIODIC, (long)s->dline, (long)s->wcet);
502
#endif
503
 
504
        keybpid = task_create ("KeyTask", keyProc, m, NULL);
505
        if (keybpid == -1) {
506
                port_delete (pkeyPort);
507
                port_delete (ukeyPort);
508
                return -1;
509
        }
522 mauro 510
#endif
519 mauro 511
 
549 mauro 512
        if (INPUT26_installed() == FALSE)
519 mauro 513
                if (INPUT26_init()) {
514
                        printk(KERN_ERR "shark_keyb.c: Unable to open Input SubSystem.\n");
515
                        port_delete (pkeyPort);
516
                        port_delete (ukeyPort);
544 giacomo 517
#ifdef KEYB_TASK
523 mauro 518
                        task_kill (keybpid);
544 giacomo 519
#endif
519 mauro 520
                        return -1;
521
                }
522
 
549 mauro 523
        status = kbd_init();
519 mauro 524
        if (status) {
549 mauro 525
                printk(KERN_ERR "shark_keyb.c: Kbd_Init return: %d\n", status);
519 mauro 526
                port_delete (pkeyPort);
527
                port_delete (ukeyPort);
544 giacomo 528
#ifdef KEYB_TASK
523 mauro 529
                task_kill (keybpid);
544 giacomo 530
#endif
519 mauro 531
                return -1;
532
        }
549 mauro 533
 
1015 mauro 534
 
535
        if (s->softrepeat == (int) KEYB_DEFAULT) {
536
                status = atkbd_init(1);
537
        } else {
538
                status = atkbd_init(s->softrepeat);
539
        }
519 mauro 540
        if (status) {
549 mauro 541
                printk(KERN_ERR "shark_keyb.c: AtKbd_Init return: %d\n", status);
519 mauro 542
                port_delete (pkeyPort);
543
                port_delete (ukeyPort);
544 giacomo 544
#ifdef KEYB_TASK
523 mauro 545
                task_kill (keybpid);
544 giacomo 546
#endif
519 mauro 547
                return -1;
548
        }
549
 
550
        kbd_setleds(scrolllock + (numlock << 1) + (capslock << 2));
551
        kbd_enable();
552
 
553
        keyb_installed = TRUE;
554
        return status;
555
}
556
 
557
/*
558
 * KEYB module cleanup
559
 * (must be called if it's needed to re-call keyb_init() with other parameters)
560
 * -1 -> ERROR
561
 */
562
int KEYB26_close(void)
563
{
522 mauro 564
#ifdef KEYB_TASK
519 mauro 565
        int free;
566
        SYS_FLAGS f;
522 mauro 567
#endif
519 mauro 568
 
569
        if (!keyb_installed)
570
                return -1;
549 mauro 571
 
519 mauro 572
        kbd_disable();
549 mauro 573
 
574
        atkbd_exit();
519 mauro 575
        kbd_exit();
576
 
522 mauro 577
#ifdef KEYB_TASK
519 mauro 578
        f = kern_fsave();
579
        free = (proc_table[keybpid].status == FREE);
580
        kern_frestore(f);
581
#ifdef __KEYB_DEBUG__
582
        printk(KERN_DEBUG "shark_keyb.c: KeyTask is %s.\n", free ? "killed" : "alive");
583
#endif
584
        if (free)
585
                task_kill (keybpid);
522 mauro 586
#endif
519 mauro 587
 
588
        /*port_delete (pkeyPort);
589
        port_delete (ukeyPort);*/
590
 
591
        keyb_installed = FALSE;
592
 
593
        return 0;
594
}