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

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

See merge request espressif/esp-idf!29791
release/v5.1
morris 2024-05-31 22:30:32 +08:00
commit 8318a2ad44
24 zmienionych plików z 1332 dodań i 653 usunięć

Wyświetl plik

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

Wyświetl plik

@ -9,7 +9,6 @@
#include <stdatomic.h>
#include "esp_log.h"
#include "hal/usb_serial_jtag_ll.h"
#include "hal/usb_fsls_phy_ll.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/ringbuf.h"
@ -176,7 +175,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
usb_fsls_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG);
#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED
usb_serial_jtag_ll_phy_enable_external(false); // Use internal PHY
usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads
#else // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED
usb_serial_jtag_ll_phy_set_defaults(); // External PHY not supported. Set default values.
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY|
USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,7 +22,8 @@ void sleep_console_usj_pad_backup_and_disable(void)
usb_serial_jtag_ll_enable_bus_clock(true);
usb_serial_jtag_ll_reset_register();
}
s_usj_state.usj_pad_enabled = usb_serial_jtag_ll_pad_backup_and_disable();
s_usj_state.usj_pad_enabled = usb_serial_jtag_ll_phy_is_pad_enabled();
usb_serial_jtag_ll_phy_enable_pad(false);
// Disable USJ clock
usb_serial_jtag_ll_enable_bus_clock(false);
}
@ -30,7 +31,7 @@ void sleep_console_usj_pad_backup_and_disable(void)
void sleep_console_usj_pad_restore(void)
{
usb_serial_jtag_ll_enable_bus_clock(true);
usb_serial_jtag_ll_enable_pad(s_usj_state.usj_pad_enabled);
usb_serial_jtag_ll_phy_enable_pad(s_usj_state.usj_pad_enabled);
if (!s_usj_state.usj_clock_enabled) {
usb_serial_jtag_ll_enable_bus_clock(false);
}

Wyświetl plik

@ -179,10 +179,14 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "ds_hal.c")
endif()
if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED)
list(APPEND srcs "usb_serial_jtag_hal.c")
endif()
if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs
"usb_dwc_hal.c"
"usb_fsls_phy_hal.c")
"usb_wrap_hal.c")
endif()
if(${target} STREQUAL "esp32")

