diff --git a/components/hal/usb_dwc_hal.c b/components/hal/usb_dwc_hal.c index c7a0637356..c6e3ad8b3a 100644 --- a/components/hal/usb_dwc_hal.c +++ b/components/hal/usb_dwc_hal.c @@ -395,6 +395,8 @@ void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t } else { tokens_per_frame = 8; // 1 token every microframe } + } else { + tokens_per_frame = 8; } usb_dwc_ll_hctsiz_set_sched_info(chan_obj->regs, tokens_per_frame, ep_char->periodic.offset); } diff --git a/components/soc/esp32p4/usb_dwc_periph.c b/components/soc/esp32p4/usb_dwc_periph.c index ce8a42997c..ede82c5ed8 100644 --- a/components/soc/esp32p4/usb_dwc_periph.c +++ b/components/soc/esp32p4/usb_dwc_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,11 @@ static const usb_otg_signal_conn_t dwc_fs_otg_signals = { .dischrgvbus = USB_SRP_DISCHRGVBUS_PAD_OUT_IDX, }; +static const usb_internal_phy_io_t internal_phy_io = { + .dp = 27, + .dm = 26, +}; + /* --------------------------------- Public --------------------------------- */ const usb_dwc_info_t usb_dwc_info = { @@ -36,6 +41,8 @@ const usb_dwc_info_t usb_dwc_info = { [0] = { .fsls_signals = NULL, .otg_signals = NULL, + .internal_phy_io = NULL, // HS PHY is not mapped to any GPIO + .supported_phys = USB_PHY_INST_UTMI_0, .irq = ETS_USB_OTG_INTR_SOURCE, .irq_2nd_cpu = ETS_USB_OTG_ENDP_MULTI_PROC_INTR_SOURCE, }, @@ -43,6 +50,8 @@ const usb_dwc_info_t usb_dwc_info = { [1] = { .fsls_signals = NULL, .otg_signals = &dwc_fs_otg_signals, + .internal_phy_io = &internal_phy_io, + .supported_phys = USB_PHY_INST_FSLS_INTERN_0, .irq = ETS_USB_OTG11_CH0_INTR_SOURCE, .irq_2nd_cpu = -1, }, diff --git a/components/soc/esp32s2/usb_dwc_periph.c b/components/soc/esp32s2/usb_dwc_periph.c index 2656918294..1d77e297fa 100644 --- a/components/soc/esp32s2/usb_dwc_periph.c +++ b/components/soc/esp32s2/usb_dwc_periph.c @@ -1,11 +1,10 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" -#include "soc/usb_periph.h" #include "soc/interrupts.h" #include "soc/usb_dwc_periph.h" @@ -40,6 +39,11 @@ static const usb_otg_signal_conn_t otg_signals = { .dischrgvbus = USB_SRP_DISCHRGVBUS_IDX, }; +static const usb_internal_phy_io_t internal_phy_io = { + .dp = 20, + .dm = 19, +}; + /* --------------------------------- Public --------------------------------- */ const usb_dwc_info_t usb_dwc_info = { @@ -47,6 +51,8 @@ const usb_dwc_info_t usb_dwc_info = { [0] = { .fsls_signals = &fsls_signals, .otg_signals = &otg_signals, + .internal_phy_io = &internal_phy_io, + .supported_phys = USB_PHY_INST_FSLS_INTERN_0, .irq = ETS_USB_INTR_SOURCE, .irq_2nd_cpu = -1, }, @@ -55,6 +61,7 @@ const usb_dwc_info_t usb_dwc_info = { /* ------------------------------- Deprecated ------------------------------- */ +#include "soc/usb_periph.h" /* Note: These IO pins are deprecated. When connecting USB OTG to an external FSLS PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO diff --git a/components/soc/esp32s3/usb_dwc_periph.c b/components/soc/esp32s3/usb_dwc_periph.c index c2690906f0..1d77e297fa 100644 --- a/components/soc/esp32s3/usb_dwc_periph.c +++ b/components/soc/esp32s3/usb_dwc_periph.c @@ -1,12 +1,10 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include #include "soc/gpio_sig_map.h" -#include "soc/usb_periph.h" #include "soc/interrupts.h" #include "soc/usb_dwc_periph.h" @@ -41,6 +39,11 @@ static const usb_otg_signal_conn_t otg_signals = { .dischrgvbus = USB_SRP_DISCHRGVBUS_IDX, }; +static const usb_internal_phy_io_t internal_phy_io = { + .dp = 20, + .dm = 19, +}; + /* --------------------------------- Public --------------------------------- */ const usb_dwc_info_t usb_dwc_info = { @@ -48,6 +51,8 @@ const usb_dwc_info_t usb_dwc_info = { [0] = { .fsls_signals = &fsls_signals, .otg_signals = &otg_signals, + .internal_phy_io = &internal_phy_io, + .supported_phys = USB_PHY_INST_FSLS_INTERN_0, .irq = ETS_USB_INTR_SOURCE, .irq_2nd_cpu = -1, }, @@ -56,6 +61,7 @@ const usb_dwc_info_t usb_dwc_info = { /* ------------------------------- Deprecated ------------------------------- */ +#include "soc/usb_periph.h" /* Note: These IO pins are deprecated. When connecting USB OTG to an external FSLS PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO diff --git a/components/soc/include/soc/usb_dwc_periph.h b/components/soc/include/soc/usb_dwc_periph.h index ae633eeeca..185a6bdb37 100644 --- a/components/soc/include/soc/usb_dwc_periph.h +++ b/components/soc/include/soc/usb_dwc_periph.h @@ -1,17 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#include -#include -#include "soc/soc_pins.h" #include "soc/soc_caps.h" -#include "soc/periph_defs.h" -#include "soc/gpio_sig_map.h" #ifdef __cplusplus extern "C" { @@ -21,6 +16,16 @@ extern "C" { /* ---------------------------------- Types --------------------------------- */ +/** + * @brief USB PHY Instance Type + */ +typedef enum { + USB_PHY_INST_FSLS_INTERN_0 = (1 << 0), + USB_PHY_INST_FSLS_INTERN_1 = (1 << 1), + USB_PHY_INST_UTMI_0 = (1 << 2), + USB_PHY_INST_EXTERN = (1 << 3), +} usb_phy_inst_t; + /** * @brief USB PHY FSLS Serial Interface Signals * @@ -65,15 +70,30 @@ typedef struct { int dischrgvbus; } usb_otg_signal_conn_t; +/** + * @brief Internal USB PHY IO + * + * Structure to store the IO numbers for a particular internal USB PHY + */ +typedef struct { + int dp; + int dm; +} usb_internal_phy_io_t; + /** * @brief USB Controller Information * * Structure to store information for all USB-DWC instances + * + * For targets with multiple USB controllers, we support only fixed mapping of the PHYs. + * This is a software limitation; the hardware supports swapping Controllers and PHYs. */ typedef struct { struct { const usb_fsls_serial_signal_conn_t * const fsls_signals; // Must be set if external PHY is supported by controller const usb_otg_signal_conn_t * const otg_signals; + const usb_internal_phy_io_t * const internal_phy_io; // Must be set for internal FSLS PHY(s) + const usb_phy_inst_t supported_phys; // Bitmap of supported PHYs by this controller const int irq; const int irq_2nd_cpu; // The USB-DWC can provide 2nd interrupt so each CPU can have its own interrupt line. Set to -1 if not supported } controllers [SOC_USB_OTG_PERIPH_NUM]; @@ -85,6 +105,8 @@ extern const usb_dwc_info_t usb_dwc_info; /* ------------------------------- Deprecated ------------------------------- */ /* Todo: Remove in ESP-IDF v6.0 (IDF-9052) */ +#include +#include "soc/periph_defs.h" #if SOC_USB_OTG_SUPPORTED diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index a20a6d6dcb..c5d510e4a2 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -369,12 +369,11 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r } // For FSLS PHY that shares pads with GPIO peripheral, we must set drive capability to 3 (40mA) -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: We must set drive capability for FSLS PHY for P4 too, to pass Full Speed eye diagram test if (phy_target == USB_PHY_TARGET_INT) { - gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); - gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); + assert(usb_dwc_info.controllers[otg11_index].internal_phy_io); + gpio_set_drive_capability(usb_dwc_info.controllers[otg11_index].internal_phy_io->dm, GPIO_DRIVE_CAP_3); + gpio_set_drive_capability(usb_dwc_info.controllers[otg11_index].internal_phy_io->dp, GPIO_DRIVE_CAP_3); } -#endif *handle_ret = (usb_phy_handle_t) phy_context; if (phy_target == USB_PHY_TARGET_EXT) {