From 46bcfc03b27fba556f6fcae1d31368e7974ea231 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 24 Jul 2023 11:08:09 +0200 Subject: [PATCH 1/6] Update usbd.c bus reset includes disconnect --- src/device/usbd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 9429cf6644..c04b1d9581 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -502,9 +502,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case DCD_EVENT_BUS_RESET: TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); - usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; - break; case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); @@ -1083,6 +1081,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) { switch (event->event_id) { + case DCD_EVENT_BUS_RESET: case DCD_EVENT_UNPLUGGED: _usbd_dev.connected = 0; _usbd_dev.addressed = 0; From 340b945289f948efcb0443cc67587943831ade8d Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 25 Jul 2023 09:08:20 +0200 Subject: [PATCH 2/6] Suppress fall through warning --- src/device/usbd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/device/usbd.c b/src/device/usbd.c index c04b1d9581..dd62aa8450 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -503,6 +503,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) case DCD_EVENT_BUS_RESET: TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); _usbd_dev.speed = event.bus_reset.speed; + TU_ATTR_FALLTHROUGH; case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); @@ -778,6 +779,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const switch(p_request->bRequest) { case TUSB_REQ_GET_INTERFACE: + TU_ATTR_FALLTHROUGH; + case TUSB_REQ_SET_INTERFACE: // Clear complete callback if driver set since it can also stall the request. usbd_control_set_complete_callback(NULL); From 08336f5cab6bd071954b48482fbf7ee260bc6ccb Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 25 Jul 2023 09:13:21 +0200 Subject: [PATCH 3/6] Undo a bad change --- src/device/usbd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index dd62aa8450..9638477581 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -779,8 +779,6 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const switch(p_request->bRequest) { case TUSB_REQ_GET_INTERFACE: - TU_ATTR_FALLTHROUGH; - case TUSB_REQ_SET_INTERFACE: // Clear complete callback if driver set since it can also stall the request. usbd_control_set_complete_callback(NULL); From 75f8ce7833e9b363434c979ea10c7a0f7bd83eca Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 22 Feb 2024 14:14:21 +0000 Subject: [PATCH 4/6] Proper power state change handling on USB reset --- src/device/usbd.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 9638477581..0a2ea12c1b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -503,14 +503,30 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) case DCD_EVENT_BUS_RESET: TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); _usbd_dev.speed = event.bus_reset.speed; - TU_ATTR_FALLTHROUGH; + TU_ATTR_FALLTHROUGH; case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); - usbd_reset(event.rhport); + // Only inform application about the unmount if it was mounted before + if ( _usbd_dev.cfg_num ) + { + _usbd_dev.cfg_num = 0; + + // invoke callback + if (tud_umount_cb) tud_umount_cb(); + } - // invoke callback - if (tud_umount_cb) tud_umount_cb(); + // Inform application about a no longer valid suspend state + if ( _usbd_dev.suspended ) + { + _usbd_dev.suspended = 0; + + // invoke callback + if (tud_resume_cb) tud_resume_cb(); + } + + // Completely clear the current USB state + usbd_reset(event.rhport); break; case DCD_EVENT_SETUP_RECEIVED: @@ -1082,15 +1098,6 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) { switch (event->event_id) { - case DCD_EVENT_BUS_RESET: - case DCD_EVENT_UNPLUGGED: - _usbd_dev.connected = 0; - _usbd_dev.addressed = 0; - _usbd_dev.cfg_num = 0; - _usbd_dev.suspended = 0; - osal_queue_send(_usbd_q, event, in_isr); - break; - case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). From 30885586fbed5bbff7a467216200f4226c5fea80 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 26 Feb 2024 18:12:56 +0000 Subject: [PATCH 5/6] Bugfix of device bus event handling - Fixing that the USB speed on reset isn't updated - Prevent an issue that a repeating bus state can fill up the event queue --- src/device/usbd.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 0a2ea12c1b..bfaed61646 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -502,7 +502,6 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case DCD_EVENT_BUS_RESET: TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); - _usbd_dev.speed = event.bus_reset.speed; TU_ATTR_FALLTHROUGH; case DCD_EVENT_UNPLUGGED: @@ -527,6 +526,16 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) // Completely clear the current USB state usbd_reset(event.rhport); + + // Recover the intended bus speed + if (DCD_EVENT_BUS_RESET == event.event_id) + { + _usbd_dev.speed = event.bus_reset.speed; + } + else if (DCD_EVENT_UNPLUGGED == event.event_id) + { + _usbd_dev.speed = DCD_EVENT_INVALID; + } break; case DCD_EVENT_SETUP_RECEIVED: @@ -1096,6 +1105,16 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) { + volatile static uint8_t last_event_id = DCD_EVENT_INVALID; + + // Skip the useless repeating bus states + if (last_event_id == event->event_id && DCD_EVENT_UNPLUGGED <= event->event_id && DCD_EVENT_RESUME >= event->event_id) + { + return; + } + + last_event_id = event->event_id; + switch (event->event_id) { case DCD_EVENT_SUSPEND: From aa11e34249ec9bf3365d6b9894581caddaba8122 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 26 Feb 2024 18:14:28 +0000 Subject: [PATCH 6/6] Fix DWC2 driver - Prevent supressed reset event when port keeps in the reset state --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c6132a1f54..82db363677 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1229,6 +1229,8 @@ void dcd_int_handler(uint8_t rhport) // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; bus_reset(rhport); + + dcd_event_bus_reset(rhport, TUSB_SPEED_INVALID, true); } if(int_status & GINTSTS_ENUMDNE)