fix(usb): Fixed missing GPIO drive capability on ESP32-P4

All USB PHYs that share their IOs with GPIOs must set
the GPIO's drive capability to maximum.
This commit is contained in:
Tomas Rezucha
2025-01-20 21:08:43 +01:00
parent febc33a094
commit d12312bf76
5 changed files with 44 additions and 16 deletions

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,7 @@ 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
.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 +49,7 @@ 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,
.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,7 @@ 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,
.irq = ETS_USB_INTR_SOURCE, .irq = ETS_USB_INTR_SOURCE,
.irq_2nd_cpu = -1, .irq_2nd_cpu = -1,
}, },
@ -55,6 +60,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,7 @@ 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,
.irq = ETS_USB_INTR_SOURCE, .irq = ETS_USB_INTR_SOURCE,
.irq_2nd_cpu = -1, .irq_2nd_cpu = -1,
}, },
@ -56,6 +60,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" {
@ -65,15 +60,29 @@ 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 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 +94,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) {