Merge branch 'refactor/usb_new_phy_hal_api' into 'master'

refactor(hal/usb): Update USB WRAP/USJ P4 LL, add new USB PHY HAL API

See merge request espressif/esp-idf!29853
This commit is contained in:
Darian
2024-04-04 14:09:03 +08:00
23 changed files with 1170 additions and 297 deletions

View File

@@ -186,8 +186,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
#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_external(false); // Use internal PHY
usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads 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

@@ -246,9 +246,12 @@ __attribute__((weak)) void esp_perip_clk_init(void)
SYSTEM_WIFI_CLK_UNUSED_BIT12; SYSTEM_WIFI_CLK_UNUSED_BIT12;
#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED #if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
/* This function only called on startup thus is thread safe. To avoid build errors/warnings
* declare __DECLARE_RCC_ATOMIC_ENV here. */
int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused));
// Disable USB-Serial-JTAG clock and it's pad if not used // Disable USB-Serial-JTAG clock and it's pad if not used
usb_serial_jtag_ll_phy_enable_pad(false); usb_serial_jtag_ll_phy_enable_pad(false);
_usb_serial_jtag_ll_enable_bus_clock(false); usb_serial_jtag_ll_enable_bus_clock(false);
#endif #endif
} }

View File

@@ -263,6 +263,9 @@ __attribute__((weak)) void esp_perip_clk_init(void)
SYSTEM_WIFI_CLK_SDIO_HOST_EN; SYSTEM_WIFI_CLK_SDIO_HOST_EN;
#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED #if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
/* This function only called on startup thus is thread safe. To avoid build errors/warnings
* declare __DECLARE_RCC_ATOMIC_ENV here. */
int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused));
// Disable USB-Serial-JTAG clock and it's pad if not used // Disable USB-Serial-JTAG clock and it's pad if not used
usb_serial_jtag_ll_phy_enable_pad(false); usb_serial_jtag_ll_phy_enable_pad(false);
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()
@@ -256,11 +256,14 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "ds_hal.c") list(APPEND srcs "ds_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 "usb_dwc_hal.c") list(APPEND srcs
if(NOT ${target} STREQUAL "esp32p4") "usb_dwc_hal.c"
list(APPEND srcs "usb_wrap_hal.c") "usb_wrap_hal.c")
endif()
endif() endif()
if(${target} STREQUAL "esp32") if(${target} STREQUAL "esp32")

View File

