feat(hal/usb): Explicitly enable clock and reset USB WRAP on init

This commit is contained in:
Tomas Rezucha 2024-11-22 11:18:46 +01:00
parent d43f647f80
commit ac3a3f801d
6 changed files with 51 additions and 27 deletions

View File

@ -238,7 +238,7 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw,
* 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)
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;
@ -247,12 +247,12 @@ FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool 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__)
#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)
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;
@ -260,7 +260,7 @@ FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
}
// 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__)
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}

View File

@ -207,25 +207,25 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw,
* 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)
FORCE_INLINE_ATTR void _usb_wrap_ll_enable_bus_clock(bool clk_en)
{
REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en);
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_enable_bus_clock(__VA_ARGS__)
#define usb_wrap_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
FORCE_INLINE_ATTR void _usb_wrap_ll_reset_register(void)
{
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 1);
REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0);
}
// SYSTEM.perip_rst_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__)
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}

View File

@ -216,25 +216,25 @@ FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw,
* 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)
FORCE_INLINE_ATTR void _usb_wrap_ll_enable_bus_clock(bool clk_en)
{
SYSTEM.perip_clk_en0.usb_clk_en = clk_en;
}
// SYSTEM.perip_clk_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_enable_bus_clock(__VA_ARGS__)
#define usb_wrap_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void)
FORCE_INLINE_ATTR void _usb_wrap_ll_reset_register(void)
{
SYSTEM.perip_rst_en0.usb_rst = 1;
SYSTEM.perip_rst_en0.usb_rst = 0;
}
// SYSTEM.perip_rst_enx are shared registers, so this function must be used in an atomic way
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__)
#define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_ll_reset_register(__VA_ARGS__)
#ifdef __cplusplus
}

View File

@ -32,7 +32,30 @@ typedef struct {
*
* @param hal USB WRAP HAL context
*/
void usb_wrap_hal_init(usb_wrap_hal_context_t *hal);
void _usb_wrap_hal_init(usb_wrap_hal_context_t *hal);
#if SOC_RCC_IS_INDEPENDENT
#define usb_wrap_hal_init(...) _usb_wrap_hal_init(__VA_ARGS__)
#else
// Use a macro to wrap the function, force the caller to use it in a critical section
// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define usb_wrap_hal_init(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_hal_init(__VA_ARGS__);} while(0)
#endif
/**
* @brief Disable USB WRAP
*
* Disable clock to the peripheral
*/
void _usb_wrap_hal_disable(void);
#if SOC_RCC_IS_INDEPENDENT
#define usb_wrap_hal_disable(...) _usb_wrap_hal_disable(__VA_ARGS__)
#else
// Use a macro to wrap the function, force the caller to use it in a critical section
// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define usb_wrap_hal_disable(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _usb_wrap_hal_disable(__VA_ARGS__);} while(0)
#endif
/* ---------------------------- USB PHY Control ---------------------------- */

View File

@ -8,14 +8,21 @@
#include "hal/usb_wrap_ll.h"
#include "hal/usb_wrap_hal.h"
void usb_wrap_hal_init(usb_wrap_hal_context_t *hal)
void _usb_wrap_hal_init(usb_wrap_hal_context_t *hal)
{
hal->dev = &USB_WRAP;
_usb_wrap_ll_enable_bus_clock(true);
_usb_wrap_ll_reset_register();
#if !USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_wrap_ll_phy_set_defaults(hal->dev);
#endif
}
void _usb_wrap_hal_disable(void)
{
_usb_wrap_ll_enable_bus_clock(false);
}
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external)
{

View File

@ -21,9 +21,9 @@
#include "soc/usb_pins.h"
#if !SOC_RCC_IS_INDEPENDENT
#define USB_WRAP_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#define USB_PHY_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define USB_WRAP_RCC_ATOMIC()
#define USB_PHY_RCC_ATOMIC()
#endif
static const char *USBPHY_TAG = "usb_phy";
@ -259,12 +259,7 @@ static esp_err_t usb_phy_install(void)
PHY_EXIT_CRITICAL();
goto cleanup;
}
// Enable USB peripheral and reset the register
PHY_EXIT_CRITICAL();
USB_WRAP_RCC_ATOMIC() {
usb_wrap_ll_enable_bus_clock(true);
usb_wrap_ll_reset_register();
}
return ESP_OK;
cleanup:
@ -302,10 +297,9 @@ 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_wrap_hal_init(&phy_context->wrap_hal);
#if SOC_USB_SERIAL_JTAG_SUPPORTED
usb_serial_jtag_hal_init(&phy_context->usj_hal);
#endif
USB_PHY_RCC_ATOMIC() {
usb_wrap_hal_init(&phy_context->wrap_hal);
}
if (config->controller == USB_PHY_CTRL_OTG) {
#if USB_WRAP_LL_EXT_PHY_SUPPORTED
usb_wrap_hal_phy_set_external(&phy_context->wrap_hal, (config->target == USB_PHY_TARGET_EXT));
@ -361,9 +355,9 @@ static void phy_uninstall(void)
if (p_phy_ctrl_obj->ref_count == 0) {
p_phy_ctrl_obj_free = p_phy_ctrl_obj;
p_phy_ctrl_obj = NULL;
USB_WRAP_RCC_ATOMIC() {
USB_PHY_RCC_ATOMIC() {
// Disable USB peripheral without reset the module
usb_wrap_ll_enable_bus_clock(false);
usb_wrap_hal_disable();
}
}
PHY_EXIT_CRITICAL();