From bc2ea111fb911a6ec7a21efe489d241741c5fd74 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 24 Oct 2023 13:29:15 +0200 Subject: [PATCH 1/2] fix(console): switch USB PHY to OTG when OTG is used for console On ESP32-S3 with the default efuse settings, USB PHY is connected to the USB_SERIAL_JTAG peripheral. If USB OTG peripheral is used for the console, we need to additionally switch the PHY to USB OTG, otherwise we won't get any output. Closes https://github.com/espressif/esp-idf/issues/12437 --- components/bootloader_support/src/bootloader_console.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 8ee4c3acdf..bbcfe38422 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -26,6 +26,9 @@ #include "esp32h2/rom/ets_sys.h" #include "esp32h2/rom/uart.h" #endif +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_phy_ll.h" +#endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -104,6 +107,9 @@ void bootloader_console_init(void) esp_rom_uart_usb_acm_init(s_usb_cdc_buf, sizeof(s_usb_cdc_buf)); esp_rom_uart_set_as_console(ESP_ROM_UART_USB); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); +#if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_phy_ll_int_otg_enable(&USB_WRAP); +#endif } #endif //CONFIG_ESP_CONSOLE_USB_CDC From 236883728d1d9ed835da15cfec4d37220ecec017 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 27 Oct 2023 18:23:50 +0800 Subject: [PATCH 2/2] fix(esp_hw_support): fix lightsleep current leakage on usb-phy controlled pad --- .../src/bootloader_console.c | 1 + components/driver/usb_serial_jtag.c | 4 + components/esp_hw_support/CMakeLists.txt | 1 + .../include/esp_private/sleep_console.h | 35 +++++++++ components/esp_hw_support/linker.lf | 2 + components/esp_hw_support/sleep_console.c | 38 ++++++++++ components/esp_hw_support/sleep_modes.c | 10 ++- .../esp32c3/include/hal/usb_serial_jtag_ll.h | 74 +++++++++++++++---- .../esp32h2/include/hal/usb_serial_jtag_ll.h | 58 ++++++++++++++- .../hal/esp32s2/include/hal/usb_phy_ll.h | 33 ++++++++- .../hal/esp32s3/include/hal/usb_phy_ll.h | 34 ++++++++- .../esp32s3/include/hal/usb_serial_jtag_ll.h | 73 ++++++++++++++---- components/hal/usb_phy_hal.c | 1 + .../soc/esp32c3/ld/esp32c3.peripherals.ld | 1 + .../soc/esp32s3/ld/esp32s3.peripherals.ld | 1 + components/usb/usb_phy.c | 15 ++-- 16 files changed, 341 insertions(+), 40 deletions(-) create mode 100644 components/esp_hw_support/include/esp_private/sleep_console.h create mode 100644 components/esp_hw_support/sleep_console.c diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index bbcfe38422..e584e7aa62 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -108,6 +108,7 @@ void bootloader_console_init(void) esp_rom_uart_set_as_console(ESP_ROM_UART_USB); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); #if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_phy_ll_usb_wrap_pad_enable(&USB_WRAP, true); usb_phy_ll_int_otg_enable(&USB_WRAP); #endif } diff --git a/components/driver/usb_serial_jtag.c b/components/driver/usb_serial_jtag.c index b39ed39839..3905157a76 100644 --- a/components/driver/usb_serial_jtag.c +++ b/components/driver/usb_serial_jtag.c @@ -151,6 +151,9 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se goto _exit; } + // Enable USB-Serial-JTAG peripheral module clock + usb_serial_jtag_ll_enable_bus_clock(true); + // Configure PHY usb_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG); @@ -214,6 +217,7 @@ esp_err_t usb_serial_jtag_driver_uninstall(void) return ESP_OK; } + /* Not disable the module clock and usb_pad_enable here since the USJ stdout might still depends on it. */ //Disable tx/rx interrupt. usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); esp_intr_free(p_usb_serial_jtag_obj->intr_handle); diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index e7dd4aaabc..d4500dc1f9 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -16,6 +16,7 @@ if(NOT BOOTLOADER_BUILD) "mac_addr.c" "revision.c" "sleep_modes.c" + "sleep_console.c" "sleep_gpio.c" "sleep_mac_bb.c" "regi2c_ctrl.c") diff --git a/components/esp_hw_support/include/esp_private/sleep_console.h b/components/esp_hw_support/include/esp_private/sleep_console.h new file mode 100644 index 0000000000..612c51692c --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_console.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_SERIAL_JTAG_SUPPORTED +typedef struct { + bool usj_clock_enabled; + bool usj_pad_enabled; +} sleep_console_usj_enable_state_t; + +/** + * @brief Disable usb-serial-jtag pad during light sleep to avoid current leakage and + * backup the enable state before light sleep + */ +void sleep_console_usj_pad_backup_and_disable(void); + +/** + * @brief Restore initial usb-serial-jtag pad enable state when wakeup from light sleep + */ +void sleep_console_usj_pad_restore(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index e8adfc884d..170eaa82f3 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -9,6 +9,8 @@ entries: rtc_pm (noflash_text) rtc_sleep (noflash_text) rtc_time (noflash_text) + if IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C3 = y || IDF_TARGET_ESP32H2 = y: + sleep_console (noflash) if IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n: rtc_wdt (noflash_text) if IDF_TARGET_ESP32S3 = y: diff --git a/components/esp_hw_support/sleep_console.c b/components/esp_hw_support/sleep_console.c new file mode 100644 index 0000000000..2ac789d275 --- /dev/null +++ b/components/esp_hw_support/sleep_console.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/soc_caps.h" +#include "esp_private/sleep_console.h" +#include "esp_attr.h" + +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_serial_jtag_ll.h" + +static sleep_console_usj_enable_state_t s_usj_state = {0}; + +void sleep_console_usj_pad_backup_and_disable(void) +{ + s_usj_state.usj_clock_enabled = usb_serial_jtag_ll_module_is_enabled(); + if (!s_usj_state.usj_clock_enabled) { + // Enable USJ clock and clear reset + usb_serial_jtag_ll_enable_bus_clock(true); + usb_serial_jtag_ll_reset_register(); + } + s_usj_state.usj_pad_enabled = usb_serial_jtag_ll_pad_backup_and_disable(); + // Disable USJ clock + usb_serial_jtag_ll_enable_bus_clock(false); +} + +void sleep_console_usj_pad_restore(void) +{ + usb_serial_jtag_ll_enable_bus_clock(true); + usb_serial_jtag_ll_enable_pad(s_usj_state.usj_pad_enabled); + if (!s_usj_state.usj_clock_enabled) { + usb_serial_jtag_ll_enable_bus_clock(false); + } +} +#endif diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 0efbcc3b76..298f9398b0 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,6 +46,7 @@ #include "esp_rom_uart.h" #include "esp_rom_sys.h" #include "brownout.h" +#include "esp_private/sleep_console.h" #include "esp_private/sleep_retention.h" #include "esp_private/sar_periph_ctrl.h" @@ -351,6 +352,10 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) #endif } } else { +#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP + // Only avoid USJ pad leakage here, USB OTG pad leakage is prevented through USB Host driver. + sleep_console_usj_pad_backup_and_disable(); +#endif #if CONFIG_MAC_BB_PD mac_bb_power_down_cb_execute(); #endif @@ -374,6 +379,9 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) */ inline static void IRAM_ATTR misc_modules_wake_prepare(void) { +#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP + sleep_console_usj_pad_restore(); +#endif sar_periph_ctrl_power_enable(); #if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD sleep_disable_memory_retention(); diff --git a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h index 8e295a4181..8e01043116 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -1,22 +1,17 @@ -// Copyright 2021 Espressif Systems (Shanghai) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // The LL layer of the USB-serial-jtag controller #pragma once +#include +#include "esp_attr.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "soc/system_struct.h" #ifdef __cplusplus extern "C" { @@ -166,6 +161,59 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/** + * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * + * @return Initial configuration of usb serial jtag pad enable before light sleep + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +{ + bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; + + // Disable USB pad function + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + + return pad_enabled; +} + +/** + * @brief Enable the internal USJ PHY control to D+/D- pad + * + * @param enable_pad Enable the USJ PHY control to D+/D- pad + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; +} + +/** + * @brief Enable the bus clock for USB Serial_JTAG module + * @param clk_en True if enable the clock of USB Serial_JTAG module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + SYSTEM.perip_clk_en0.reg_usb_device_clk_en = clk_en; +} + +/** + * @brief Reset the usb serial jtag module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.reg_usb_device_rst = 1; + SYSTEM.perip_rst_en0.reg_usb_device_rst = 0; +} + +/** + * Get the enable status USB Serial_JTAG module + * + * @return Return true if USB Serial_JTAG module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (SYSTEM.perip_clk_en0.reg_usb_device_clk_en && !SYSTEM.perip_rst_en0.reg_usb_device_rst); +} + #ifdef __cplusplus } diff --git a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h index 0241436ec4..fc17c8929e 100644 --- a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h @@ -15,10 +15,12 @@ // The LL layer of the USB-serial-jtag controller #pragma once - +#include +#include "esp_attr.h" #include "hal/misc.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "soc/clkrst_reg.h" #ifdef __cplusplus extern "C" { @@ -166,6 +168,60 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) } +/** + * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * + * @return Initial configuration of usb serial jtag pad enable before light sleep + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +{ + bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; + + // Disable USB pad function + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + + return pad_enabled; +} + +/** + * @brief Enable the internal USJ PHY control to D+/D- pad + * + * @param enable_pad Enable the USJ PHY control to D+/D- pad + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; +} + +/** + * @brief Enable the bus clock for USB Serial_JTAG module + * @param clk_en True if enable the clock of USB Serial_JTAG module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + REG_SET_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_USB_DEVICE_CLK_EN); +} + +/** + * @brief Reset the usb serial jtag module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + REG_SET_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_USB_DEVICE_RST); + REG_CLR_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_USB_DEVICE_RST); +} + +/** + * Get the enable status USB Serial_JTAG module + * + * @return Return true if USB Serial_JTAG module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (REG_GET_BIT(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_USB_DEVICE_CLK_EN) \ + && !REG_GET_BIT(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_USB_DEVICE_RST)); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s2/include/hal/usb_phy_ll.h b/components/hal/esp32s2/include/hal/usb_phy_ll.h index ed175cf9ce..a0b74f6727 100644 --- a/components/hal/esp32s2/include/hal/usb_phy_ll.h +++ b/components/hal/esp32s2/include/hal/usb_phy_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #pragma once #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/system_reg.h" #include "soc/usb_wrap_struct.h" @@ -22,8 +23,6 @@ extern "C" { */ static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw) { - //Enable internal PHY - hw->otg_conf.pad_enable = 1; hw->otg_conf.phy_sel = 0; } @@ -58,6 +57,16 @@ static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool hw->otg_conf = conf; } +/** + * @brief Enable the internal PHY control to D+/D- pad + * @param hw Start address of the USB Wrap registers + * @param pad_en Enable the PHY control to D+/D- pad + */ +static inline void usb_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en) +{ + hw->otg_conf.pad_enable = pad_en; +} + /** * @brief Enable the internal PHY's test mode * @@ -78,6 +87,24 @@ static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en) } } +/** + * Enable the bus clock for USB Wrap module + * @param clk_en True if enable the clock of USB Wrap module + */ +FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_enable_bus_clock(bool clk_en) +{ + REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en); +} + +/** + * @brief Reset the USB Wrap module + */ +FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_reset_register(void) +{ + REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 1); + REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/usb_phy_ll.h b/components/hal/esp32s3/include/hal/usb_phy_ll.h index acf6eed102..133daf3054 100644 --- a/components/hal/esp32s3/include/hal/usb_phy_ll.h +++ b/components/hal/esp32s3/include/hal/usb_phy_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,8 +7,9 @@ #pragma once #include +#include "esp_attr.h" #include "soc/soc.h" -#include "soc/system_reg.h" +#include "soc/system_struct.h" #include "soc/usb_wrap_struct.h" #include "soc/rtc_cntl_struct.h" #include "soc/usb_serial_jtag_struct.h" @@ -24,7 +25,6 @@ extern "C" { */ static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw) { - hw->otg_conf.pad_enable = 1; // USB_OTG use internal PHY hw->otg_conf.phy_sel = 0; // phy_sel is controlled by the following register value @@ -104,6 +104,16 @@ static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool hw->otg_conf = conf; } +/** + * @brief Enable the internal PHY control to D+/D- pad + * @param hw Start address of the USB Wrap registers + * @param pad_en Enable the PHY control to D+/D- pad + */ +static inline void usb_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en) +{ + hw->otg_conf.pad_enable = pad_en; +} + /** * @brief Enable the internal PHY's test mode * @@ -124,6 +134,24 @@ static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en) } } +/** + * Enable the bus clock for USB Wrap module + * @param clk_en True if enable the clock of USB Wrap module + */ +FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_enable_bus_clock(bool clk_en) +{ + SYSTEM.perip_clk_en0.usb_clk_en = clk_en; +} + +/** + * @brief Reset the USB Wrap module + */ +FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_reset_register(void) +{ + SYSTEM.perip_rst_en0.usb_rst = 1; + SYSTEM.perip_rst_en0.usb_rst = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h index 335663ff12..d3bdacb8e0 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -1,20 +1,15 @@ -// Copyright 2021 Espressif Systems (Shanghai) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // The LL layer of the USB-serial-jtag controller #pragma once +#include +#include "esp_attr.h" +#include "soc/system_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" @@ -163,6 +158,58 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/** + * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * + * @return Initial configuration of usb serial jtag pad enable before light sleep + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +{ + bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; + + // Disable USB pad function + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + + return pad_enabled; +} + +/** + * @brief Enable the internal USJ PHY control to D+/D- pad + * + * @param enable_pad Enable the USJ PHY control to D+/D- pad + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; +} + +/** + * @brief Enable the bus clock for USB Serial_JTAG module + * @param clk_en True if enable the clock of USB Serial_JTAG module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + SYSTEM.perip_clk_en1.usb_device_clk_en = clk_en; +} + +/** + * @brief Reset the usb serial jtag module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + SYSTEM.perip_rst_en1.usb_device_rst = 1; + SYSTEM.perip_rst_en1.usb_device_rst = 0; +} + +/** + * Get the enable status USB Serial_JTAG module + * + * @return Return true if USB Serial_JTAG module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (SYSTEM.perip_clk_en1.usb_device_clk_en && !SYSTEM.perip_rst_en1.usb_device_rst); +} #ifdef __cplusplus } diff --git a/components/hal/usb_phy_hal.c b/components/hal/usb_phy_hal.c index 16a8f60d81..ec24d08aa3 100644 --- a/components/hal/usb_phy_hal.c +++ b/components/hal/usb_phy_hal.c @@ -20,6 +20,7 @@ void usb_phy_hal_otg_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_targe if (phy_target == USB_PHY_TARGET_EXT) { usb_phy_ll_ext_otg_enable(hal->wrap_dev); } else if (phy_target == USB_PHY_TARGET_INT) { + usb_phy_ll_usb_wrap_pad_enable(hal->wrap_dev, true); usb_phy_ll_int_otg_enable(hal->wrap_dev); } } diff --git a/components/soc/esp32c3/ld/esp32c3.peripherals.ld b/components/soc/esp32c3/ld/esp32c3.peripherals.ld index c64266b54b..0ae0e5522a 100644 --- a/components/soc/esp32c3/ld/esp32c3.peripherals.ld +++ b/components/soc/esp32c3/ld/esp32c3.peripherals.ld @@ -28,3 +28,4 @@ PROVIDE ( GPSPI4 = 0x60037000 ); PROVIDE ( APB_SARADC = 0x60040000 ); PROVIDE ( USB_SERIAL_JTAG = 0x60043000 ); PROVIDE ( GDMA = 0x6003F000 ); +PROVIDE ( SYSTEM = 0x600C0000 ); diff --git a/components/soc/esp32s3/ld/esp32s3.peripherals.ld b/components/soc/esp32s3/ld/esp32s3.peripherals.ld index 6dfffd9900..8e59dd5354 100644 --- a/components/soc/esp32s3/ld/esp32s3.peripherals.ld +++ b/components/soc/esp32s3/ld/esp32s3.peripherals.ld @@ -47,3 +47,4 @@ PROVIDE ( USB_SERIAL_JTAG = 0x60038000 ); PROVIDE ( USB0 = 0x60080000 ); PROVIDE ( USB_DWC = 0x60080000 ); PROVIDE ( USB_WRAP = 0x60039000 ); +PROVIDE ( SYSTEM = 0x600C0000 ); diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index 62fbb78f56..f336748bc9 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "esp_rom_gpio.h" #include "driver/gpio.h" #include "hal/gpio_ll.h" +#include "soc/soc_caps.h" #include "soc/usb_pins.h" static const char *USBPHY_TAG = "usb_phy"; @@ -196,9 +197,10 @@ static esp_err_t usb_phy_install(void) portEXIT_CRITICAL(&phy_spinlock); goto cleanup; } + usb_phy_ll_usb_wrap_enable_bus_clock(true); + usb_phy_ll_usb_wrap_reset_register(); + // Enable USB peripheral and reset the register portEXIT_CRITICAL(&phy_spinlock); - periph_module_enable(usb_phy_periph_signal.module); - periph_module_reset(usb_phy_periph_signal.module); return ESP_OK; cleanup: @@ -285,8 +287,8 @@ static void phy_uninstall(void) if (p_phy_ctrl_obj->ref_count == 0) { p_phy_ctrl_obj_free = p_phy_ctrl_obj; p_phy_ctrl_obj = NULL; - // Disable USB peripheral - periph_module_disable(usb_phy_periph_signal.module); + // Disable USB peripheral without reset the module + usb_phy_ll_usb_wrap_enable_bus_clock(false); } portEXIT_CRITICAL(&phy_spinlock); free(p_phy_ctrl_obj_free); @@ -301,8 +303,9 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle) if (handle->target == USB_PHY_TARGET_EXT) { p_phy_ctrl_obj->external_phy = NULL; } else { - // Clear pullup and pulldown loads on D+ / D- + // Clear pullup and pulldown loads on D+ / D-, and disable the pads usb_phy_ll_int_load_conf(handle->hal_context.wrap_dev, false, false, false, false); + usb_phy_ll_usb_wrap_pad_enable(handle->hal_context.wrap_dev, false); p_phy_ctrl_obj->internal_phy = NULL; } portEXIT_CRITICAL(&phy_spinlock);