summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Diamond <josh@windowoffire.com>2021-02-01 19:12:41 -0500
committerDrashna Jael're <drashna@live.com>2021-02-02 09:29:51 -0800
commit0aaf72a2b9bef2fb035f03dfa14fdbd6ef01fbfb (patch)
tree837806eeb0d28a3c01592b70bca10caf756ddcc5
parent9ee0271c00c05ee5dddb7d77b04b5ec2fac2bd41 (diff)
Address wake from sleep instability (#11450)
* resolve race condition between suspend and wake in LUFA * avoid multiple calls to suspend_power_down() / suspend_wakeup_init() * Remove duplicate suspend_power_down_kb() call * pause on wakeup to wait for USB state to settle * need the repeated suspend_power_down() (that's where the sleep is) * more efficient implementation * fine tune the pause after sending wakeup * speculative chibios version of pause-after-wake * make wakeup delay configurable, and adjust value * better location for wakeup delay
-rw-r--r--tmk_core/common/avr/suspend.c1
-rw-r--r--tmk_core/common/suspend.h4
-rw-r--r--tmk_core/protocol/chibios/usb_main.c11
-rw-r--r--tmk_core/protocol/lufa/lufa.c24
4 files changed, 35 insertions, 5 deletions
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index a879d6bab0..807c837e36 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -110,7 +110,6 @@ static void power_down(uint8_t wdto) {
rgblight_disable_noeeprom();
}
# endif
- suspend_power_down_kb();
// TODO: more power saving
// See PicoPower application note
diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h
index 766df95aa1..9d17d984ed 100644
--- a/tmk_core/common/suspend.h
+++ b/tmk_core/common/suspend.h
@@ -12,3 +12,7 @@ void suspend_wakeup_init_user(void);
void suspend_wakeup_init_kb(void);
void suspend_power_down_user(void);
void suspend_power_down_kb(void);
+
+#ifndef USB_SUSPEND_WAKEUP_DELAY
+# define USB_SUSPEND_WAKEUP_DELAY 200
+#endif
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 4e3176ab26..67ae8520fd 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -701,6 +701,17 @@ void init_usb_driver(USBDriver *usbp) {
void restart_usb_driver(USBDriver *usbp) {
usbStop(usbp);
usbDisconnectBus(usbp);
+
+#if USB_SUSPEND_WAKEUP_DELAY > 0
+ // Some hubs, kvm switches, and monitors do
+ // weird things, with USB device state bouncing
+ // around wildly on wakeup, yielding race
+ // conditions that can corrupt the keyboard state.
+ //
+ // Pause for a while to let things settle...
+ wait_ms(USB_SUSPEND_WAKEUP_DELAY);
+#endif
+
usbStart(usbp, &usbcfg);
usbConnectBus(usbp);
}
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index ce31e54990..3c6b1cffaf 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -498,7 +498,9 @@ void EVENT_USB_Device_Suspend() {
*/
void EVENT_USB_Device_WakeUp() {
print("[W]");
+#if defined(NO_USB_STARTUP_CHECK)
suspend_wakeup_init();
+#endif
#ifdef SLEEP_LED_ENABLE
sleep_led_disable();
@@ -1184,12 +1186,26 @@ int main(void) {
print("Keyboard start.\n");
while (1) {
#if !defined(NO_USB_STARTUP_CHECK)
- while (USB_DeviceState == DEVICE_STATE_Suspended) {
+ if (USB_DeviceState == DEVICE_STATE_Suspended) {
print("[s]");
- suspend_power_down();
- if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
- USB_Device_SendRemoteWakeup();
+ while (USB_DeviceState == DEVICE_STATE_Suspended) {
+ suspend_power_down();
+ if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
+ USB_Device_SendRemoteWakeup();
+ clear_keyboard();
+
+# if USB_SUSPEND_WAKEUP_DELAY > 0
+ // Some hubs, kvm switches, and monitors do
+ // weird things, with USB device state bouncing
+ // around wildly on wakeup, yielding race
+ // conditions that can corrupt the keyboard state.
+ //
+ // Pause for a while to let things settle...
+ wait_ms(USB_SUSPEND_WAKEUP_DELAY);
+# endif
+ }
}
+ suspend_wakeup_init();
}
#endif