diff options
Diffstat (limited to 'app/keypad.c')
-rw-r--r-- | app/keypad.c | 148 |
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) { |