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
This commit is contained in:
committed by
Drashna Jael're
parent
9ee0271c00
commit
0aaf72a2b9
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,13 +1186,27 @@ 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]");
|
||||
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
|
||||
|
||||
keyboard_task();
|
||||
|
||||
Reference in New Issue
Block a user