Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address wake from sleep instability #11450

Merged
merged 10 commits into from
Feb 2, 2021
2 changes: 2 additions & 0 deletions docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ This is a C header file that is one of the first things included, and will persi
* sets the maximum power (in mA) over USB for the device (default: 500)
* `#define USB_POLLING_INTERVAL_MS 10`
* sets the USB polling rate in milliseconds for the keyboard, mouse, and shared (NKRO/media keys) interfaces
* `#define USB_SUSPEND_WAKEUP_DELAY 200`
* set the number of milliseconde to pause after sending a wakeup packet
* `#define F_SCL 100000L`
* sets the I2C clock rate speed for keyboards using I2C. The default is `400000L`, except for keyboards using `split_common`, where the default is `100000L`.

Expand Down
1 change: 0 additions & 1 deletion tmk_core/common/avr/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
spidey3 marked this conversation as resolved.
Show resolved Hide resolved

// TODO: more power saving
// See PicoPower application note
Expand Down
4 changes: 4 additions & 0 deletions tmk_core/common/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 11 additions & 0 deletions tmk_core/protocol/chibios/usb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
24 changes: 20 additions & 4 deletions tmk_core/protocol/lufa/lufa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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

Expand Down