diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-10-09 13:05:49 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-10-10 14:53:16 -0700 |
commit | 160b343e7c75a939d64ef92146c78db97498c9d6 (patch) | |
tree | e7bba985e53c5dbaf507720e5f74fabe14b6affd /chip/stm32 | |
parent | 8d187addc8ca7f8379185b33171995e1b113e55f (diff) | |
download | chrome-ec-160b343e7c75a939d64ef92146c78db97498c9d6.tar.gz |
stm32: fix race condition enabling keyboard interrupt
Previously, if a key was pressed after the last polling but
the interrupts were fully enabled, we were missing the edge.
So dropping the key press event and seeing only the key release.
Now we check if keys are down before waiting for the next interrupt,
if any, we re-start polling immediatly.
The row state reading code is unchanged, just moved to a function
in order to re-use it.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
(Note: This patch was originally submitted in the firmware-snow-2695.B
branch, but needed some re-factoring to merge cleanly into ToT)
BRANCH=snow
BUG=chrome-os-partner:7484 chrome-os-partner:12179
TEST=type on the keyboard and do not see any missing key presses.
On instrumented board, record the the matrix scans with a logic analyzer
and stare at the waveforms.
Change-Id: I98dc4c3af9611a276b960887384a6304b91d8b30
Reviewed-on: https://gerrit.chromium.org/gerrit/35168
Commit-Ready: David Hendricks <dhendrix@chromium.org>
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Tested-by: David Hendricks <dhendrix@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip/stm32')
-rw-r--r-- | chip/stm32/keyboard_scan.c | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c index 23513ee4c0..243292287a 100644 --- a/chip/stm32/keyboard_scan.c +++ b/chip/stm32/keyboard_scan.c @@ -282,6 +282,44 @@ static void print_state(const uint8_t *state, const char *msg) CPUTS("]\n"); } +static uint8_t read_raw_row_state(void) +{ + uint16_t tmp; + uint8_t r = 0; + + /* + * TODO(sjg@chromium.org): This code can be improved by doing + * the job in 3 shift/or operations. + */ + tmp = STM32_GPIO_IDR(C); + /* KB_COL00:04 = PC8:12 */ + if (tmp & (1 << 8)) + r |= 1 << 0; + if (tmp & (1 << 9)) + r |= 1 << 1; + if (tmp & (1 << 10)) + r |= 1 << 2; + if (tmp & (1 << 11)) + r |= 1 << 3; + if (tmp & (1 << 12)) + r |= 1 << 4; + /* KB_COL05:06 = PC14:15 */ + if (tmp & (1 << 14)) + r |= 1 << 5; + if (tmp & (1 << 15)) + r |= 1 << 6; + + tmp = STM32_GPIO_IDR(D); + /* KB_COL07 = PD2 */ + if (tmp & (1 << 2)) + r |= 1 << 7; + + /* Invert it so 0=not pressed, 1=pressed */ + r ^= 0xff; + + return r; +} + /** * Read the raw keyboard matrix state. * @@ -299,42 +337,11 @@ static int read_matrix(uint8_t *state) int pressed = 0; for (c = 0; c < KB_OUTPUTS; c++) { - uint16_t tmp; - /* Select column, then wait a bit for it to settle */ select_column(c); udelay(config.output_settle_us); - /* - * TODO(sjg@chromium.org): This code can be improved by doing - * the job in 3 shift/or operations. - */ - r = 0; - tmp = STM32_GPIO_IDR(C); - /* KB_COL00:04 = PC8:12 */ - if (tmp & (1 << 8)) - r |= 1 << 0; - if (tmp & (1 << 9)) - r |= 1 << 1; - if (tmp & (1 << 10)) - r |= 1 << 2; - if (tmp & (1 << 11)) - r |= 1 << 3; - if (tmp & (1 << 12)) - r |= 1 << 4; - /* KB_COL05:06 = PC14:15 */ - if (tmp & (1 << 14)) - r |= 1 << 5; - if (tmp & (1 << 15)) - r |= 1 << 6; - - tmp = STM32_GPIO_IDR(D); - /* KB_COL07 = PD2 */ - if (tmp & (1 << 2)) - r |= 1 << 7; - - /* Invert it so 0=not pressed, 1=pressed */ - r ^= 0xff; + r = read_raw_row_state(); #ifdef OR_WITH_CURRENT_STATE_FOR_TESTING /* KLUDGE - or current state in, so we can make sure @@ -512,8 +519,13 @@ static void scan_keyboard(void) setup_interrupts(); mutex_unlock(&scanning_enabled); - /* Wait until we get an interrupt */ - task_wait_event(-1); + /* + * if a key was pressed after the last polling, + * re-start immediatly polling instead of waiting + * for the next interrupt. + */ + if (!read_raw_row_state()) + task_wait_event(-1); enter_polling_mode(); @@ -543,11 +555,6 @@ static void scan_keyboard(void) wait_time = config.min_post_scan_delay_us; task_wait_event(wait_time); } - /* - * TODO: (crosbug.com/p/7484) A race condition here. - * If a key state is changed here (before interrupt is - * enabled), it will be lost. - */ } void keyboard_scan_task(void) |