mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'feat/usb_fsls_only_backport_v5.4' into 'release/v5.4'
feat(esp_hal_usb): Add option to run FS/LS only host on HS target (backport to v5.4) See merge request espressif/esp-idf!52791
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -19,6 +19,8 @@ that don't support USB OTG.
|
|||||||
#include "hal/assert.h"
|
#include "hal/assert.h"
|
||||||
#endif // SOC_USB_OTG_SUPPORTED
|
#endif // SOC_USB_OTG_SUPPORTED
|
||||||
|
|
||||||
|
#define USB_DWC_HAL_INIT_HAS_CONFIG (1) // This version of HAL has usb_dwc_hal_init_with_config()
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -53,6 +55,16 @@ typedef struct {
|
|||||||
uint32_t ptx_fifo_lines; /**< Size of the Periodic FIFO in terms the number of FIFO lines */
|
uint32_t ptx_fifo_lines; /**< Size of the Periodic FIFO in terms the number of FIFO lines */
|
||||||
} usb_dwc_hal_fifo_config_t;
|
} usb_dwc_hal_fifo_config_t;
|
||||||
|
|
||||||
|
// USB DWC HAL configuration flags
|
||||||
|
#define USB_DWC_HAL_CONFIG_FLAG_FSLS_ONLY (0x01u) // Init a High-Speed capable USB-DWC core as Full/Low-Speed only host
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB DWC HAL configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t flags; /**< USB DWC HAL configuration flags, see USB_DWC_HAL_CONFIG_FLAG_* macros */
|
||||||
|
} usb_dwc_hal_config_t;
|
||||||
|
|
||||||
// --------------------- HAL Events ------------------------
|
// --------------------- HAL Events ------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,13 +185,25 @@ typedef struct {
|
|||||||
// FIFO related
|
// FIFO related
|
||||||
usb_dwc_hal_fifo_config_t fifo_config; /**< FIFO sizes configuration */
|
usb_dwc_hal_fifo_config_t fifo_config; /**< FIFO sizes configuration */
|
||||||
|
|
||||||
// Configuration of the USB-DWC core. Read from read-only HW registers
|
// Constants, do not change after HAL init
|
||||||
struct {
|
struct {
|
||||||
|
// Configuration of the USB-DWC core
|
||||||
|
// These constants are cached from read-only HW registers to avoid repeated reads
|
||||||
unsigned chan_num_total; /**< Total number of channels for this configuration */
|
unsigned chan_num_total; /**< Total number of channels for this configuration */
|
||||||
unsigned hsphy_type; /**< HS PHY type of this configuration */
|
unsigned hsphy_type; /**< HS PHY type of this configuration */
|
||||||
unsigned fifo_size; /**< Total FIFO size [in lines] in this configuration */
|
unsigned fifo_size; /**< Total FIFO size [in lines] in this configuration */
|
||||||
|
|
||||||
|
// Constant HAL configuration
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t fsls_only: 1; /**< Even if USB Core supports HS, force FS/LS only. Can be configured only during HAL init */
|
||||||
|
uint32_t reserved: 31;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} flags;
|
||||||
} constant_config;
|
} constant_config;
|
||||||
|
|
||||||
|
// HAL internal flags. Reset (zeroized) during soft-reset procedure
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
|
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
|
||||||
@@ -201,6 +225,19 @@ typedef struct {
|
|||||||
|
|
||||||
// -------------------------------------------------- Core (Global) ----------------------------------------------------
|
// -------------------------------------------------- Core (Global) ----------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the HAL context and check if DWC_OTG is alive
|
||||||
|
*
|
||||||
|
* Same as `usb_dwc_hal_init()` but accepts configuration structure.
|
||||||
|
*
|
||||||
|
* @attention The user must allocate memory for channel handlers with
|
||||||
|
* `hal->channels.hdls = malloc(hal->constant_config.chan_num_total * sizeof(usb_dwc_hal_chan_t*))`
|
||||||
|
* @param[inout] hal Context of the HAL layer
|
||||||
|
* @param[in] port_id USB port ID
|
||||||
|
* @param[in] config USB DWC HAL configuration. Can be NULL.
|
||||||
|
*/
|
||||||
|
void usb_dwc_hal_init_with_config(usb_dwc_hal_context_t *hal, int port_id, const usb_dwc_hal_config_t *config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the HAL context and check if DWC_OTG is alive
|
* @brief Initialize the HAL context and check if DWC_OTG is alive
|
||||||
*
|
*
|
||||||
@@ -224,7 +261,10 @@ typedef struct {
|
|||||||
* @param[inout] hal Context of the HAL layer
|
* @param[inout] hal Context of the HAL layer
|
||||||
* @param[in] port_id USB port ID
|
* @param[in] port_id USB port ID
|
||||||
*/
|
*/
|
||||||
void usb_dwc_hal_init(usb_dwc_hal_context_t *hal, int port_id);
|
static inline void usb_dwc_hal_init(usb_dwc_hal_context_t *hal, int port_id)
|
||||||
|
{
|
||||||
|
usb_dwc_hal_init_with_config(hal, port_id, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deinitialize the HAL context
|
* @brief Deinitialize the HAL context
|
||||||
@@ -349,14 +389,13 @@ static inline void usb_dwc_hal_port_toggle_power(usb_dwc_hal_context_t *hal, boo
|
|||||||
* @note If the host port is already enabled, then issuing a reset will cause it be disabled and generate a
|
* @note If the host port is already enabled, then issuing a reset will cause it be disabled and generate a
|
||||||
* USB_DWC_HAL_PORT_EVENT_DISABLED event. The host port will not be enabled until the reset signal is released (thus
|
* USB_DWC_HAL_PORT_EVENT_DISABLED event. The host port will not be enabled until the reset signal is released (thus
|
||||||
* generating the USB_DWC_HAL_PORT_EVENT_ENABLED event)
|
* generating the USB_DWC_HAL_PORT_EVENT_ENABLED event)
|
||||||
|
* @note If this port is HS an it is configured for FS/LS operation only, HCFG.fslssupp will be set
|
||||||
|
* so the host port does not respond to device's HS chirp.
|
||||||
*
|
*
|
||||||
* @param hal Context of the HAL layer
|
* @param hal Context of the HAL layer
|
||||||
* @param enable Enable/disable reset signal
|
* @param enable Enable/disable reset signal
|
||||||
*/
|
*/
|
||||||
static inline void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable)
|
void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable);
|
||||||
{
|
|
||||||
usb_dwc_ll_hprt_set_port_reset(hal->dev, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the host port
|
* @brief Enable the host port
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -128,7 +128,7 @@ static void set_defaults(usb_dwc_hal_context_t *hal)
|
|||||||
usb_dwc_ll_gusbcfg_force_host_mode(hal->dev);
|
usb_dwc_ll_gusbcfg_force_host_mode(hal->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_dwc_hal_init(usb_dwc_hal_context_t *hal, int port_id)
|
void usb_dwc_hal_init_with_config(usb_dwc_hal_context_t *hal, int port_id, const usb_dwc_hal_config_t *config)
|
||||||
{
|
{
|
||||||
// Check if a peripheral is alive by reading the core ID registers
|
// Check if a peripheral is alive by reading the core ID registers
|
||||||
HAL_ASSERT(port_id < SOC_USB_OTG_PERIPH_NUM);
|
HAL_ASSERT(port_id < SOC_USB_OTG_PERIPH_NUM);
|
||||||
@@ -151,6 +151,13 @@ void usb_dwc_hal_init(usb_dwc_hal_context_t *hal, int port_id)
|
|||||||
hal->constant_config.hsphy_type = usb_dwc_ll_ghwcfg_get_hsphy_type(dev);
|
hal->constant_config.hsphy_type = usb_dwc_ll_ghwcfg_get_hsphy_type(dev);
|
||||||
hal->constant_config.chan_num_total = usb_dwc_ll_ghwcfg_get_channel_num(dev);
|
hal->constant_config.chan_num_total = usb_dwc_ll_ghwcfg_get_channel_num(dev);
|
||||||
|
|
||||||
|
// Check passed configuration flags
|
||||||
|
if (config) {
|
||||||
|
if (config->flags & USB_DWC_HAL_CONFIG_FLAG_FSLS_ONLY) {
|
||||||
|
hal->constant_config.flags.fsls_only = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set_defaults(hal);
|
set_defaults(hal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +262,15 @@ static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal)
|
|||||||
hal->flags.dbnc_lock_enabled = 1;
|
hal->flags.dbnc_lock_enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable)
|
||||||
|
{
|
||||||
|
// If the core is connected to HS PHY but configuration is FS/LS only
|
||||||
|
if (enable && hal->constant_config.hsphy_type && hal->constant_config.flags.fsls_only) {
|
||||||
|
usb_dwc_ll_hcfg_set_fsls_supp_only(hal->dev);
|
||||||
|
}
|
||||||
|
usb_dwc_ll_hprt_set_port_reset(hal->dev, enable);
|
||||||
|
}
|
||||||
|
|
||||||
void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal)
|
void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal)
|
||||||
{
|
{
|
||||||
// Host Configuration
|
// Host Configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user