fix(gpio): add USB PHY1 (USB OTG) pin support for ESP32H4

This commit is contained in:
Song Ruo Jing
2025-09-03 19:59:56 +08:00
parent f4c40f7e69
commit da785a8f71
9 changed files with 36 additions and 14 deletions

View File

@@ -801,7 +801,7 @@ TEST_CASE("GPIO_input_and_output_of_USB_pins_test", "[gpio]")
{ {
const int test_pins[] = {USB_INT_PHY0_DP_GPIO_NUM, const int test_pins[] = {USB_INT_PHY0_DP_GPIO_NUM,
USB_INT_PHY0_DM_GPIO_NUM, USB_INT_PHY0_DM_GPIO_NUM,
#if CONFIG_IDF_TARGET_ESP32P4 // TODO: Use proper soc_caps macro #ifdef USB_INT_PHY1_DP_GPIO_NUM
USB_INT_PHY1_DP_GPIO_NUM, USB_INT_PHY1_DP_GPIO_NUM,
USB_INT_PHY1_DM_GPIO_NUM USB_INT_PHY1_DM_GPIO_NUM
#endif #endif
@@ -847,7 +847,7 @@ TEST_CASE("GPIO_USB_DP_pin_pullup_disable_test", "[gpio]")
// Therefore, when D+ pin's pull-up value is set to 0, it will also clear USB D+ pull-up value to allow // Therefore, when D+ pin's pull-up value is set to 0, it will also clear USB D+ pull-up value to allow
// its full functionality as a normal gpio pin // its full functionality as a normal gpio pin
const int test_pins[] = {USB_INT_PHY0_DP_GPIO_NUM, const int test_pins[] = {USB_INT_PHY0_DP_GPIO_NUM,
#if CONFIG_IDF_TARGET_ESP32P4 // TODO: Use proper soc_caps macro #ifdef USB_INT_PHY1_DP_GPIO_NUM
USB_INT_PHY1_DP_GPIO_NUM, USB_INT_PHY1_DP_GPIO_NUM,
#endif #endif
}; };

View File

@@ -20,7 +20,9 @@
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
#include "soc/io_mux_struct.h" #include "soc/io_mux_struct.h"
#include "soc/io_mux_reg.h"
#include "soc/usb_serial_jtag_struct.h" #include "soc/usb_serial_jtag_struct.h"
#include "soc/usb_wrap_struct.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/clk_tree_defs.h" #include "soc/clk_tree_defs.h"
#include "hal/gpio_types.h" #include "hal/gpio_types.h"
@@ -89,10 +91,17 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
// Note that esp32h4 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin // Note that esp32h4 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin
// which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead.
// TODO: read the specific efuse with efuse_ll.h // TODO: read the specific efuse with efuse_ll.h
if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) {
// One more noticeable point is H4 has two internal PHYs connecting to USJ and USB_WRAP(OTG1.1) separately.
// We only consider the default connection here: PHY0 -> USJ, PHY1 -> USB_OTG
if (gpio_num == USB_USJ_INT_PHY_DP_GPIO_NUM) {
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_pad_pull_override = 1; USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_pad_pull_override = 1;
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_dp_pullup = 0; USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_dp_pullup = 0;
} else if (gpio_num == USB_OTG_INT_PHY_DP_GPIO_NUM) {
USB_WRAP.wrap_otg_conf.wrap_pad_pull_override = 1;
USB_WRAP.wrap_otg_conf.wrap_dp_pullup = 0;
} }
IO_MUX.gpio[gpio_num].fun_wpu = 0; IO_MUX.gpio[gpio_num].fun_wpu = 0;
} }
@@ -547,9 +556,13 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
__attribute__((always_inline)) __attribute__((always_inline))
static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func) static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
{ {
// Disable USB Serial JTAG if USB pins needs to select an IOMUX function // Disable USB PHY configuration if pins (13, 14) (21, 22) needs to select an IOMUX function
if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { // P4 has two internal PHYs connecting to USJ and USB_WRAP(OTG1.1) separately.
// We only consider the default connection here: PHY0 -> USJ, PHY1 -> USB_OTG
if (gpio_num == USB_USJ_INT_PHY_DM_GPIO_NUM || gpio_num == USB_USJ_INT_PHY_DP_GPIO_NUM) {
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_usb_pad_enable = 0; USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_usb_pad_enable = 0;
} else if (gpio_num == USB_OTG_INT_PHY_DM_GPIO_NUM || gpio_num == USB_OTG_INT_PHY_DP_GPIO_NUM) {
USB_WRAP.wrap_otg_conf.wrap_usb_pad_enable = 0;
} }
IO_MUX.gpio[gpio_num].mcu_sel = func; IO_MUX.gpio[gpio_num].mcu_sel = func;
} }

