Subversion Repositories shark

Rev

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