@@ -4,23 +4,18 @@
* 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,11 @@ 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 ----------------------------- */ /* ----------------------------- 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. * 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.
*/ */
@@ -182,13 +182,18 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
/* ---------------------------- USB PHY Control ---------------------------- */ /* ---------------------------- 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 * @brief Enable override of USB FSLS PHY's pull up/down resistors
* *
* @param dp_pu Enable D+ pullup * @param vals Override values to set
* @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) 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_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1; USB_SERIAL_JTAG.conf0.pad_pull_override = 1;
} }
@@ -286,19 +288,19 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable)
/* ----------------------------- RCC Functions ----------------------------- */ /* ----------------------------- RCC Functions ----------------------------- */
/** /**
* @brief Enable the bus clock for USB Serial_JTAG module * @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USB Serial_JTAG 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)
{ {
SYSTEM.perip_clk_en0.reg_usb_device_clk_en = clk_en; SYSTEM.perip_clk_en0.reg_usb_device_clk_en = clk_en;
} }
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way // SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#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)
{ {
@@ -310,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

@@ -4,23 +4,18 @@
* 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,11 @@ 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 ----------------------------- */ /* ----------------------------- 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. * 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.
*/ */
@@ -195,13 +195,18 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
/* ---------------------------- USB PHY Control ---------------------------- */ /* ---------------------------- 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 * @brief Enable override of USB FSLS PHY's pull up/down resistors
* *
* @param dp_pu Enable D+ pullup * @param vals Override values to set
* @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) 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_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1; 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 ----------------------------- */ /* ----------------------------- RCC Functions ----------------------------- */
/** /**
* @brief Enable the bus clock for USB Serial_JTAG module * @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USB Serial_JTAG 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)
{ {
@@ -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) 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) FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{ {

View File

@@ -4,23 +4,18 @@
* 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,11 @@ 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 ----------------------------- */ /* ----------------------------- 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. * 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.
*/ */
@@ -195,13 +195,18 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
/* ---------------------------- USB PHY Control ---------------------------- */ /* ---------------------------- 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 * @brief Enable override of USB FSLS PHY's pull up/down resistors
* *
* @param dp_pu Enable D+ pullup * @param vals Override values to set
* @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) 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_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1; 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 ----------------------------- */ /* ----------------------------- RCC Functions ----------------------------- */
/** /**
* @brief Enable the bus clock for USB Serial_JTAG module * @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USB Serial_JTAG 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)
{ {
@@ -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) 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) FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{ {

View File

@@ -0,0 +1,204 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/lp_system_struct.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
// This header is temporarily disabled until USJ is supported on the P4 (IDF-7496)
#if SOC_USB_SERIAL_JTAG_SUPPORTED
/* ----------------------------- Macros & Types ----------------------------- */
#define USB_SERIAL_JTAG_LL_SELECT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
#ifdef __cplusplus
extern "C" {
#endif
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Sets PHY defaults
*
* Some PHY register fields/features of the USJ are redundant on the ESP32-P4.
* This function those fields are set to the appropriate default values.
*/
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 Select the internal USB FSLS PHY for the USJ
*
* @param phy_idx Selected PHY's index
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_select(unsigned int phy_idx)
{
// Enable SW control mapping USB_WRAP and USJ to USB FSLS PHY 0 and 1
LP_SYS.usb_ctrl.sw_hw_usb_phy_sel = 1;
/*
For 'sw_usb_phy_sel':
False - USJ mapped to USB FSLS PHY 0, USB_WRAP mapped to USB FSLS PHY 1
True - USJ mapped to USB FSLS PHY 1, USB_WRAP mapped to USB FSLS PHY 0
*/
switch (phy_idx) {
case 0:
LP_SYS.usb_ctrl.sw_usb_phy_sel = false;
case 1:
LP_SYS.usb_ctrl.sw_usb_phy_sel = true;
default:
break;
}
}
/**
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable)
{
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 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)
{
HP_SYS_CLKRST.soc_clk_ctrl2.reg_usb_device_apb_clk_en = clk_en;
// Enable PHY clock (48MHz) for USB FSLS PHY 0
LP_AON_CLKRST.hp_usb_clkrst_ctrl0.usb_device_48m_clk_en = clk_en;
}
// HP_SYS_CLKRST.soc_clk_ctrlx and LP_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way
#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 USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_device = 1;
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_device = 0;
}
// HP_SYS_CLKRST.soc_clk_ctrlx and LP_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way
#define usb_serial_jtag_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_serial_jtag_ll_reset_register(__VA_ARGS__)
/**
* Get the enable status of the USJ module
*
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{
return (HP_SYS_CLKRST.soc_clk_ctrl2.reg_usb_device_apb_clk_en && !LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_device);
}
// HP_SYS_CLKRST.soc_clk_ctrlx and LP_AON_CLKRST.hp_usb_clkrst_ctrlx 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
}
#endif
#endif // #if SOC_USB_SERIAL_JTAG_SUPPORTED

View File

@@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/usb_utmi_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- RCC Functions ----------------------------- */
/**
* @brief Enable the bus clock for the USB UTMI PHY and USB_DWC_HS controller
*
* @param clk_en True to enable, false to disable
*/
FORCE_INLINE_ATTR void usb_utmi_ll_enable_bus_clock(bool clk_en)
{
// Enable/disable system clock for USB_UTMI and USB_DWC_HS
HP_SYS_CLKRST.soc_clk_ctrl1.reg_usb_otg20_sys_clk_en = clk_en;
// Enable PHY ref clock (48MHz) for USB UTMI PHY
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.usb_otg20_phyref_clk_en = clk_en;
}
// HP_SYS_CLKRST.soc_clk_ctrlx and LP_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way
#define usb_utmi_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_utmi_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB UTMI PHY and USB_DWC_HS controller
*/
FORCE_INLINE_ATTR void usb_utmi_ll_reset_register(void)
{
// Reset the USB_UTMI and USB_DWC_HS
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg20 = 1;
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg20 = 0;
}
// P_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way
#define usb_utmi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_utmi_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,267 @@
/*
* SPDX-FileCopyrightText: 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/lp_system_struct.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_types.h"
/* ----------------------------- Macros & Types ----------------------------- */
#define USB_WRAP_LL_SELECT_PHY_SUPPORTED 1 // Can swap to another internal FSLS PHY
#ifdef __cplusplus
extern "C" {
#endif
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Sets default
*
* Some register fields/features of the USB WRAP are redundant on the ESP32-P4.
* 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_wrap_ll_phy_set_defaults(usb_wrap_dev_t *hw)
{
// External FSLS PHY is not supported
hw->otg_conf.phy_sel = 0;
hw->otg_conf.usb_pad_enable = 1;
}
/**
* @brief Select the internal USB FSLS PHY for the USB WRAP
*
* @param hw Start address of the USB Wrap registers
* @param phy_idx Selected PHY's index
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_select(usb_wrap_dev_t *hw, unsigned int phy_idx)
{
// Enable SW control mapping USB_WRAP and USJ to USB FSLS PHY 0 and 1
LP_SYS.usb_ctrl.sw_hw_usb_phy_sel = 1;
/*
For 'sw_usb_phy_sel':
False - USJ mapped to USB FSLS PHY 0, USB_WRAP mapped to USB FSLS PHY 1 (default)
True - USJ mapped to USB FSLS PHY 1, USB_WRAP mapped to USB FSLS PHY 0
*/
switch (phy_idx) {
case 0:
LP_SYS.usb_ctrl.sw_usb_phy_sel = true;
case 1:
LP_SYS.usb_ctrl.sw_usb_phy_sel = false;
default:
break;
}
}
/**
* @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 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.usb_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.usb_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 and USB_DWC_FS controller
* @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)
{
// Enable/disable system clock for USB_WRAP and USB_DWC_FS
HP_SYS_CLKRST.soc_clk_ctrl1.reg_usb_otg11_sys_clk_en = clk_en;
// Enable PHY clock (48MHz) for USB FSLS PHY 1
LP_AON_CLKRST.hp_usb_clkrst_ctrl0.usb_otg11_48m_clk_en = clk_en;
}
// HP_SYS_CLKRST.soc_clk_ctrlx and LP_AON_CLKRST.hp_usb_clkrst_ctrlx 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 and USB_DWC_FS controller
*/
FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
{
// Reset the USB_WRAP and USB_DWC_FS
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg11 = 1;
LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg11 = 0;
}
// P_AON_CLKRST.hp_usb_clkrst_ctrlx 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

@@ -11,6 +11,12 @@
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/system_reg.h" #include "soc/system_reg.h"
#include "soc/usb_wrap_struct.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 #ifdef __cplusplus
extern "C" { 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 * @brief Enable override of USB FSLS PHY's pull up/down resistors
* *
* @param hw Start address of the USB Wrap registers * @param hw Start address of the USB Wrap registers
* @param dp_pu Enable D+ pullup * @param vals Override values to set
* @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) 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_pullup = vals->dp_pu;
hw->otg_conf.dp_pulldown = dp_pd; hw->otg_conf.dp_pulldown = vals->dp_pd;
hw->otg_conf.dm_pullup = dm_pu; hw->otg_conf.dm_pullup = vals->dm_pu;
hw->otg_conf.dm_pulldown = dm_pd; hw->otg_conf.dm_pulldown = vals->dm_pd;
hw->otg_conf.pad_pull_override = 1; 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 * @brief Set the USB FSLS PHY's signal test values
* *
* @param hw Start address of the USB Wrap registers * @param hw Start address of the USB Wrap registers
* @param oen Output Enable (active low) signal * @param vals Test values to set
* @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, 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)
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; usb_wrap_test_conf_reg_t test_conf;
test_conf.val = hw->test_conf.val; test_conf.val = hw->test_conf.val;
test_conf.test_usb_wrap_oe = oen; test_conf.test_usb_wrap_oe = vals->tx_enable_n;
test_conf.test_tx_dp = tx_dp; test_conf.test_tx_dp = vals->tx_dp;
test_conf.test_tx_dm = tx_dm; test_conf.test_tx_dm = vals->tx_dm;
test_conf.test_rx_rcv = rx_rcv; test_conf.test_rx_rcv = vals->rx_rcv;
test_conf.test_rx_dp = rx_dp; test_conf.test_rx_dp = vals->rx_dp;
test_conf.test_rx_dm = rx_dm; test_conf.test_rx_dm = vals->rx_dm;
hw->test_conf.val = test_conf.val; hw->test_conf.val = test_conf.val;
} }
@@ -232,7 +224,7 @@ FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0); 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 // 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__) #define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -4,24 +4,20 @@
* 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/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
@@ -35,6 +31,11 @@ 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 ----------------------------- */ /* ----------------------------- 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. * 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.
*/ */
@@ -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 * @brief Enable override of USB FSLS PHY's pull up/down resistors
* *
* @param dp_pu Enable D+ pullup * @param vals Override values to set
* @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) 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_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd; USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu; USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd; USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1; USB_SERIAL_JTAG.conf0.pad_pull_override = 1;
} }
@@ -318,19 +316,19 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_tx_edge(bool clk_neg_edge)
/* ----------------------------- RCC Functions ----------------------------- */ /* ----------------------------- RCC Functions ----------------------------- */
/** /**
* @brief Enable the bus clock for USB Serial_JTAG module * @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USB Serial_JTAG 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)
{ {
SYSTEM.perip_clk_en1.usb_device_clk_en = clk_en; SYSTEM.perip_clk_en1.usb_device_clk_en = clk_en;
} }
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way // SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#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)
{ {
@@ -342,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

@@ -12,6 +12,12 @@
#include "soc/system_struct.h" #include "soc/system_struct.h"
#include "soc/usb_wrap_struct.h" #include "soc/usb_wrap_struct.h"
#include "soc/rtc_cntl_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 #ifdef __cplusplus
extern "C" { 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 * @brief Enable override of USB FSLS PHY's pull up/down resistors
* *
* @param hw Start address of the USB Wrap registers * @param hw Start address of the USB Wrap registers
* @param dp_pu Enable D+ pullup * @param vals Override values to set
* @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) 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_pullup = vals->dp_pu;
hw->otg_conf.dp_pulldown = dp_pd; hw->otg_conf.dp_pulldown = vals->dp_pd;
hw->otg_conf.dm_pullup = dm_pu; hw->otg_conf.dm_pullup = vals->dm_pu;
hw->otg_conf.dm_pulldown = dm_pd; hw->otg_conf.dm_pulldown = vals->dm_pd;
hw->otg_conf.pad_pull_override = 1; 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 * @brief Set the USB FSLS PHY's signal test values
* *
* @param hw Start address of the USB Wrap registers * @param hw Start address of the USB Wrap registers
* @param oen Output Enable (active low) signal * @param vals Test values to set
* @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, 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)
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; usb_wrap_test_conf_reg_t test_conf;
test_conf.val = hw->test_conf.val; test_conf.val = hw->test_conf.val;
test_conf.test_usb_wrap_oe = oen; test_conf.test_usb_wrap_oe = vals->tx_enable_n;
test_conf.test_tx_dp = tx_dp; test_conf.test_tx_dp = vals->tx_dp;
test_conf.test_tx_dm = tx_dm; test_conf.test_tx_dm = vals->tx_dm;
test_conf.test_rx_rcv = rx_rcv; test_conf.test_rx_rcv = vals->rx_rcv;
test_conf.test_rx_dp = rx_dp; test_conf.test_rx_dp = vals->rx_dp;
test_conf.test_rx_dm = rx_dm; test_conf.test_rx_dm = vals->rx_dm;
hw->test_conf.val = test_conf.val; hw->test_conf.val = test_conf.val;
} }
@@ -241,7 +233,7 @@ FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
SYSTEM.perip_rst_en0.usb_rst = 0; SYSTEM.perip_rst_en0.usb_rst = 0;
} }
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way // 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__) #define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus #ifdef __cplusplus

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

@@ -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
*/ */
@@ -7,82 +7,89 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include "usb_dwc_types.h"
#include "usb_phy_types.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#if SOC_USB_OTG_SUPPORTED #if SOC_USB_OTG_SUPPORTED
#include "soc/usb_wrap_struct.h" #include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_ll.h"
#endif #endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED #include "hal/usb_wrap_types.h"
#include "soc/usb_serial_jtag_struct.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#if SOC_USB_OTG_SUPPORTED #if SOC_USB_OTG_SUPPORTED
/**
* Context that should be maintained by both the driver and the HAL
*/
/**
* @brief HAL context type of USB WRAP driver
*/
typedef struct { typedef struct {
usb_wrap_dev_t *wrap_dev; /**< Pointer to base address of USB Wrapper registers */ usb_wrap_dev_t *dev;
#if SOC_USB_SERIAL_JTAG_SUPPORTED } usb_wrap_hal_context_t;
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 * @brief Initialize the USB WRAP HAL driver
* *
* @param hal Context of the HAL layer * @param hal USB WRAP HAL context
*/ */
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal); 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 Configure internal/external PHY for USB_OTG * @brief Enables and sets override of pull up/down resistors
* *
* @param hal Context of the HAL layer * @param hal USB WRAP HAL context
* @param phy_target USB PHY target * @param vals Override values
*/ */
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target); static inline void usb_wrap_hal_phy_enable_pull_override(usb_wrap_hal_context_t *hal, const usb_wrap_pull_override_vals_t *vals)
{
#if SOC_USB_SERIAL_JTAG_SUPPORTED usb_wrap_ll_phy_enable_pull_override(hal->dev, vals);
/** }
* @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 * @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 hal USB WRAP HAL context
* @param speed USB speed * @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 mimick host-device disconnection * @brief Set the USB FSLS PHY's signal test values
* *
* @param hal Context of the HAL layer * @param hal USB WRAP HAL context
* @param disconn Whether to disconnect * @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 #endif // SOC_USB_OTG_SUPPORTED
#ifdef __cplusplus #ifdef __cplusplus
} }

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

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

@@ -5,77 +5,25 @@
*/ */
#include "soc/soc_caps.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_ll.h"
#include "hal/usb_wrap_hal.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; hal->dev = &USB_WRAP;
#if SOC_USB_SERIAL_JTAG_SUPPORTED #if !USB_WRAP_LL_EXT_PHY_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG; usb_wrap_ll_phy_set_defaults(hal->dev);
#endif #endif
} }
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) #if USB_WRAP_LL_EXT_PHY_SUPPORTED
void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external)
{ {
if (phy_target == USB_PHY_TARGET_EXT) { if (external) {
usb_wrap_ll_phy_enable_external(hal->wrap_dev, true); usb_wrap_ll_phy_enable_external(hal->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 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_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)
{
// 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);
} else { } else {
// FS: dp_pu = 1 usb_wrap_ll_phy_enable_external(hal->dev, false);
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, true, false, false, false); usb_wrap_ll_phy_enable_pad(hal->dev, true);
}
}
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool 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);
} }
} }
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED

