feat(hal/usb): Update USB WRAP and USJ LL, add missing ESP32-P4 LL

This commit updates updates the LLs of USB WRAP and USJ as follows:

- Added missing 'usb_wrap_ll.h' and 'usb_serial_jtag_ll.h' for the ESP32-P4
- Added LL cap macros to distinguish feature differences between the LLs of
  different targets:
    - '..._LL_EXT_PHY_SUPPORTED' indicates whether the USB WRAP/USJ supports
      routing to an external FSLS PHY.
    - '..._LL_SWAP_PHY_SUPPORTED' indicates whether the USB WRAP/USJ supports
      swapping between multiple internal FSLS PHYs.
- Tidied up some RCC LL functions and their callers.
- Added 'usb_wrap_types.h' and 'usb_serial_jtag_types.h' to provide types used
  in LLs.
- Fixed some spelling/naming issues as part of code-spell pre-commit
pull/13550/head
Darian Leung 2024-04-02 19:55:44 +08:00
rodzic 84ba2ef2e8
commit 023eae4f0b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 8AC9127B487AA4EF
18 zmienionych plików z 838 dodań i 193 usunięć

Wyświetl plik

@ -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);
// Configure PHY
#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED
usb_serial_jtag_ll_phy_enable_external(false); // Use internal PHY
usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads
#else // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED
usb_serial_jtag_ll_phy_set_defaults(); // External PHY not supported. Set default values.
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY |
USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);

Wyświetl plik

@ -246,9 +246,12 @@ __attribute__((weak)) void esp_perip_clk_init(void)
SYSTEM_WIFI_CLK_UNUSED_BIT12;
#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
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
}

Wyświetl plik

@ -263,6 +263,9 @@ __attribute__((weak)) void esp_perip_clk_init(void)
SYSTEM_WIFI_CLK_SDIO_HOST_EN;
#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
usb_serial_jtag_ll_phy_enable_pad(false);
usb_serial_jtag_ll_enable_bus_clock(false);

Wyświetl plik

@ -4,7 +4,7 @@ set(srcs "hal_utils.c")
set(includes "platform_port/include")
# 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")
list(APPEND includes "${target}/include")
endif()
@ -257,10 +257,9 @@ if(NOT BOOTLOADER_BUILD)
endif()
if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs "usb_dwc_hal.c")
if(NOT ${target} STREQUAL "esp32p4")
list(APPEND srcs "usb_wrap_hal.c")
endif()
list(APPEND srcs
"usb_dwc_hal.c"
"usb_wrap_hal.c")
endif()
if(${target} STREQUAL "esp32")

Wyświetl plik

@ -4,23 +4,18 @@
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer of the USB-serial-jtag controller
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h"
#include "soc/system_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- Macros & Types ----------------------------- */
//The in and out endpoints are this long.
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
// Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging
@ -34,6 +29,11 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
@ -125,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer.
*
* @param buf The data buffer.
* @param wr_len The data length needs to be writen.
* @param wr_len The data length needs to be written.
*
* @return Amount of bytes actually written. May be less than wr_len.
*/
@ -182,13 +182,18 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY
* @brief Sets PHY defaults
*
* @param enable Enables external PHY, internal otherwise
* Some PHY register fields/features of the USJ are redundant on the ESP32-C3.
* This function those fields are set to the appropriate default values.
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{
USB_SERIAL_JTAG.conf0.phy_sel = enable;
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
}
/**
@ -231,17 +236,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void)
/**
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param dp_pu Enable D+ pullup
* @param dm_pu Enable D- pullup
* @param dp_pd Enable D+ pulldown
* @param dm_pd Enable D- pulldown
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals)
{
USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd;
USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1;
}
@ -286,19 +288,19 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable)
/* ----------------------------- RCC Functions ----------------------------- */
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USJ module
*/
FORCE_INLINE_ATTR void _usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
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_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)
{
@ -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__)
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{
return (SYSTEM.perip_clk_en0.reg_usb_device_clk_en && !SYSTEM.perip_rst_en0.reg_usb_device_rst);
}
// 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
}

Wyświetl plik

