summaryrefslogtreecommitdiff
path: root/src/device/usbd.c
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-08-17 01:01:37 +0700
committerhathach <[email protected]>2026-08-18 20:51:21 +0700
commit073942589355676980ba401cb88c0eb9f065e468 (patch)
treea6447b4ee77f12a8127ea45d78fbfdc09c9e0337 /src/device/usbd.c
parentaf7d199e73461c25555abbdc72441ab79eb74245 (diff)
usbd: split bus reset into start/end edge events
A driver that can see reset signalling begin has no way to say so: the only event carries the negotiated speed, which does not exist until the reset ends. On ChipIdea that left the stack believing it was still configured for the whole reset window - 3 ms at minimum, tens of milliseconds in practice - while the controller had already torn its endpoints down, so a class driver writing in that window primed a disabled endpoint over a zeroed queue head. Add DCD_EVENT_BUS_RESET_START for the leading edge and rename the existing event to DCD_EVENT_BUS_RESET_END, keeping DCD_EVENT_BUS_RESET as an alias. START is optional and END stays self-sufficient, so every other driver and the unit tests are untouched.
Diffstat (limited to 'src/device/usbd.c')
-rw-r--r--src/device/usbd.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c
index f5c3046d6..7215a8dc5 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -456,7 +456,8 @@ TU_ATTR_WEAK bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
static char const *const _usbd_event_str[DCD_EVENT_COUNT] = {
"Invalid",
- "Bus Reset",
+ "Bus Reset Start",
+ "Bus Reset End",
"Unplugged",
"SOF",
"Suspend",
@@ -697,8 +698,15 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
#endif
switch (event.event_id) {
- case DCD_EVENT_BUS_RESET:
+ case DCD_EVENT_BUS_RESET_START:
+ TU_LOG_USBD("\r\n");
+ usbd_reset(event.rhport);
+ break;
+
+ case DCD_EVENT_BUS_RESET_END:
TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
+ // TODO a DCD that reports both edges pays for two teardowns: track a per-rhport
+ // "start seen" flag and skip this reset, keeping it for the single-event DCDs.
usbd_reset(event.rhport);
_usbd_dev.speed = event.bus_reset.speed;
break;