Subversion Repositories shark

Rev

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