Wyświetl plik

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/usb_serial_jtag_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_Serial_JTAG
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;
// Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1)
hw->conf0.pad_pull_override = 0;
// Enable USB D+ pullup
hw->conf0.dp_pullup = 1;
// Enable USB pad function
hw->conf0.usb_pad_enable = 1;
}
#ifdef __cplusplus
}
#endif

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,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
*
@ -123,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer.
*
* @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.
*/
@ -177,34 +179,117 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
USB_SERIAL_JTAG.ep1_conf.wr_done=1;
}
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Disable usb serial jtag pad during light sleep to avoid current leakage
* @brief Sets PHY defaults
*
* @return Initial configuration of usb serial jtag pad enable before light sleep
* Some PHY register fields/features of the USJ are redundant on the ESP32-C3.
* This function those fields are set to the appropriate default values.
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{
bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable;
// Disable USB pad function
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
return pad_enabled;
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
}
/**
* @brief Enable the internal USJ PHY control to D+/D- pad
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param enable_pad Enable the USJ PHY control to D+/D- pad
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable)
{
USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad;
if (enable) {
USB_SERIAL_JTAG.conf0.exchg_pins = 1;
USB_SERIAL_JTAG.conf0.exchg_pins_override = 1;
} else {
USB_SERIAL_JTAG.conf0.exchg_pins_override = 0;
USB_SERIAL_JTAG.conf0.exchg_pins = 0;
}
}
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @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)
{
@ -212,7 +297,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
}
/**
* @brief Reset the usb serial jtag module
* @brief Reset the USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
@ -221,16 +306,15 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
}
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{
return (SYSTEM.perip_clk_en0.reg_usb_device_clk_en && !SYSTEM.perip_rst_en0.reg_usb_device_rst);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/usb_serial_jtag_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_Serial_JTAG
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;
// Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1)
hw->conf0.pad_pull_override = 0;
// Enable USB D+ pullup
hw->conf0.dp_pullup = 1;
// Enable USB pad function
hw->conf0.usb_pad_enable = 1;
}
#ifdef __cplusplus
}
#endif

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,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
*
@ -123,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer.
*
* @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.
*/
@ -177,35 +179,130 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
USB_SERIAL_JTAG.ep1_conf.wr_done=1;
}
/**
* @brief Enable USJ JTAG bridge
*
* If enabled, USJ is disconnected from internal JTAG interface. JTAG interface
* is routed through GPIO matrix instead.
*
* @param enable Enable USJ JTAG bridge
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
{
USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable;
}
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Disable usb serial jtag pad during light sleep to avoid current leakage
* @brief Sets PHY defaults
*
* @return Initial configuration of usb serial jtag pad enable before light sleep
* Some PHY register fields/features of the USJ are redundant on the ESP32-C6.
* This function those fields are set to the appropriate default values.
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{
bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable;
// Disable USB pad function
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
return pad_enabled;
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
}
/**
* @brief Enable the internal USJ PHY control to D+/D- pad
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param enable_pad Enable the USJ PHY control to D+/D- pad
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable)
{
USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad;
if (enable) {
USB_SERIAL_JTAG.conf0.exchg_pins = 1;
USB_SERIAL_JTAG.conf0.exchg_pins_override = 1;
} else {
USB_SERIAL_JTAG.conf0.exchg_pins_override = 0;
USB_SERIAL_JTAG.conf0.exchg_pins = 0;
}
}
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @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)
{
@ -213,7 +310,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
}
/**
* @brief Reset the usb serial jtag module
* @brief Reset the USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
@ -222,9 +319,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
}
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{

Wyświetl plik

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/usb_serial_jtag_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_Serial_JTAG
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;
// Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1)
hw->conf0.pad_pull_override = 0;
// Enable USB D+ pullup
hw->conf0.dp_pullup = 1;
// Enable USB pad function
hw->conf0.usb_pad_enable = 1;
}
#ifdef __cplusplus
}
#endif

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,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_ll_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
*
@ -123,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
* is room in the buffer.
*
* @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.
*/
@ -178,33 +180,129 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
}
/**
* @brief Disable usb serial jtag pad during light sleep to avoid current leakage
* @brief Enable USJ JTAG bridge
*
* @return Initial configuration of usb serial jtag pad enable before light sleep
* If enabled, USJ is disconnected from internal JTAG interface. JTAG interface
* is routed through GPIO matrix instead.
*
* @param enable Enable USJ JTAG bridge
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
{
bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable;
USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable;
}
// Disable USB pad function
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
/* ---------------------------- USB PHY Control ---------------------------- */
return pad_enabled;
/**
* @brief Sets PHY defaults
*
* Some PHY register fields/features of the USJ are redundant on the ESP32-H2.
* This function those fields are set to the appropriate default values.
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void)
{
// External FSLS PHY is not supported
USB_SERIAL_JTAG.conf0.phy_sel = 0;
USB_SERIAL_JTAG.conf0.usb_pad_enable = 1;
}
/**
* @brief Enable the internal USJ PHY control to D+/D- pad
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param enable_pad Enable the USJ PHY control to D+/D- pad
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable)
{
USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad;
if (enable) {
USB_SERIAL_JTAG.conf0.exchg_pins = 1;
USB_SERIAL_JTAG.conf0.exchg_pins_override = 1;
} else {
USB_SERIAL_JTAG.conf0.exchg_pins_override = 0;
USB_SERIAL_JTAG.conf0.exchg_pins = 0;
}
}
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @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)
{
@ -212,7 +310,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
}
/**
* @brief Reset the usb serial jtag module
* @brief Reset the USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
@ -221,9 +319,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
}
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{

Wyświetl plik

@ -1,110 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/system_reg.h"
#include "soc/usb_wrap_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
{
hw->otg_conf.phy_sel = 0;
}
/**
* @brief Configures the external PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
{
//Enable external PHY
hw->otg_conf.phy_sel = 1;
}
/**
* @brief Configures port loads for the internal PHY
*
* @param hw Start address of the USB Wrap registers
* @param dp_pu D+ pullup load
* @param dp_pd D+ pulldown load
* @param dm_pu D- pullup load
* @param dm_pd D- pulldown load
*/
static inline void usb_fsls_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd)
{
usb_wrap_otg_conf_reg_t conf = hw->otg_conf;
conf.pad_pull_override = 1;
conf.dp_pullup = dp_pu;
conf.dp_pulldown = dp_pd;
conf.dm_pullup = dm_pu;
conf.dm_pulldown = dm_pd;
hw->otg_conf = conf;
}
/**
* @brief Enable the internal PHY control to D+/D- pad
* @param hw Start address of the USB Wrap registers
* @param pad_en Enable the PHY control to D+/D- pad
*/
static inline void usb_fsls_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en)
{
hw->otg_conf.pad_enable = pad_en;
}
/**
* @brief Enable the internal PHY's test mode
*
* @param hw Start address of the USB Wrap registers
* @param en Whether to enable the internal PHY's test mode
*/
static inline void usb_fsls_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
{
if (en) {
// Clear USB_WRAP_TEST_CONF_REG
hw->test_conf.val = 0;
// Set USB test pad oen
hw->test_conf.test_usb_wrap_oe = 1;
// Enable USB test mode
hw->test_conf.test_enable = 1;
} else {
hw->test_conf.test_enable = 0;
}
}
/**
* Enable the bus clock for USB Wrap module
* @param clk_en True if enable the clock of USB Wrap module
*/
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
{
REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en);
}
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void)
{
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 1);
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,226 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/system_reg.h"
#include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_types.h"
/* ----------------------------- Macros & Types ----------------------------- */
#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
#ifdef __cplusplus
extern "C" {
#endif
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Enables and sets the override value for the session end signal
*
* @param hw Start address of the USB Wrap registers
* @param sessend Session end override value. True means VBus < 0.2V, false means VBus > 0.8V
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_srp_sessend_override(usb_wrap_dev_t *hw, bool sessend)
{
hw->otg_conf.srp_sessend_value = sessend;
hw->otg_conf.srp_sessend_override = 1;
}
/**
* @brief Disable session end override
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.srp_sessend_override = 0;
}
/**
* @brief Sets whether the USB Wrap's FSLS PHY interface routes to an internal or external PHY
*
* @param hw Start address of the USB Wrap registers
* @param enable Enables external PHY, internal otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable)
{
hw->otg_conf.phy_sel = enable;
}
/**
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param hw Start address of the USB Wrap registers
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable)
{
if (enable) {
hw->otg_conf.exchg_pins = 1;
hw->otg_conf.exchg_pins_override = 1;
} else {
hw->otg_conf.exchg_pins_override = 0;
hw->otg_conf.exchg_pins = 0;
}
}
/**
* @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs
*
* @param hw Start address of the USB Wrap registers
* @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V.
* @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V.
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_vref_override(usb_wrap_dev_t *hw, unsigned int vrefh_step, unsigned int vrefl_step)
{
hw->otg_conf.vrefh = vrefh_step;
hw->otg_conf.vrefl = vrefl_step;
hw->otg_conf.vref_override = 1;
}
/**
* @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.vref_override = 0;
}
/**
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param hw Start address of the USB Wrap registers
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals)
{
hw->otg_conf.dp_pullup = vals->dp_pu;
hw->otg_conf.dp_pulldown = vals->dp_pd;
hw->otg_conf.dm_pullup = vals->dm_pu;
hw->otg_conf.dm_pulldown = vals->dm_pd;
hw->otg_conf.pad_pull_override = 1;
}
/**
* @brief Disable override of USB FSLS PHY pull up/down resistors
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_pull_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.pad_pull_override = 0;
}
/**
* @brief Sets the strength of the pullup resistor
*
* @param hw Start address of the USB Wrap registers
* @param strong True is a ~1.4K pullup, false is a ~2.4K pullup
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_pullup_strength(usb_wrap_dev_t *hw, bool strong)
{
hw->otg_conf.pullup_value = strong;
}
/**
* @brief Check if USB FSLS PHY pads are enabled
*
* @param hw Start address of the USB Wrap registers
* @return True if enabled, false otherwise
*/
FORCE_INLINE_ATTR bool usb_wrap_ll_phy_is_pad_enabled(usb_wrap_dev_t *hw)
{
return hw->otg_conf.pad_enable;
}
/**
* @brief Enable the USB FSLS PHY pads
*
* @param hw Start address of the USB Wrap registers
* @param enable Whether to enable the USB FSLS PHY pads
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pad(usb_wrap_dev_t *hw, bool enable)
{
hw->otg_conf.pad_enable = enable;
}
/**
* @brief Set USB FSLS PHY TX output clock edge
*
* @param hw Start address of the USB Wrap registers
* @param clk_neg_edge True if TX output at negedge, posedge otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_tx_edge(usb_wrap_dev_t *hw, bool clk_neg_edge)
{
hw->otg_conf.phy_tx_edge_sel = clk_neg_edge;
}
/* ------------------------------ USB PHY Test ------------------------------ */
/**
* @brief Enable the USB FSLS PHY's test mode
*
* @param hw Start address of the USB Wrap registers
* @param enable Whether to enable the USB FSLS PHY's test mode
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool enable)
{
hw->test_conf.test_enable = enable;
}
/**
* @brief Set the USB FSLS PHY's signal test values
*
* @param hw Start address of the USB Wrap registers
* @param vals Test values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals)
{
usb_wrap_test_conf_reg_t test_conf;
test_conf.val = hw->test_conf.val;
test_conf.test_usb_wrap_oe = vals->tx_enable_n;
test_conf.test_tx_dp = vals->tx_dp;
test_conf.test_tx_dm = vals->tx_dm;
test_conf.test_rx_rcv = vals->rx_rcv;
test_conf.test_rx_dp = vals->rx_dp;
test_conf.test_rx_dm = vals->rx_dm;
hw->test_conf.val = test_conf.val;
}
/* ----------------------------- RCC Functions ----------------------------- */
/**
* Enable the bus clock for USB Wrap module
* @param clk_en True if enable the clock of USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool clk_en)
{
REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en);
}
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
{
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 1);
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,157 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/system_struct.h"
#include "soc/usb_wrap_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/usb_serial_jtag_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Configures the internal PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
{
// USB_OTG use internal PHY
hw->otg_conf.phy_sel = 0;
// phy_sel is controlled by the following register value
RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1;
// phy_sel=sw_usb_phy_sel=1, USB_OTG is connected with internal PHY
RTCCNTL.usb_conf.sw_usb_phy_sel = 1;
}
/**
* @brief Configures the external PHY for USB_OTG
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
{
// USB_OTG use external PHY
hw->otg_conf.phy_sel = 1;
// phy_sel is controlled by the following register value
RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1;
// phy_sel=sw_usb_phy_sel=0, USB_OTG is connected with external PHY through GPIO Matrix
RTCCNTL.usb_conf.sw_usb_phy_sel = 0;
}
/**
* @brief Configures the internal PHY for USB_Serial_JTAG
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;
// Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1)
hw->conf0.pad_pull_override = 0;
// Enable USB D+ pullup
hw->conf0.dp_pullup = 1;
// Enable USB pad function
hw->conf0.usb_pad_enable = 1;
// phy_sel is controlled by the following register value
RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1;
// phy_sel=sw_usb_phy_sel=0, USB_Serial_JTAG is connected with internal PHY
RTCCNTL.usb_conf.sw_usb_phy_sel = 0;
}
/**
* @brief Configures the external PHY for USB_Serial_JTAG
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_fsls_phy_ll_ext_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use external PHY
hw->conf0.phy_sel = 1;
// phy_sel is controlled by the following register value
RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1;
// phy_sel=sw_usb_phy_sel=1, USB_Serial_JTAG is connected with external PHY
RTCCNTL.usb_conf.sw_usb_phy_sel = 1;
}
/**
* @brief Configures port loads for the internal PHY
*
* @param hw Start address of the USB Wrap registers
* @param dp_pu D+ pullup load
* @param dp_pd D+ pulldown load
* @param dm_pu D- pullup load
* @param dm_pd D- pulldown load
*/
static inline void usb_fsls_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd)
{
usb_wrap_otg_conf_reg_t conf = hw->otg_conf;
conf.pad_pull_override = 1;
conf.dp_pullup = dp_pu;
conf.dp_pulldown = dp_pd;
conf.dm_pullup = dm_pu;
conf.dm_pulldown = dm_pd;
hw->otg_conf = conf;
}
/**
* @brief Enable the internal PHY control to D+/D- pad
* @param hw Start address of the USB Wrap registers
* @param pad_en Enable the PHY control to D+/D- pad
*/
static inline void usb_fsls_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en)
{
hw->otg_conf.pad_enable = pad_en;
}
/**
* @brief Enable the internal PHY's test mode
*
* @param hw Start address of the USB Wrap registers
* @param en Whether to enable the internal PHY's test mode
*/
static inline void usb_fsls_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
{
if (en) {
// Clear USB_WRAP_TEST_CONF_REG
hw->test_conf.val = 0;
// Set USB test pad oen
hw->test_conf.test_usb_wrap_oe = 1;
// Enable USB test mode
hw->test_conf.test_enable = 1;
} else {
hw->test_conf.test_enable = 0;
}
}
/**
* Enable the bus clock for USB Wrap module
* @param clk_en True if enable the clock of USB Wrap module
*/
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
{
SYSTEM.perip_clk_en0.usb_clk_en = clk_en;
}
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void)
{
SYSTEM.perip_rst_en0.usb_rst = 1;
SYSTEM.perip_rst_en0.usb_rst = 0;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -4,23 +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
@ -34,6 +31,13 @@ typedef enum {
USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10),
} usb_serial_jtag_intr_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------- USJ Peripheral ----------------------------- */
/**
* @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask.
*
@ -123,7 +127,7 @@ static inline uint32_t usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_
* is room in the buffer.
*
* @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.
*/
@ -178,33 +182,142 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void)
}
/**
* @brief Disable usb serial jtag pad during light sleep to avoid current leakage
* @brief Enable USJ JTAG bridge
*
* @return Initial configuration of usb serial jtag pad enable before light sleep
* If enabled, USJ is disconnected from internal JTAG interface. JTAG interface
* is routed through GPIO matrix instead.
*
* @param enable Enable USJ JTAG bridge
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_pad_backup_and_disable(void)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable)
{
bool pad_enabled = USB_SERIAL_JTAG.conf0.usb_pad_enable;
USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable;
}
// Disable USB pad function
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
/* ---------------------------- USB PHY Control ---------------------------- */
return pad_enabled;
/**
* @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY
*
* @param enable Enables external PHY, internal otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable)
{
USB_SERIAL_JTAG.conf0.phy_sel = enable;
// Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY
RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1;
/*
For 'sw_usb_phy_sel':
0 - Internal USB FSLS PHY is mapped to the USJ. USB Wrap mapped to external PHY
1 - Internal USB FSLS PHY is mapped to the USB Wrap. USJ mapped to external PHY
*/
RTCCNTL.usb_conf.sw_usb_phy_sel = enable;
}
/**
* @brief Enable the internal USJ PHY control to D+/D- pad
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param enable_pad Enable the USJ PHY control to D+/D- pad
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_pad(bool enable_pad)
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable)
{
USB_SERIAL_JTAG.conf0.usb_pad_enable = enable_pad;
if (enable) {
USB_SERIAL_JTAG.conf0.exchg_pins = 1;
USB_SERIAL_JTAG.conf0.exchg_pins_override = 1;
} else {
USB_SERIAL_JTAG.conf0.exchg_pins_override = 0;
USB_SERIAL_JTAG.conf0.exchg_pins = 0;
}
}
/**
* @brief Enable the bus clock for USB Serial_JTAG module
* @param clk_en True if enable the clock of USB Serial_JTAG module
* @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;
}
/**
* @brief Set USB FSLS PHY TX output clock edge
*
* @param clk_neg_edge True if TX output at negedge, posedge otherwise
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_tx_edge(bool clk_neg_edge)
{
USB_SERIAL_JTAG.conf0.phy_tx_edge_sel = clk_neg_edge;
}
/* ----------------------------- RCC Functions ----------------------------- */
/**
* @brief Enable the bus clock for USJ module
* @param clk_en True if enable the clock of USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
{
@ -212,7 +325,7 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en)
}
/**
* @brief Reset the usb serial jtag module
* @brief Reset the USJ module
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
{
@ -221,9 +334,9 @@ FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void)
}
/**
* Get the enable status USB Serial_JTAG module
* Get the enable status of the USJ module
*
* @return Return true if USB Serial_JTAG module is enabled
* @return Return true if USJ module is enabled
*/
FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
{

Wyświetl plik

@ -0,0 +1,235 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/system_struct.h"
#include "soc/usb_wrap_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "hal/usb_wrap_types.h"
/* ----------------------------- Macros & Types ----------------------------- */
#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY
#ifdef __cplusplus
extern "C" {
#endif
/* ---------------------------- USB PHY Control ---------------------------- */
/**
* @brief Enables and sets the override value for the session end signal
*
* @param hw Start address of the USB Wrap registers
* @param sessend Session end override value. True means VBus < 0.2V, false means VBus > 0.8V
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_srp_sessend_override(usb_wrap_dev_t *hw, bool sessend)
{
hw->otg_conf.srp_sessend_value = sessend;
hw->otg_conf.srp_sessend_override = 1;
}
/**
* @brief Disable session end override
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.srp_sessend_override = 0;
}
/**
* @brief Sets whether the USB Wrap's FSLS PHY interface routes to an internal or external PHY
*
* @param hw Start address of the USB Wrap registers
* @param enable Enables external PHY, internal otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable)
{
hw->otg_conf.phy_sel = enable;
// Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY
RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1;
/*
For 'sw_usb_phy_sel':
0 - Internal USB FSLS PHY is mapped to the USJ. USB Wrap mapped to external PHY
1 - Internal USB FSLS PHY is mapped to the USB Wrap. USJ mapped to external PHY
*/
RTCCNTL.usb_conf.sw_usb_phy_sel = !enable;
}
/**
* @brief Enables/disables exchanging of the D+/D- pins USB PHY
*
* @param hw Start address of the USB Wrap registers
* @param enable Enables pin exchange, disabled otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable)
{
if (enable) {
hw->otg_conf.exchg_pins = 1;
hw->otg_conf.exchg_pins_override = 1;
} else {
hw->otg_conf.exchg_pins_override = 0;
hw->otg_conf.exchg_pins = 0;
}
}
/**
* @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs
*
* @param hw Start address of the USB Wrap registers
* @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V.
* @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V.
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_vref_override(usb_wrap_dev_t *hw, unsigned int vrefh_step, unsigned int vrefl_step)
{
hw->otg_conf.vrefh = vrefh_step;
hw->otg_conf.vrefl = vrefl_step;
hw->otg_conf.vref_override = 1;
}
/**
* @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.vref_override = 0;
}
/**
* @brief Enable override of USB FSLS PHY's pull up/down resistors
*
* @param hw Start address of the USB Wrap registers
* @param vals Override values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals)
{
hw->otg_conf.dp_pullup = vals->dp_pu;
hw->otg_conf.dp_pulldown = vals->dp_pd;
hw->otg_conf.dm_pullup = vals->dm_pu;
hw->otg_conf.dm_pulldown = vals->dm_pd;
hw->otg_conf.pad_pull_override = 1;
}
/**
* @brief Disable override of USB FSLS PHY pull up/down resistors
*
* @param hw Start address of the USB Wrap registers
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_pull_override(usb_wrap_dev_t *hw)
{
hw->otg_conf.pad_pull_override = 0;
}
/**
* @brief Sets the strength of the pullup resistor
*
* @param hw Start address of the USB Wrap registers
* @param strong True is a ~1.4K pullup, false is a ~2.4K pullup
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_pullup_strength(usb_wrap_dev_t *hw, bool strong)
{
hw->otg_conf.pullup_value = strong;
}
/**
* @brief Check if USB FSLS PHY pads are enabled
*
* @param hw Start address of the USB Wrap registers
* @return True if enabled, false otherwise
*/
FORCE_INLINE_ATTR bool usb_wrap_ll_phy_is_pad_enabled(usb_wrap_dev_t *hw)
{
return hw->otg_conf.pad_enable;
}
/**
* @brief Enable the USB FSLS PHY pads
*
* @param hw Start address of the USB Wrap registers
* @param enable Whether to enable the USB FSLS PHY pads
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pad(usb_wrap_dev_t *hw, bool enable)
{
hw->otg_conf.pad_enable = enable;
}
/**
* @brief Set USB FSLS PHY TX output clock edge
*
* @param hw Start address of the USB Wrap registers
* @param clk_neg_edge True if TX output at negedge, posedge otherwise
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_tx_edge(usb_wrap_dev_t *hw, bool clk_neg_edge)
{
hw->otg_conf.phy_tx_edge_sel = clk_neg_edge;
}
/* ------------------------------ USB PHY Test ------------------------------ */
/**
* @brief Enable the USB FSLS PHY's test mode
*
* @param hw Start address of the USB Wrap registers
* @param enable Whether to enable the USB FSLS PHY's test mode
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool enable)
{
hw->test_conf.test_enable = enable;
}
/**
* @brief Set the USB FSLS PHY's signal test values
*
* @param hw Start address of the USB Wrap registers
* @param vals Test values to set
*/
FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals)
{
usb_wrap_test_conf_reg_t test_conf;
test_conf.val = hw->test_conf.val;
test_conf.test_usb_wrap_oe = vals->tx_enable_n;
test_conf.test_tx_dp = vals->tx_dp;
test_conf.test_tx_dm = vals->tx_dm;
test_conf.test_rx_rcv = vals->rx_rcv;
test_conf.test_rx_dp = vals->rx_dp;
test_conf.test_rx_dm = vals->rx_dm;
hw->test_conf.val = test_conf.val;
}
/* ----------------------------- RCC Functions ----------------------------- */
/**
* Enable the bus clock for USB Wrap module
* @param clk_en True if enable the clock of USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool clk_en)
{
SYSTEM.perip_clk_en0.usb_clk_en = clk_en;
}
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
{
SYSTEM.perip_rst_en0.usb_rst = 1;
SYSTEM.perip_rst_en0.usb_rst = 0;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,82 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "usb_dwc_types.h"
#include "usb_phy_types.h"
#include "soc/soc_caps.h"
#include "soc/usb_wrap_struct.h"
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "soc/usb_serial_jtag_struct.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* Context that should be maintained by both the driver and the HAL
*/
typedef struct {
usb_wrap_dev_t *wrap_dev; /**< Pointer to base address of USB Wrapper registers */
#if SOC_USB_SERIAL_JTAG_SUPPORTED
usb_serial_jtag_dev_t *jtag_dev; /**< Pointer to base address of USB Serial JTAG registers */
#endif
} usb_fsls_phy_hal_context_t;
/**
* @brief Init the USB PHY hal. This function should be called first before other hal layer function is called
*
* @param hal Context of the HAL layer
*/
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal);
/**
* @brief Configure internal/external PHY for USB_OTG
*
* @param hal Context of the HAL layer
* @param phy_target USB PHY target
*/
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target);
#if SOC_USB_SERIAL_JTAG_SUPPORTED
/**
* @brief Configure internal/external PHY for USB_Serial_JTAG
*
* @param hal Context of the HAL layer
* @param phy_target USB PHY target
*/
void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target);
#endif
/**
* @brief Configure pullup/pulldown loads for the D+/D- as a host
*
* @param hal Context of the HAL layer
*/
void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal);
/**
* @brief Configure pullup/pulldown loads for the D+/D- as a device
*
* @param hal Context of the HAL layer
* @param speed USB speed
*/
void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed);
/**
* @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection
*
* @param hal Context of the HAL layer
* @param disconn Whether to disconnect
*/
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn);
#ifdef __cplusplus
}
#endif