View File

@@ -38,7 +38,7 @@
#define DR_REG_ZERO_DET_BASE 0x60029000 #define DR_REG_ZERO_DET_BASE 0x60029000
#define DR_REG_USB_OTG_FS_CORE0_BASE 0x60040000 #define DR_REG_USB_OTG_FS_CORE0_BASE 0x60040000
#define DR_REG_USB_OTG_FS_CORE1_BASE 0x6007F000 #define DR_REG_USB_OTG_FS_CORE1_BASE 0x6007F000
#define DR_REG_USB_OTG_FS_PHY_BASE 0x60080000 #define DR_REG_USB_WRAP_BASE 0x60080000
#define DR_REG_TIMERG0_BASE 0x60090000 #define DR_REG_TIMERG0_BASE 0x60090000
#define DR_REG_TIMERG1_BASE 0x60091000 #define DR_REG_TIMERG1_BASE 0x60091000
#define DR_REG_IO_MUX_BASE 0x60092000 #define DR_REG_IO_MUX_BASE 0x60092000

View File

@@ -38,7 +38,7 @@ PROVIDE ( SAMPLE_RATE_CONVERTER = 0x60028000 );
PROVIDE ( ZERO_DET = 0x60029000 ); PROVIDE ( ZERO_DET = 0x60029000 );
PROVIDE ( USB_OTG_FS_CORE0 = 0x60040000 ); PROVIDE ( USB_OTG_FS_CORE0 = 0x60040000 );
PROVIDE ( USB_OTG_FS_CORE1 = 0x6007F000 ); PROVIDE ( USB_OTG_FS_CORE1 = 0x6007F000 );
PROVIDE ( USB_OTG_FS_PHY = 0x60080000 ); PROVIDE ( USB_WRAP = 0x60080000 );
PROVIDE ( TIMERG0 = 0x60090000 ); PROVIDE ( TIMERG0 = 0x60090000 );
PROVIDE ( TIMERG1 = 0x60091000 ); PROVIDE ( TIMERG1 = 0x60091000 );
PROVIDE ( IO_MUX = 0x60092000 ); PROVIDE ( IO_MUX = 0x60092000 );

View File

@@ -38,7 +38,7 @@ PROVIDE ( SAMPLE_RATE_CONVERTER = 0x60028000 );
PROVIDE ( ZERO_DET = 0x60029000 ); PROVIDE ( ZERO_DET = 0x60029000 );
PROVIDE ( USB_OTG_FS_CORE0 = 0x60040000 ); PROVIDE ( USB_OTG_FS_CORE0 = 0x60040000 );
PROVIDE ( USB_OTG_FS_CORE1 = 0x6007F000 ); PROVIDE ( USB_OTG_FS_CORE1 = 0x6007F000 );
PROVIDE ( USB_OTG_FS_PHY = 0x60080000 ); PROVIDE ( USB_WRAP = 0x60080000 );
PROVIDE ( TIMERG0 = 0x60090000 ); PROVIDE ( TIMERG0 = 0x60090000 );
PROVIDE ( TIMERG1 = 0x60091000 ); PROVIDE ( TIMERG1 = 0x60091000 );
PROVIDE ( IO_MUX = 0x60092000 ); PROVIDE ( IO_MUX = 0x60092000 );

View File

