X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fdrv%2Fkbd.c;h=b75db360354c82214de1c2c1550bb02ff0bbb45c;hb=12a865a058c2c3da0e4da685158f3a506ffad876;hp=8074ad3f1b3e17cffe8b6d620ab2720f6947a0cc;hpb=aef90f5745580ad12b9a69409bf1af85aa382f9d;p=bertos.git diff --git a/bertos/drv/kbd.c b/bertos/drv/kbd.c index 8074ad3f..b75db360 100644 --- a/bertos/drv/kbd.c +++ b/bertos/drv/kbd.c @@ -33,7 +33,6 @@ * * \brief Keyboard driver (implementation) * - * \version $Id$ * * \author Bernie Innocenti * \author Stefano Fedrigo @@ -48,6 +47,7 @@ #include #include +#include #include @@ -84,6 +84,8 @@ /** Status for keyboard repeat state machine */ static enum { KS_IDLE, KS_REPDELAY, KS_REPEAT } kbd_rptStatus; +/** Used to notify the occurrence of a key pressed event */ +static Event key_pressed; static volatile keymask_t kbd_buf; /**< Single entry keyboard buffer */ static volatile keymask_t kbd_cnt; /**< Number of keypress events in \c kbd_buf */ @@ -174,20 +176,29 @@ static void kbd_softint(UNUSED_ARG(iptr_t, arg)) * */ keymask_t kbd_peek(void) +{ + return kbd_peekMask((keymask_t)0xFFFFFFFFFFFFFFFFULL); +} + + +keymask_t kbd_peekMask(keymask_t mask) { keymask_t key = 0; #if CONFIG_KBD_SCHED + /* Let other tasks run for a while */ extern void schedule(void); schedule(); #endif /* Extract an event from the keyboard buffer */ IRQ_DISABLE; - if (kbd_cnt) + if (kbd_cnt && (kbd_buf & mask)) { - --kbd_cnt; - key = kbd_buf; + key = kbd_buf & mask; + kbd_buf &= ~mask; + if (!kbd_buf) + --kbd_cnt; } IRQ_ENABLE; @@ -200,10 +211,25 @@ keymask_t kbd_peek(void) * \note This function is \b not interrupt safe! */ keymask_t kbd_get(void) +{ + return kbd_getMask((keymask_t)0xFFFFFFFFFFFFFFFFULL); +} + +keymask_t kbd_getMask(keymask_t mask) { keymask_t key; - while (!(key = kbd_peek())) {} + #if CONFIG_KBD_POLL == KBD_POLL_SOFTINT + do + { + event_wait(&key_pressed); + key = kbd_peekMask(mask); + } + while (!key); + #else + while (!(key = kbd_peekMask(mask))) + cpu_relax(); + #endif return key; } @@ -216,18 +242,10 @@ keymask_t kbd_get(void) */ keymask_t kbd_get_timeout(mtime_t timeout) { - keymask_t key; - - ticks_t start = timer_clock(); - ticks_t stop = ms_to_ticks(timeout); - do - { - if ((key = kbd_peek())) - return key; - } - while (timer_clock() - start < stop); - - return K_TIMEOUT; + if (event_waitTimeout(&key_pressed, timeout)) + return kbd_peek(); + else + return K_TIMEOUT; } @@ -278,6 +296,9 @@ static keymask_t kbd_defHandlerFunc(keymask_t key) /* Force a single event in kbd buffer */ kbd_buf = key; kbd_cnt = 1; + #if CONFIG_KBD_POLL == KBD_POLL_SOFTINT + event_do(&key_pressed); + #endif #if CONFIG_KBD_OBSERVER observer_notify(&kbd_subject, KBD_EVENT_KEY, &key); @@ -471,6 +492,12 @@ void kbd_init(void) #if CONFIG_KBD_POLL == KBD_POLL_SOFTINT MOD_CHECK(timer); + #if CONFIG_KERN + MOD_CHECK(proc); + #endif + + /* Initialize the keyboard event (key pressed) */ + event_initGeneric(&key_pressed); /* Add kbd handler to soft timers list */ event_initSoftint(&kbd_timer.expire, kbd_softint, NULL);