From f9dc545b831e4139eebb9d011bbd4e00bcc6a899 Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Mon, 1 Apr 2024 18:00:36 +0200 Subject: [PATCH] suspend: update wake up matrix after wake up delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If USB_SUSPEND_WAKEUP_DELAY is set, the keyboard sleeps during wake up - which can be up to multiple seconds. To handle key presses and releases in that time frame we have to handle the following cases: 1. Key not pressed before suspend, and not pressed after wakeup → do nothing (normal case). 2. Key not pressed before suspend, but pressed after wakeup → set the wakeup_matrix bit to 1 (so that the press and release events would be suppressed). 3. Key pressed before suspend, but not pressed after wakeup → do nothing (the release event will be generated on the first matrix_task() call after the wakeup). 4. Key pressed before suspend, and still pressed after wakeup → do nothing (the release event will be generated some time later). Signed-off-by: Stefan Kerkmann Co-authored-by: Sergey Vlasov --- platforms/suspend.c | 19 ++++++++++++++++--- platforms/suspend.h | 1 + quantum/keyboard.c | 4 ++-- tmk_core/protocol/chibios/chibios.c | 3 +++ tmk_core/protocol/lufa/lufa.c | 3 +++ tmk_core/protocol/vusb/protocol.c | 3 +++ 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/platforms/suspend.c b/platforms/suspend.c index 0818a726ce1..4756796ea43 100644 --- a/platforms/suspend.c +++ b/platforms/suspend.c @@ -4,6 +4,7 @@ #include "suspend.h" #include "matrix.h" +extern matrix_row_t matrix_previous[MATRIX_ROWS]; static matrix_row_t wakeup_matrix[MATRIX_ROWS]; // TODO: Move to more correct location @@ -48,14 +49,26 @@ bool suspend_wakeup_condition(void) { matrix_power_down(); bool wakeup = false; - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - wakeup_matrix[r] = matrix_get_row(r); - wakeup |= wakeup_matrix[r] != 0; + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + wakeup_matrix[row] = matrix_get_row(row); + wakeup |= wakeup_matrix[row] != 0; } return wakeup; } +void update_matrix_state_after_wakeup(void) { + matrix_power_up(); + matrix_scan(); + matrix_power_down(); + + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + const matrix_row_t current_row = matrix_get_row(row); + wakeup_matrix[row] |= current_row & ~matrix_previous[row]; + matrix_previous[row] |= current_row; + } +} + bool keypress_is_wakeup_key(uint8_t row, uint8_t col) { return (wakeup_matrix[row] & ((matrix_row_t)1 << col)); } diff --git a/platforms/suspend.h b/platforms/suspend.h index 762bef12dbc..3a7f51f9f07 100644 --- a/platforms/suspend.h +++ b/platforms/suspend.h @@ -15,6 +15,7 @@ void suspend_power_down_kb(void); void suspend_power_down_quantum(void); bool keypress_is_wakeup_key(uint8_t row, uint8_t col); +void update_matrix_state_after_wakeup(void); void wakeup_matrix_handle_key_event(uint8_t row, uint8_t col, bool pressed); #ifndef USB_SUSPEND_WAKEUP_DELAY diff --git a/quantum/keyboard.c b/quantum/keyboard.c index 42087c75d38..7da56cb30ec 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -571,6 +571,8 @@ static inline void generate_tick_event(void) { } } +matrix_row_t matrix_previous[MATRIX_ROWS]; + /** * @brief This task scans the keyboards matrix and processes any key presses * that occur. @@ -584,8 +586,6 @@ static bool matrix_task(void) { return false; } - static matrix_row_t matrix_previous[MATRIX_ROWS]; - matrix_scan(); bool matrix_changed = false; for (uint8_t row = 0; row < MATRIX_ROWS && !matrix_changed; row++) { diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index cf948154f9b..7c78bf5afe3 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c @@ -193,6 +193,9 @@ void protocol_pre_task(void) { // // Pause for a while to let things settle... wait_ms(USB_SUSPEND_WAKEUP_DELAY); + // ...and then update the wakeup matrix again as the waking key + // might have been released during the delay + update_matrix_state_after_wakeup(); # endif } } diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 81da035f0c0..4f026319136 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -836,6 +836,9 @@ void protocol_pre_task(void) { // // Pause for a while to let things settle... wait_ms(USB_SUSPEND_WAKEUP_DELAY); + // ...and then update the wakeup matrix again as the waking key + // might have been released during the delay + update_matrix_state_after_wakeup(); # endif } } diff --git a/tmk_core/protocol/vusb/protocol.c b/tmk_core/protocol/vusb/protocol.c index 41ccf451fdb..b1851f1f1d0 100644 --- a/tmk_core/protocol/vusb/protocol.c +++ b/tmk_core/protocol/vusb/protocol.c @@ -145,6 +145,9 @@ void protocol_pre_task(void) { // // Pause for a while to let things settle... wait_ms(USB_SUSPEND_WAKEUP_DELAY); + // ...and then update the wakeup matrix again as the waking key + // might have been released during the delay + update_matrix_state_after_wakeup(); # endif } }