Subversion Repositories shark

Rev

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