@ -4,23 +4,18 @@
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer of the USB-serial-jtag controller
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/pcr_struct.h"
#include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- Macros & Types ----------------------------- */
//The in and out endpoints are this long.
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
// Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging
@ -34,6 +29,11 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
@ -125,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer.
*
* @param buf The data buffer.
* @param wr_len The data length needs to be writen.
* @param wr_len The data length needs to be written.
*
* @return Amount of bytes actually written. May be less than wr_len.
*/
@ -195,13 +195,18 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY
* @brief Sets PHY defaults
*
* @param enable Enables external PHY, internal otherwise
* Some PHY register fields/features of the USJ are redundant on the ESP32-C6.
* This function those fields are set to the appropriate default values.
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{
USB_SERIAL_JTAG.conf0.phy_sel = enable;
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
}
/**
@ -244,17 +249,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void)
/**
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param dp_pu Enable D+ pullup
* @param dm_pu Enable D- pullup
* @param dp_pd Enable D+ pulldown
* @param dm_pd Enable D- pulldown
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals)
{
USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd;
USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1;
}
@ -299,8 +301,8 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable)
/* ----------------------------- RCC Functions ----------------------------- */
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{
@ -308,7 +310,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
}
/**
* @brief Reset the usb serial jtag module
* @brief Reset the USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
@ -317,9 +319,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
}
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{

Wyświetl plik

@ -4,23 +4,18 @@
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer of the USB-serial-jtag controller
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/pcr_struct.h"
#include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- Macros & Types ----------------------------- */
//The in and out endpoints are this long.
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
// Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging
@ -34,6 +29,11 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
@ -125,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer.
*
* @param buf The data buffer.
* @param wr_len The data length needs to be writen.
* @param wr_len The data length needs to be written.
*
* @return Amount of bytes actually written. May be less than wr_len.
*/
@ -195,13 +195,18 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY
* @brief Sets PHY defaults
*
* @param enable Enables external PHY, internal otherwise
* Some PHY register fields/features of the USJ are redundant on the ESP32-H2.
* This function those fields are set to the appropriate default values.
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{
USB_SERIAL_JTAG.conf0.phy_sel = enable;
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
}
/**
@ -244,17 +249,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void)
/**
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param dp_pu Enable D+ pullup
* @param dm_pu Enable D- pullup
* @param dp_pd Enable D+ pulldown
* @param dm_pd Enable D- pulldown
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals)
{
USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd;
USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1;
}
@ -299,8 +301,8 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable)
/* ----------------------------- RCC Functions ----------------------------- */
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{
@ -308,7 +310,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
}
/**
* @brief Reset the usb serial jtag module
* @brief Reset the USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
@ -317,9 +319,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
}
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -11,6 +11,12 @@
#include "soc/soc.h"
#include "soc/system_reg.h"
#include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_types.h"
/* ----------------------------- Macros & Types ----------------------------- */
#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
#ifdef __cplusplus
extern "C" {
@ -96,17 +102,14 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw)
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param hw Start address of the USB Wrap registers
* @param dp_pu Enable D+ pullup
* @param dm_pu Enable D- pullup
* @param dp_pd Enable D+ pulldown
* @param dm_pd Enable D- pulldown
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd)
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals)
{
hw->otg_conf.dp_pullup = dp_pu;
hw->otg_conf.dp_pulldown = dp_pd;
hw->otg_conf.dm_pullup = dm_pu;
hw->otg_conf.dm_pulldown = dm_pd;
hw->otg_conf.dp_pullup = vals->dp_pu;
hw->otg_conf.dp_pulldown = vals->dp_pd;
hw->otg_conf.dm_pullup = vals->dm_pu;
hw->otg_conf.dm_pulldown = vals->dm_pd;
hw->otg_conf.pad_pull_override = 1;
}
@ -181,30 +184,19 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool
* @brief Set the USB FSLS PHY's signal test values
*
* @param hw Start address of the USB Wrap registers
* @param oen Output Enable (active low) signal
* @param tx_dp TX D+
* @param tx_dm TX D-
* @param rx_dp RX D+
* @param rx_dm RX D-
* @param rx_rcv RX RCV
* @param vals Test values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw,
bool oen,
bool tx_dp,
bool tx_dm,
bool rx_dp,
bool rx_dm,
bool rx_rcv)
FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals)
{
usb_wrap_test_conf_reg_t test_conf;
test_conf.val = hw->test_conf.val;
test_conf.test_usb_wrap_oe = oen;
test_conf.test_tx_dp = tx_dp;
test_conf.test_tx_dm = tx_dm;
test_conf.test_rx_rcv = rx_rcv;
test_conf.test_rx_dp = rx_dp;
test_conf.test_rx_dm = rx_dm;
test_conf.test_usb_wrap_oe = vals->tx_enable_n;
test_conf.test_tx_dp = vals->tx_dp;
test_conf.test_tx_dm = vals->tx_dm;
test_conf.test_rx_rcv = vals->rx_rcv;
test_conf.test_rx_dp = vals->rx_dp;
test_conf.test_rx_dm = vals->rx_dm;
hw->test_conf.val = test_conf.val;
}
@ -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);
}
// 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__)
#ifdef __cplusplus

