circuitpython: NRF: USB Disconnect / Reconnect / Enumeration fails during sleep
With the most recent patches, issuing time.sleep(x)
issues a wfi
instruction. This aggressively puts the CPU to sleep. However, this appears to cause USB to no longer enumerate. While this is not an issue with a device that’s powered off of USB, if a device has its own battery, then this will prevent the device from enumerating during sleep.
Steps to reproduce
The following code.py
should trigger this bug:
from time import sleep
sleep(60)
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 16 (4 by maintainers)
Commits related to this issue
- nrf: disable interrupts before running wfi Also, run background tasks with interrupts disabled. This ensures that any buffers are drained, and if an interrupt arrives after buffers are drained but b... — committed to simmel-project/circuitpython by xobs 4 years ago
- nrf: disable interrupts before running wfi Also, run background tasks with interrupts disabled. This ensures that any buffers are drained, and if an interrupt arrives after buffers are drained but b... — committed to simmel-project/circuitpython by xobs 4 years ago
- nrf: disable interrupts before running wfi Also, run background tasks with interrupts disabled. This ensures that any buffers are drained, and if an interrupt arrives after buffers are drained but b... — committed to simmel-project/circuitpython by xobs 4 years ago
- nrf: disable interrupts before running wfi In order to ensure we don't have any outstanding requests, disable interrupts prior to issuing `WFI`. As part of this process, check to see if there are an... — committed to simmel-project/circuitpython by xobs 4 years ago
WFI does work fine if interrupts are enabled, but without disabling interrupts you can never be sure that there isn’t pending data before issuing
WFI
For example:Even though
usb_background()
drains the buffer, you still could have an interrupt arrive between thebx lr
and thewfi
instruction. If interrupts are enabled, then that will get serviced and there will be data waiting in the queue. If that is a packet from the host, then you will go to sleep without responding to that packet and the host will time out the device.The solution is to disable interrupts, flush buffers, and issue
wfi
. If there’s a pending interrupt it will return immediately, allowing you to re-enable interrupts and have it serviced.