diff options
author | Angus Gratton <angus@redyak.com.au> | 2024-05-07 17:02:11 +1000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-05-09 15:22:31 +1000 |
commit | 9a43989a8651dacc004f9bb8df6574c814ec98ca (patch) | |
tree | 66d93538ca85b0b963d58196efb3ae5116aef3f5 /shared/tinyusb/mp_usbd_runtime.c | |
parent | 8762fe8b4c6a7608d48daa8458e6501fafd3eafc (diff) |
shared/tinyusb: Stall the CDC IN endpoint while disconnecting.
Only when dynamic USB devices are enabled.
The issue here is that when the USB reset triggers, the dynamic USB device
reset callback is called from inside the TinyUSB task.
If that callback tries to print something then it'll call through to
tud_cdc_write_flush(), but TinyUSB hasn't finished updating state yet to
know it's no longer configured. Subsequently it may try to queue a transfer
and then the low-level DCD layer panics.
By explicitly stalling the endpoint first, usbd_edpt_claim() will fail and
tud_cdc_write_flush() returns immediately.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Diffstat (limited to 'shared/tinyusb/mp_usbd_runtime.c')
-rw-r--r-- | shared/tinyusb/mp_usbd_runtime.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/shared/tinyusb/mp_usbd_runtime.c b/shared/tinyusb/mp_usbd_runtime.c index 7ff7dd4ab..e10d1cb3f 100644 --- a/shared/tinyusb/mp_usbd_runtime.c +++ b/shared/tinyusb/mp_usbd_runtime.c @@ -472,6 +472,8 @@ static void mp_usbd_disconnect(mp_obj_usb_device_t *usbd) { #if MICROPY_HW_USB_CDC // Ensure no pending static CDC writes, as these can cause TinyUSB to crash tud_cdc_write_clear(); + // Prevent cdc write flush from initiating any new transfers while disconnecting + usbd_edpt_stall(USBD_RHPORT, USBD_CDC_EP_IN); #endif bool was_connected = tud_connected(); |