keyboardio / Kaleidoscope

Firmware for Keyboardio keyboards and other keyboards with AVR or ARM MCUs.
http://keyboard.io
GNU General Public License v3.0
756 stars 259 forks source link

Model 01 doesn't always stay suspended #1261

Open tlyu opened 2 years ago

tlyu commented 2 years ago

Describe the bug The Model 01 will turn off its LEDs for a normal USB suspend if it's still attached to a host. However, when connected to a powered USB hub, and the hub is then disconnected from a non-suspended host, the Model 01 will turn off its LEDs, and then turn them back on in less than a second. The Model 100 doesn't have this behavior.

To Reproduce Connect a Model 01 to a host through a powered hub. Disconnect the powered hub from the host.

Expected behavior The Model 01 should keep its LEDs off when a powered hub that it's connected to is disconnected from a host.

Environment (please complete the following information):

Additional context N/A

tlyu commented 2 years ago

Some close reading of the ATmega32U4 datasheet suggests that the Arduino AVR core might have a very old bug where it's using the wrong interrupt flag to detect a wakeup/resume condition. It might be using the wakeup interrupt flag (WAKEUPI), which detects any bus activity, possibly including a long-SE0 (reset) condition. There's a different interrupt flag (EORSMI) that detects an end-of-resume status.

I think (but haven't confirmed) that a self-powered hub sets its downstream ports to SE0 when disconnected from the host.

tlyu commented 11 months ago

Update: hub is a Belkin USB 3 hub with apparently some battery charging capability. When disconnected from a host, it sets D- to an intermediate value, and the AVR core sees it as a wakeup (because WAKEUPI triggers on any non-idle signal). A quick patch to use EORSMI seems to partially work, but doesn't always stay suspended when connected to hub when the hub is powered, but disconnected from the host. I'm guessing SUSPI won't reliably trigger unless it detects an electrical bus idle condition (D+ high, D- low), rather than a lack of SOF packets.