From 75498cdb7afdf857d43d5fb95ce8d6970d05dc9d Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Thu, 14 Mar 2024 07:49:37 +0800 Subject: [PATCH 1/5] refactor(hal/usj): Add USB PHY related functions to USJ LL --- components/esp_hw_support/sleep_console.c | 7 +- .../esp32c3/include/hal/usb_serial_jtag_ll.h | 109 ++++++++++++-- .../esp32c6/include/hal/usb_serial_jtag_ll.h | 121 ++++++++++++++-- .../esp32h2/include/hal/usb_serial_jtag_ll.h | 118 +++++++++++++-- .../esp32s3/include/hal/usb_serial_jtag_ll.h | 137 ++++++++++++++++-- 5 files changed, 441 insertions(+), 51 deletions(-) diff --git a/components/esp_hw_support/sleep_console.c b/components/esp_hw_support/sleep_console.c index 2ac789d275..62df8daf06 100644 --- a/components/esp_hw_support/sleep_console.c +++ b/components/esp_hw_support/sleep_console.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,8 @@ void sleep_console_usj_pad_backup_and_disable(void) 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(); + s_usj_state.usj_pad_enabled = usb_serial_jtag_ll_phy_is_pad_enabled(); + usb_serial_jtag_ll_phy_enable_pad(false); // Disable USJ clock usb_serial_jtag_ll_enable_bus_clock(false); } @@ -30,7 +31,7 @@ void sleep_console_usj_pad_backup_and_disable(void) 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); + usb_serial_jtag_ll_phy_enable_pad(s_usj_state.usj_pad_enabled); if (!s_usj_state.usj_clock_enabled) { usb_serial_jtag_ll_enable_bus_clock(false); } 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 07d1bdf52e..d52839a320 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -34,6 +34,8 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -177,31 +179,112 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/* ---------------------------- USB PHY Control ---------------------------- */ + /** - * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY * - * @return Initial configuration of usb serial jtag pad enable before light sleep + * @param enable Enables external PHY, internal otherwise */ -FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) { - 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; + USB_SERIAL_JTAG.conf0.phy_sel = enable; } /** - * @brief Enable the internal USJ PHY control to D+/D- pad + * @brief Enables/disables exchanging of the D+/D- pins USB PHY * - * @param enable_pad Enable the USJ PHY control to D+/D- pad + * @param enable Enables pin exchange, disabled otherwise */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) { - USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } } +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param dp_pu Enable D+ pullup + * @param dm_pu Enable D- pullup + * @param dp_pd Enable D+ pulldown + * @param dm_pd Enable D- pulldown + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + /** * @brief Enable the bus clock for USB Serial_JTAG module * @param clk_en True if enable the clock of USB Serial_JTAG module diff --git a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h index 145913356e..d21821ad35 100644 --- a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h @@ -34,6 +34,8 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -177,32 +179,125 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/** + * @brief Enable USJ JTAG bridge + * + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} + +/* ---------------------------- USB PHY Control ---------------------------- */ /** - * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY * - * @return Initial configuration of usb serial jtag pad enable before light sleep + * @param enable Enables external PHY, internal otherwise */ -FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) { - 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; + USB_SERIAL_JTAG.conf0.phy_sel = enable; } /** - * @brief Enable the internal USJ PHY control to D+/D- pad + * @brief Enables/disables exchanging of the D+/D- pins USB PHY * - * @param enable_pad Enable the USJ PHY control to D+/D- pad + * @param enable Enables pin exchange, disabled otherwise */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) { - USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } } +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param dp_pu Enable D+ pullup + * @param dm_pu Enable D- pullup + * @param dp_pd Enable D+ pulldown + * @param dm_pd Enable D- pulldown + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + /** * @brief Enable the bus clock for USB Serial_JTAG module * @param clk_en True if enable the clock of USB Serial_JTAG module 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 565eecea4c..ec8a32ea67 100644 --- a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h @@ -34,6 +34,8 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -178,30 +180,124 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) } /** - * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * @brief Enable USJ JTAG bridge * - * @return Initial configuration of usb serial jtag pad enable before light sleep + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge */ -FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) { - bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} - // Disable USB pad function - USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; +/* ---------------------------- USB PHY Control ---------------------------- */ - return pad_enabled; +/** + * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY + * + * @param enable Enables external PHY, internal otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) +{ + USB_SERIAL_JTAG.conf0.phy_sel = enable; } /** - * @brief Enable the internal USJ PHY control to D+/D- pad + * @brief Enables/disables exchanging of the D+/D- pins USB PHY * - * @param enable_pad Enable the USJ PHY control to D+/D- pad + * @param enable Enables pin exchange, disabled otherwise */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) { - USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } } +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param dp_pu Enable D+ pullup + * @param dm_pu Enable D- pullup + * @param dp_pd Enable D+ pulldown + * @param dm_pd Enable D- pulldown + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + /** * @brief Enable the bus clock for USB Serial_JTAG module * @param clk_en True if enable the clock of USB Serial_JTAG module 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 463c6ac76f..96a989a2f4 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -10,6 +10,7 @@ #include #include "esp_attr.h" #include "soc/system_struct.h" +#include "soc/rtc_cntl_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" @@ -34,6 +35,8 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_intr_t; +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -178,30 +181,142 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) } /** - * @brief Disable usb serial jtag pad during light sleep to avoid current leakage + * @brief Enable USJ JTAG bridge * - * @return Initial configuration of usb serial jtag pad enable before light sleep + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge */ -FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) { - bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} - // Disable USB pad function - USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; +/* ---------------------------- USB PHY Control ---------------------------- */ - return pad_enabled; +/** + * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY + * + * @param enable Enables external PHY, internal otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) +{ + USB_SERIAL_JTAG.conf0.phy_sel = enable; + // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY + RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; + /* + For 'sw_usb_phy_sel': + 0 - Internal USB FSLS PHY is mapped to the USJ. USB Wrap mapped to external PHY + 1 - Internal USB FSLS PHY is mapped to the USB Wrap. USJ mapped to external PHY + */ + RTCCNTL.usb_conf.sw_usb_phy_sel = enable; } /** - * @brief Enable the internal USJ PHY control to D+/D- pad + * @brief Enables/disables exchanging of the D+/D- pins USB PHY * - * @param enable_pad Enable the USJ PHY control to D+/D- pad + * @param enable Enables pin exchange, disabled otherwise */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) { - USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad; + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } } +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param dp_pu Enable D+ pullup + * @param dm_pu Enable D- pullup + * @param dp_pd Enable D+ pulldown + * @param dm_pd Enable D- pulldown + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/** + * @brief Set USB FSLS PHY TX output clock edge + * + * @param clk_neg_edge True if TX output at negedge, posedge otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_tx_edge(bool clk_neg_edge) +{ + USB_SERIAL_JTAG.conf0.phy_tx_edge_sel = clk_neg_edge; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + /** * @brief Enable the bus clock for USB Serial_JTAG module * @param clk_en True if enable the clock of USB Serial_JTAG module From c776d40df149990d62ee7686ece77c00eea59340 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Thu, 14 Mar 2024 21:20:33 +0800 Subject: [PATCH 2/5] refactor(hal/usb): Remove usb_fsls_phy_ll.h For targets that only contain a USJ peripheral (and not a DWC OTG), their 'usb_fsls_phy_ll.h' headers only contain a single function ('usb_fsls_phy_ll_int_jtag_enable()') whose feature is already covered by functions in 'usb_serial_jtag_ll.h'. Thus, this header is redundant. This commit does the following: - Remove 'usb_fsls_phy_ll.h' for targets that only contain a USJ peripheral - Rename 'usb_fsls_phy_[hal|ll].[h|c]' to `usb_wrap_[hal|ll].[h|c]` for targets that contain a DWC OTG peripheral. This better reflects the underlying peripheral that the LL header accesses. --- .../src/bootloader_console.c | 5 +-- .../driver/usb_serial_jtag/usb_serial_jtag.c | 4 +-- components/hal/CMakeLists.txt | 2 +- .../hal/esp32c3/include/hal/usb_fsls_phy_ll.h | 34 ------------------- .../hal/esp32c6/include/hal/usb_fsls_phy_ll.h | 34 ------------------- .../hal/esp32h2/include/hal/usb_fsls_phy_ll.h | 34 ------------------- .../hal/{usb_fsls_phy_ll.h => usb_wrap_ll.h} | 0 .../hal/{usb_fsls_phy_ll.h => usb_wrap_ll.h} | 0 .../{usb_fsls_phy_hal.h => usb_wrap_hal.h} | 0 .../{usb_fsls_phy_hal.c => usb_wrap_hal.c} | 22 +++++++++--- components/usb/usb_phy.c | 4 +-- 11 files changed, 26 insertions(+), 113 deletions(-) delete mode 100644 components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h delete mode 100644 components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h delete mode 100644 components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h rename components/hal/esp32s2/include/hal/{usb_fsls_phy_ll.h => usb_wrap_ll.h} (100%) rename components/hal/esp32s3/include/hal/{usb_fsls_phy_ll.h => usb_wrap_ll.h} (100%) rename components/hal/include/hal/{usb_fsls_phy_hal.h => usb_wrap_hal.h} (100%) rename components/hal/{usb_fsls_phy_hal.c => usb_wrap_hal.c} (68%) diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 7fe7f60a08..0e43c8aaf8 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -6,6 +6,7 @@ #include "sdkconfig.h" #include "bootloader_console.h" +#include "soc/soc_caps.h" #include "soc/uart_periph.h" #include "soc/uart_channel.h" #include "soc/io_mux_reg.h" @@ -18,8 +19,8 @@ #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_common.h" #endif -#if SOC_USB_SERIAL_JTAG_SUPPORTED -#include "hal/usb_fsls_phy_ll.h" +#if CONFIG_ESP_CONSOLE_USB_CDC && SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_wrap_ll.h" #endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" diff --git a/components/driver/usb_serial_jtag/usb_serial_jtag.c b/components/driver/usb_serial_jtag/usb_serial_jtag.c index 3e591cfb43..7d0cc554eb 100644 --- a/components/driver/usb_serial_jtag/usb_serial_jtag.c +++ b/components/driver/usb_serial_jtag/usb_serial_jtag.c @@ -9,7 +9,6 @@ #include #include "esp_log.h" #include "hal/usb_serial_jtag_ll.h" -#include "hal/usb_fsls_phy_ll.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/ringbuf.h" @@ -176,7 +175,8 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); // Configure PHY - usb_fsls_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG); + usb_serial_jtag_ll_phy_enable_external(false); // Use internal PHY + usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY| USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 067ac01093..177255c4a4 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -182,7 +182,7 @@ if(NOT BOOTLOADER_BUILD) if(CONFIG_SOC_USB_OTG_SUPPORTED) list(APPEND srcs "usb_dwc_hal.c" - "usb_fsls_phy_hal.c") + "usb_wrap_hal.c") endif() if(${target} STREQUAL "esp32") diff --git a/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h deleted file mode 100644 index b8d98219b0..0000000000 --- a/components/hal/esp32c3/include/hal/usb_fsls_phy_ll.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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_fsls_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/esp32c6/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h deleted file mode 100644 index 4893e96106..0000000000 --- a/components/hal/esp32c6/include/hal/usb_fsls_phy_ll.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 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_fsls_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/usb_fsls_phy_ll.h b/components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h deleted file mode 100644 index 271f2fd83b..0000000000 --- a/components/hal/esp32h2/include/hal/usb_fsls_phy_ll.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 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_fsls_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/esp32s2/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32s2/include/hal/usb_wrap_ll.h similarity index 100% rename from components/hal/esp32s2/include/hal/usb_fsls_phy_ll.h rename to components/hal/esp32s2/include/hal/usb_wrap_ll.h diff --git a/components/hal/esp32s3/include/hal/usb_fsls_phy_ll.h b/components/hal/esp32s3/include/hal/usb_wrap_ll.h similarity index 100% rename from components/hal/esp32s3/include/hal/usb_fsls_phy_ll.h rename to components/hal/esp32s3/include/hal/usb_wrap_ll.h diff --git a/components/hal/include/hal/usb_fsls_phy_hal.h b/components/hal/include/hal/usb_wrap_hal.h similarity index 100% rename from components/hal/include/hal/usb_fsls_phy_hal.h rename to components/hal/include/hal/usb_wrap_hal.h diff --git a/components/hal/usb_fsls_phy_hal.c b/components/hal/usb_wrap_hal.c similarity index 68% rename from components/hal/usb_fsls_phy_hal.c rename to components/hal/usb_wrap_hal.c index 7bceb8c364..58b77bba23 100644 --- a/components/hal/usb_fsls_phy_hal.c +++ b/components/hal/usb_wrap_hal.c @@ -4,8 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "hal/usb_fsls_phy_ll.h" -#include "hal/usb_fsls_phy_hal.h" +#include "soc/soc_caps.h" +#include "soc/rtc_cntl_struct.h" +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_serial_jtag_ll.h" +#endif +#include "hal/usb_wrap_ll.h" +#include "hal/usb_wrap_hal.h" void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal) { @@ -29,9 +34,18 @@ void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) { if (phy_target == USB_PHY_TARGET_EXT) { - usb_fsls_phy_ll_ext_jtag_enable(hal->jtag_dev); + usb_serial_jtag_ll_phy_enable_external(true); // USJ uses external PHY + // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY + RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; + // Internal USB FSLS PHY is mapped to the USJ + RTCCNTL.usb_conf.sw_usb_phy_sel = 1; } else if (phy_target == USB_PHY_TARGET_INT) { - usb_fsls_phy_ll_int_jtag_enable(hal->jtag_dev); + usb_serial_jtag_ll_phy_enable_external(true); // USJ uses internal PHY + usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads + // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY + RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; + // Internal USB FSLS PHY is mapped to the USJ + RTCCNTL.usb_conf.sw_usb_phy_sel = 0; } } #endif diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index 0e36500f5e..56f1c56119 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -12,8 +12,8 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/usb_phy.h" #include "soc/usb_dwc_periph.h" -#include "hal/usb_fsls_phy_hal.h" -#include "hal/usb_fsls_phy_ll.h" +#include "hal/usb_wrap_hal.h" +#include "hal/usb_wrap_ll.h" #include "esp_rom_gpio.h" #include "driver/gpio.h" #include "hal/gpio_ll.h" From 06821a8fe62f587221f77d73643212fce4f0d4c4 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Fri, 15 Mar 2024 02:37:26 +0800 Subject: [PATCH 3/5] refactor(hal/usb): Refactor usb_wrap_ll.h This commit rewrite the 'usb_wrap_ll.h' API as follows: - All APIs renamed from 'usb_fsls_phy_ll_...()' to 'usb_wrap_ll_...()' - APIs now match their equivalent counter parts in 'usb_serial_jtag_ll.h' --- .../src/bootloader_console.c | 11 +- .../hal/esp32s2/include/hal/usb_wrap_ll.h | 212 ++++++++++--- .../hal/esp32s3/include/hal/usb_wrap_ll.h | 278 ++++++++++++------ components/hal/usb_wrap_hal.c | 45 +-- components/usb/usb_phy.c | 12 +- 5 files changed, 385 insertions(+), 173 deletions(-) diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 0e43c8aaf8..a9b9aeb3ea 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,7 @@ #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_common.h" #endif -#if CONFIG_ESP_CONSOLE_USB_CDC && SOC_USB_SERIAL_JTAG_SUPPORTED +#if CONFIG_ESP_CONSOLE_USB_CDC #include "hal/usb_wrap_ll.h" #endif #include "esp_rom_gpio.h" @@ -101,10 +101,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_USB_OTG_NUM); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); -#if SOC_USB_SERIAL_JTAG_SUPPORTED - usb_fsls_phy_ll_usb_wrap_pad_enable(&USB_WRAP, true); - usb_fsls_phy_ll_int_otg_enable(&USB_WRAP); -#endif + // Ensure that the USB FSLS PHY is mapped to the USB WRAP + usb_wrap_ll_phy_enable_pad(&USB_WRAP, true); + usb_wrap_ll_phy_enable_external(&USB_WRAP, false); } #endif //CONFIG_ESP_CONSOLE_USB_CDC diff --git a/components/hal/esp32s2/include/hal/usb_wrap_ll.h b/components/hal/esp32s2/include/hal/usb_wrap_ll.h index e833d0a61c..c5c77cf59e 100644 --- a/components/hal/esp32s2/include/hal/usb_wrap_ll.h +++ b/components/hal/esp32s2/include/hal/usb_wrap_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,82 +16,206 @@ extern "C" { #endif +/* ---------------------------- USB PHY Control ---------------------------- */ + /** - * @brief Configures the internal PHY for USB_OTG + * @brief Enables and sets the override value for the session end signal * * @param hw Start address of the USB Wrap registers + * @param sessend Session end override value. True means VBus < 0.2V, false means VBus > 0.8V */ -static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_srp_sessend_override(usb_wrap_dev_t *hw, bool sessend) { - hw->otg_conf.phy_sel = 0; + hw->otg_conf.srp_sessend_value = sessend; + hw->otg_conf.srp_sessend_override = 1; } /** - * @brief Configures the external PHY for USB_OTG + * @brief Disable session end override * * @param hw Start address of the USB Wrap registers */ -static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw) { - //Enable external PHY - hw->otg_conf.phy_sel = 1; + hw->otg_conf.srp_sessend_override = 0; } /** - * @brief Configures port loads for the internal PHY + * @brief Sets whether the USB Wrap's FSLS PHY interface routes to an internal or external PHY * * @param hw Start address of the USB Wrap registers - * @param dp_pu D+ pullup load - * @param dp_pd D+ pulldown load - * @param dm_pu D- pullup load - * @param dm_pd D- pulldown load + * @param enable Enables external PHY, internal otherwise */ -static inline void usb_fsls_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable) { - usb_wrap_otg_conf_reg_t conf = hw->otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = dp_pu; - conf.dp_pulldown = dp_pd; - conf.dm_pullup = dm_pu; - conf.dm_pulldown = dm_pd; - hw->otg_conf = conf; + hw->otg_conf.phy_sel = enable; } /** - * @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_fsls_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 + * @brief Enables/disables exchanging of the D+/D- pins USB PHY * * @param hw Start address of the USB Wrap registers - * @param en Whether to enable the internal PHY's test mode + * @param enable Enables pin exchange, disabled otherwise */ -static inline void usb_fsls_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable) { - if (en) { - // Clear USB_WRAP_TEST_CONF_REG - hw->test_conf.val = 0; - // Set USB test pad oen - hw->test_conf.test_usb_wrap_oe = 1; - // Enable USB test mode - hw->test_conf.test_enable = 1; + if (enable) { + hw->otg_conf.exchg_pins = 1; + hw->otg_conf.exchg_pins_override = 1; } else { - hw->test_conf.test_enable = 0; + hw->otg_conf.exchg_pins_override = 0; + hw->otg_conf.exchg_pins = 0; } } +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_vref_override(usb_wrap_dev_t *hw, unsigned int vrefh_step, unsigned int vrefl_step) +{ + hw->otg_conf.vrefh = vrefh_step; + hw->otg_conf.vrefl = vrefl_step; + hw->otg_conf.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + * @param dp_pu Enable D+ pullup + * @param dm_pu Enable D- pullup + * @param dp_pd Enable D+ pulldown + * @param dm_pd Enable D- pulldown + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +{ + hw->otg_conf.dp_pullup = dp_pu; + hw->otg_conf.dp_pulldown = dp_pd; + hw->otg_conf.dm_pullup = dm_pu; + hw->otg_conf.dm_pulldown = dm_pd; + hw->otg_conf.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_pull_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param hw Start address of the USB Wrap registers + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_pullup_strength(usb_wrap_dev_t *hw, bool strong) +{ + hw->otg_conf.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @param hw Start address of the USB Wrap registers + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_wrap_ll_phy_is_pad_enabled(usb_wrap_dev_t *hw) +{ + return hw->otg_conf.pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pad(usb_wrap_dev_t *hw, bool enable) +{ + hw->otg_conf.pad_enable = enable; +} + +/** + * @brief Set USB FSLS PHY TX output clock edge + * + * @param hw Start address of the USB Wrap registers + * @param clk_neg_edge True if TX output at negedge, posedge otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_tx_edge(usb_wrap_dev_t *hw, bool clk_neg_edge) +{ + hw->otg_conf.phy_tx_edge_sel = clk_neg_edge; +} + +/* ------------------------------ USB PHY Test ------------------------------ */ + +/** + * @brief Enable the USB FSLS PHY's test mode + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY's test mode + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool enable) +{ + hw->test_conf.test_enable = enable; +} + +/** + * @brief Set the USB FSLS PHY's signal test values + * + * @param hw Start address of the USB Wrap registers + * @param oen Output Enable (active low) signal + * @param tx_dp TX D+ + * @param tx_dm TX D- + * @param rx_dp RX D+ + * @param rx_dm RX D- + * @param rx_rcv RX RCV + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, + bool oen, + bool tx_dp, + bool tx_dm, + bool rx_dp, + bool rx_dm, + bool rx_rcv) +{ + usb_wrap_test_conf_reg_t test_conf; + test_conf.val = hw->test_conf.val; + + test_conf.test_usb_wrap_oe = oen; + test_conf.test_tx_dp = tx_dp; + test_conf.test_tx_dm = tx_dm; + test_conf.test_rx_rcv = rx_rcv; + test_conf.test_rx_dp = rx_dp; + test_conf.test_rx_dm = rx_dm; + + hw->test_conf.val = test_conf.val; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + /** * 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_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en) +FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool clk_en) { REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en); } @@ -99,7 +223,7 @@ FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en) /** * @brief Reset the USB Wrap module */ -FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void) +FORCE_INLINE_ATTR void usb_wrap_ll_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); diff --git a/components/hal/esp32s3/include/hal/usb_wrap_ll.h b/components/hal/esp32s3/include/hal/usb_wrap_ll.h index 74ec2979e8..fd8cdb4568 100644 --- a/components/hal/esp32s3/include/hal/usb_wrap_ll.h +++ b/components/hal/esp32s3/include/hal/usb_wrap_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,133 +12,219 @@ #include "soc/system_struct.h" #include "soc/usb_wrap_struct.h" #include "soc/rtc_cntl_struct.h" -#include "soc/usb_serial_jtag_struct.h" #ifdef __cplusplus extern "C" { #endif +/* ---------------------------- USB PHY Control ---------------------------- */ + /** - * @brief Configures the internal PHY for USB_OTG + * @brief Enables and sets the override value for the session end signal + * + * @param hw Start address of the USB Wrap registers + * @param sessend Session end override value. True means VBus < 0.2V, false means VBus > 0.8V + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_srp_sessend_override(usb_wrap_dev_t *hw, bool sessend) +{ + hw->otg_conf.srp_sessend_value = sessend; + hw->otg_conf.srp_sessend_override = 1; +} + +/** + * @brief Disable session end override * * @param hw Start address of the USB Wrap registers */ -static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw) { - // USB_OTG use internal PHY - hw->otg_conf.phy_sel = 0; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=1, USB_OTG is connected with internal PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 1; + hw->otg_conf.srp_sessend_override = 0; } /** - * @brief Configures the external PHY for USB_OTG + * @brief Sets whether the USB Wrap's FSLS PHY interface routes to an internal or external PHY * * @param hw Start address of the USB Wrap registers + * @param enable Enables external PHY, internal otherwise */ -static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable) { - // USB_OTG use external PHY - hw->otg_conf.phy_sel = 1; - // phy_sel is controlled by the following register value + hw->otg_conf.phy_sel = enable; + // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=0, USB_OTG is connected with external PHY through GPIO Matrix - RTCCNTL.usb_conf.sw_usb_phy_sel = 0; + /* + For 'sw_usb_phy_sel': + 0 - Internal USB FSLS PHY is mapped to the USJ. USB Wrap mapped to external PHY + 1 - Internal USB FSLS PHY is mapped to the USB Wrap. USJ mapped to external PHY + */ + RTCCNTL.usb_conf.sw_usb_phy_sel = !enable; } /** - * @brief Configures the internal PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_fsls_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; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=0, USB_Serial_JTAG is connected with internal PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 0; -} - -/** - * @brief Configures the external PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_fsls_phy_ll_ext_jtag_enable(usb_serial_jtag_dev_t *hw) -{ - // USB_Serial_JTAG use external PHY - hw->conf0.phy_sel = 1; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=1, USB_Serial_JTAG is connected with external PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 1; -} - -/** - * @brief Configures port loads for the internal PHY + * @brief Enables/disables exchanging of the D+/D- pins USB PHY * * @param hw Start address of the USB Wrap registers - * @param dp_pu D+ pullup load - * @param dp_pd D+ pulldown load - * @param dm_pu D- pullup load - * @param dm_pd D- pulldown load + * @param enable Enables pin exchange, disabled otherwise */ -static inline void usb_fsls_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable) { - usb_wrap_otg_conf_reg_t conf = hw->otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = dp_pu; - conf.dp_pulldown = dp_pd; - conf.dm_pullup = dm_pu; - conf.dm_pulldown = dm_pd; - 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_fsls_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 - * - * @param hw Start address of the USB Wrap registers - * @param en Whether to enable the internal PHY's test mode - */ -static inline void usb_fsls_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en) -{ - if (en) { - // Clear USB_WRAP_TEST_CONF_REG - hw->test_conf.val = 0; - // Set USB test pad oen - hw->test_conf.test_usb_wrap_oe = 1; - // Enable USB test mode - hw->test_conf.test_enable = 1; + if (enable) { + hw->otg_conf.exchg_pins = 1; + hw->otg_conf.exchg_pins_override = 1; } else { - hw->test_conf.test_enable = 0; + hw->otg_conf.exchg_pins_override = 0; + hw->otg_conf.exchg_pins = 0; } } +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_vref_override(usb_wrap_dev_t *hw, unsigned int vrefh_step, unsigned int vrefl_step) +{ + hw->otg_conf.vrefh = vrefh_step; + hw->otg_conf.vrefl = vrefl_step; + hw->otg_conf.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + * @param dp_pu Enable D+ pullup + * @param dm_pu Enable D- pullup + * @param dp_pd Enable D+ pulldown + * @param dm_pd Enable D- pulldown + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +{ + hw->otg_conf.dp_pullup = dp_pu; + hw->otg_conf.dp_pulldown = dp_pd; + hw->otg_conf.dm_pullup = dm_pu; + hw->otg_conf.dm_pulldown = dm_pd; + hw->otg_conf.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_pull_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param hw Start address of the USB Wrap registers + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_pullup_strength(usb_wrap_dev_t *hw, bool strong) +{ + hw->otg_conf.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @param hw Start address of the USB Wrap registers + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_wrap_ll_phy_is_pad_enabled(usb_wrap_dev_t *hw) +{ + return hw->otg_conf.pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pad(usb_wrap_dev_t *hw, bool enable) +{ + hw->otg_conf.pad_enable = enable; +} + +/** + * @brief Set USB FSLS PHY TX output clock edge + * + * @param hw Start address of the USB Wrap registers + * @param clk_neg_edge True if TX output at negedge, posedge otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_tx_edge(usb_wrap_dev_t *hw, bool clk_neg_edge) +{ + hw->otg_conf.phy_tx_edge_sel = clk_neg_edge; +} + +/* ------------------------------ USB PHY Test ------------------------------ */ + +/** + * @brief Enable the USB FSLS PHY's test mode + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY's test mode + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool enable) +{ + hw->test_conf.test_enable = enable; +} + +/** + * @brief Set the USB FSLS PHY's signal test values + * + * @param hw Start address of the USB Wrap registers + * @param oen Output Enable (active low) signal + * @param tx_dp TX D+ + * @param tx_dm TX D- + * @param rx_dp RX D+ + * @param rx_dm RX D- + * @param rx_rcv RX RCV + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, + bool oen, + bool tx_dp, + bool tx_dm, + bool rx_dp, + bool rx_dm, + bool rx_rcv) +{ + usb_wrap_test_conf_reg_t test_conf; + test_conf.val = hw->test_conf.val; + + test_conf.test_usb_wrap_oe = oen; + test_conf.test_tx_dp = tx_dp; + test_conf.test_tx_dm = tx_dm; + test_conf.test_rx_rcv = rx_rcv; + test_conf.test_rx_dp = rx_dp; + test_conf.test_rx_dm = rx_dm; + + hw->test_conf.val = test_conf.val; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + /** * 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_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en) +FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool clk_en) { SYSTEM.perip_clk_en0.usb_clk_en = clk_en; } @@ -146,7 +232,7 @@ FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en) /** * @brief Reset the USB Wrap module */ -FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void) +FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void) { SYSTEM.perip_rst_en0.usb_rst = 1; SYSTEM.perip_rst_en0.usb_rst = 0; diff --git a/components/hal/usb_wrap_hal.c b/components/hal/usb_wrap_hal.c index 58b77bba23..ffa4656634 100644 --- a/components/hal/usb_wrap_hal.c +++ b/components/hal/usb_wrap_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,10 +23,10 @@ void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal) void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) { if (phy_target == USB_PHY_TARGET_EXT) { - usb_fsls_phy_ll_ext_otg_enable(hal->wrap_dev); + usb_wrap_ll_phy_enable_external(hal->wrap_dev, true); } else if (phy_target == USB_PHY_TARGET_INT) { - usb_fsls_phy_ll_usb_wrap_pad_enable(hal->wrap_dev, true); - usb_fsls_phy_ll_int_otg_enable(hal->wrap_dev); + usb_wrap_ll_phy_enable_external(hal->wrap_dev, false); + usb_wrap_ll_phy_enable_pad(hal->wrap_dev, true); } } @@ -35,17 +35,9 @@ void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_ { if (phy_target == USB_PHY_TARGET_EXT) { usb_serial_jtag_ll_phy_enable_external(true); // USJ uses external PHY - // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // Internal USB FSLS PHY is mapped to the USJ - RTCCNTL.usb_conf.sw_usb_phy_sel = 1; } else if (phy_target == USB_PHY_TARGET_INT) { - usb_serial_jtag_ll_phy_enable_external(true); // USJ uses internal PHY + usb_serial_jtag_ll_phy_enable_external(false); // USJ uses internal PHY usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads - // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // Internal USB FSLS PHY is mapped to the USJ - RTCCNTL.usb_conf.sw_usb_phy_sel = 0; } } #endif @@ -53,7 +45,7 @@ void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_ void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal) { // HOST - upstream: dp_pd = 1, dm_pd = 1 - usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true); + usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, false, false, true, true); } void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed) @@ -61,18 +53,29 @@ void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy // DEVICE - downstream if (speed == USB_PHY_SPEED_LOW) { // LS: dm_pu = 1 - usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false); + usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, false, true, false, false); } else { // FS: dp_pu = 1 - usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, true, false, false, false); + usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, true, false, false, false); } } void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn) { - /* - We mimick a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will: - A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection. - */ - usb_fsls_phy_ll_int_enable_test_mode(hal->wrap_dev, disconn); + if (disconn) { + /* + We mimick a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will: + A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection. + */ + usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev, + true, // OEN + false, // TX D+ + false, // TX D- + false, // RX D+ + false, // RX D- + false); // RX RCv + usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, true); + } else { + usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, false); + } } diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index 56f1c56119..c83532bd6e 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -214,8 +214,8 @@ static esp_err_t usb_phy_install(void) portEXIT_CRITICAL(&phy_spinlock); goto cleanup; } - usb_fsls_phy_ll_usb_wrap_enable_bus_clock(true); - usb_fsls_phy_ll_usb_wrap_reset_register(); + usb_wrap_ll_enable_bus_clock(true); + usb_wrap_ll_reset_register(); // Enable USB peripheral and reset the register portEXIT_CRITICAL(&phy_spinlock); return ESP_OK; @@ -308,7 +308,7 @@ static void phy_uninstall(void) p_phy_ctrl_obj_free = p_phy_ctrl_obj; p_phy_ctrl_obj = NULL; // Disable USB peripheral without reset the module - usb_fsls_phy_ll_usb_wrap_enable_bus_clock(false); + usb_wrap_ll_enable_bus_clock(false); } portEXIT_CRITICAL(&phy_spinlock); free(p_phy_ctrl_obj_free); @@ -324,8 +324,8 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle) p_phy_ctrl_obj->external_phy = NULL; } else { // Clear pullup and pulldown loads on D+ / D-, and disable the pads - usb_fsls_phy_ll_int_load_conf(handle->hal_context.wrap_dev, false, false, false, false); - usb_fsls_phy_ll_usb_wrap_pad_enable(handle->hal_context.wrap_dev, false); + usb_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, false, false, false, false); + usb_wrap_ll_phy_enable_pad(handle->hal_context.wrap_dev, false); p_phy_ctrl_obj->internal_phy = NULL; } portEXIT_CRITICAL(&phy_spinlock); From 4f996fc421334ba91080cf7f7b94d3d5583da0ba Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Thu, 4 Apr 2024 15:04:48 +0800 Subject: [PATCH 4/5] feat(hal/usb): Update USB WRAP and USJ LL - Added LL cap macros to distinguish feature differences between the LLs of different targets: - '..._LL_EXT_PHY_SUPPORTED' indicates whether the USB WRAP/USJ supports routing to an external FSLS PHY. - Added 'usb_wrap_types.h' and 'usb_serial_jtag_types.h' to provide types used in LLs. - Fixed some spelling/naming issues as part of code-spell pre-commit --- .../driver/usb_serial_jtag/usb_serial_jtag.c | 4 ++ .../esp32c3/include/hal/usb_serial_jtag_ll.h | 59 ++++++++++--------- .../esp32c6/include/hal/usb_serial_jtag_ll.h | 58 +++++++++--------- .../esp32h2/include/hal/usb_serial_jtag_ll.h | 58 +++++++++--------- .../hal/esp32s2/include/hal/usb_wrap_ll.h | 48 +++++++-------- .../esp32s3/include/hal/usb_serial_jtag_ll.h | 46 +++++++-------- .../hal/esp32s3/include/hal/usb_wrap_ll.h | 48 +++++++-------- .../hal/include/hal/usb_serial_jtag_types.h | 35 +++++++++++ components/hal/include/hal/usb_wrap_hal.h | 9 ++- components/hal/include/hal/usb_wrap_types.h | 53 +++++++++++++++++ components/hal/usb_wrap_hal.c | 48 +++++++++++---- components/usb/usb_phy.c | 10 +++- 12 files changed, 296 insertions(+), 180 deletions(-) create mode 100644 components/hal/include/hal/usb_serial_jtag_types.h create mode 100644 components/hal/include/hal/usb_wrap_types.h diff --git a/components/driver/usb_serial_jtag/usb_serial_jtag.c b/components/driver/usb_serial_jtag/usb_serial_jtag.c index 7d0cc554eb..8eb09bfb75 100644 --- a/components/driver/usb_serial_jtag/usb_serial_jtag.c +++ b/components/driver/usb_serial_jtag/usb_serial_jtag.c @@ -175,8 +175,12 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); // Configure PHY +#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED usb_serial_jtag_ll_phy_enable_external(false); // Use internal PHY usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads +#else // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED + usb_serial_jtag_ll_phy_set_defaults(); // External PHY not supported. Set default values. +#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY| USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); 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 d52839a320..ac5cd14865 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -4,23 +4,18 @@ * 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" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif +/* ----------------------------- Macros & Types ----------------------------- */ -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 - -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -34,6 +29,11 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + /* ----------------------------- USJ Peripheral ----------------------------- */ /** @@ -125,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -182,13 +182,18 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) /* ---------------------------- USB PHY Control ---------------------------- */ /** - * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY + * @brief Sets PHY defaults * - * @param enable Enables external PHY, internal otherwise + * Some PHY register fields/features of the USJ are redundant on the ESP32-C3. + * This function those fields are set to the appropriate default values. + * + * @param hw Start address of the USB Wrap registers */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void) { - USB_SERIAL_JTAG.conf0.phy_sel = enable; + // External FSLS PHY is not supported + USB_SERIAL_JTAG.conf0.phy_sel = 0; + USB_SERIAL_JTAG.conf0.usb_pad_enable = 1; } /** @@ -231,17 +236,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) /** * @brief Enable override of USB FSLS PHY's pull up/down resistors * - * @param dp_pu Enable D+ pullup - * @param dm_pu Enable D- pullup - * @param dp_pd Enable D+ pulldown - * @param dm_pd Enable D- pulldown + * @param vals Override values to set */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) { - USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; - USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; - USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; - USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; USB_SERIAL_JTAG.conf0.pad_pull_override = 1; } @@ -286,8 +288,8 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) /* ----------------------------- RCC Functions ----------------------------- */ /** - * @brief Enable the bus clock for USB Serial_JTAG module - * @param clk_en True if enable the clock of USB Serial_JTAG module + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) { @@ -295,7 +297,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) } /** - * @brief Reset the usb serial jtag module + * @brief Reset the USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) { @@ -304,16 +306,15 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) } /** - * Get the enable status USB Serial_JTAG module + * Get the enable status of the USJ module * - * @return Return true if USB Serial_JTAG module is enabled + * @return Return true if USJ 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 } #endif diff --git a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h index d21821ad35..56b44d0a1a 100644 --- a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h @@ -4,23 +4,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer of the USB-serial-jtag controller - #pragma once + #include #include "esp_attr.h" #include "soc/pcr_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif +/* ----------------------------- Macros & Types ----------------------------- */ -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 - -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -34,6 +29,11 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + /* ----------------------------- USJ Peripheral ----------------------------- */ /** @@ -125,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -195,13 +195,18 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) /* ---------------------------- USB PHY Control ---------------------------- */ /** - * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY + * @brief Sets PHY defaults * - * @param enable Enables external PHY, internal otherwise + * Some PHY register fields/features of the USJ are redundant on the ESP32-C6. + * This function those fields are set to the appropriate default values. + * + * @param hw Start address of the USB Wrap registers */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void) { - USB_SERIAL_JTAG.conf0.phy_sel = enable; + // External FSLS PHY is not supported + USB_SERIAL_JTAG.conf0.phy_sel = 0; + USB_SERIAL_JTAG.conf0.usb_pad_enable = 1; } /** @@ -244,17 +249,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) /** * @brief Enable override of USB FSLS PHY's pull up/down resistors * - * @param dp_pu Enable D+ pullup - * @param dm_pu Enable D- pullup - * @param dp_pd Enable D+ pulldown - * @param dm_pd Enable D- pulldown + * @param vals Override values to set */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) { - USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; - USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; - USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; - USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; USB_SERIAL_JTAG.conf0.pad_pull_override = 1; } @@ -299,8 +301,8 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) /* ----------------------------- RCC Functions ----------------------------- */ /** - * @brief Enable the bus clock for USB Serial_JTAG module - * @param clk_en True if enable the clock of USB Serial_JTAG module + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) { @@ -308,7 +310,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) } /** - * @brief Reset the usb serial jtag module + * @brief Reset the USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) { @@ -317,9 +319,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) } /** - * Get the enable status USB Serial_JTAG module + * Get the enable status of the USJ module * - * @return Return true if USB Serial_JTAG module is enabled + * @return Return true if USJ module is enabled */ FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) { 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 ec8a32ea67..bacbf3d3fb 100644 --- a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h @@ -4,23 +4,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer of the USB-serial-jtag controller - #pragma once + #include #include "esp_attr.h" #include "soc/pcr_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif +/* ----------------------------- Macros & Types ----------------------------- */ -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 - -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -34,6 +29,11 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + /* ----------------------------- USJ Peripheral ----------------------------- */ /** @@ -125,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -195,13 +195,18 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) /* ---------------------------- USB PHY Control ---------------------------- */ /** - * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY + * @brief Sets PHY defaults * - * @param enable Enables external PHY, internal otherwise + * Some PHY register fields/features of the USJ are redundant on the ESP32-H2. + * This function those fields are set to the appropriate default values. + * + * @param hw Start address of the USB Wrap registers */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void) { - USB_SERIAL_JTAG.conf0.phy_sel = enable; + // External FSLS PHY is not supported + USB_SERIAL_JTAG.conf0.phy_sel = 0; + USB_SERIAL_JTAG.conf0.usb_pad_enable = 1; } /** @@ -244,17 +249,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) /** * @brief Enable override of USB FSLS PHY's pull up/down resistors * - * @param dp_pu Enable D+ pullup - * @param dm_pu Enable D- pullup - * @param dp_pd Enable D+ pulldown - * @param dm_pd Enable D- pulldown + * @param vals Override values to set */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) { - USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; - USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; - USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; - USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; USB_SERIAL_JTAG.conf0.pad_pull_override = 1; } @@ -299,8 +301,8 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) /* ----------------------------- RCC Functions ----------------------------- */ /** - * @brief Enable the bus clock for USB Serial_JTAG module - * @param clk_en True if enable the clock of USB Serial_JTAG module + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) { @@ -308,7 +310,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) } /** - * @brief Reset the usb serial jtag module + * @brief Reset the USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) { @@ -317,9 +319,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) } /** - * Get the enable status USB Serial_JTAG module + * Get the enable status of the USJ module * - * @return Return true if USB Serial_JTAG module is enabled + * @return Return true if USJ module is enabled */ FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) { diff --git a/components/hal/esp32s2/include/hal/usb_wrap_ll.h b/components/hal/esp32s2/include/hal/usb_wrap_ll.h index c5c77cf59e..858a236cd3 100644 --- a/components/hal/esp32s2/include/hal/usb_wrap_ll.h +++ b/components/hal/esp32s2/include/hal/usb_wrap_ll.h @@ -11,6 +11,12 @@ #include "soc/soc.h" #include "soc/system_reg.h" #include "soc/usb_wrap_struct.h" +#include "hal/usb_wrap_types.h" + +/* ----------------------------- Macros & Types ----------------------------- */ + +#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY + #ifdef __cplusplus extern "C" { @@ -96,17 +102,14 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw) * @brief Enable override of USB FSLS PHY's pull up/down resistors * * @param hw Start address of the USB Wrap registers - * @param dp_pu Enable D+ pullup - * @param dm_pu Enable D- pullup - * @param dp_pd Enable D+ pulldown - * @param dm_pd Enable D- pulldown + * @param vals Override values to set */ -FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals) { - hw->otg_conf.dp_pullup = dp_pu; - hw->otg_conf.dp_pulldown = dp_pd; - hw->otg_conf.dm_pullup = dm_pu; - hw->otg_conf.dm_pulldown = dm_pd; + hw->otg_conf.dp_pullup = vals->dp_pu; + hw->otg_conf.dp_pulldown = vals->dp_pd; + hw->otg_conf.dm_pullup = vals->dm_pu; + hw->otg_conf.dm_pulldown = vals->dm_pd; hw->otg_conf.pad_pull_override = 1; } @@ -181,30 +184,19 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool * @brief Set the USB FSLS PHY's signal test values * * @param hw Start address of the USB Wrap registers - * @param oen Output Enable (active low) signal - * @param tx_dp TX D+ - * @param tx_dm TX D- - * @param rx_dp RX D+ - * @param rx_dm RX D- - * @param rx_rcv RX RCV + * @param vals Test values to set */ -FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, - bool oen, - bool tx_dp, - bool tx_dm, - bool rx_dp, - bool rx_dm, - bool rx_rcv) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals) { usb_wrap_test_conf_reg_t test_conf; test_conf.val = hw->test_conf.val; - test_conf.test_usb_wrap_oe = oen; - test_conf.test_tx_dp = tx_dp; - test_conf.test_tx_dm = tx_dm; - test_conf.test_rx_rcv = rx_rcv; - test_conf.test_rx_dp = rx_dp; - test_conf.test_rx_dm = rx_dm; + test_conf.test_usb_wrap_oe = vals->tx_enable_n; + test_conf.test_tx_dp = vals->tx_dp; + test_conf.test_tx_dm = vals->tx_dm; + test_conf.test_rx_rcv = vals->rx_rcv; + test_conf.test_rx_dp = vals->rx_dp; + test_conf.test_rx_dm = vals->rx_dm; hw->test_conf.val = test_conf.val; } 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 96a989a2f4..f8a867eb1f 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -4,24 +4,20 @@ * 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/rtc_cntl_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif +/* ----------------------------- Macros & Types ----------------------------- */ -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 - -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -35,6 +31,11 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + /* ----------------------------- USJ Peripheral ----------------------------- */ /** @@ -126,7 +127,7 @@ static inline uint32_t usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_ * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -253,17 +254,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) /** * @brief Enable override of USB FSLS PHY's pull up/down resistors * - * @param dp_pu Enable D+ pullup - * @param dm_pu Enable D- pullup - * @param dp_pd Enable D+ pulldown - * @param dm_pd Enable D- pulldown + * @param vals Override values to set */ -FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) { - USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu; - USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; - USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; - USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; USB_SERIAL_JTAG.conf0.pad_pull_override = 1; } @@ -318,8 +316,8 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_tx_edge(bool clk_neg_edge) /* ----------------------------- RCC Functions ----------------------------- */ /** - * @brief Enable the bus clock for USB Serial_JTAG module - * @param clk_en True if enable the clock of USB Serial_JTAG module + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) { @@ -327,7 +325,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) } /** - * @brief Reset the usb serial jtag module + * @brief Reset the USJ module */ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) { @@ -336,9 +334,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) } /** - * Get the enable status USB Serial_JTAG module + * Get the enable status of the USJ module * - * @return Return true if USB Serial_JTAG module is enabled + * @return Return true if USJ module is enabled */ FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) { diff --git a/components/hal/esp32s3/include/hal/usb_wrap_ll.h b/components/hal/esp32s3/include/hal/usb_wrap_ll.h index fd8cdb4568..8fcd4177ed 100644 --- a/components/hal/esp32s3/include/hal/usb_wrap_ll.h +++ b/components/hal/esp32s3/include/hal/usb_wrap_ll.h @@ -12,6 +12,12 @@ #include "soc/system_struct.h" #include "soc/usb_wrap_struct.h" #include "soc/rtc_cntl_struct.h" +#include "hal/usb_wrap_types.h" + +/* ----------------------------- Macros & Types ----------------------------- */ + +#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY + #ifdef __cplusplus extern "C" { @@ -105,17 +111,14 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw) * @brief Enable override of USB FSLS PHY's pull up/down resistors * * @param hw Start address of the USB Wrap registers - * @param dp_pu Enable D+ pullup - * @param dm_pu Enable D- pullup - * @param dp_pd Enable D+ pulldown - * @param dm_pd Enable D- pulldown + * @param vals Override values to set */ -FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals) { - hw->otg_conf.dp_pullup = dp_pu; - hw->otg_conf.dp_pulldown = dp_pd; - hw->otg_conf.dm_pullup = dm_pu; - hw->otg_conf.dm_pulldown = dm_pd; + hw->otg_conf.dp_pullup = vals->dp_pu; + hw->otg_conf.dp_pulldown = vals->dp_pd; + hw->otg_conf.dm_pullup = vals->dm_pu; + hw->otg_conf.dm_pulldown = vals->dm_pd; hw->otg_conf.pad_pull_override = 1; } @@ -190,30 +193,19 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool * @brief Set the USB FSLS PHY's signal test values * * @param hw Start address of the USB Wrap registers - * @param oen Output Enable (active low) signal - * @param tx_dp TX D+ - * @param tx_dm TX D- - * @param rx_dp RX D+ - * @param rx_dm RX D- - * @param rx_rcv RX RCV + * @param vals Test values to set */ -FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, - bool oen, - bool tx_dp, - bool tx_dm, - bool rx_dp, - bool rx_dm, - bool rx_rcv) +FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals) { usb_wrap_test_conf_reg_t test_conf; test_conf.val = hw->test_conf.val; - test_conf.test_usb_wrap_oe = oen; - test_conf.test_tx_dp = tx_dp; - test_conf.test_tx_dm = tx_dm; - test_conf.test_rx_rcv = rx_rcv; - test_conf.test_rx_dp = rx_dp; - test_conf.test_rx_dm = rx_dm; + test_conf.test_usb_wrap_oe = vals->tx_enable_n; + test_conf.test_tx_dp = vals->tx_dp; + test_conf.test_tx_dm = vals->tx_dm; + test_conf.test_rx_rcv = vals->rx_rcv; + test_conf.test_rx_dp = vals->rx_dp; + test_conf.test_rx_dm = vals->rx_dm; hw->test_conf.val = test_conf.val; } diff --git a/components/hal/include/hal/usb_serial_jtag_types.h b/components/hal/include/hal/usb_serial_jtag_types.h new file mode 100644 index 0000000000..1418ea528b --- /dev/null +++ b/components/hal/include/hal/usb_serial_jtag_types.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_SERIAL_JTAG_SUPPORTED + +/** + * @brief USJ test mode values + * + * Specifies the logic values of each of the USB FSLS Serial PHY interface + * signals when in test mode. + */ +typedef struct { + bool dp_pu; /**< D+ pull-up resistor enable/disable */ + bool dm_pu; /**< D- pull-up resistor enable/disable */ + bool dp_pd; /**< D+ pull-down resistor enable/disable */ + bool dm_pd; /**< D- pull-down resistor enable/disable */ +} usb_serial_jtag_pull_override_vals_t; + +#endif // SOC_USB_SERIAL_JTAG_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/usb_wrap_hal.h b/components/hal/include/hal/usb_wrap_hal.h index 72e9551c45..fb8183a834 100644 --- a/components/hal/include/hal/usb_wrap_hal.h +++ b/components/hal/include/hal/usb_wrap_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,10 @@ #include "usb_dwc_types.h" #include "usb_phy_types.h" #include "soc/soc_caps.h" +#if SOC_USB_OTG_SUPPORTED #include "soc/usb_wrap_struct.h" +#include "hal/usb_wrap_ll.h" +#endif #if SOC_USB_SERIAL_JTAG_SUPPORTED #include "soc/usb_serial_jtag_struct.h" #endif @@ -36,6 +39,7 @@ typedef struct { */ void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal); +#if USB_WRAP_LL_EXT_PHY_SUPPORTED /** * @brief Configure internal/external PHY for USB_OTG * @@ -43,6 +47,7 @@ void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal); * @param phy_target USB PHY target */ void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target); +#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED #if SOC_USB_SERIAL_JTAG_SUPPORTED /** @@ -70,7 +75,7 @@ void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal); void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed); /** - * @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection + * @brief Enable/Disable test mode for internal PHY to mimic host-device disconnection * * @param hal Context of the HAL layer * @param disconn Whether to disconnect diff --git a/components/hal/include/hal/usb_wrap_types.h b/components/hal/include/hal/usb_wrap_types.h new file mode 100644 index 0000000000..9d3310fb06 --- /dev/null +++ b/components/hal/include/hal/usb_wrap_types.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_OTG_SUPPORTED + +/** + * @brief USB WRAP pull up/down resistor override values + * + * Specifies whether each pull up/down resistor should be enabled/disabled when + * overriding connected USB PHY's pull resistors. + */ +typedef struct { + bool dp_pu; /**< D+ pull-up resistor enable/disable */ + bool dm_pu; /**< D- pull-up resistor enable/disable */ + bool dp_pd; /**< D+ pull-down resistor enable/disable */ + bool dm_pd; /**< D- pull-down resistor enable/disable */ +} usb_wrap_pull_override_vals_t; + +/** + * @brief USB WRAP test mode values + * + * Specifies the logic values of each of the USB FSLS Serial PHY interface + * signals when in test mode. + * + * @note See section "2.2.1.13 FsLsSerialMode" of UTMI+ specification for more + * details of each signal. + */ +typedef struct { + bool tx_enable_n; /**< Active low output enable signal */ + bool tx_dp; /**< Single-ended D+ line driver */ + bool tx_dm; /**< Single-ended D- line driver */ + bool rx_dp; /**< Single-ended D+ signal from the transceiver */ + bool rx_dm; /**< Single-ended D- signal from the transceiver */ + bool rx_rcv; /**< Differential receive data from D+ and D- lines */ +} usb_wrap_test_mode_vals_t; + +#endif // SOC_USB_OTG_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/usb_wrap_hal.c b/components/hal/usb_wrap_hal.c index ffa4656634..de805083d8 100644 --- a/components/hal/usb_wrap_hal.c +++ b/components/hal/usb_wrap_hal.c @@ -5,7 +5,6 @@ */ #include "soc/soc_caps.h" -#include "soc/rtc_cntl_struct.h" #if SOC_USB_SERIAL_JTAG_SUPPORTED #include "hal/usb_serial_jtag_ll.h" #endif @@ -18,8 +17,12 @@ void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal) #if SOC_USB_SERIAL_JTAG_SUPPORTED hal->jtag_dev = &USB_SERIAL_JTAG; #endif +#if !USB_WRAP_LL_EXT_PHY_SUPPORTED + usb_wrap_ll_phy_set_defaults(hal->wrap_dev); +#endif } +#if USB_WRAP_LL_EXT_PHY_SUPPORTED void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) { if (phy_target == USB_PHY_TARGET_EXT) { @@ -29,6 +32,7 @@ void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t usb_wrap_ll_phy_enable_pad(hal->wrap_dev, true); } } +#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED #if SOC_USB_SERIAL_JTAG_SUPPORTED void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) @@ -45,7 +49,13 @@ void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_ void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal) { // HOST - upstream: dp_pd = 1, dm_pd = 1 - usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, false, false, true, true); + usb_wrap_pull_override_vals_t vals = { + .dp_pu = false, + .dm_pu = false, + .dp_pd = true, + .dm_pd = true, + }; + usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals); } void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed) @@ -53,10 +63,22 @@ void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy // DEVICE - downstream if (speed == USB_PHY_SPEED_LOW) { // LS: dm_pu = 1 - usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, false, true, false, false); + usb_wrap_pull_override_vals_t vals = { + .dp_pu = false, + .dm_pu = true, + .dp_pd = false, + .dm_pd = false, + }; + usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals); } else { // FS: dp_pu = 1 - usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, true, false, false, false); + usb_wrap_pull_override_vals_t vals = { + .dp_pu = true, + .dm_pu = false, + .dm_pd = false, + .dp_pd = false, + }; + usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals); } } @@ -64,16 +86,18 @@ void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool d { if (disconn) { /* - We mimick a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will: + We mimic a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will: A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection. */ - usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev, - true, // OEN - false, // TX D+ - false, // TX D- - false, // RX D+ - false, // RX D- - false); // RX RCv + usb_wrap_test_mode_vals_t vals = { + .tx_enable_n = true, + .tx_dp = false, + .tx_dm = false, + .rx_dp = false, + .rx_dm = false, + .rx_rcv = false, + }; + usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev, &vals); usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, true); } else { usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, false); diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index c83532bd6e..c1747da3fe 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -257,7 +257,9 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r usb_fsls_phy_hal_init(&(phy_context->hal_context)); if (config->controller == USB_PHY_CTRL_OTG) { +#if USB_WRAP_LL_EXT_PHY_SUPPORTED usb_fsls_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT); +#endif } #if SOC_USB_SERIAL_JTAG_SUPPORTED else if (config->controller == USB_PHY_CTRL_SERIAL_JTAG) { @@ -324,7 +326,13 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle) p_phy_ctrl_obj->external_phy = NULL; } else { // Clear pullup and pulldown loads on D+ / D-, and disable the pads - usb_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, false, false, false, false); + usb_wrap_pull_override_vals_t vals = { + .dp_pu = false, + .dm_pu = false, + .dp_pd = false, + .dm_pd = false, + }; + usb_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, &vals); usb_wrap_ll_phy_enable_pad(handle->hal_context.wrap_dev, false); p_phy_ctrl_obj->internal_phy = NULL; } From d41515f94891476debd1a7d1db4b4c9a80fbe4a2 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Tue, 2 Apr 2024 21:10:35 +0800 Subject: [PATCH 5/5] refactor(hal/usb): Add new USB PHY related HAL API This commit adds/updates the USB PHY related HAL APIs. The following changes are made: - Updated 'usb_wrap_hal.h' API - Added 'usb_serial_jtag_hal.h' API --- components/hal/CMakeLists.txt | 4 + .../hal/include/hal/usb_serial_jtag_hal.h | 51 ++++++++++ components/hal/include/hal/usb_wrap_hal.h | 87 +++++++++-------- components/hal/usb_serial_jtag_hal.c | 28 ++++++ components/hal/usb_wrap_hal.c | 94 ++----------------- components/usb/usb_phy.c | 66 +++++++++---- 6 files changed, 189 insertions(+), 141 deletions(-) create mode 100644 components/hal/include/hal/usb_serial_jtag_hal.h create mode 100644 components/hal/usb_serial_jtag_hal.c diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 177255c4a4..d509a02642 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -179,6 +179,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "ds_hal.c") endif() + if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED) + list(APPEND srcs "usb_serial_jtag_hal.c") + endif() + if(CONFIG_SOC_USB_OTG_SUPPORTED) list(APPEND srcs "usb_dwc_hal.c" diff --git a/components/hal/include/hal/usb_serial_jtag_hal.h b/components/hal/include/hal/usb_serial_jtag_hal.h new file mode 100644 index 0000000000..410ed66355 --- /dev/null +++ b/components/hal/include/hal/usb_serial_jtag_hal.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_serial_jtag_ll.h" +#endif +#include "hal/usb_serial_jtag_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_SERIAL_JTAG_SUPPORTED + +/** + * @brief HAL context type of USJ driver + */ +typedef struct { + usb_serial_jtag_dev_t *dev; +} usb_serial_jtag_hal_context_t; + +/** + * @brief Initialize the USJ HAL driver + * + * @param hal USJ HAL context + */ +void usb_serial_jtag_hal_init(usb_serial_jtag_hal_context_t *hal); + +/* ---------------------------- USB PHY Control ---------------------------- */ + +#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED +/** + * @brief Configure whether USJ is routed to internal/external FSLS PHY + * + * @param hal USJ HAL context + * @param external True if external, False if internal + */ +void usb_serial_jtag_hal_phy_set_external(usb_serial_jtag_hal_context_t *hal, bool external); +#endif // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED + +#endif // SOC_USB_SERIAL_JTAG_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/usb_wrap_hal.h b/components/hal/include/hal/usb_wrap_hal.h index fb8183a834..ceb69f3652 100644 --- a/components/hal/include/hal/usb_wrap_hal.h +++ b/components/hal/include/hal/usb_wrap_hal.h @@ -7,80 +7,89 @@ #pragma once #include -#include "usb_dwc_types.h" -#include "usb_phy_types.h" #include "soc/soc_caps.h" #if SOC_USB_OTG_SUPPORTED #include "soc/usb_wrap_struct.h" #include "hal/usb_wrap_ll.h" #endif -#if SOC_USB_SERIAL_JTAG_SUPPORTED -#include "soc/usb_serial_jtag_struct.h" -#endif +#include "hal/usb_wrap_types.h" #ifdef __cplusplus extern "C" { #endif -/** - * Context that should be maintained by both the driver and the HAL - */ -typedef struct { - usb_wrap_dev_t *wrap_dev; /**< Pointer to base address of USB Wrapper registers */ -#if SOC_USB_SERIAL_JTAG_SUPPORTED - usb_serial_jtag_dev_t *jtag_dev; /**< Pointer to base address of USB Serial JTAG registers */ -#endif -} usb_fsls_phy_hal_context_t; +#if SOC_USB_OTG_SUPPORTED /** - * @brief Init the USB PHY hal. This function should be called first before other hal layer function is called - * - * @param hal Context of the HAL layer + * @brief HAL context type of USB WRAP driver */ -void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal); +typedef struct { + usb_wrap_dev_t *dev; +} usb_wrap_hal_context_t; + +/** + * @brief Initialize the USB WRAP HAL driver + * + * @param hal USB WRAP HAL context + */ +void usb_wrap_hal_init(usb_wrap_hal_context_t *hal); + +/* ---------------------------- USB PHY Control ---------------------------- */ #if USB_WRAP_LL_EXT_PHY_SUPPORTED /** - * @brief Configure internal/external PHY for USB_OTG + * @brief Configure whether USB WRAP is routed to internal/external FSLS PHY * - * @param hal Context of the HAL layer - * @param phy_target USB PHY target + * @param hal USB WRAP HAL context + * @param external True if external, False if internal */ -void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target); +void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external); #endif // USB_WRAP_LL_EXT_PHY_SUPPORTED -#if SOC_USB_SERIAL_JTAG_SUPPORTED /** - * @brief Configure internal/external PHY for USB_Serial_JTAG + * @brief Enables and sets override of pull up/down resistors * - * @param hal Context of the HAL layer - * @param phy_target USB PHY target + * @param hal USB WRAP HAL context + * @param vals Override values */ -void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target); -#endif +static inline void usb_wrap_hal_phy_enable_pull_override(usb_wrap_hal_context_t *hal, const usb_wrap_pull_override_vals_t *vals) +{ + usb_wrap_ll_phy_enable_pull_override(hal->dev, vals); +} /** - * @brief Configure pullup/pulldown loads for the D+/D- as a host + * @brief Disables pull up/down resistor override * - * @param hal Context of the HAL layer + * @param hal USB WRAP HAL context */ -void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal); +static inline void usb_wrap_hal_phy_disable_pull_override(usb_wrap_hal_context_t *hal) +{ + usb_wrap_ll_phy_disable_pull_override(hal->dev); +} /** - * @brief Configure pullup/pulldown loads for the D+/D- as a device + * @brief Enables/disables the USB FSLS PHY's test mode * - * @param hal Context of the HAL layer - * @param speed USB speed + * @param hal USB WRAP HAL context + * @param enable Whether to enable test mode */ -void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed); +static inline void usb_wrap_hal_phy_enable_test_mode(usb_wrap_hal_context_t *hal, bool enable) +{ + usb_wrap_ll_phy_enable_test_mode(hal->dev, enable); +} /** - * @brief Enable/Disable test mode for internal PHY to mimic host-device disconnection + * @brief Set the USB FSLS PHY's signal test values * - * @param hal Context of the HAL layer - * @param disconn Whether to disconnect + * @param hal USB WRAP HAL context + * @param vals Test values */ -void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn); +static inline void usb_wrap_hal_phy_test_mode_set_signals(usb_wrap_hal_context_t *hal, const usb_wrap_test_mode_vals_t *vals) +{ + usb_wrap_ll_phy_test_mode_set_signals(hal->dev, vals); +} + +#endif // SOC_USB_OTG_SUPPORTED #ifdef __cplusplus } diff --git a/components/hal/usb_serial_jtag_hal.c b/components/hal/usb_serial_jtag_hal.c new file mode 100644 index 0000000000..094ff81763 --- /dev/null +++ b/components/hal/usb_serial_jtag_hal.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_serial_jtag_hal.h" + +void usb_serial_jtag_hal_init(usb_serial_jtag_hal_context_t *hal) +{ + hal->dev = &USB_SERIAL_JTAG; +#if !USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED + usb_serial_jtag_ll_phy_set_defaults(); +#endif +} + +#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED +void usb_serial_jtag_hal_phy_set_external(usb_serial_jtag_hal_context_t *hal, bool external) +{ + if (external) { + usb_serial_jtag_ll_phy_enable_external(true); + } else { + usb_serial_jtag_ll_phy_enable_external(false); + usb_serial_jtag_ll_phy_enable_pad(true); + } +} +#endif // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED diff --git a/components/hal/usb_wrap_hal.c b/components/hal/usb_wrap_hal.c index de805083d8..52d6933bce 100644 --- a/components/hal/usb_wrap_hal.c +++ b/components/hal/usb_wrap_hal.c @@ -5,101 +5,25 @@ */ #include "soc/soc_caps.h" -#if SOC_USB_SERIAL_JTAG_SUPPORTED -#include "hal/usb_serial_jtag_ll.h" -#endif #include "hal/usb_wrap_ll.h" #include "hal/usb_wrap_hal.h" -void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal) +void usb_wrap_hal_init(usb_wrap_hal_context_t *hal) { - hal->wrap_dev = &USB_WRAP; -#if SOC_USB_SERIAL_JTAG_SUPPORTED - hal->jtag_dev = &USB_SERIAL_JTAG; -#endif + hal->dev = &USB_WRAP; #if !USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_wrap_ll_phy_set_defaults(hal->wrap_dev); + usb_wrap_ll_phy_set_defaults(hal->dev); #endif } #if USB_WRAP_LL_EXT_PHY_SUPPORTED -void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) +void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external) { - if (phy_target == USB_PHY_TARGET_EXT) { - usb_wrap_ll_phy_enable_external(hal->wrap_dev, true); - } else if (phy_target == USB_PHY_TARGET_INT) { - usb_wrap_ll_phy_enable_external(hal->wrap_dev, false); - usb_wrap_ll_phy_enable_pad(hal->wrap_dev, true); + if (external) { + usb_wrap_ll_phy_enable_external(hal->dev, true); + } else { + usb_wrap_ll_phy_enable_external(hal->dev, false); + usb_wrap_ll_phy_enable_pad(hal->dev, true); } } #endif // USB_WRAP_LL_EXT_PHY_SUPPORTED - -#if SOC_USB_SERIAL_JTAG_SUPPORTED -void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) -{ - if (phy_target == USB_PHY_TARGET_EXT) { - usb_serial_jtag_ll_phy_enable_external(true); // USJ uses external PHY - } else if (phy_target == USB_PHY_TARGET_INT) { - usb_serial_jtag_ll_phy_enable_external(false); // USJ uses internal PHY - usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads - } -} -#endif - -void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal) -{ - // HOST - upstream: dp_pd = 1, dm_pd = 1 - usb_wrap_pull_override_vals_t vals = { - .dp_pu = false, - .dm_pu = false, - .dp_pd = true, - .dm_pd = true, - }; - usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals); -} - -void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed) -{ - // DEVICE - downstream - if (speed == USB_PHY_SPEED_LOW) { - // LS: dm_pu = 1 - usb_wrap_pull_override_vals_t vals = { - .dp_pu = false, - .dm_pu = true, - .dp_pd = false, - .dm_pd = false, - }; - usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals); - } else { - // FS: dp_pu = 1 - usb_wrap_pull_override_vals_t vals = { - .dp_pu = true, - .dm_pu = false, - .dm_pd = false, - .dp_pd = false, - }; - usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals); - } -} - -void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn) -{ - if (disconn) { - /* - We mimic a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will: - A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection. - */ - usb_wrap_test_mode_vals_t vals = { - .tx_enable_n = true, - .tx_dp = false, - .tx_dm = false, - .rx_dp = false, - .rx_dm = false, - .rx_rcv = false, - }; - usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev, &vals); - usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, true); - } else { - usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, false); - } -} diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index c1747da3fe..bd07287a3c 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -13,7 +13,7 @@ #include "esp_private/usb_phy.h" #include "soc/usb_dwc_periph.h" #include "hal/usb_wrap_hal.h" -#include "hal/usb_wrap_ll.h" +#include "hal/usb_serial_jtag_hal.h" #include "esp_rom_gpio.h" #include "driver/gpio.h" #include "hal/gpio_ll.h" @@ -33,7 +33,10 @@ struct phy_context_t { usb_otg_mode_t otg_mode; /**< USB OTG mode */ usb_phy_speed_t otg_speed; /**< USB speed */ usb_phy_ext_io_conf_t *iopins; /**< external PHY I/O pins */ - usb_fsls_phy_hal_context_t hal_context; /**< USB_PHY hal context */ + usb_wrap_hal_context_t wrap_hal; /**< USB WRAP HAL context */ +#if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_serial_jtag_hal_context_t usj_hal; /**< USJ HAL context */ +#endif }; typedef struct { @@ -120,7 +123,14 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode) esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from host esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_AVALID_IN_IDX, false); // HIGH to force USB host mode if (handle->target == USB_PHY_TARGET_INT) { - usb_fsls_phy_hal_int_load_conf_host(&(handle->hal_context)); + // Configure pull resistors for host + usb_wrap_pull_override_vals_t vals = { + .dp_pu = false, + .dm_pu = false, + .dp_pd = true, + .dm_pd = true, + }; + usb_wrap_hal_phy_enable_pull_override(&handle->wrap_hal, &vals); } } else if (mode == USB_OTG_MODE_DEVICE) { esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is mini-B side @@ -141,7 +151,19 @@ esp_err_t usb_phy_otg_dev_set_speed(usb_phy_handle_t handle, usb_phy_speed_t spe USBPHY_TAG, "set speed not supported"); handle->otg_speed = speed; - usb_fsls_phy_hal_int_load_conf_dev(&(handle->hal_context), speed); + // Configure pull resistors for device + usb_wrap_pull_override_vals_t vals = { + .dp_pd = false, + .dm_pd = false, + }; + if (speed == USB_PHY_SPEED_LOW) { + vals.dp_pu = false; + vals.dm_pu = true; + } else { + vals.dp_pu = true; + vals.dm_pu = false; + } + usb_wrap_hal_phy_enable_pull_override(&handle->wrap_hal, &vals); return ESP_OK; } @@ -157,7 +179,7 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action) switch (action) { case USB_PHY_ACTION_HOST_ALLOW_CONN: if (handle->target == USB_PHY_TARGET_INT) { - usb_fsls_phy_hal_int_mimick_disconn(&(handle->hal_context), false); + usb_wrap_hal_phy_enable_test_mode(&handle->wrap_hal, false); } else { if (!handle->iopins) { ret = ESP_FAIL; @@ -174,7 +196,21 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action) case USB_PHY_ACTION_HOST_FORCE_DISCONN: if (handle->target == USB_PHY_TARGET_INT) { - usb_fsls_phy_hal_int_mimick_disconn(&(handle->hal_context), true); + /* + We mimic a disconnect by enabling the internal PHY's test mode, + then forcing the output_enable to HIGH. This will cause the received + VP and VM to be zero, thus mimicking a disconnection. + */ + const usb_wrap_test_mode_vals_t vals = { + .tx_enable_n = true, + .tx_dp = false, + .tx_dm = false, + .rx_dp = false, + .rx_dm = false, + .rx_rcv = false, + }; + usb_wrap_hal_phy_test_mode_set_signals(&handle->wrap_hal, &vals); + usb_wrap_hal_phy_enable_test_mode(&handle->wrap_hal, true); } else { /* Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal. @@ -255,15 +291,18 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r phy_context->controller = config->controller; phy_context->status = USB_PHY_STATUS_IN_USE; - usb_fsls_phy_hal_init(&(phy_context->hal_context)); + usb_wrap_hal_init(&phy_context->wrap_hal); +#if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_serial_jtag_hal_init(&phy_context->usj_hal); +#endif if (config->controller == USB_PHY_CTRL_OTG) { #if USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_fsls_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT); + usb_wrap_hal_phy_set_external(&phy_context->wrap_hal, (config->target == USB_PHY_TARGET_EXT)); #endif } #if SOC_USB_SERIAL_JTAG_SUPPORTED else if (config->controller == USB_PHY_CTRL_SERIAL_JTAG) { - usb_fsls_phy_hal_jtag_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT); + usb_serial_jtag_hal_phy_set_external(&phy_context->usj_hal, (config->target == USB_PHY_TARGET_EXT)); phy_context->otg_mode = USB_OTG_MODE_DEVICE; phy_context->otg_speed = USB_PHY_SPEED_FULL; } @@ -326,14 +365,7 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle) p_phy_ctrl_obj->external_phy = NULL; } else { // Clear pullup and pulldown loads on D+ / D-, and disable the pads - usb_wrap_pull_override_vals_t vals = { - .dp_pu = false, - .dm_pu = false, - .dp_pd = false, - .dm_pd = false, - }; - usb_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, &vals); - usb_wrap_ll_phy_enable_pad(handle->hal_context.wrap_dev, false); + usb_wrap_hal_phy_disable_pull_override(&handle->wrap_hal); p_phy_ctrl_obj->internal_phy = NULL; } portEXIT_CRITICAL(&phy_spinlock);