Wyświetl plik

@ -4,24 +4,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer of the USB-serial-jtag controller
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/system_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/usb_serial_jtag_reg.h"
#include "soc/usb_serial_jtag_struct.h"
#include "hal/usb_serial_jtag_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- Macros & Types ----------------------------- */
//The in and out endpoints are this long.
#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask
#define USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
// Define USB_SERIAL_JTAG interrupts
// Note the hardware has more interrupts, but they're only useful for debugging
@ -35,6 +31,11 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
@ -126,7 +127,7 @@ static inline uint32_t usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_
* is room in the buffer.
*
* @param buf The data buffer.
* @param wr_len The data length needs to be writen.
* @param wr_len The data length needs to be written.
*
* @return Amount of bytes actually written. May be less than wr_len.
*/
@ -253,17 +254,14 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void)
/**
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param dp_pu Enable D+ pullup
* @param dm_pu Enable D- pullup
* @param dp_pd Enable D+ pulldown
* @param dm_pd Enable D- pulldown
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals)
{
USB_SERIAL_JTAG.conf0.dp_pullup = dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = dm_pd;
USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu;
USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd;
USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu;
USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd;
USB_SERIAL_JTAG.conf0.pad_pull_override = 1;
}
@ -318,19 +316,19 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_tx_edge(bool clk_neg_edge)
/* ----------------------------- RCC Functions ----------------------------- */
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USJ module
*/
FORCE_INLINE_ATTR void _usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
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_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)
{
@ -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__)
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{
return (SYSTEM.perip_clk_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
}
#endif

Wyświetl plik

@ -12,6 +12,12 @@
#include "soc/system_struct.h"
#include "soc/usb_wrap_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "hal/usb_wrap_types.h"
/* ----------------------------- Macros & Types ----------------------------- */
#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
#ifdef __cplusplus
extern "C" {
@ -105,17 +111,14 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw)
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param hw Start address of the USB Wrap registers
* @param dp_pu Enable D+ pullup
* @param dm_pu Enable D- pullup
* @param dp_pd Enable D+ pulldown
* @param dm_pd Enable D- pulldown
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, bool dp_pu, bool dm_pu, bool dp_pd, bool dm_pd)
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals)
{
hw->otg_conf.dp_pullup = dp_pu;
hw->otg_conf.dp_pulldown = dp_pd;
hw->otg_conf.dm_pullup = dm_pu;
hw->otg_conf.dm_pulldown = dm_pd;
hw->otg_conf.dp_pullup = vals->dp_pu;
hw->otg_conf.dp_pulldown = vals->dp_pd;
hw->otg_conf.dm_pullup = vals->dm_pu;
hw->otg_conf.dm_pulldown = vals->dm_pd;
hw->otg_conf.pad_pull_override = 1;
}
@ -190,30 +193,19 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool
* @brief Set the USB FSLS PHY's signal test values
*
* @param hw Start address of the USB Wrap registers
* @param oen Output Enable (active low) signal
* @param tx_dp TX D+
* @param tx_dm TX D-
* @param rx_dp RX D+
* @param rx_dm RX D-
* @param rx_rcv RX RCV
* @param vals Test values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw,
bool oen,
bool tx_dp,
bool tx_dm,
bool rx_dp,
bool rx_dm,
bool rx_rcv)
FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals)
{
usb_wrap_test_conf_reg_t test_conf;
test_conf.val = hw->test_conf.val;
test_conf.test_usb_wrap_oe = oen;
test_conf.test_tx_dp = tx_dp;
test_conf.test_tx_dm = tx_dm;
test_conf.test_rx_rcv = rx_rcv;
test_conf.test_rx_dp = rx_dp;
test_conf.test_rx_dm = rx_dm;
test_conf.test_usb_wrap_oe = vals->tx_enable_n;
test_conf.test_tx_dp = vals->tx_dp;
test_conf.test_tx_dm = vals->tx_dm;
test_conf.test_rx_rcv = vals->rx_rcv;
test_conf.test_rx_dp = vals->rx_dp;
test_conf.test_rx_dm = vals->rx_dm;
hw->test_conf.val = test_conf.val;
}
@ -241,7 +233,7 @@ FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
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__)
#ifdef __cplusplus

Wyświetl plik

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

Wyświetl plik

