tmk / tmk_keyboard

Keyboard firmwares for Atmel AVR and Cortex-M
3.99k stars 1.71k forks source link

LUFA: ATMega32u2 not remote wakeup #361

Closed tmk closed 8 years ago

tmk commented 8 years ago

Alps64(ATMega32u2 and LUFA) can't wake Windows10 from sleep. HHKB can wake it, though. Investigation of the differences is needed.

tmk commented 8 years ago

ATMega32u2 has no VBUS monitoring feature unlike 32u4 and limited ability of USB event firing. LUFA cannot determine suspend and wakeup device state accurately with 32u2, it fires connect and disconnect respectively instead unless NO_LIMITED_CONTROLLER_CONNECT is not defined.

In TMK remote wakeup cannot be used because suspend state is not available for 32u2. To make use of suspend/wakeup state on the controller you need to define NO_LIMITED_CONTROLLER_CONNECT. As LUFA document says those states are not necessarily accurate but it seems like that is not problem for our purpose.

WORKAROUND: Add this line in Makefile.

OPT_DEFS += -DNO_LIMITED_CONTROLLER_CONNECT

From LUFA document

http://www.fourwalledcubicle.com/files/LUFA/Doc/140302/html/group___group___events.html#gaf7772033ffb4f51edf02d791f976cfd5

void EVENT_USB_Device_Suspend ( void ) void EVENT_USB_Device_WakeUp ( void )

This event does not exist on the microcontrollers with limited USB VBUS sensing abilities when the NO_LIMITED_CONTROLLER_CONNECT compile time token is not set

void EVENT_USB_Device_Connect ( void ) void EVENT_USB_Device_Disconnect ( void )

This event may fire multiple times during device enumeration on the microcontrollers with limited USB controllers if NO_LIMITED_CONTROLLER_CONNECT is not defined.

For the microcontrollers with limited USB controller functionality, VBUS sensing is not available. this means that the current connection state is derived from the bus suspension and wake up events by default, which is not always accurate (host may suspend the bus while still connected). If the actual connection state needs to be determined, VBUS should be routed to an external pin, and the auto-detect behavior turned off by passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection and disconnection events may be manually fired, and the USB_DeviceState global changed manually.

tmk commented 8 years ago

I guess lacking of VBUS monitoring affects when the device is self-powered, Host throws pulse on VBUS line to reset the device but self-powered 32u2 cannot detect this reset signal LUFA cannot discreminate suspend and resume on bus(D-/D+) from plug and unplug(including power control on VBUS by host), LUFA emulates this reset with fake pair of handles suspend/resume singals as disconnect and connect events at the sacrifice of suspend and resume event. But most of our device is bus-powered except for Bluetooth keyboard with battery, they are forced to be powered off and on again at the VBUS reset pulse power control by host and replug action by user so we will have no problem.

EDIT: Fixed at 2019-03-30

Battery powered devices should be concerned though. We probably have to use 32u4 or detect the VBUS pulse with pin change interruption for these devices. Without this we won't be able to control USB engine properly for power saving.

tmk commented 8 years ago

We can define the macro by default.

diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk
index 87386be..d239585 100644
--- a/tmk_core/protocol/lufa.mk
+++ b/tmk_core/protocol/lufa.mk
@@ -37,6 +37,10 @@ LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABL
 #LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
 LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
 LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
+# Remote wakeup fix for ATmega32U2        https://github.com/tmk/tmk_keyboard/issues/361
+ifeq ($(MCU),atmega32u2)
+       LUFA_OPTS += -DNO_LIMITED_CONTROLLER_CONNECT
+endif

 OPT_DEFS += -DF_USB=$(F_USB)UL
 OPT_DEFS += -DARCH=ARCH_$(ARCH)
tmk commented 8 years ago

With the patch above I confirmed alps64(32u2) wakes up Windows10 on Lenovo Thinkpad X201s(upgraded from Windows7).

But Windows10 with Intel x58 still doesn't work. This needs more test on various systems. https://geekhack.org/index.php?topic=69740.msg2198714#msg2198714

I think this patch is correct move and it will be merged later anyway.

tmk commented 8 years ago

Merged. https://github.com/tmk/tmk_keyboard/commit/a65fa6437c0187766d59d3d939ebbc3c001b5b05