diff --git a/components/hal/esp32p4/include/hal/usb_dwc_ll.h b/components/hal/esp32p4/include/hal/usb_dwc_ll.h index 95600a6e5a..3afb678e78 100644 --- a/components/hal/esp32p4/include/hal/usb_dwc_ll.h +++ b/components/hal/esp32p4/include/hal/usb_dwc_ll.h @@ -764,6 +764,23 @@ static inline void usb_dwc_ll_hcintmsk_set_intr_mask(volatile usb_dwc_host_chan_ // ---------------------------- HCTSIZi Register ------------------------------- +static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan) +{ + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + hctsiz.dopng = 0; // Don't do ping + hctsiz.pid = 0; // Set PID to DATA0 + /* + * Set SCHED_INFO which occupies xfersize[7:0] + * + * Although the hardware documentation suggests that SCHED_INFO is only used for periodic channels, + * empirical evidence shows that omitting this configuration on non-periodic channels can cause them to freeze. + * Therefore, we set this field for all channels to ensure reliable operation. + */ + hctsiz.xfersize |= 0xFF; + chan->hctsiz_reg.val = hctsiz.val; +} + static inline void usb_dwc_ll_hctsiz_set_pid(volatile usb_dwc_host_chan_regs_t *chan, uint32_t data_pid) { if (data_pid == 0) { diff --git a/components/hal/esp32s2/include/hal/usb_dwc_ll.h b/components/hal/esp32s2/include/hal/usb_dwc_ll.h index 940497d2e8..1497edd2ff 100644 --- a/components/hal/esp32s2/include/hal/usb_dwc_ll.h +++ b/components/hal/esp32s2/include/hal/usb_dwc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -763,6 +763,23 @@ static inline void usb_dwc_ll_hcintmsk_set_intr_mask(volatile usb_dwc_host_chan_ // ---------------------------- HCTSIZi Register ------------------------------- +static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan) +{ + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + hctsiz.dopng = 0; // Don't do ping + hctsiz.pid = 0; // Set PID to DATA0 + /* + * Set SCHED_INFO which occupies xfersize[7:0] + * + * Although the hardware documentation suggests that SCHED_INFO is only used for periodic channels, + * empirical evidence shows that omitting this configuration on non-periodic channels can cause them to freeze. + * Therefore, we set this field for all channels to ensure reliable operation. + */ + hctsiz.xfersize |= 0xFF; + chan->hctsiz_reg.val = hctsiz.val; +} + static inline void usb_dwc_ll_hctsiz_set_pid(volatile usb_dwc_host_chan_regs_t *chan, uint32_t data_pid) { if (data_pid == 0) { diff --git a/components/hal/esp32s3/include/hal/usb_dwc_ll.h b/components/hal/esp32s3/include/hal/usb_dwc_ll.h index 29a9787eba..75ffe37665 100644 --- a/components/hal/esp32s3/include/hal/usb_dwc_ll.h +++ b/components/hal/esp32s3/include/hal/usb_dwc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -763,6 +763,23 @@ static inline void usb_dwc_ll_hcintmsk_set_intr_mask(volatile usb_dwc_host_chan_ // ---------------------------- HCTSIZi Register ------------------------------- +static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan) +{ + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + hctsiz.dopng = 0; // Don't do ping + hctsiz.pid = 0; // Set PID to DATA0 + /* + * Set SCHED_INFO which occupies xfersize[7:0] + * + * Although the hardware documentation suggests that SCHED_INFO is only used for periodic channels, + * empirical evidence shows that omitting this configuration on non-periodic channels can cause them to freeze. + * Therefore, we set this field for all channels to ensure reliable operation. + */ + hctsiz.xfersize |= 0xFF; + chan->hctsiz_reg.val = hctsiz.val; +} + static inline void usb_dwc_ll_hctsiz_set_pid(volatile usb_dwc_host_chan_regs_t *chan, uint32_t data_pid) { if (data_pid == 0) { diff --git a/components/hal/usb_dwc_hal.c b/components/hal/usb_dwc_hal.c index c6e3ad8b3a..342d76ee7f 100644 --- a/components/hal/usb_dwc_hal.c +++ b/components/hal/usb_dwc_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -311,7 +311,7 @@ bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan usb_dwc_ll_hcint_read_and_clear_intrs(chan_obj->regs); //Clear the interrupt bits for that channel usb_dwc_ll_haintmsk_en_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx); usb_dwc_ll_hcintmsk_set_intr_mask(chan_obj->regs, CHAN_INTRS_EN_MSK); //Unmask interrupts for this channel - usb_dwc_ll_hctsiz_set_pid(chan_obj->regs, 0); //Set the initial PID to zero + usb_dwc_ll_hctsiz_init(chan_obj->regs); return true; }