mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
feat(esp_hal_usb): Add option to run FS/LS only host on HS target
Add function usb_dwc_hal_init_with_config() that takes a bitmap of configuration flags. Currently only FS/LS only flag is implemented, but the design allows extension in the future.
This commit is contained in:
@@ -19,6 +19,8 @@ that don't support USB OTG.
|
||||
#include "hal/assert.h"
|
||||
#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
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -53,6 +55,16 @@ typedef struct {
|
||||
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 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 ------------------------
|
||||
|
||||
/**
|
||||
@@ -173,16 +185,27 @@ typedef struct {
|
||||
// FIFO related
|
||||
usb_dwc_hal_fifo_config_t fifo_config; /**< FIFO sizes configuration */
|
||||
|
||||
// Configuration of the USB-DWC core. Read from read-only HW registers
|
||||
// These constants are cached from HW registers to avoid repeated reads
|
||||
// Constants, do not change after HAL init
|
||||
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 hsphy_type; /**< HS PHY type of this configuration */
|
||||
unsigned fifo_size; /**< Total FIFO size [in lines] in this configuration */
|
||||
unsigned max_size_byte_limit; /**< Maximum size of a transfer in bytes */
|
||||
unsigned max_size_packet_limit; /**< Maximum size of a transfer in packets */
|
||||
|
||||
// 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;
|
||||
|
||||
// HAL internal flags. Reset (zeroized) during soft-reset procedure
|
||||
union {
|
||||
struct {
|
||||
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
|
||||
@@ -204,6 +227,19 @@ typedef struct {
|
||||
|
||||
// -------------------------------------------------- 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
|
||||
*
|
||||
@@ -227,7 +263,10 @@ typedef struct {
|
||||
* @param[inout] hal Context of the HAL layer
|
||||
* @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
|
||||
@@ -370,14 +409,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
|
||||
* 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)
|
||||
* @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 enable Enable/disable reset signal
|
||||
*/
|
||||
static inline 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);
|
||||
}
|
||||
void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable);
|
||||
|
||||
/**
|
||||
* @brief Enable the host port
|
||||
|
||||
@@ -143,7 +143,7 @@ static void set_defaults(usb_dwc_hal_context_t *hal)
|
||||
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
|
||||
HAL_ASSERT(port_id < SOC_USB_OTG_PERIPH_NUM);
|
||||
@@ -168,6 +168,13 @@ void usb_dwc_hal_init(usb_dwc_hal_context_t *hal, int port_id)
|
||||
hal->constant_config.max_size_byte_limit = (1U << usb_dwc_ll_ghwcfg_get_xfer_size_width(dev)) - 1;
|
||||
hal->constant_config.max_size_packet_limit = (1U << usb_dwc_ll_ghwcfg_get_packet_size_width(dev)) - 1;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -288,6 +295,15 @@ static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal)
|
||||
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)
|
||||
{
|
||||
// Host Configuration
|
||||
|
||||
Reference in New Issue
Block a user