Wyświetl plik

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

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

@ -0,0 +1,96 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "soc/soc_caps.h"
#if SOC_USB_OTG_SUPPORTED
#include "soc/usb_wrap_struct.h"
#include "hal/usb_wrap_ll.h"
#endif
#include "hal/usb_wrap_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_USB_OTG_SUPPORTED
/**
* @brief HAL context type of USB WRAP driver
*/
typedef struct {
usb_wrap_dev_t *dev;
} usb_wrap_hal_context_t;
/**
* @brief Initialize the USB WRAP HAL driver
*
* @param hal USB WRAP HAL context
*/
void usb_wrap_hal_init(usb_wrap_hal_context_t *hal);
/* ---------------------------- USB PHY Control ---------------------------- */
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
/**
* @brief Configure whether USB WRAP is routed to internal/external FSLS PHY
*
* @param hal USB WRAP HAL context
* @param external True if external, False if internal
*/
void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external);
#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED
/**
* @brief Enables and sets override of pull up/down resistors
*
* @param hal USB WRAP HAL context
* @param vals Override values
*/
static inline void usb_wrap_hal_phy_enable_pull_override(usb_wrap_hal_context_t *hal, const usb_wrap_pull_override_vals_t *vals)
{
usb_wrap_ll_phy_enable_pull_override(hal->dev, vals);
}
/**
* @brief Disables pull up/down resistor override
*
* @param hal USB WRAP HAL context
*/
static inline void usb_wrap_hal_phy_disable_pull_override(usb_wrap_hal_context_t *hal)
{
usb_wrap_ll_phy_disable_pull_override(hal->dev);
}
/**
* @brief Enables/disables the USB FSLS PHY's test mode
*
* @param hal USB WRAP HAL context
* @param enable Whether to enable test mode
*/
static inline void usb_wrap_hal_phy_enable_test_mode(usb_wrap_hal_context_t *hal, bool enable)
{
usb_wrap_ll_phy_enable_test_mode(hal->dev, enable);
}
/**
* @brief Set the USB FSLS PHY's signal test values
*
* @param hal USB WRAP HAL context
* @param vals Test values
*/
static inline void usb_wrap_hal_phy_test_mode_set_signals(usb_wrap_hal_context_t *hal, const usb_wrap_test_mode_vals_t *vals)
{
usb_wrap_ll_phy_test_mode_set_signals(hal->dev, vals);
}
#endif // SOC_USB_OTG_SUPPORTED
#ifdef __cplusplus
}
#endif

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

