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 {
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);
}

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
*/
@ -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,
},

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
*/
#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

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
*/
#include <stddef.h>
#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

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
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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 <stdint.h>
#include "soc/periph_defs.h"
#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)
#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) {