@@ -128,6 +128,14 @@ extern "C" {
#define USB_INT_PHY0_DM_GPIO_NUM 13 #define USB_INT_PHY0_DM_GPIO_NUM 13
#define USB_INT_PHY0_DP_GPIO_NUM 14 #define USB_INT_PHY0_DP_GPIO_NUM 14
#define USB_INT_PHY1_DM_GPIO_NUM 21
#define USB_INT_PHY1_DP_GPIO_NUM 22
// We would fix the USB PHY usage on H4: PHY0 -> USJ, PHY1 -> USB_OTG
#define USB_USJ_INT_PHY_DM_GPIO_NUM USB_INT_PHY0_DM_GPIO_NUM
#define USB_USJ_INT_PHY_DP_GPIO_NUM USB_INT_PHY0_DP_GPIO_NUM
#define USB_OTG_INT_PHY_DM_GPIO_NUM USB_INT_PHY1_DM_GPIO_NUM
#define USB_OTG_INT_PHY_DP_GPIO_NUM USB_INT_PHY1_DP_GPIO_NUM
#define MAX_RTC_GPIO_NUM 5 #define MAX_RTC_GPIO_NUM 5
#define MAX_PAD_GPIO_NUM 39 #define MAX_PAD_GPIO_NUM 39

View File

@@ -974,7 +974,7 @@ typedef struct {
extern usb_serial_jtag_dev_t USB_SERIAL_JTAG; extern usb_serial_jtag_dev_t USB_SERIAL_JTAG;
#ifndef __cplusplus #ifndef __cplusplus
_Static_assert(sizeof(usb_serial_jtag_dev_t) == 0x84, "Invalid size of usb_dev_t structure"); _Static_assert(sizeof(usb_serial_jtag_dev_t) == 0x84, "Invalid size of usb_serial_jtag_dev_t structure");
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -14,7 +14,7 @@ extern "C" {
/** USB_WRAP_OTG_CONF_REG register /** USB_WRAP_OTG_CONF_REG register
* USB wrapper configuration registers. * USB wrapper configuration registers.
*/ */
#define USB_WRAP_OTG_CONF_REG (DR_REG_USB_BASE + 0x0) #define USB_WRAP_OTG_CONF_REG (DR_REG_USB_WRAP_BASE + 0x0)
/** USB_WRAP_SRP_SESSEND_OVERRIDE : R/W; bitpos: [0]; default: 0; /** USB_WRAP_SRP_SESSEND_OVERRIDE : R/W; bitpos: [0]; default: 0;
* This bit is used to enable the software over-ride of srp session end signal. 1'b0: * This bit is used to enable the software over-ride of srp session end signal. 1'b0:
* the signal is controlled by the chip input, 1'b1: the signal is controlled by the * the signal is controlled by the chip input, 1'b1: the signal is controlled by the
@@ -154,7 +154,7 @@ extern "C" {
/** USB_WRAP_DATE_REG register /** USB_WRAP_DATE_REG register
* Date register. * Date register.
*/ */
#define USB_WRAP_DATE_REG (DR_REG_USB_BASE + 0x3fc) #define USB_WRAP_DATE_REG (DR_REG_USB_WRAP_BASE + 0x3fc)
/** USB_WRAP_USB_WRAP_DATE : R/W; bitpos: [31:0]; default: 37761536; /** USB_WRAP_USB_WRAP_DATE : R/W; bitpos: [31:0]; default: 37761536;
* Date register. * Date register.
*/ */

View File

@@ -114,15 +114,16 @@ typedef union {
} usb_wrap_date_reg_t; } usb_wrap_date_reg_t;
typedef struct { typedef struct usb_wrap_dev_t {
volatile usb_wrap_otg_conf_reg_t wrap_otg_conf; volatile usb_wrap_otg_conf_reg_t wrap_otg_conf;
uint32_t reserved_004[254]; uint32_t reserved_004[254];
volatile usb_wrap_date_reg_t wrap_date; volatile usb_wrap_date_reg_t wrap_date;
} usb_dev_t; } usb_wrap_dev_t;
extern usb_wrap_dev_t USB_WRAP;
#ifndef __cplusplus #ifndef __cplusplus
_Static_assert(sizeof(usb_dev_t) == 0x400, "Invalid size of usb_dev_t structure"); _Static_assert(sizeof(usb_wrap_dev_t) == 0x400, "Invalid size of usb_wrap_dev_t structure");
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus