Merge branch 'fix/periodic_fs_usb_on_p4_backport_v5.4' into 'release/v5.4'

fix(usb/host): Fixed Full Speed periodic transfers on ESP32-P4 (backport v5.4)

See merge request espressif/esp-idf!36647
This commit is contained in:
morris 2025-02-05 14:17:43 +08:00
commit 724f762f57
6 changed files with 61 additions and 16 deletions

View File

@ -395,6 +395,8 @@ void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t
} else { } else {
tokens_per_frame = 8; // 1 token every microframe 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); usb_dwc_ll_hctsiz_set_sched_info(chan_obj->regs, tokens_per_frame, ep_char->periodic.offset);
} }

View File

@ -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 * 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, .dischrgvbus = USB_SRP_DISCHRGVBUS_PAD_OUT_IDX,
}; };
static const usb_internal_phy_io_t internal_phy_io = {
.dp = 27,
.dm = 26,
};
/* --------------------------------- Public --------------------------------- */ /* --------------------------------- Public --------------------------------- */
const usb_dwc_info_t usb_dwc_info = { const usb_dwc_info_t usb_dwc_info = {
@ -36,6 +41,8 @@ const usb_dwc_info_t usb_dwc_info = {
[0] = { [0] = {
.fsls_signals = NULL, .fsls_signals = NULL,
.otg_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 = ETS_USB_OTG_INTR_SOURCE,
.irq_2nd_cpu = ETS_USB_OTG_ENDP_MULTI_PROC_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] = { [1] = {
.fsls_signals = NULL, .fsls_signals = NULL,
.otg_signals = &dwc_fs_otg_signals, .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 = ETS_USB_OTG11_CH0_INTR_SOURCE,
.irq_2nd_cpu = -1, .irq_2nd_cpu = -1,
}, },

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/usb_periph.h"
#include "soc/interrupts.h" #include "soc/interrupts.h"
#include "soc/usb_dwc_periph.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, .dischrgvbus = USB_SRP_DISCHRGVBUS_IDX,
}; };
static const usb_internal_phy_io_t internal_phy_io = {
.dp = 20,
.dm = 19,
};
/* --------------------------------- Public --------------------------------- */ /* --------------------------------- Public --------------------------------- */
const usb_dwc_info_t usb_dwc_info = { const usb_dwc_info_t usb_dwc_info = {
@ -47,6 +51,8 @@ const usb_dwc_info_t usb_dwc_info = {
[0] = { [0] = {
.fsls_signals = &fsls_signals, .fsls_signals = &fsls_signals,
.otg_signals = &otg_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 = ETS_USB_INTR_SOURCE,
.irq_2nd_cpu = -1, .irq_2nd_cpu = -1,
}, },
@ -55,6 +61,7 @@ const usb_dwc_info_t usb_dwc_info = {
/* ------------------------------- Deprecated ------------------------------- */ /* ------------------------------- Deprecated ------------------------------- */
#include "soc/usb_periph.h"
/* /*
Note: These IO pins are deprecated. When connecting USB OTG to an external FSLS 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 PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stddef.h>
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/usb_periph.h"
#include "soc/interrupts.h" #include "soc/interrupts.h"
#include "soc/usb_dwc_periph.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, .dischrgvbus = USB_SRP_DISCHRGVBUS_IDX,
}; };
static const usb_internal_phy_io_t internal_phy_io = {
.dp = 20,
.dm = 19,
};
/* --------------------------------- Public --------------------------------- */ /* --------------------------------- Public --------------------------------- */
const usb_dwc_info_t usb_dwc_info = { const usb_dwc_info_t usb_dwc_info = {
@ -48,6 +51,8 @@ const usb_dwc_info_t usb_dwc_info = {
[0] = { [0] = {
.fsls_signals = &fsls_signals, .fsls_signals = &fsls_signals,
.otg_signals = &otg_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 = ETS_USB_INTR_SOURCE,
.irq_2nd_cpu = -1, .irq_2nd_cpu = -1,
}, },
@ -56,6 +61,7 @@ const usb_dwc_info_t usb_dwc_info = {
/* ------------------------------- Deprecated ------------------------------- */ /* ------------------------------- Deprecated ------------------------------- */
#include "soc/usb_periph.h"
/* /*
Note: These IO pins are deprecated. When connecting USB OTG to an external FSLS 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 PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_pins.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/periph_defs.h"
#include "soc/gpio_sig_map.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -21,6 +16,16 @@ extern "C" {
/* ---------------------------------- Types --------------------------------- */ /* ---------------------------------- 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 * @brief USB PHY FSLS Serial Interface Signals
* *
@ -65,15 +70,30 @@ typedef struct {
int dischrgvbus; int dischrgvbus;
} usb_otg_signal_conn_t; } 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 * @brief USB Controller Information
* *
* Structure to store information for all USB-DWC instances * 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 { typedef struct {
struct { struct {
const usb_fsls_serial_signal_conn_t * const fsls_signals; // Must be set if external PHY is supported by controller 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_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;
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 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]; } controllers [SOC_USB_OTG_PERIPH_NUM];
@ -85,6 +105,8 @@ extern const usb_dwc_info_t usb_dwc_info;
/* ------------------------------- Deprecated ------------------------------- */ /* ------------------------------- Deprecated ------------------------------- */
/* Todo: Remove in ESP-IDF v6.0 (IDF-9052) */ /* Todo: Remove in ESP-IDF v6.0 (IDF-9052) */
#include <stdint.h>
#include "soc/periph_defs.h"
#if SOC_USB_OTG_SUPPORTED #if SOC_USB_OTG_SUPPORTED

View File

@ -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) // 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) { if (phy_target == USB_PHY_TARGET_INT) {
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); assert(usb_dwc_info.controllers[otg11_index].internal_phy_io);
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); 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; *handle_ret = (usb_phy_handle_t) phy_context;
if (phy_target == USB_PHY_TARGET_EXT) { if (phy_target == USB_PHY_TARGET_EXT) {