Merge branch 'feature/usb_new_phy_driver_collective_backport_v5.2' into 'release/v5.2'

refactor(usb/host): PHY driver preqrequisite refacotring collective backport (v5.2)

See merge request espressif/esp-idf!29792
This commit is contained in:
morris
2024-06-07 13:11:37 +08:00
24 changed files with 1361 additions and 680 deletions

View File

@@ -1,11 +1,12 @@
/* /*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "sdkconfig.h" #include "sdkconfig.h"
#include "bootloader_console.h" #include "bootloader_console.h"
#include "soc/soc_caps.h"
#include "soc/uart_periph.h" #include "soc/uart_periph.h"
#include "soc/uart_channel.h" #include "soc/uart_channel.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
@@ -18,8 +19,8 @@
#include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/cdc_acm.h"
#include "esp32s2/rom/usb/usb_common.h" #include "esp32s2/rom/usb/usb_common.h"
#endif #endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED #if CONFIG_ESP_CONSOLE_USB_CDC
#include "hal/usb_fsls_phy_ll.h" #include "hal/usb_wrap_ll.h"
#endif #endif
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
@@ -105,10 +106,9 @@ void bootloader_console_init(void)
esp_rom_uart_usb_acm_init(s_usb_cdc_buf, sizeof(s_usb_cdc_buf)); 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_uart_set_as_console(ESP_ROM_USB_OTG_NUM);
esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb);
#if SOC_USB_SERIAL_JTAG_SUPPORTED // Ensure that the USB FSLS PHY is mapped to the USB WRAP
usb_fsls_phy_ll_usb_wrap_pad_enable(&USB_WRAP, true); usb_wrap_ll_phy_enable_pad(&USB_WRAP, true);
usb_fsls_phy_ll_int_otg_enable(&USB_WRAP); usb_wrap_ll_phy_enable_external(&USB_WRAP, false);
#endif
} }
#endif //CONFIG_ESP_CONSOLE_USB_CDC #endif //CONFIG_ESP_CONSOLE_USB_CDC

View File

@@ -9,7 +9,6 @@
#include <stdatomic.h> #include <stdatomic.h>
#include "esp_log.h" #include "esp_log.h"
#include "hal/usb_serial_jtag_ll.h" #include "hal/usb_serial_jtag_ll.h"
#include "hal/usb_fsls_phy_ll.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
@@ -186,7 +185,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); atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE);
// Configure PHY // Configure PHY
usb_fsls_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG); #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_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY|
USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);

View File

@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -27,7 +27,8 @@ void sleep_console_usj_pad_backup_and_disable(void)
usb_serial_jtag_ll_enable_bus_clock(true); usb_serial_jtag_ll_enable_bus_clock(true);
usb_serial_jtag_ll_reset_register(); 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 // Disable USJ clock
usb_serial_jtag_ll_enable_bus_clock(false); usb_serial_jtag_ll_enable_bus_clock(false);
} }
@@ -40,7 +41,7 @@ void sleep_console_usj_pad_restore(void)
int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused)); int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused));
usb_serial_jtag_ll_enable_bus_clock(true); 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) { if (!s_usj_state.usj_clock_enabled) {
usb_serial_jtag_ll_enable_bus_clock(false); usb_serial_jtag_ll_enable_bus_clock(false);
} }

View File

@@ -4,7 +4,7 @@ set(srcs "hal_utils.c")
set(includes "platform_port/include") set(includes "platform_port/include")
# target specific include must be added before the generic one # target specific include must be added before the generic one
# becuase of the "include_next" directive used by the efuse_hal.h # because of the "include_next" directive used by the efuse_hal.h
if(NOT ${target} STREQUAL "linux") if(NOT ${target} STREQUAL "linux")
list(APPEND includes "${target}/include") list(APPEND includes "${target}/include")
endif() endif()
@@ -234,10 +234,14 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "huk_hal.c") list(APPEND srcs "huk_hal.c")
endif() endif()
if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED)
list(APPEND srcs "usb_serial_jtag_hal.c")
endif()
if(CONFIG_SOC_USB_OTG_SUPPORTED) if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs list(APPEND srcs
"usb_dwc_hal.c" "usb_dwc_hal.c"
"usb_fsls_phy_hal.c") "usb_wrap_hal.c")
endif() endif()
if(${target} STREQUAL "esp32") if(${target} STREQUAL "esp32")

View File

@@ -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

View File

@@ -1,26 +1,21 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
// The LL layer of the USB-serial-jtag controller
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h" #include "soc/usb_serial_jtag_struct.h"
#include "soc/system_struct.h" #include "soc/system_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus /* ----------------------------- Macros & Types ----------------------------- */
extern "C" {
#endif
//The in and out endpoints are this long. #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define USB_SERIAL_JTAG interrupts // Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging // Note the hardware has more interrupts, but they're only useful for debugging
@@ -34,6 +29,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t; } usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/** /**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
* *
@@ -123,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer. * is room in the buffer.
* *
* @param buf The data 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. * @return Amount of bytes actually written. May be less than wr_len.
*/ */
@@ -177,34 +179,117 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
USB_SERIAL_JTAG.ep1_conf.wr_done=1; 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 PHY defaults
* *
* @return Initial configuration of usb serial jtag pad enable before light sleep * 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 bool usb_serial_jtag_ll_pad_backup_and_disable(void) FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{ {
bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; // External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
// Disable USB pad function USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
return pad_enabled;
} }
/** /**
* @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 Enable the bus clock for USB Serial_JTAG module * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs
* @param clk_en True if enable the clock of USB Serial_JTAG module *
* @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 vals Override values to set
*/
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 = 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;
}
/**
* @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 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) FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{ {
@@ -215,7 +300,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
#define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__) #define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__)
/** /**
* @brief Reset the usb serial jtag module * @brief Reset the USJ module
*/ */
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{ {
@@ -227,15 +312,21 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
#define usb_serial_jtag_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_reset_register(__VA_ARGS__) #define usb_serial_jtag_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_reset_register(__VA_ARGS__)
/** /**
* 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) 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); return (SYSTEM.perip_clk_en0.reg_usb_device_clk_en && !SYSTEM.perip_rst_en0.reg_usb_device_rst);
} }
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_serial_jtag_ll_module_is_enabled(...) ({ \
(void)__DECLARE_RCC_ATOMIC_ENV; \
usb_serial_jtag_ll_module_is_enabled(__VA_ARGS__); \
})
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -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

View File

@@ -1,26 +1,21 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
// The LL layer of the USB-serial-jtag controller
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h" #include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus /* ----------------------------- Macros & Types ----------------------------- */
extern "C" {
#endif
//The in and out endpoints are this long. #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define USB_SERIAL_JTAG interrupts // Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging // Note the hardware has more interrupts, but they're only useful for debugging
@@ -34,6 +29,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t; } usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/** /**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
* *
@@ -123,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer. * is room in the buffer.
* *
* @param buf The data 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. * @return Amount of bytes actually written. May be less than wr_len.
*/ */
@@ -177,35 +179,130 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
USB_SERIAL_JTAG.ep1_conf.wr_done=1; 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 PHY defaults
* *
* @return Initial configuration of usb serial jtag pad enable before light sleep * 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 bool usb_serial_jtag_ll_pad_backup_and_disable(void) FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{ {
bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable; // External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
// Disable USB pad function USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
return pad_enabled;
} }
/** /**
* @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 Enable the bus clock for USB Serial_JTAG module * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs
* @param clk_en True if enable the clock of USB Serial_JTAG module *
* @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 vals Override values to set
*/
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 = 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;
}
/**
* @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 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) FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{ {
@@ -213,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) FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{ {
@@ -222,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) FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{ {

View File

@@ -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

View File

@@ -1,26 +1,21 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
// The LL layer of the USB-serial-jtag controller
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h" #include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus /* ----------------------------- Macros & Types ----------------------------- */
extern "C" {
#endif
//The in and out endpoints are this long. #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define USB_SERIAL_JTAG interrupts // Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging // Note the hardware has more interrupts, but they're only useful for debugging
@@ -34,6 +29,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t; } usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/** /**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
* *
@@ -123,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer. * is room in the buffer.
* *
* @param buf The data 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. * @return Amount of bytes actually written. May be less than wr_len.
*/ */
@@ -178,33 +180,129 @@ 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 PHY Control ---------------------------- */
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
return pad_enabled; /**
* @brief Sets PHY defaults
*
* 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_set_defaults(void)
{
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
} }
/** /**
* @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 Enable the bus clock for USB Serial_JTAG module * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs
* @param clk_en True if enable the clock of USB Serial_JTAG module *
* @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 vals Override values to set
*/
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 = 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;
}
/**
* @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 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) FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{ {
@@ -212,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) FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{ {
@@ -221,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) FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{ {

View File

@@ -1,117 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/system_reg.h"
#include "soc/usb_wrap_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
{
hw->otg_conf.phy_sel = 0;
}
/**
* @brief Configures the external PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
{
//Enable external PHY
hw->otg_conf.phy_sel = 1;
}
/**
* @brief Configures port loads for the internal 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
*/
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)
{
usb_wrap_otg_conf_reg_t conf;
conf.val = hw->otg_conf.val;
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.val = conf.val;
}
/**
* @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;
} else {
hw->test_conf.test_enable = 0;
}
}
/**
* 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)
{
REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en);
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_fsls_phy_ll_usb_wrap_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_fsls_phy_ll_usb_wrap_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void)
{
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 1);
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0);
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_fsls_phy_ll_usb_wrap_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_fsls_phy_ll_usb_wrap_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,232 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#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" {
#endif
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @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
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.srp_sessend_override = 0;
}
/**
* @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
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable)
{
hw->otg_conf.phy_sel = enable;
}
/**
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param hw Start address of the USB Wrap registers
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable)
{
if (enable) {
hw->otg_conf.exchg_pins = 1;
hw->otg_conf.exchg_pins_override = 1;
} else {
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 vals Override values to set
*/
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 = 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;
}
/**
* @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 vals Test values to set
*/
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 = 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;
}
/* ----------------------------- 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_wrap_ll_enable_bus_clock(bool clk_en)
{
REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en);
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB Wrap module
*/
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);
}
// SYSTEM.perip_rst_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -1,166 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/system_struct.h"
#include "soc/usb_wrap_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/usb_serial_jtag_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_int_otg_enable(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;
}
/**
* @brief Configures the external PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
{
// USB_OTG use external PHY
hw->otg_conf.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=0, USB_OTG is connected with external PHY through GPIO Matrix
RTCCNTL.usb_conf.sw_usb_phy_sel = 0;
}
/**
* @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
*
* @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
*/
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)
{
usb_wrap_otg_conf_reg_t conf;
conf.val = hw->otg_conf.val;
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.val = conf.val;
}
/**
* @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;
} else {
hw->test_conf.test_enable = 0;
}
}
/**
* 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)
{
SYSTEM.perip_clk_en0.usb_clk_en = clk_en;
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_fsls_phy_ll_usb_wrap_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_fsls_phy_ll_usb_wrap_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void)
{
SYSTEM.perip_rst_en0.usb_rst = 1;
SYSTEM.perip_rst_en0.usb_rst = 0;
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_fsls_phy_ll_usb_wrap_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_fsls_phy_ll_usb_wrap_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -1,26 +1,23 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
// The LL layer of the USB-serial-jtag controller
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/system_struct.h" #include "soc/system_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h" #include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus /* ----------------------------- Macros & Types ----------------------------- */
extern "C" {
#endif
//The in and out endpoints are this long. #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 #define USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define USB_SERIAL_JTAG interrupts // Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging // Note the hardware has more interrupts, but they're only useful for debugging
@@ -34,6 +31,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_intr_t; } usb_serial_jtag_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/** /**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
* *
@@ -123,7 +127,7 @@ static inline uint32_t usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_
* is room in the buffer. * is room in the buffer.
* *
* @param buf The data 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. * @return Amount of bytes actually written. May be less than wr_len.
*/ */
@@ -178,33 +182,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 PHY Control ---------------------------- */
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
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 Enable the bus clock for USB Serial_JTAG module * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs
* @param clk_en True if enable the clock of USB Serial_JTAG module *
* @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 vals Override values to set
*/
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 = 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;
}
/**
* @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 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) FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{ {
@@ -215,7 +328,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
#define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__) #define usb_serial_jtag_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_enable_bus_clock(__VA_ARGS__)
/** /**
* @brief Reset the usb serial jtag module * @brief Reset the USJ module
*/ */
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{ {
@@ -227,15 +340,21 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
#define usb_serial_jtag_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_reset_register(__VA_ARGS__) #define usb_serial_jtag_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_reset_register(__VA_ARGS__)
/** /**
* 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) FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{ {
return (SYSTEM.perip_clk_en1.usb_device_clk_en && !SYSTEM.perip_rst_en1.usb_device_rst); return (SYSTEM.perip_clk_en1.usb_device_clk_en && !SYSTEM.perip_rst_en1.usb_device_rst);
} }
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_serial_jtag_ll_module_is_enabled(...) ({ \
(void)__DECLARE_RCC_ATOMIC_ENV; \
usb_serial_jtag_ll_module_is_enabled(__VA_ARGS__); \
})
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -0,0 +1,241 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#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" {
#endif
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @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
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.srp_sessend_override = 0;
}
/**
* @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
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable)
{
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;
/*
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 Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param hw Start address of the USB Wrap registers
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable)
{
if (enable) {
hw->otg_conf.exchg_pins = 1;
hw->otg_conf.exchg_pins_override = 1;
} else {
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 vals Override values to set
*/
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 = 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;
}
/**
* @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 vals Test values to set
*/
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 = 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;
}
/* ----------------------------- 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_wrap_ll_enable_bus_clock(bool clk_en)
{
SYSTEM.perip_clk_en0.usb_clk_en = clk_en;
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
{
SYSTEM.perip_rst_en0.usb_rst = 1;
SYSTEM.perip_rst_en0.usb_rst = 0;
}
// SYSTEM.perip_rst_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -1,89 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#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"
#endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "soc/usb_serial_jtag_struct.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_USB_OTG_SUPPORTED
/**
* 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;
/**
* @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
*/
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal);
/**
* @brief Configure internal/external PHY for USB_OTG
*
* @param hal Context of the HAL layer
* @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);
#if SOC_USB_SERIAL_JTAG_SUPPORTED
/**
* @brief Configure internal/external PHY for USB_Serial_JTAG
*
* @param hal Context of the HAL layer
* @param phy_target USB PHY target
*/
void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target);
#endif
/**
* @brief Configure pullup/pulldown loads for the D+/D- as a host
*
* @param hal Context of the HAL layer
*/
void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal);
/**
* @brief Configure pullup/pulldown loads for the D+/D- as a device
*
* @param hal Context of the HAL layer
* @param speed USB speed
*/
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
*
* @param hal Context of the HAL layer
* @param disconn Whether to disconnect
*/
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -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

