From 778c2e6863613de73fb693349036046495247505 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Tue, 2 Apr 2024 21:10:35 +0800 Subject: [PATCH] refactor(hal/usb): Add new USB PHY related HAL API This commit adds/updates the USB PHY related HAL APIs. The following changes are made: - Updated 'usb_wrap_hal.h' API - Added 'usb_serial_jtag_hal.h' API --- components/hal/CMakeLists.txt | 4 + .../hal/include/hal/usb_serial_jtag_hal.h | 51 ++++++++++ components/hal/include/hal/usb_wrap_hal.h | 84 +++++++++-------- components/hal/usb_serial_jtag_hal.c | 28 ++++++ components/hal/usb_wrap_hal.c | 94 ++----------------- components/usb/usb_phy.c | 66 +++++++++---- 6 files changed, 185 insertions(+), 142 deletions(-) create mode 100644 components/hal/include/hal/usb_serial_jtag_hal.h create mode 100644 components/hal/usb_serial_jtag_hal.c diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 7ab06d3728..dea07390ad 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -256,6 +256,10 @@ 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" diff --git a/components/hal/include/hal/usb_serial_jtag_hal.h b/components/hal/include/hal/usb_serial_jtag_hal.h new file mode 100644 index 0000000000..410ed66355 --- /dev/null +++ b/components/hal/include/hal/usb_serial_jtag_hal.h @@ -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 diff --git a/components/hal/include/hal/usb_wrap_hal.h b/components/hal/include/hal/usb_wrap_hal.h index d484eb89c0..ceb69f3652 100644 --- a/components/hal/include/hal/usb_wrap_hal.h +++ b/components/hal/include/hal/usb_wrap_hal.h @@ -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 */ @@ -7,85 +7,89 @@ #pragma once #include -#include "usb_dwc_types.h" -#include "usb_phy_types.h" #include "soc/soc_caps.h" #if SOC_USB_OTG_SUPPORTED #include "soc/usb_wrap_struct.h" #include "hal/usb_wrap_ll.h" #endif -#if SOC_USB_SERIAL_JTAG_SUPPORTED -#include "soc/usb_serial_jtag_struct.h" -#endif +#include "hal/usb_wrap_types.h" #ifdef __cplusplus extern "C" { #endif #if SOC_USB_OTG_SUPPORTED -/** - * Context that should be maintained by both the driver and the HAL - */ +/** + * @brief HAL context type of USB WRAP driver + */ typedef struct { - 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; - + usb_wrap_dev_t *dev; +} usb_wrap_hal_context_t; /** - * @brief Init the USB PHY hal. This function should be called first before other hal layer function is called + * @brief Initialize the USB WRAP HAL driver * - * @param hal Context of the HAL layer + * @param hal USB WRAP HAL context */ -void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal); +void usb_wrap_hal_init(usb_wrap_hal_context_t *hal); + +/* ---------------------------- USB PHY Control ---------------------------- */ #if USB_WRAP_LL_EXT_PHY_SUPPORTED /** - * @brief Configure internal/external PHY for USB_OTG + * @brief Configure whether USB WRAP is routed to internal/external FSLS PHY * - * @param hal Context of the HAL layer - * @param phy_target USB PHY target + * @param hal USB WRAP HAL context + * @param external True if external, False if internal */ -void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target); +void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external); #endif // USB_WRAP_LL_EXT_PHY_SUPPORTED -#if SOC_USB_SERIAL_JTAG_SUPPORTED /** - * @brief Configure internal/external PHY for USB_Serial_JTAG + * @brief Enables and sets override of pull up/down resistors * - * @param hal Context of the HAL layer - * @param phy_target USB PHY target + * @param hal USB WRAP HAL context + * @param vals Override values */ -void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target); -#endif +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 Configure pullup/pulldown loads for the D+/D- as a host + * @brief Disables pull up/down resistor override * - * @param hal Context of the HAL layer + * @param hal USB WRAP HAL context */ -void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal); +static inline void usb_wrap_hal_phy_disable_pull_override(usb_wrap_hal_context_t *hal) +{ + usb_wrap_ll_phy_disable_pull_override(hal->dev); +} /** - * @brief Configure pullup/pulldown loads for the D+/D- as a device + * @brief Enables/disables the USB FSLS PHY's test mode * - * @param hal Context of the HAL layer - * @param speed USB speed + * @param hal USB WRAP HAL context + * @param enable Whether to enable test mode */ -void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed); +static inline void usb_wrap_hal_phy_enable_test_mode(usb_wrap_hal_context_t *hal, bool enable) +{ + usb_wrap_ll_phy_enable_test_mode(hal->dev, enable); +} /** - * @brief Enable/Disable test mode for internal PHY to mimic host-device disconnection + * @brief Set the USB FSLS PHY's signal test values * - * @param hal Context of the HAL layer - * @param disconn Whether to disconnect + * @param hal USB WRAP HAL context + * @param vals Test values */ -void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn); +static inline void usb_wrap_hal_phy_test_mode_set_signals(usb_wrap_hal_context_t *hal, const usb_wrap_test_mode_vals_t *vals) +{ + usb_wrap_ll_phy_test_mode_set_signals(hal->dev, vals); +} -#endif +#endif // SOC_USB_OTG_SUPPORTED #ifdef __cplusplus } diff --git a/components/hal/usb_serial_jtag_hal.c b/components/hal/usb_serial_jtag_hal.c new file mode 100644 index 0000000000..094ff81763 --- /dev/null +++ b/components/hal/usb_serial_jtag_hal.c @@ -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 diff --git a/components/hal/usb_wrap_hal.c b/components/hal/usb_wrap_hal.c index de805083d8..52d6933bce 100644 --- a/components/hal/usb_wrap_hal.c +++ b/components/hal/usb_wrap_hal.c @@ -5,101 +5,25 @@ */ #include "soc/soc_caps.h" -#if SOC_USB_SERIAL_JTAG_SUPPORTED -#include "hal/usb_serial_jtag_ll.h" -#endif #include "hal/usb_wrap_ll.h" #include "hal/usb_wrap_hal.h" -void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal) +void usb_wrap_hal_init(usb_wrap_hal_context_t *hal) { - hal->wrap_dev = &USB_WRAP; -#if SOC_USB_SERIAL_JTAG_SUPPORTED - hal->jtag_dev = &USB_SERIAL_JTAG; -#endif + hal->dev = &USB_WRAP; #if !USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_wrap_ll_phy_set_defaults(hal->wrap_dev); + usb_wrap_ll_phy_set_defaults(hal->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) +void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external) { - if (phy_target == USB_PHY_TARGET_EXT) { - usb_wrap_ll_phy_enable_external(hal->wrap_dev, true); - } else if (phy_target == USB_PHY_TARGET_INT) { - usb_wrap_ll_phy_enable_external(hal->wrap_dev, false); - usb_wrap_ll_phy_enable_pad(hal->wrap_dev, true); + if (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 - -#if SOC_USB_SERIAL_JTAG_SUPPORTED -void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target) -{ - if (phy_target == USB_PHY_TARGET_EXT) { - usb_serial_jtag_ll_phy_enable_external(true); // USJ uses external PHY - } else if (phy_target == USB_PHY_TARGET_INT) { - usb_serial_jtag_ll_phy_enable_external(false); // USJ uses internal PHY - usb_serial_jtag_ll_phy_enable_pad(true); // Enable USB PHY pads - } -} -#endif - -void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal) -{ - // HOST - upstream: dp_pd = 1, dm_pd = 1 - usb_wrap_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) -{ - // DEVICE - downstream - if (speed == USB_PHY_SPEED_LOW) { - // LS: dm_pu = 1 - 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_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); - } -} - -void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn) -{ - if (disconn) { - /* - 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_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); - } -} diff --git a/components/usb/usb_phy.c b/components/usb/usb_phy.c index 40df183f07..cfaf90abd2 100644 --- a/components/usb/usb_phy.c +++ b/components/usb/usb_phy.c @@ -13,7 +13,7 @@ #include "esp_private/usb_phy.h" #include "soc/usb_dwc_periph.h" #include "hal/usb_wrap_hal.h" -#include "hal/usb_wrap_ll.h" +#include "hal/usb_serial_jtag_hal.h" #include "esp_rom_gpio.h" #include "driver/gpio.h" #include "hal/gpio_ll.h" @@ -39,7 +39,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 { @@ -126,7 +129,14 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode) esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_VBUSVALID_IN_IDX, false); // receiving a valid Vbus from host esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, USB_OTG_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 @@ -147,7 +157,19 @@ esp_err_t usb_phy_otg_dev_set_speed(usb_phy_handle_t handle, usb_phy_speed_t spe USBPHY_TAG, "set speed not supported"); 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; } @@ -163,7 +185,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; @@ -180,7 +202,21 @@ esp_err_t usb_phy_action(usb_phy_handle_t handle, usb_phy_action_t action) case USB_PHY_ACTION_HOST_FORCE_DISCONN: 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. @@ -263,15 +299,18 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r phy_context->controller = config->controller; phy_context->status = USB_PHY_STATUS_IN_USE; - usb_fsls_phy_hal_init(&(phy_context->hal_context)); + usb_wrap_hal_init(&phy_context->wrap_hal); +#if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_serial_jtag_hal_init(&phy_context->usj_hal); +#endif if (config->controller == USB_PHY_CTRL_OTG) { #if USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_fsls_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT); + 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; } @@ -336,14 +375,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_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); + usb_wrap_hal_phy_disable_pull_override(&handle->wrap_hal); p_phy_ctrl_obj->internal_phy = NULL; } portEXIT_CRITICAL(&phy_spinlock);