From 4bee8a84e255509fc47c63dc6c85b4ebb470f77b Mon Sep 17 00:00:00 2001 From: songruojing Date: Fri, 22 Jul 2022 15:52:54 +0800 Subject: [PATCH] gpio: fix USB D+ pin cannot disable pullup Internally, disable usb serial jtag DP pin's pullup when calling gpio_ll_pullup_dis and rtcio_ll_pullup_disable At usb serial jtag setup/install, re-enable DP pin's pullup Closes https://github.com/espressif/esp-idf/issues/9495 --- components/driver/usb_serial_jtag.c | 4 +++ components/hal/esp32c3/include/hal/gpio_ll.h | 6 ++++ .../hal/esp32c3/include/hal/usb_phy_ll.h | 34 +++++++++++++++++++ components/hal/esp32h2/include/hal/gpio_ll.h | 16 ++++++--- .../hal/esp32h2/include/hal/usb_phy_ll.h | 34 +++++++++++++++++++ components/hal/esp32s3/include/hal/gpio_ll.h | 8 +++++ .../hal/esp32s3/include/hal/rtc_io_ll.h | 10 ++++++ .../hal/esp32s3/include/hal/usb_phy_ll.h | 2 ++ .../soc/esp32c3/include/soc/io_mux_reg.h | 3 ++ .../soc/esp32h2/include/soc/io_mux_reg.h | 3 ++ .../soc/esp32s3/include/soc/io_mux_reg.h | 2 ++ 11 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 components/hal/esp32c3/include/hal/usb_phy_ll.h create mode 100644 components/hal/esp32h2/include/hal/usb_phy_ll.h diff --git a/components/driver/usb_serial_jtag.c b/components/driver/usb_serial_jtag.c index 07f0bb1ee6..3f7db5ee8f 100644 --- a/components/driver/usb_serial_jtag.c +++ b/components/driver/usb_serial_jtag.c @@ -16,6 +16,7 @@ #include #include "esp_log.h" #include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_phy_ll.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/ringbuf.h" @@ -120,6 +121,9 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se goto _exit; } + // Configure PHY + usb_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG); + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY| USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY| diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 91343f8477..0b57785955 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -50,6 +50,12 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num) */ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + if (gpio_num == USB_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + } REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU); } diff --git a/components/hal/esp32c3/include/hal/usb_phy_ll.h b/components/hal/esp32c3/include/hal/usb_phy_ll.h new file mode 100644 index 0000000000..40d4cd1800 --- /dev/null +++ b/components/hal/esp32c3/include/hal/usb_phy_ll.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/usb_serial_jtag_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configures the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) +{ + // USB_Serial_JTAG use internal PHY + hw->conf0.phy_sel = 0; + // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) + hw->conf0.pad_pull_override = 0; + // Enable USB D+ pullup + hw->conf0.dp_pullup = 1; + // Enable USB pad function + hw->conf0.usb_pad_enable = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index f38cf9c5d4..a834c8b24e 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -26,15 +26,17 @@ extern "C" { #endif /* - * The following defines are used to disable USB JTAG when pins 18 and pins 19 - * are set to be used as GPIO. + * The following defines are used to disable USB JTAG and DP pullup when + * pins 18 and pins 19 are set to be used as GPIO. * See gpio_pad_select_gpio() below. * * TODO: Delete these definitions once the USB device registers definition is * merged. */ -#define USB_DEVICE_CONF0_REG (0x60043018) -#define USB_DEVICE_USB_PAD_ENABLE (BIT(14)) +#define USB_DEVICE_CONF0_REG (0x60043018) +#define USB_DEVICE_USB_PAD_ENABLE (BIT(14)) +#define USB_DEVICE_DP_PULLUP (BIT(9)) +#define USB_DEVICE_PAD_PULL_OVERRIDE (BIT(8)) // Get GPIO hardware instance with giving gpio num #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) @@ -60,6 +62,12 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num) */ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + if (gpio_num == USB_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_DP_PULLUP); + } REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU); } diff --git a/components/hal/esp32h2/include/hal/usb_phy_ll.h b/components/hal/esp32h2/include/hal/usb_phy_ll.h new file mode 100644 index 0000000000..40d4cd1800 --- /dev/null +++ b/components/hal/esp32h2/include/hal/usb_phy_ll.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/usb_serial_jtag_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configures the internal PHY for USB_Serial_JTAG + * + * @param hw Start address of the USB Serial_JTAG registers + */ +static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) +{ + // USB_Serial_JTAG use internal PHY + hw->conf0.phy_sel = 0; + // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) + hw->conf0.pad_pull_override = 0; + // Enable USB D+ pullup + hw->conf0.dp_pullup = 1; + // Enable USB pad function + hw->conf0.usb_pad_enable = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 6a5b7b1b85..a68ff6729c 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -52,6 +52,14 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num) */ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that from esp32s3 ECO1, USB_EXCHG_PINS feature has been supported. If this efuse is burnt, the gpio pin + // which should be checked is USB_DM_GPIO_NUM instead. + if (gpio_num == USB_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + } REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU); } diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 08a3c63e6a..97eff5f368 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -17,6 +17,8 @@ #include "soc/rtc_io_struct.h" #include "hal/rtc_io_types.h" #include "hal/gpio_types.h" +#include "soc/io_mux_reg.h" +#include "soc/usb_serial_jtag_reg.h" #define RTCIO_LL_PIN_FUNC 0 @@ -181,6 +183,14 @@ static inline void rtcio_ll_pullup_enable(int rtcio_num) */ static inline void rtcio_ll_pullup_disable(int rtcio_num) { + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that from esp32s3 ECO1, USB_EXCHG_PINS feature has been supported. If this efuse is burnt, the gpio pin + // which should be checked is USB_DM_GPIO_NUM instead. + if (rtcio_num == USB_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + } if (rtc_io_desc[rtcio_num].pullup) { CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup); } diff --git a/components/hal/esp32s3/include/hal/usb_phy_ll.h b/components/hal/esp32s3/include/hal/usb_phy_ll.h index fc665552d8..acf6eed102 100644 --- a/components/hal/esp32s3/include/hal/usb_phy_ll.h +++ b/components/hal/esp32s3/include/hal/usb_phy_ll.h @@ -59,6 +59,8 @@ static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) hw->conf0.phy_sel = 0; // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) hw->conf0.pad_pull_override = 0; + // Enable USB D+ pullup + hw->conf0.dp_pullup = 1; // Enable USB pad function hw->conf0.usb_pad_enable = 1; // phy_sel is controlled by the following register value diff --git a/components/soc/esp32c3/include/soc/io_mux_reg.h b/components/soc/esp32c3/include/soc/io_mux_reg.h index 618f8fa5d3..7eb6d25867 100644 --- a/components/soc/esp32c3/include/soc/io_mux_reg.h +++ b/components/soc/esp32c3/include/soc/io_mux_reg.h @@ -138,6 +138,9 @@ #define SD_DATA2_GPIO_NUM 9 #define SD_DATA3_GPIO_NUM 10 +#define USB_DM_GPIO_NUM 18 +#define USB_DP_GPIO_NUM 19 + #define MAX_RTC_GPIO_NUM 5 #define MAX_PAD_GPIO_NUM 21 #define MAX_GPIO_NUM 25 diff --git a/components/soc/esp32h2/include/soc/io_mux_reg.h b/components/soc/esp32h2/include/soc/io_mux_reg.h index e9a0795167..de79ebb807 100644 --- a/components/soc/esp32h2/include/soc/io_mux_reg.h +++ b/components/soc/esp32h2/include/soc/io_mux_reg.h @@ -138,6 +138,9 @@ #define SD_DATA2_GPIO_NUM 9 #define SD_DATA3_GPIO_NUM 10 +#define USB_DM_GPIO_NUM 18 +#define USB_DP_GPIO_NUM 19 + #define MAX_RTC_GPIO_NUM 0 #define MAX_PAD_GPIO_NUM 22 #define MAX_GPIO_NUM 22 diff --git a/components/soc/esp32s3/include/soc/io_mux_reg.h b/components/soc/esp32s3/include/soc/io_mux_reg.h index 4b9057400c..877a84e757 100644 --- a/components/soc/esp32s3/include/soc/io_mux_reg.h +++ b/components/soc/esp32s3/include/soc/io_mux_reg.h @@ -163,6 +163,8 @@ #define SD_DATA1_GPIO_NUM 14 #define SD_DATA2_GPIO_NUM 9 #define SD_DATA3_GPIO_NUM 10 +#define USB_DM_GPIO_NUM 19 +#define USB_DP_GPIO_NUM 20 #define MAX_RTC_GPIO_NUM 21 #define MAX_PAD_GPIO_NUM 48