/*#*
*#* $Log$
+ *#* Revision 1.7 2006/06/03 13:57:36 bernie
+ *#* Make keyboard repeat mask run-time configurable.
+ *#*
+ *#* Revision 1.6 2006/03/20 17:50:17 bernie
+ *#* Add FreeRTOS and Observers support.
+ *#*
*#* Revision 1.5 2006/02/27 22:39:45 bernie
*#* Misc build and doc fixes from project_grl.
*#*
#include <drv/timer.h>
#include <drv/kbd.h>
-#include <drv/buzzer.h>
#include <cfg/debug.h>
#include <cfg/module.h>
#if !defined(CONFIG_KBD_POLL) || (CONFIG_KBD_POLL != KBD_POLL_SOFTINT && CONFIG_KBD_POLL != CONFIG_POLL_FREERTOS)
#error CONFIG_KBD_POLL must be defined to either KBD_POLL_SOFTINT or CONFIG_POLL_FREERTOS
#endif
+#if !defined(CONFIG_KBD_BEEP) || (CONFIG_KBD_BEEP != 0 && CONFIG_KBD_BEEP != 1)
+ #error CONFIG_KBD_BEEP must be defined to either 0 or 1
+#endif
+#if !defined(CONFIG_KBD_OBSERVER) || (CONFIG_KBD_OBSERVER != 0 && CONFIG_KBD_OBSERVER != 1)
+ #error CONFIG_KBD_OBSERVER must be defined to either 0 or 1
+#endif
+#if CONFIG_KBD_BEEP
+ #include <drv/buzzer.h>
+#endif
#define KBD_CHECK_INTERVAL 10 /*!< (ms) Timing for kbd softint */
#define KBD_DEBOUNCE_TIME 30 /*!< (ms) Debounce time */
static volatile keymask_t kbd_buf; /*!< Single entry keyboard buffer */
static volatile keymask_t kbd_cnt; /*!< Number of keypress events in \c kbd_buf */
+static keymask_t kbd_rpt_mask; /**< Mask of repeatable keys. */
#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
static Timer kbd_timer; /*!< Keyboard softtimer */
static KbdHandler kbd_lngHandler; /*!< Long pression keys handler */
#endif
+#if CONFIG_KBD_OBSERVER
+ #include <mware/observer.h>
+ Subject kbd_subject;
+#endif
/*!
keymask_t key = 0;
// FIXME
+ /* Let other tasks run for a while */
extern void schedule(void);
schedule();
return key;
}
-
/*!
* Wait for a keypress and return the mask of depressed keys.
*
keymask_t key;
while (!(key = kbd_peek())) {}
+
return key;
}
kbd_buf = key;
kbd_cnt = 1;
-#if KBD_BEEP_TIME
- if (!(key & K_REPEAT))
- buz_beep(KBD_BEEP_TIME);
-#endif
+ #if CONFIG_KBD_OBSERVER
+ observer_notify(&kbd_subject, KBD_EVENT_KEY, &key);
+ #endif
+
+ #if CONFIG_KBD_BEEP
+ if (!(key & K_REPEAT))
+ buz_beep(KBD_BEEP_TIME);
+ #endif
}
/* Eat all input */
}
#ifdef K_LNG_MASK
-/*!
- * Handle long pression keys
+/**
+ * Handle long pression keys.
*/
static keymask_t kbd_lngHandlerFunc(keymask_t key)
{
- static ticks_t stop;
+ static ticks_t start;
ticks_t now = timer_clock();
if (key & K_LNG_MASK)
{
- if (now - stop > 0)
- key &= K_LNG_MASK;
- else
- key &= ~K_LNG_MASK;
+ if (now - start > ms_to_ticks(KBD_LNG_DELAY))
+ key |= K_LONG;
}
else
- stop = now + ms_to_ticks(KBD_LNG_DELAY);
+ start = now;
return key;
}
#endif
+/**
+ * Set current mask of repeatable keys.
+ */
+keymask_t kbd_setRepeatMask(keymask_t mask)
+{
+ keymask_t oldmask = kbd_rpt_mask;
+ ATOMIC(kbd_rpt_mask = mask);
+ return oldmask;
+}
+
/*!
* Handle keyboard repeat
*/
static keymask_t kbd_rptHandlerFunc(keymask_t key)
{
- /*! Timer for keyboard repeat events */
+ /* Timer for keyboard repeat events. */
static ticks_t repeat_time;
+ /* Current repeat rate (for acceleration). */
static ticks_t repeat_rate; /*! Current repeat rate (for acceleration) */
ticks_t now = timer_clock();
switch (kbd_rptStatus)
{
case KS_IDLE:
- if (key & K_RPT_MASK)
+ if (key & kbd_rpt_mask)
{
repeat_time = now;
kbd_rptStatus = KS_REPDELAY;
break;
case KS_REPDELAY:
- if (key & K_RPT_MASK)
+ if (key & kbd_rpt_mask)
{
if (now - repeat_time > ms_to_ticks(KBD_REPEAT_DELAY))
{
- key = (key & K_RPT_MASK) | K_REPEAT;
+ key = (key & kbd_rpt_mask) | K_REPEAT;
repeat_time = now;
repeat_rate = ms_to_ticks(KBD_REPEAT_RATE);
kbd_rptStatus = KS_REPEAT;
break;
case KS_REPEAT:
- if (key & K_RPT_MASK)
+ if (key & kbd_rpt_mask)
{
if (now - repeat_time > repeat_rate)
{
/* Enqueue a new event in the buffer */
- key = (key & K_RPT_MASK) | K_REPEAT;
+ key = (key & kbd_rpt_mask) | K_REPEAT;
repeat_time = now;
/* Repeat rate acceleration */
*/
void kbd_init(void)
{
+#if CONFIG_KBD_BEEP
MOD_CHECK(buzzer);
+#endif
KBD_HW_INIT;
kbd_defHandler.pri = -128; /* lowest priority */
kbd_addHandler(&kbd_defHandler);
+#if CONFIG_KBD_OBSERVER
+ observer_InitSubject(&kbd_subject);
+#endif
+
#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
MOD_CHECK(timer);