summaryrefslogtreecommitdiffstats
path: root/app/keypad.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/keypad.c')
-rw-r--r--app/keypad.c148
1 files changed, 106 insertions, 42 deletions
diff --git a/app/keypad.c b/app/keypad.c
index daea5c7..d4a82db 100644
--- a/app/keypad.c
+++ b/app/keypad.c
@@ -7,76 +7,140 @@
#define KEYPAD_DELAY do { delay_us(1); } while (0)
-uint16_t keypad_read(void)
-{
-uint16_t ret=0;
-uint16_t c;
-/*Reset the state machine in the keypad */
+#define SCAN_INTERVAL 73
+#define DEBOUNCE_INTERVAL 1
+#define DEBOUNCE_COUNT 3
-gpio_set (GPIO_DATA, DATA);
-KEYPAD_DELAY;
-gpio_clear (GPIO_DATA, DATA);
-KEYPAD_DELAY;
-gpio_set (GPIO_DATA, DATA);
-KEYPAD_DELAY;
+static uint32_t next_scan;
-gpio_clear (GPIO_CLOCK, CLOCK);
-KEYPAD_DELAY;
-for (c=0x8000;c;c>>=1)
+uint16_t
+keypad_raw_read (void)
{
-gpio_set (GPIO_CLOCK, CLOCK);
-KEYPAD_DELAY;
-if (!(gpio_get (GPIO_DATA, DATA) & DATA)) ret|=c;
-gpio_clear (GPIO_CLOCK, CLOCK);
-KEYPAD_DELAY;
-}
+ uint16_t ret = 0;
+ uint16_t c;
-gpio_set (GPIO_CLOCK, CLOCK);
+/*Reset the state machine in the keypad */
-return ret;
+ gpio_set (GPIO_DATA, DATA);
+ KEYPAD_DELAY;
+ gpio_clear (GPIO_DATA, DATA);
+ KEYPAD_DELAY;
+ gpio_set (GPIO_DATA, DATA);
+ KEYPAD_DELAY;
+
+ gpio_clear (GPIO_CLOCK, CLOCK);
+ KEYPAD_DELAY;
+
+ for (c = 0x8000; c; c >>= 1)
+ {
+ gpio_set (GPIO_CLOCK, CLOCK);
+ KEYPAD_DELAY;
+ if (!(gpio_get (GPIO_DATA, DATA) & DATA))
+ ret |= c;
+ gpio_clear (GPIO_CLOCK, CLOCK);
+ KEYPAD_DELAY;
+ }
+
+ gpio_set (GPIO_CLOCK, CLOCK);
+
+ return ret;
}
-static void
-keypad_scan (void)
+uint16_t
+keypad_read (void)
{
+ int c;
+ const uint8_t lut[] = "cdef89ab45670123";
+ uint8_t ret = 0;
- uint16_t v;
- char buf[16];
- v=keypad_read();
-
- sprintf (buf, "%04x", v);
- lcd_write (buf, 0, 1);
-
+/*Reset the state machine in the keypad */
+ gpio_set (GPIO_DATA, DATA);
+ KEYPAD_DELAY;
+ gpio_clear (GPIO_DATA, DATA);
+ KEYPAD_DELAY;
+ gpio_set (GPIO_DATA, DATA);
+ KEYPAD_DELAY;
+
+ gpio_clear (GPIO_CLOCK, CLOCK);
+ KEYPAD_DELAY;
+
+ for (c = 0; c < 16; ++c)
+ {
+ gpio_set (GPIO_CLOCK, CLOCK);
+ KEYPAD_DELAY;
+ if (!(gpio_get (GPIO_DATA, DATA) & DATA))
+ ret = lut[c];
+ gpio_clear (GPIO_CLOCK, CLOCK);
+ KEYPAD_DELAY;
+ }
+
+ gpio_set (GPIO_CLOCK, CLOCK);
+
+ return ret;
}
-void
-keypad_tick (void)
-{
- static int c;
- c++;
+static void
+keypad_scan (void)
+{
+ static uint8_t last_v;
+ static uint8_t key_down;
+ static int same;
+ uint8_t v;
+
+ v = keypad_read ();
+
+ next_scan = DEBOUNCE_INTERVAL;
+
+ if (v!=last_v) {
+ last_v=v;
+ same=0;
+ return;
+ } else {
+ if (same<DEBOUNCE_COUNT) {
+ same++;
+ return;
+ }
+ }
+
+ if (!v && !key_down) {
+ next_scan = SCAN_INTERVAL;
+ return;
+ }
+
+ if (key_down==v) {
+ return;
+ } else if (key_down!=v) {
+ if (key_down)
+ key_event (key_down, 0);
+ key_down=v;
+ if (key_down)
+ key_event (key_down, 1);
+ }
+}
- if (c < 73)
- return;
- c = 0;
- keypad_scan ();
+void
+keypad_tick (void)
+{
+ if (!next_scan)
+ keypad_scan ();
+ else
+ next_scan--;
}
-
-
void
keypad_init (void)
{