View File

@@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#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

View File

@@ -0,0 +1,96 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "soc/soc_caps.h"
#if SOC_USB_OTG_SUPPORTED
#include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_ll.h"
#endif
#include "hal/usb_wrap_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_USB_OTG_SUPPORTED
/**
* @brief HAL context type of USB WRAP driver
*/
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 whether USB WRAP is routed to internal/external FSLS PHY
*
* @param hal USB WRAP HAL context
* @param external True if external, False if internal
*/
void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external);
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
/**
* @brief Enables and sets override of pull up/down resistors
*
* @param hal USB WRAP HAL context
* @param vals Override values
*/
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 Disables pull up/down resistor override
*
* @param hal USB WRAP HAL context
*/
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 Enables/disables the USB FSLS PHY's test mode
*
* @param hal USB WRAP HAL context
* @param enable Whether to enable test mode
*/
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 Set the USB FSLS PHY's signal test values
*
* @param hal USB WRAP HAL context
* @param vals Test values
*/
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
}
#endif

View File

@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#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

View File

@@ -1,64 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/usb_fsls_phy_ll.h"
#include "hal/usb_fsls_phy_hal.h"
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal)
{
hal->wrap_dev = &USB_WRAP;
#if SOC_USB_SERIAL_JTAG_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG;
#endif
}
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);
} 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);
}
}
#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_fsls_phy_ll_ext_jtag_enable(hal->jtag_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_fsls_phy_ll_int_jtag_enable(hal->jtag_dev);
}
}
#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_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true);
}
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_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false);
} else {
// FS: dp_pu = 1
usb_fsls_phy_ll_int_load_conf(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);
}

