From 53567226fce0e7be7e7b5e7a019d0f4d14064c33 Mon Sep 17 00:00:00 2001 From: Javid Khan Date: Mon, 17 Aug 2026 20:56:27 +0530 Subject: bound endpoint number in tu_bind_driver_to_ep_itf --- src/common/tusb_private.h | 2 +- src/device/usbd.c | 4 ++-- src/host/usbh.c | 3 ++- src/tusb.c | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 0bbc119fd..b91fc0608 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -63,7 +63,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoi // Bind drivers to all interfaces and endpoints in the provided configuration descriptor bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max, - const uint8_t *p_desc, uint16_t desc_len); + uint8_t ep_max, const uint8_t *p_desc, uint16_t desc_len); // Claim an endpoint with provided mutex bool tu_edpt_claim(volatile uint8_t* ep_state, osal_mutex_t mutex); diff --git a/src/device/usbd.c b/src/device/usbd.c index f5c3046d6..5b20d0870 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1281,8 +1281,8 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { TU_LOG_USBD(" %s opened\r\n", driver->name); // bind found driver to all interfaces and endpoint within drv_len - TU_ASSERT(tu_bind_driver_to_ep_itf(drv_id, _usbd_dev.ep2drv, _usbd_dev.itf2drv, CFG_TUD_INTERFACE_MAX, p_desc, - drv_len)); + TU_ASSERT(tu_bind_driver_to_ep_itf(drv_id, _usbd_dev.ep2drv, _usbd_dev.itf2drv, CFG_TUD_INTERFACE_MAX, + CFG_TUD_ENDPPOINT_MAX, p_desc, drv_len)); p_desc += drv_len; // next Interface break; // exit driver find loop diff --git a/src/host/usbh.c b/src/host/usbh.c index e307bb5e5..cb4977dd2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -2160,7 +2160,8 @@ static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configurat TU_LOG_USBH(" %s opened\r\n", driver->name); // bind found driver to all interfaces and endpoint within drv_len - tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, p_desc, drv_len); + tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, CFG_TUH_ENDPOINT_MAX, + p_desc, drv_len); p_desc += drv_len; // next Interface break; // exit driver find loop diff --git a/src/tusb.c b/src/tusb.c index 78ee7aeda..e1548e8c1 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -274,7 +274,7 @@ bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) { #endif bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max, - const uint8_t *p_desc, uint16_t desc_len) { + uint8_t ep_max, const uint8_t *p_desc, uint16_t desc_len) { const uint8_t *desc_end = p_desc + desc_len; while (tu_desc_in_bounds(p_desc, desc_end)) { const uint8_t desc_type = tu_desc_type(p_desc); @@ -283,6 +283,7 @@ bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t it const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress; const uint8_t ep_num = tu_edpt_number(ep_addr); const uint8_t ep_dir = tu_edpt_dir(ep_addr); + TU_ASSERT(ep_num < ep_max); ep2drv[ep_num][ep_dir] = driver_id; } else if (desc_type == TUSB_DESC_INTERFACE) { const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc; -- cgit v1.3.1 From 1e3c2faed4db782f093aa4c88fc98fa81cccc77a Mon Sep 17 00:00:00 2001 From: Mike Ajax <14773392+michaelajax@users.noreply.github.com> Date: Sun, 30 Aug 2026 09:44:23 -0700 Subject: Add "attached" state callback for UCPD --- src/typec/usbc.c | 10 +++++++++- src/typec/usbc.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/typec/usbc.c b/src/typec/usbc.c index dc59b35be..ab7dd0b92 100644 --- a/src/typec/usbc.c +++ b/src/typec/usbc.c @@ -57,6 +57,11 @@ TU_ATTR_WEAK bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* return false; } +TU_ATTR_WEAK void tuc_attach_changed_cb(uint8_t rhport, bool attached) { + (void) rhport; + (void) attached; +} + TU_ATTR_WEAK void tcd_connect(uint8_t rhport) { (void) rhport; } @@ -124,8 +129,11 @@ void tuc_task_ext(uint32_t timeout_ms, bool in_isr) { if (!osal_queue_receive(_usbc_q, &event, timeout_ms)) return; switch (event.event_id) { - case TCD_EVENT_CC_CHANGED: + case TCD_EVENT_CC_CHANGED: { + bool const attached = event.cc_changed.cc_state[0] != 0 || event.cc_changed.cc_state[1] != 0; + tuc_attach_changed_cb(event.rhport, attached); break; + } case TCD_EVENT_RX_COMPLETE: // TODO process message here in ISR, move to thread later diff --git a/src/typec/usbc.h b/src/typec/usbc.h index 9fca7da0d..fc4773b07 100644 --- a/src/typec/usbc.h +++ b/src/typec/usbc.h @@ -65,6 +65,7 @@ extern void tcd_int_handler(uint8_t rhport); bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end); bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* header); +void tuc_attach_changed_cb(uint8_t rhport, bool attached); //--------------------------------------------------------------------+ // -- cgit v1.3.1 From aa535e8268ec962aa69a5d613b37075973ac1d5c Mon Sep 17 00:00:00 2001 From: Mike Ajax <14773392+michaelajax@users.noreply.github.com> Date: Sun, 30 Aug 2026 09:59:00 -0700 Subject: Suppress USB-C attached callback unless cable state changed from disconnected->connected or connected->disconnected --- src/typec/usbc.c | 7 ++++++- src/typec/usbc.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/typec/usbc.c b/src/typec/usbc.c index ab7dd0b92..5b0e4423a 100644 --- a/src/typec/usbc.c +++ b/src/typec/usbc.c @@ -31,6 +31,7 @@ static bool _usbc_inited = false; // if port is initialized static bool _port_inited[TUP_TYPEC_RHPORTS_NUM]; +static bool _port_attached[TUP_TYPEC_RHPORTS_NUM]; // Max possible PD size is 262 bytes static uint8_t _rx_buf[64] TU_ATTR_ALIGNED(4); @@ -95,6 +96,7 @@ bool tuc_init(uint8_t rhport, uint32_t port_type) { // Initialize stack if (!_usbc_inited) { tu_memclr(_port_inited, sizeof(_port_inited)); + tu_memclr(_port_attached, sizeof(_port_attached)); _usbc_q = osal_queue_create(&_usbc_qdef); TU_ASSERT(_usbc_q != NULL); @@ -131,7 +133,10 @@ void tuc_task_ext(uint32_t timeout_ms, bool in_isr) { switch (event.event_id) { case TCD_EVENT_CC_CHANGED: { bool const attached = event.cc_changed.cc_state[0] != 0 || event.cc_changed.cc_state[1] != 0; - tuc_attach_changed_cb(event.rhport, attached); + if (_port_attached[event.rhport] != attached) { + _port_attached[event.rhport] = attached; + tuc_attach_changed_cb(event.rhport, attached); + } break; } diff --git a/src/typec/usbc.h b/src/typec/usbc.h index fc4773b07..dfc96dee9 100644 --- a/src/typec/usbc.h +++ b/src/typec/usbc.h @@ -65,6 +65,7 @@ extern void tcd_int_handler(uint8_t rhport); bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end); bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* header); +// Invoked from tuc_task() only when the derived attachment state changes. void tuc_attach_changed_cb(uint8_t rhport, bool attached); //--------------------------------------------------------------------+ -- cgit v1.3.1 From e056a04a011225479f0be61fc9b37d828e506a26 Mon Sep 17 00:00:00 2001 From: Mike Ajax <14773392+michaelajax@users.noreply.github.com> Date: Sun, 30 Aug 2026 10:15:49 -0700 Subject: remove unnecessary comment --- src/typec/usbc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/typec/usbc.h b/src/typec/usbc.h index dfc96dee9..fc4773b07 100644 --- a/src/typec/usbc.h +++ b/src/typec/usbc.h @@ -65,7 +65,6 @@ extern void tcd_int_handler(uint8_t rhport); bool tuc_pd_data_received_cb(uint8_t rhport, pd_header_t const* header, uint8_t const* dobj, uint8_t const* p_end); bool tuc_pd_control_received_cb(uint8_t rhport, pd_header_t const* header); -// Invoked from tuc_task() only when the derived attachment state changes. void tuc_attach_changed_cb(uint8_t rhport, bool attached); //--------------------------------------------------------------------+ -- cgit v1.3.1 From 04a6ec80d94e13c70087c44dcf095d842302bafa Mon Sep 17 00:00:00 2001 From: runelauridsen Date: Tue, 1 Sep 2026 10:10:33 +0200 Subject: Fix DWC2 DMA data toggle mismatch in IN-transfers --- src/portable/synopsys/dwc2/hcd_dwc2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 089b839ae..761627730 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -1129,6 +1129,10 @@ static bool handle_channel_in_dma(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hci channel_send_in_token(dwc2, channel); } } else if (hcint & (HCINT_XFER_COMPLETE | HCINT_STALL | HCINT_BABBLE_ERR)) { + if (edpt->hcchar_bm.ep_num != 0 && (hcint & HCINT_XFER_COMPLETE)) { + edpt->next_pid = hctsiz.pid; // save pid (already toggled) + } + const uint16_t remain_bytes = (uint16_t) hctsiz.xfer_size; const uint16_t remain_packets = hctsiz.packet_count; const uint16_t actual_len = edpt->buflen - remain_bytes; -- cgit v1.3.1 From bc359e55b8d3fb5fc5b9e026d5c21b52d554fdd2 Mon Sep 17 00:00:00 2001 From: HiFiPHile Date: Tue, 1 Sep 2026 10:36:58 +0200 Subject: propagate the endpoint-bound failure on the host path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tu_bind_driver_to_ep_itf() now returns false when ep_num >= CFG_TUH_ENDPOINT_MAX, but the host caller ignores that result and continues enumeration. Configurations such as host/bare_api set the limit to 8, while valid USB devices may use endpoints 8–15. A recognized class can therefore continue and later index ep_status[epnum] or ep2drv[epnum] out of bounds. Wrap this call in TU_ASSERT(...), as the device path already does, so parsing fails immediately. Signed-off-by: HiFiPHile --- src/host/usbh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index cb4977dd2..69074661d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -2160,8 +2160,8 @@ static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configurat TU_LOG_USBH(" %s opened\r\n", driver->name); // bind found driver to all interfaces and endpoint within drv_len - tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, CFG_TUH_ENDPOINT_MAX, - p_desc, drv_len); + TU_ASSERT(tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, + CFG_TUH_ENDPOINT_MAX, p_desc, drv_len)); p_desc += drv_len; // next Interface break; // exit driver find loop -- cgit v1.3.1