diff options
-rw-r--r-- | chip/stm32/keyboard_scan.c | 87 | ||||
-rw-r--r-- | include/keyboard_scan.h | 3 |
2 files changed, 87 insertions, 3 deletions
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c index 1338f1b889..14bb331b1b 100644 --- a/chip/stm32/keyboard_scan.c +++ b/chip/stm32/keyboard_scan.c @@ -9,6 +9,7 @@ * TODO: Finish cleaning up nomenclature (cols/rows/inputs/outputs), */ +#include "atomic.h" #include "board.h" #include "console.h" #include "gpio.h" @@ -76,6 +77,82 @@ void __board_keyboard_suppress_noise(void) void board_keyboard_suppress_noise(void) __attribute__((weak, alias("__board_keyboard_suppress_noise"))); +#define KB_FIFO_DEPTH 16 /* FIXME: this is pretty huge */ +static int kb_fifo_start; /* first entry */ +static int kb_fifo_end; /* last entry */ +static uint32_t kb_fifo_entries; /* number of existing entries */ +static uint8_t kb_fifo[KB_FIFO_DEPTH][KB_OUTPUTS]; + +/* clear keyboard state variables */ +void keyboard_clear_state(void) +{ + int i; + + CPRINTF("clearing keyboard fifo\n"); + kb_fifo_start = 0; + kb_fifo_end = 0; + kb_fifo_entries = 0; + for (i = 0; i < KB_FIFO_DEPTH; i++) + memset(kb_fifo[i], 0, KB_OUTPUTS); +} + +/** + * Add keyboard state into FIFO + * + * @return EC_SUCCESS if entry added, EC_ERROR_OVERFLOW if FIFO is full + */ +static int kb_fifo_add(uint8_t *buffp) +{ + int ret = EC_SUCCESS; + + if (kb_fifo_entries == KB_FIFO_DEPTH) { + CPRINTF("%s: FIFO depth reached\n", __func__); + ret = EC_ERROR_OVERFLOW; + goto kb_fifo_push_done; + } + + memcpy(kb_fifo[kb_fifo_end], buffp, KB_OUTPUTS); + + if (kb_fifo_end == KB_FIFO_DEPTH - 1) + kb_fifo_end = 0; + else + kb_fifo_end++; + + atomic_add(&kb_fifo_entries, 1); + +kb_fifo_push_done: + return ret; +} + +/** + * Pop keyboard state from FIFO + * + * @return EC_SUCCESS if entry popped, EC_ERROR_UNKNOWN if FIFO is empty + */ +static int kb_fifo_remove(uint8_t *buffp) +{ + memcpy(buffp, kb_fifo[kb_fifo_start], KB_OUTPUTS); + + if (!kb_fifo_entries) { + CPRINTF("%s: No entries remaining in FIFO\n", __func__); + /* + * Bail out without changing any FIFO indices and let the + * caller know something strange happened. The buffer will + * will contain the last known state of the keyboard. + */ + return EC_ERROR_UNKNOWN; + } + + if (kb_fifo_start == KB_FIFO_DEPTH - 1) + kb_fifo_start = 0; + else + kb_fifo_start++; + + atomic_sub(&kb_fifo_entries, 1); + + return EC_SUCCESS; +} + static void select_column(int col) { int i, done = 0; @@ -224,9 +301,7 @@ static int check_keys_changed(void) } if (change) { - memcpy(saved_state, raw_state, sizeof(saved_state)); board_keyboard_suppress_noise(); - board_interrupt_host(); CPRINTF("[%d keys pressed: ", num_press); for (c = 0; c < KB_OUTPUTS; c++) { @@ -236,6 +311,11 @@ static int check_keys_changed(void) CPUTS(" --"); } CPUTS("]\n"); + + if (kb_fifo_add(raw_state) == EC_SUCCESS) + board_interrupt_host(); + else + CPRINTF("dropped keystroke\n"); } return num_press ? 1 : 0; @@ -308,6 +388,7 @@ int keyboard_scan_recovery_pressed(void) int keyboard_get_scan(uint8_t **buffp, int max_bytes) { + kb_fifo_remove(saved_state); *buffp = saved_state; - return sizeof(saved_state); + return KB_OUTPUTS; } diff --git a/include/keyboard_scan.h b/include/keyboard_scan.h index 6ba01f9d0e..895fdfd2b8 100644 --- a/include/keyboard_scan.h +++ b/include/keyboard_scan.h @@ -31,4 +31,7 @@ int keyboard_scan_recovery_pressed(void); */ int keyboard_get_scan(uint8_t **buffp, int max_bytes); +/* clear any saved keyboard state (empty FIFO, etc) */ +void keyboard_clear_state(void); + #endif /* __CROS_KEYBOARD_SCAN_H */ |