View File

@@ -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

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc_caps.h"
#include "hal/usb_wrap_ll.h"
#include "hal/usb_wrap_hal.h"
void usb_wrap_hal_init(usb_wrap_hal_context_t *hal)
{
hal->dev = &USB_WRAP;
#if !USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_wrap_ll_phy_set_defaults(hal->dev);
#endif
}
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external)
{
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

View File

@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,8 +12,8 @@
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "esp_private/usb_phy.h" #include "esp_private/usb_phy.h"
#include "soc/usb_dwc_periph.h" #include "soc/usb_dwc_periph.h"
#include "hal/usb_fsls_phy_hal.h" #include "hal/usb_wrap_hal.h"
#include "hal/usb_fsls_phy_ll.h" #include "hal/usb_serial_jtag_hal.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "hal/gpio_ll.h" #include "hal/gpio_ll.h"
@@ -39,7 +39,10 @@ struct phy_context_t {
usb_otg_mode_t otg_mode; /**< USB OTG mode */ usb_otg_mode_t otg_mode; /**< USB OTG mode */
usb_phy_speed_t otg_speed; /**< USB speed */ usb_phy_speed_t otg_speed; /**< USB speed */
usb_phy_ext_io_conf_t *iopins; /**< external PHY I/O pins */ 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 { typedef struct {
@@ -126,7 +129,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_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 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) { 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) { } 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 esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is mini-B side
@@ -147,7 +157,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"); USBPHY_TAG, "set speed not supported");
handle->otg_speed = speed; 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; return ESP_OK;
} }
@@ -163,7 +185,7 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
switch (action) { switch (action) {
case USB_PHY_ACTION_HOST_ALLOW_CONN: case USB_PHY_ACTION_HOST_ALLOW_CONN:
if (handle->target == USB_PHY_TARGET_INT) { 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 { } else {
if (!handle->iopins) { if (!handle->iopins) {
ret = ESP_FAIL; ret = ESP_FAIL;
@@ -180,7 +202,21 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
case USB_PHY_ACTION_HOST_FORCE_DISCONN: case USB_PHY_ACTION_HOST_FORCE_DISCONN:
if (handle->target == USB_PHY_TARGET_INT) { 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 { } else {
/* /*
Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal. Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal.
@@ -223,8 +259,8 @@ static esp_err_t usb_phy_install(void)
// Enable USB peripheral and reset the register // Enable USB peripheral and reset the register
portEXIT_CRITICAL(&phy_spinlock); portEXIT_CRITICAL(&phy_spinlock);
USB_WRAP_RCC_ATOMIC() { USB_WRAP_RCC_ATOMIC() {
usb_fsls_phy_ll_usb_wrap_enable_bus_clock(true); usb_wrap_ll_enable_bus_clock(true);
usb_fsls_phy_ll_usb_wrap_reset_register(); usb_wrap_ll_reset_register();
} }
return ESP_OK; return ESP_OK;
@@ -263,13 +299,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->controller = config->controller;
phy_context->status = USB_PHY_STATUS_IN_USE; 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 (config->controller == USB_PHY_CTRL_OTG) {
usb_fsls_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT); #if USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_wrap_hal_phy_set_external(&phy_context->wrap_hal, (config->target == USB_PHY_TARGET_EXT));
#endif
} }
#if SOC_USB_SERIAL_JTAG_SUPPORTED #if SOC_USB_SERIAL_JTAG_SUPPORTED
else if (config->controller == USB_PHY_CTRL_SERIAL_JTAG) { 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_mode = USB_OTG_MODE_DEVICE;
phy_context->otg_speed = USB_PHY_SPEED_FULL; phy_context->otg_speed = USB_PHY_SPEED_FULL;
} }
@@ -317,7 +358,7 @@ static void phy_uninstall(void)
p_phy_ctrl_obj = NULL; p_phy_ctrl_obj = NULL;
USB_WRAP_RCC_ATOMIC() { USB_WRAP_RCC_ATOMIC() {
// Disable USB peripheral without reset the module // 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); portEXIT_CRITICAL(&phy_spinlock);
@@ -334,8 +375,7 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle)
p_phy_ctrl_obj->external_phy = NULL; p_phy_ctrl_obj->external_phy = NULL;
} else { } else {
// Clear pullup and pulldown loads on D+ / D-, and disable the pads // 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_wrap_hal_phy_disable_pull_override(&handle->wrap_hal);
usb_fsls_phy_ll_usb_wrap_pad_enable(handle->hal_context.wrap_dev, false);
p_phy_ctrl_obj->internal_phy = NULL; p_phy_ctrl_obj->internal_phy = NULL;
} }
portEXIT_CRITICAL(&phy_spinlock); portEXIT_CRITICAL(&phy_spinlock);