@ -12,6 +12,7 @@
#include "soc/soc_caps.h"
#if SOC_USB_OTG_SUPPORTED
#include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_ll.h"
#endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "soc/usb_serial_jtag_struct.h"
@ -41,6 +42,7 @@ typedef struct {
*/
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal);
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
/**
* @brief Configure internal/external PHY for USB_OTG
*
@ -48,6 +50,7 @@ void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal);
* @param phy_target USB PHY target
*/
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target);
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
#if SOC_USB_SERIAL_JTAG_SUPPORTED
/**
@ -75,7 +78,7 @@ void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal);
void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed);
/**
* @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection
* @brief Enable/Disable test mode for internal PHY to mimic host-device disconnection
*
* @param hal Context of the HAL layer
* @param disconn Whether to disconnect

Wyświetl plik

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

Wyświetl plik

@ -5,7 +5,6 @@
*/
#include "soc/soc_caps.h"
#include "soc/rtc_cntl_struct.h"
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "hal/usb_serial_jtag_ll.h"
#endif
@ -18,8 +17,12 @@ void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal)
#if SOC_USB_SERIAL_JTAG_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG;
#endif
#if !USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_wrap_ll_phy_set_defaults(hal->wrap_dev);
#endif
}
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
@ -29,6 +32,7 @@ void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t
usb_wrap_ll_phy_enable_pad(hal->wrap_dev, true);
}
}
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
#if SOC_USB_SERIAL_JTAG_SUPPORTED
void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
@ -45,7 +49,13 @@ void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_
void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal)
{
// HOST - upstream: dp_pd = 1, dm_pd = 1
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, false, false, true, true);
usb_wrap_pull_override_vals_t vals = {
.dp_pu = false,
.dm_pu = false,
.dp_pd = true,
.dm_pd = true,
};
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals);
}
void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed)
@ -53,10 +63,22 @@ void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy
// DEVICE - downstream
if (speed == USB_PHY_SPEED_LOW) {
// LS: dm_pu = 1
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, false, true, false, false);
usb_wrap_pull_override_vals_t vals = {
.dp_pu = false,
.dm_pu = true,
.dp_pd = false,
.dm_pd = false,
};
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals);
} else {
// FS: dp_pu = 1
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, true, false, false, false);
usb_wrap_pull_override_vals_t vals = {
.dp_pu = true,
.dm_pu = false,
.dm_pd = false,
.dp_pd = false,
};
usb_wrap_ll_phy_enable_pull_override(hal->wrap_dev, &vals);
}
}
@ -64,16 +86,18 @@ void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool d
{
if (disconn) {
/*
We mimick a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will:
We mimic a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will:
A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection.
*/
usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev,
true, // OEN
false, // TX D+
false, // TX D-
false, // RX D+
false, // RX D-
false); // RX RCv
usb_wrap_test_mode_vals_t vals = {
.tx_enable_n = true,
.tx_dp = false,
.tx_dm = false,
.rx_dp = false,
.rx_dm = false,
.rx_rcv = false,
};
usb_wrap_ll_phy_test_mode_set_signals(hal->wrap_dev, &vals);
usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, true);
} else {
usb_wrap_ll_phy_enable_test_mode(hal->wrap_dev, false);

Wyświetl plik

@ -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
*/
@ -94,7 +94,10 @@ typedef union {
* Force phy clock always on.
*/
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;
* 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;
} 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
* Date register.
*/
@ -124,7 +165,8 @@ typedef union {
typedef struct usb_wrap_dev_t {
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;
} usb_wrap_dev_t;

Wyświetl plik

@ -265,7 +265,9 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
usb_fsls_phy_hal_init(&(phy_context->hal_context));
if (config->controller == USB_PHY_CTRL_OTG) {
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_fsls_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT);
#endif
}
#if SOC_USB_SERIAL_JTAG_SUPPORTED
else if (config->controller == USB_PHY_CTRL_SERIAL_JTAG) {
@ -334,7 +336,13 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle)
p_phy_ctrl_obj->external_phy = NULL;
} else {
// Clear pullup and pulldown loads on D+ / D-, and disable the pads
usb_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, false, false, false, false);
usb_wrap_pull_override_vals_t vals = {
.dp_pu = false,
.dm_pu = false,
.dp_pd = false,
.dm_pd = false,
};
usb_wrap_ll_phy_enable_pull_override(handle->hal_context.wrap_dev, &vals);
usb_wrap_ll_phy_enable_pad(handle->hal_context.wrap_dev, false);
p_phy_ctrl_obj->internal_phy = NULL;
}