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:
		
							parent
							
								
									85079d6a2e
								
							
						
					
					
						commit
						9a4618b05b
					
				
					 5 changed files with 37 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -102,7 +102,6 @@ static void power_down(uint8_t wdto) {
 | 
			
		|||
#    if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
 | 
			
		||||
    rgblight_suspend();
 | 
			
		||||
#    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -708,6 +708,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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -435,7 +435,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();
 | 
			
		||||
| 
						 | 
				
			
			@ -1073,12 +1075,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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue