From fe35558ec77efa375080ba7eafbd6ca773eb86f5 Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Mon, 1 Apr 2024 14:16:29 +0200 Subject: [PATCH 1/2] suspend: suppress wake up keypress Waking the host from suspend is done by pressing any key on the keyboard, the regular key codes assigned to the keys are not important and must not be sent - otherwise they usually end up in password prompts as ghost characters that have to be deleted again. This commit adds suppression for all keys pressed at the time of wake up. Once a key is released it functions as a regular key again. Signed-off-by: Stefan Kerkmann --- platforms/suspend.c | 20 ++++++++++++++++++-- platforms/suspend.h | 3 +++ quantum/keyboard.c | 4 +++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/platforms/suspend.c b/platforms/suspend.c index fea23cbd02b..0818a726ce1 100644 --- a/platforms/suspend.c +++ b/platforms/suspend.c @@ -4,6 +4,8 @@ #include "suspend.h" #include "matrix.h" +static matrix_row_t wakeup_matrix[MATRIX_ROWS]; + // TODO: Move to more correct location __attribute__((weak)) void matrix_power_up(void) {} __attribute__((weak)) void matrix_power_down(void) {} @@ -44,8 +46,22 @@ bool suspend_wakeup_condition(void) { matrix_power_up(); matrix_scan(); matrix_power_down(); + + bool wakeup = false; for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - if (matrix_get_row(r)) return true; + wakeup_matrix[r] = matrix_get_row(r); + wakeup |= wakeup_matrix[r] != 0; + } + + return wakeup; +} + +bool keypress_is_wakeup_key(uint8_t row, uint8_t col) { + return (wakeup_matrix[row] & ((matrix_row_t)1 << col)); +} + +void wakeup_matrix_handle_key_event(uint8_t row, uint8_t col, bool pressed) { + if (!pressed) { + wakeup_matrix[row] &= ~((matrix_row_t)1 << col); } - return false; } diff --git a/platforms/suspend.h b/platforms/suspend.h index e4f7f39ddb8..762bef12dbc 100644 --- a/platforms/suspend.h +++ b/platforms/suspend.h @@ -14,6 +14,9 @@ void suspend_power_down_user(void); void suspend_power_down_kb(void); void suspend_power_down_quantum(void); +bool keypress_is_wakeup_key(uint8_t row, uint8_t col); +void wakeup_matrix_handle_key_event(uint8_t row, uint8_t col, bool pressed); + #ifndef USB_SUSPEND_WAKEUP_DELAY # define USB_SUSPEND_WAKEUP_DELAY 0 #endif diff --git a/quantum/keyboard.c b/quantum/keyboard.c index df1dc1c3ee0..759ccf9cd68 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -32,6 +32,7 @@ along with this program. If not, see . #include "sendchar.h" #include "eeconfig.h" #include "action_layer.h" +#include "suspend.h" #ifdef BOOTMAGIC_ENABLE # include "bootmagic.h" #endif @@ -505,6 +506,7 @@ void switch_events(uint8_t row, uint8_t col, bool pressed) { #if defined(RGB_MATRIX_ENABLE) rgb_matrix_handle_key_event(row, col, pressed); #endif + wakeup_matrix_handle_key_event(row, col, pressed); } /** @@ -568,7 +570,7 @@ static bool matrix_task(void) { if (row_changes & col_mask) { const bool key_pressed = current_row & col_mask; - if (process_keypress) { + if (process_keypress && !keypress_is_wakeup_key(row, col)) { action_exec(MAKE_KEYEVENT(row, col, key_pressed)); } From 71521d71c58a257efaa68c344633dd2e53e9550b Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Mon, 1 Apr 2024 18:00:36 +0200 Subject: [PATCH 2/2] suspend: update wake up matrix after wake up delay If USB_SUSPEND_WAKEUP_DELAY is set, the keyboard sleeps during wake up - which can be up to multiple seconds. To not miss any key releases the wake up matrix is updated with the current state of the matrix - only resetting the keys that have been released. Signed-off-by: Stefan Kerkmann --- platforms/suspend.c | 14 ++++++++++++++ platforms/suspend.h | 1 + tmk_core/protocol/chibios/chibios.c | 3 +++ tmk_core/protocol/lufa/lufa.c | 3 +++ tmk_core/protocol/vusb/protocol.c | 3 +++ 5 files changed, 24 insertions(+) diff --git a/platforms/suspend.c b/platforms/suspend.c index 0818a726ce1..74b45a3327b 100644 --- a/platforms/suspend.c +++ b/platforms/suspend.c @@ -56,6 +56,20 @@ bool suspend_wakeup_condition(void) { return wakeup; } +void wakeup_matrix_update(void) { + matrix_power_up(); + matrix_scan(); + matrix_power_down(); + + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + matrix_row_t matrix_row = matrix_get_row(row); + matrix_row_t col_mask = 1; + for (uint8_t col = 0; col < MATRIX_COLS; col++, col_mask <<= 1) { + wakeup_matrix_handle_key_event(row, col, matrix_row & col_mask); + } + } +} + 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..dbaab90805c 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 wakeup_matrix_update(void); void wakeup_matrix_handle_key_event(uint8_t row, uint8_t col, bool pressed); #ifndef USB_SUSPEND_WAKEUP_DELAY diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index b879bdac778..3ae1e7d0239 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c @@ -194,6 +194,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 + wakeup_matrix_update(); # endif } } diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index b0c9758d2fd..1ce81220282 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -848,6 +848,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 + wakeup_matrix_update(); # endif } } diff --git a/tmk_core/protocol/vusb/protocol.c b/tmk_core/protocol/vusb/protocol.c index 41ccf451fdb..1b9ba2951d6 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 + wakeup_matrix_update(); # endif } }