View File

@@ -0,0 +1,132 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
struct {
/** clk_gate_rx : R/W; bitpos: [0]; default 2'b0;
* Clock Gating Control Signal for Rx.
* 2'b0 Lower power consumption
* 2'b1 Lowest power consumption mode
* 2'b2 Normal power consumption mode
*/
uint32_t clk_gate_rx:2;
/** clk_gate_tx : R/W; bitpos: [2]; default: 1'b0;
* Clock Gating Control Signal for Rx.
* 1'b0 Low power consumption mode
* 1'b1 Normal power consumption mode
*/
uint32_t clk_gate_tx:1;
/** adj_res_fs : Reserved; bitpos: [3]; default: 0;
* Fine tune the 45ohm termination resistor (FS)
* Reserved
*/
uint32_t adj_res_fs:2;
/** adj_res_hs : R/W; bitpos: [5]; default: 3'b100;
* Fine tune the 45ohm termination resistor (HS)
* 3'b000 40 Ohm
* 3'b100 45 Ohm
* 3'b110 50 Ohm
*/
uint32_t adj_res_hs:3;
uint32_t reserved_8:24;
};
uint32_t val;
} usb_utmi_fc_00_reg_t;
typedef union {
struct {
/** adj_vref_sq : R/W; bitpos: [0]; default: 4'b0010;
* Squelch detection threshold voltage control bits
* 4'b0000 92 mV
* 4'b0010 124 mV
* 4'b0011 152 mV
*/
uint32_t adj_vref_sq:4;
/** adj_pw_hs : R/W; bitpos: [4]; default: 4'b1111;
* Super power saving with reduced output swing mode control bits (for HS mode only)
* 4'b0001 100 mV output swing
* 4'b0011 200 mV output swing
* 4'b0111 300 mV output swing
* 4'b1111 400 mV output swing
*/
uint32_t adj_pw_hs:4;
uint32_t reserved_8:24;
};
uint32_t val;
} usb_utmi_fc_01_reg_t;
typedef union {
struct {
/** adj_iref_res : R/W; bitpos: [0]; default: 4'b0111
* Internal bias current adjustment control bits
* 4'b0000 125 uA
* 4'b0111 100 uA
* 4'b1111 78 uA
*/
uint32_t adj_iref_res:4;
/** adj_vsw_hs : R/W; bitpos: [4]; default: 3'b100
* Output eye shape adjustment control bits
* 3'b000 320 mV
* 3'b100 400 mV
* 3'b111 460 mV
*/
uint32_t adj_vsw_hs:3;
uint32_t reserved_7:25;
};
uint32_t val;
} usb_utmi_fc_02_reg_t;
typedef union {
struct {
/** adj_pll : R/W; bitpos: [0]; default: 4'b0101
* PLL adjustment signal
*/
uint32_t adj_pll:4;
/** adj_osc : R/W; bitpos: [4]; default: 2'b00
* PLL adjustment signal
*/
uint32_t adj_osc:2;
uint32_t reserved_6:26;
};
uint32_t val;
} usb_utmi_fc_03_reg_t;
typedef union {
struct {
/** reserved_out5 : R/W; bitpos: [0]; default: 8'b0
* RESERVED_OUT5
*/
uint32_t reserved_out5:8;
uint32_t reserved_8:24;
};
uint32_t val;
} usb_utmi_fc_04_reg_t;
typedef struct usb_utmi_dev_t {
volatile usb_utmi_fc_00_reg_t fc_00;
volatile usb_utmi_fc_01_reg_t fc_01;
volatile usb_utmi_fc_02_reg_t fc_02;
volatile usb_utmi_fc_03_reg_t fc_03;
usb_utmi_fc_04_reg_t fc_04;
} usb_utmi_dev_t;
extern usb_utmi_dev_t USB_UTMI;
#ifndef __cplusplus
_Static_assert(sizeof(usb_utmi_dev_t) == 0x14, "Invalid size of usb_utmi_dev_t structure");
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/** /**
* 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
*/ */
@@ -94,7 +94,10 @@ typedef union {
* Force phy clock always on. * Force phy clock always on.
*/ */
uint32_t phy_clk_force_on:1; uint32_t phy_clk_force_on:1;
uint32_t reserved_21:1; /** phy_tx_edge_sel : R/W; bitpos: [21]; default: 0;
* Select PHY tx signal output clock edge.1'b0: negedge;1'b1: posedge.
*/
uint32_t phy_tx_edge_sel:1;
/** dfifo_force_pu : R/W; bitpos: [22]; default: 0; /** dfifo_force_pu : R/W; bitpos: [22]; default: 0;
* Disable the dfifo to go into low power mode. The data in dfifo will not lost. * Disable the dfifo to go into low power mode. The data in dfifo will not lost.
*/ */
@@ -108,6 +111,44 @@ typedef union {
uint32_t val; uint32_t val;
} usb_wrap_otg_conf_reg_t; } usb_wrap_otg_conf_reg_t;
/** Type of test_conf register
* TEST relative configuration registers.
*/
typedef union {
struct {
/** test_enable : R/W; bitpos: [0]; default: 0;
* Enable to test the USB pad.
*/
uint32_t test_enable:1;
/** test_usb_wrap_oe : R/W; bitpos: [1]; default: 0;
* USB pad one in test.
*/
uint32_t test_usb_wrap_oe:1;
/** test_tx_dp : R/W; bitpos: [2]; default: 0;
* USB D+ tx value in test.
*/
uint32_t test_tx_dp:1;
/** test_tx_dm : R/W; bitpos: [3]; default: 0;
* USB D- tx value in test.
*/
uint32_t test_tx_dm:1;
/** test_rx_rcv : RO; bitpos: [4]; default: 0;
* USB differential rx value in test.
*/
uint32_t test_rx_rcv:1;
/** test_rx_dp : RO; bitpos: [5]; default: 0;
* USB D+ rx value in test.
*/
uint32_t test_rx_dp:1;
/** test_rx_dm : RO; bitpos: [6]; default: 0;
* USB D- rx value in test.
*/
uint32_t test_rx_dm:1;
uint32_t reserved_7:25;
};
uint32_t val;
} usb_wrap_test_conf_reg_t;
/** Type of date register /** Type of date register
* Date register. * Date register.
*/ */
@@ -124,7 +165,8 @@ typedef union {
typedef struct usb_wrap_dev_t { typedef struct usb_wrap_dev_t {
volatile usb_wrap_otg_conf_reg_t otg_conf; volatile usb_wrap_otg_conf_reg_t otg_conf;
uint32_t reserved_004[254]; volatile usb_wrap_test_conf_reg_t test_conf;
uint32_t reserved_008[253];
volatile usb_wrap_date_reg_t date; volatile usb_wrap_date_reg_t date;
} usb_wrap_dev_t; } usb_wrap_dev_t;

View File

@@ -108,6 +108,7 @@ PROVIDE ( DMA2D = 0x50088000 );
PROVIDE ( USB_WRAP = 0x50080000 ); PROVIDE ( USB_WRAP = 0x50080000 );
PROVIDE ( USB_DWC_HS = 0x50000000 ); PROVIDE ( USB_DWC_HS = 0x50000000 );
PROVIDE ( USB_DWC_FS = 0x50040000 ); PROVIDE ( USB_DWC_FS = 0x50040000 );
PROVIDE ( USB_UTMI = 0x5009C000 );
PROVIDE ( EMAC_MAC = 0x50098000 ); PROVIDE ( EMAC_MAC = 0x50098000 );
PROVIDE ( EMAC_DMA = 0x50099000 ); PROVIDE ( EMAC_DMA = 0x50099000 );

View File

@@ -13,7 +13,7 @@
#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_wrap_hal.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 "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.
@@ -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;
} }
@@ -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_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, false, false, false, false); usb_wrap_hal_phy_disable_pull_override(&handle->wrap_hal);
usb_wrap_ll_phy_enable_pad(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);