@ -1,64 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/usb_fsls_phy_ll.h"
#include "hal/usb_fsls_phy_hal.h"
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal)
{
hal->wrap_dev = &USB_WRAP;
#if SOC_USB_SERIAL_JTAG_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG;
#endif
}
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_fsls_phy_ll_ext_otg_enable(hal->wrap_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_fsls_phy_ll_usb_wrap_pad_enable(hal->wrap_dev, true);
usb_fsls_phy_ll_int_otg_enable(hal->wrap_dev);
}
}
#if SOC_USB_SERIAL_JTAG_SUPPORTED
void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_fsls_phy_ll_ext_jtag_enable(hal->jtag_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_fsls_phy_ll_int_jtag_enable(hal->jtag_dev);
}
}
#endif
void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal)
{
// HOST - upstream: dp_pd = 1, dm_pd = 1
usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true);
}
void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed)
{
// DEVICE - downstream
if (speed == USB_PHY_SPEED_LOW) {
// LS: dm_pu = 1
usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false);
} else {
// FS: dp_pu = 1
usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, true, false, false, false);
}
}
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn)
{
/*
We mimick a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will:
A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection.
*/
usb_fsls_phy_ll_int_enable_test_mode(hal->wrap_dev, disconn);
}

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -12,8 +12,8 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/usb_phy.h"
#include "soc/usb_dwc_periph.h"
#include "hal/usb_fsls_phy_hal.h"
#include "hal/usb_fsls_phy_ll.h"
#include "hal/usb_wrap_hal.h"
#include "hal/usb_serial_jtag_hal.h"
#include "esp_rom_gpio.h"
#include "driver/gpio.h"
#include "hal/gpio_ll.h"
@ -33,7 +33,10 @@ struct phy_context_t {
usb_otg_mode_t otg_mode; /**< USB OTG mode */
usb_phy_speed_t otg_speed; /**< USB speed */
usb_phy_ext_io_conf_t *iopins; /**< external PHY I/O pins */
usb_fsls_phy_hal_context_t hal_context; /**< USB_PHY hal context */
usb_wrap_hal_context_t wrap_hal; /**< USB WRAP HAL context */
#if SOC_USB_SERIAL_JTAG_SUPPORTED
usb_serial_jtag_hal_context_t usj_hal; /**< USJ HAL context */
#endif
};
typedef struct {
@ -120,7 +123,14 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode)
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from host
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_AVALID_IN_IDX, false); // HIGH to force USB host mode
if (handle->target == USB_PHY_TARGET_INT) {
usb_fsls_phy_hal_int_load_conf_host(&(handle->hal_context));
// Configure pull resistors for host
usb_wrap_pull_override_vals_t vals = {
.dp_pu = false,
.dm_pu = false,
.dp_pd = true,
.dm_pd = true,
};
usb_wrap_hal_phy_enable_pull_override(&handle->wrap_hal, &vals);
}
} else if (mode == USB_OTG_MODE_DEVICE) {
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_IDDIG_IN_IDX, false); // connected connector is mini-B side
@ -141,7 +151,19 @@ esp_err_t usb_phy_otg_dev_set_speed(usb_phy_handle_t handle, usb_phy_speed_t spe
USBPHY_TAG, "set speed not supported");
handle->otg_speed = speed;
usb_fsls_phy_hal_int_load_conf_dev(&(handle->hal_context), speed);
// Configure pull resistors for device
usb_wrap_pull_override_vals_t vals = {
.dp_pd = false,
.dm_pd = false,
};
if (speed == USB_PHY_SPEED_LOW) {
vals.dp_pu = false;
vals.dm_pu = true;
} else {
vals.dp_pu = true;
vals.dm_pu = false;
}
usb_wrap_hal_phy_enable_pull_override(&handle->wrap_hal, &vals);
return ESP_OK;
}
@ -157,7 +179,7 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
switch (action) {
case USB_PHY_ACTION_HOST_ALLOW_CONN:
if (handle->target == USB_PHY_TARGET_INT) {
usb_fsls_phy_hal_int_mimick_disconn(&(handle->hal_context), false);
usb_wrap_hal_phy_enable_test_mode(&handle->wrap_hal, false);
} else {
if (!handle->iopins) {
ret = ESP_FAIL;
@ -174,7 +196,21 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action)
case USB_PHY_ACTION_HOST_FORCE_DISCONN:
if (handle->target == USB_PHY_TARGET_INT) {
usb_fsls_phy_hal_int_mimick_disconn(&(handle->hal_context), true);
/*
We mimic a disconnect by enabling the internal PHY's test mode,
then forcing the output_enable to HIGH. This will cause the received
VP and VM to be zero, thus mimicking a disconnection.
*/
const usb_wrap_test_mode_vals_t vals = {
.tx_enable_n = true,
.tx_dp = false,
.tx_dm = false,
.rx_dp = false,
.rx_dm = false,
.rx_rcv = false,
};
usb_wrap_hal_phy_test_mode_set_signals(&handle->wrap_hal, &vals);
usb_wrap_hal_phy_enable_test_mode(&handle->wrap_hal, true);
} else {
/*
Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal.
@ -214,8 +250,8 @@ static esp_err_t usb_phy_install(void)
portEXIT_CRITICAL(&phy_spinlock);
goto cleanup;
}
usb_fsls_phy_ll_usb_wrap_enable_bus_clock(true);
usb_fsls_phy_ll_usb_wrap_reset_register();
usb_wrap_ll_enable_bus_clock(true);
usb_wrap_ll_reset_register();
// Enable USB peripheral and reset the register
portEXIT_CRITICAL(&phy_spinlock);
return ESP_OK;
@ -255,13 +291,18 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r
phy_context->controller = config->controller;
phy_context->status = USB_PHY_STATUS_IN_USE;
usb_fsls_phy_hal_init(&(phy_context->hal_context));
usb_wrap_hal_init(&phy_context->wrap_hal);
#if SOC_USB_SERIAL_JTAG_SUPPORTED
usb_serial_jtag_hal_init(&phy_context->usj_hal);
#endif
if (config->controller == USB_PHY_CTRL_OTG) {
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
else if (config->controller == USB_PHY_CTRL_SERIAL_JTAG) {
usb_fsls_phy_hal_jtag_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT);
usb_serial_jtag_hal_phy_set_external(&phy_context->usj_hal, (config->target == USB_PHY_TARGET_EXT));
phy_context->otg_mode = USB_OTG_MODE_DEVICE;
phy_context->otg_speed = USB_PHY_SPEED_FULL;
}
@ -308,7 +349,7 @@ static void phy_uninstall(void)
p_phy_ctrl_obj_free = p_phy_ctrl_obj;
p_phy_ctrl_obj = NULL;
// Disable USB peripheral without reset the module
usb_fsls_phy_ll_usb_wrap_enable_bus_clock(false);
usb_wrap_ll_enable_bus_clock(false);
}
portEXIT_CRITICAL(&phy_spinlock);
free(p_phy_ctrl_obj_free);
@ -324,8 +365,7 @@ esp_err_t usb_del_phy(usb_phy_handle_t handle)
p_phy_ctrl_obj->external_phy = NULL;
} else {
// Clear pullup and pulldown loads on D+ / D-, and disable the pads
usb_fsls_phy_ll_int_load_conf(handle->hal_context.wrap_dev, false, false, false, false);
usb_fsls_phy_ll_usb_wrap_pad_enable(handle->hal_context.wrap_dev, false);
usb_wrap_hal_phy_disable_pull_override(&handle->wrap_hal);
p_phy_ctrl_obj->internal_phy = NULL;
}
portEXIT_CRITICAL(&phy_spinlock);