Skip to content

Commit

Permalink
shared/tinyusb: Stall the CDC IN endpoint while disconnecting.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
projectgus authored and dpgeorge committed May 9, 2024
1 parent 8762fe8 commit 9a43989
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions shared/tinyusb/mp_usbd_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 9a43989

Please sign in to comment.