IDF master 1d7068e4b (#5257)

esp-dsp: master 7cc5073
esp-face: master 420fc7e
esp-rainmaker: f1b82c7
esp32-camera: master 7a06a7e
esp_littlefs: master b58f00c
This commit is contained in:
Me No Dev
2021-06-09 13:12:47 +03:00
committed by GitHub
parent 7f87d0fc3a
commit 4f9e583b29
606 changed files with 6709 additions and 3956 deletions

View File

@ -370,6 +370,12 @@ static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
dev->user.cs_hold = (hold_n > 0? 1: 0);
}
static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
{
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
}
#ifdef __cplusplus
}
#endif

View File

@ -75,6 +75,7 @@ typedef union {
#define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy)
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
#else
@ -103,6 +104,7 @@ typedef union {
#define spi_flash_ll_set_dummy(dev, dummy) spimem_flash_ll_set_dummy((spi_mem_dev_t*)dev, dummy)
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
#endif

View File

@ -539,6 +539,12 @@ static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n)
dev->user.cs_hold = (hold_n > 0? 1: 0);
}
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
{
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
}
#ifdef __cplusplus
}

View File

@ -56,9 +56,9 @@ typedef enum {
*/
typedef enum {
ADC_ATTEN_DB_0 = 0, /*!<No input attenumation, ADC can measure up to approx. 800 mV. */
ADC_ATTEN_DB_2_5 = 1, /*!<The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV. */
ADC_ATTEN_DB_6 = 2, /*!<The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1350 mV. */
ADC_ATTEN_DB_11 = 3, /*!<The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 2600 mV. */
ADC_ATTEN_DB_2_5 = 1, /*!<The input voltage of ADC will be attenuated extending the range of measurement by about 2.5 dB (1.33 x) */
ADC_ATTEN_DB_6 = 2, /*!<The input voltage of ADC will be attenuated extending the range of measurement by about 6 dB (2 x) */
ADC_ATTEN_DB_11 = 3, /*!<The input voltage of ADC will be attenuated extending the range of measurement by about 11 dB (3.55 x) */
ADC_ATTEN_MAX,
} adc_atten_t;

View File

@ -42,7 +42,7 @@ typedef struct {
int cs_num; ///< Which cs pin is used, 0-2.
struct {
uint8_t extra_dummy; ///< Pre-calculated extra dummy used for compensation
uint8_t reserved1; ///< Reserved, set to 0.
uint8_t cs_setup; ///< (cycles-1) of prepare phase by spi clock.
uint8_t cs_hold; ///< CS hold time config used by the host
uint8_t reserved2; ///< Reserved, set to 0.
};
@ -63,6 +63,7 @@ typedef struct {
int input_delay_ns; ///< Input delay on the MISO pin after the launch clock, used for timing compensation.
esp_flash_speed_t speed;///< SPI flash clock speed to work at.
uint32_t cs_hold; ///< CS hold time config used by the host
uint8_t cs_setup; ///< (cycles-1) of prepare phase by spi clock
bool auto_sus_en; ///< Auto suspend feature enable bit 1: enable, 0: disable.
} spi_flash_hal_config_t;

View File

@ -44,6 +44,29 @@ typedef enum {
USB_PRIV_XFER_TYPE_INTR,
} usb_priv_xfer_type_t;
/**
* @brief Enumeration of different possible lengths of the periodic frame list
*/
typedef enum {
USB_HAL_FRAME_LIST_LEN_8 = 8,
USB_HAL_FRAME_LIST_LEN_16 = 16,
USB_HAL_FRAME_LIST_LEN_32 = 32,
USB_HAL_FRAME_LIST_LEN_64 = 64,
} usb_hal_frame_list_len_t;
/**
* @brief Support intervals in number of USB frames (i.e., 1ms)
*/
typedef enum {
USB_HAL_INTERVAL_1 = 1,
USB_HAL_INTERVAL_2 = 2,
USB_HAL_INTERVAL_4 = 4,
USB_HAL_INTERVAL_8 = 8,
USB_HAL_INTERVAL_16 = 16,
USB_HAL_INTERVAL_32 = 32,
USB_HAL_INTERVAL_64 = 64,
} usb_hal_interval_t;
#ifdef __cplusplus
}
#endif

View File

@ -20,7 +20,7 @@ extern "C" {
/*
NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
functions should be called from critical sections unless specified otherwise
functions must be called from critical sections unless specified otherwise
*/
#include <stdlib.h>
@ -30,21 +30,29 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
#include "hal/usbh_ll.h"
#include "hal/usb_types_private.h"
/* -----------------------------------------------------------------------------
------------------------------- Macros and Types -------------------------------
----------------------------------------------------------------------------- */
// ------------------------------------------------ Macros and Types ---------------------------------------------------
// ---------------------------- Constants/Configs ------------------------------
// ------------------ Constants/Configs --------------------
#define USBH_HAL_DMA_MEM_ALIGN 512
#define USBH_HAL_FRAME_LIST_MEM_ALIGN 512 //The frame list needs to be 512 bytes aligned (contrary to the databook)
#define USBH_HAL_NUM_CHAN 8
#define USBH_HAL_XFER_DESC_SIZE (sizeof(usbh_ll_dma_qtd_t))
#define USBH_HAL_FIFO_TOTAL_USABLE_LINES 200 //Although we have a 256 lines, only 200 lines are usuable due to EPINFO_CTL
// ------------------------------- HAL States ----------------------------------
/**
* @brief FIFO size configuration structure
*/
typedef struct {
uint32_t rx_fifo_lines; /**< Size of the RX FIFO in terms the number of FIFO lines */
uint32_t nptx_fifo_lines; /**< Size of the Non-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 */
} usbh_hal_fifo_config_t;
// --------------------- HAL States ------------------------
/**
* @brief Channel states
*
*/
typedef enum {
USBH_HAL_CHAN_STATE_HALTED = 0, /**< The channel is halted. No transfer descriptor list is being executed */
@ -52,7 +60,7 @@ typedef enum {
USBH_HAL_CHAN_STATE_ERROR, /**< The channel is in the error state */
} usbh_hal_chan_state_t;
// ------------------------------- HAL Events ----------------------------------
// --------------------- HAL Events ------------------------
/**
* @brief Host port HAL events
@ -72,48 +80,46 @@ typedef enum {
* @brief Channel events
*/
typedef enum {
USBH_HAL_CHAN_EVENT_SLOT_DONE, /**< The channel has completed execution of an entire transfer descriptor list. Channel is now halted */
USBH_HAL_CHAN_EVENT_SLOT_HALT, /**< The channel as completed execution of a single transfer descriptor in a list. Channel is now halted */
USBH_HAL_CHAN_EVENT_CPLT, /**< The channel has completed execution of a transfer descriptor that had the USBH_HAL_XFER_DESC_FLAG_HOC flag set. Channel is now halted */
USBH_HAL_CHAN_EVENT_ERROR, /**< The channel has encountered an error. Channel is now halted. */
USBH_HAL_CHAN_EVENT_HALT_REQ, /**< The channel has been successfully halted as requested */
USBH_HAL_CHAN_EVENT_NONE, /**< No event (interrupt ran for internal processing) */
} usbh_hal_chan_event_t;
// ------------------------------- HAL Errors ----------------------------------
// --------------------- HAL Errors ------------------------
/**
* @brief Channel errors
*/
typedef enum {
USBH_HAL_CHAN_ERROR_XCS_XACT = 0, /**< Excessive (three consecutive) transaction errors (e.g., no response, bad CRC etc */
USBH_HAL_CHAN_ERROR_BNA, /**< Buffer Not Available error (i.e., transfer slot is unfilled */
USBH_HAL_CHAN_ERROR_BNA, /**< Buffer Not Available error (i.e., An inactive transfer descriptor was fetched by the channel) */
USBH_HAL_CHAN_ERROR_PKT_BBL, /**< Packet babbler error (packet exceeded MPS) */
USBH_HAL_CHAN_ERROR_STALL, /**< STALL response received */
} usbh_hal_chan_error_t;
// ----------------------- Transfer Descriptor Related -------------------------
// ------------- Transfer Descriptor Related ---------------
/**
* @brief Flags used to describe the type of transfer descriptor to fill
*/
#define USBH_HAL_XFER_DESC_FLAG_IN 0x01
#define USBH_HAL_XFER_DESC_FLAG_SETUP 0x02
#define USBH_HAL_XFER_DESC_FLAG_NULL 0x04
#define USBH_HAL_XFER_DESC_FLAG_HALT 0x08
#define USBH_HAL_XFER_DESC_FLAG_IN 0x01 /**< Indicates this transfer descriptor is of the IN direction */
#define USBH_HAL_XFER_DESC_FLAG_SETUP 0x02 /**< Indicates this transfer descriptor is an OUT setup */
#define USBH_HAL_XFER_DESC_FLAG_HOC 0x04 /**< Indicates that the channel will be halted after this transfer descriptor completes */
/**
* @brief Status value of a transfer descriptor
*
* A transfer descriptor's status remains unexecuted until the entire transfer
* descriptor completes (either successfully or an error). Therefore, if a
* channel halt is requested before a transfer descriptor completes, the
* transfer descriptoor remains unexecuted.
* A transfer descriptor's status remains unexecuted until the entire transfer descriptor completes (either successfully
* or an error). Therefore, if a channel halt is requested before a transfer descriptor completes, the transfer
* descriptor remains unexecuted.
*/
#define USBH_HAL_XFER_DESC_STS_SUCCESS USBH_LL_QTD_STATUS_SUCCESS
#define USBH_HAL_XFER_DESC_STS_PKTERR USBH_LL_QTD_STATUS_PKTERR
#define USBH_HAL_XFER_DESC_STS_BUFFER_ERR USBH_LL_QTD_STATUS_BUFFER
#define USBH_HAL_XFER_DESC_STS_NOT_EXECUTED USBH_LL_QTD_STATUS_NOT_EXECUTED
// ------------------------------ Object Types ---------------------------------
// -------------------- Object Types -----------------------
/**
* @brief Endpoint characteristics structure
@ -131,6 +137,10 @@ typedef struct {
};
uint32_t val;
};
struct {
usb_hal_interval_t interval; /**< The interval of the endpoint */
uint32_t phase_offset_frames; /**< Phase offset in number of frames */
} periodic; /**< Characteristic for periodic (interrupt/isochronous) endpoints only */
} usbh_hal_ep_char_t;
/**
@ -143,29 +153,16 @@ typedef struct {
uint32_t active: 1; /**< The channel is enabled */
uint32_t halt_requested: 1; /**< A halt has been requested */
uint32_t error_pending: 1; /**< The channel is waiting for the error to be handled */
uint32_t reserved: 1;
uint32_t chan_idx: 4; /**< The index number of the channel */
uint32_t reserved25: 25;
uint32_t reserved24: 24;
};
uint32_t val;
} flags; /**< Flags regarding channel's status and information */
usb_host_chan_regs_t *regs; /**< Pointer to the channel's register set */
usbh_hal_chan_error_t error; /**< The last error that occurred on the channel */
usb_priv_xfer_type_t type; /**< The transfer type of the channel */
void *chan_ctx; /**< Context variable for the owner of the channel */
//Transfer Descriptor List Slot
struct {
union {
struct {
uint32_t slot_acquired: 1; /**< The transfer descriptor list slot has been acquired */
uint32_t reserved7: 7;
uint32_t cur_qtd_idx: 8; /**< Index of the first QTD in chain of QTDs being executed */
uint32_t qtd_list_len: 8; /**< Length of QTD list in number of QTDs */
uint32_t reserved8: 8;
};
uint32_t val;
} flags;
void *owner_ctx; /**< Context variable for the owner of the slot */
usbh_ll_dma_qtd_t *xfer_desc_list; /**< Pointer to transfer descriptor list */
} slot;
} usbh_hal_chan_t;
/**
@ -176,10 +173,15 @@ typedef struct {
usbh_dev_t *dev; /**< Pointer to base address of DWC_OTG registers */
usb_wrap_dev_t *wrap_dev; /**< Pointer to base address of USB Wrapper registers */
//Host Port related
uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */
usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */
union {
struct {
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
uint32_t reserved31: 31;
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
uint32_t fifo_sizes_set: 1; /**< Whether the FIFO sizes have been set or not */
uint32_t periodic_sched_enabled: 1; /**< Periodic scheduling (for interrupt and isochronous transfers) is enabled */
uint32_t reserved: 5;
uint32_t reserved24: 24;
};
uint32_t val;
} flags;
@ -191,9 +193,7 @@ typedef struct {
} channels;
} usbh_hal_context_t;
/* -----------------------------------------------------------------------------
--------------------------------- Core (Global) --------------------------------
----------------------------------------------------------------------------- */
// -------------------------------------------------- Core (Global) ----------------------------------------------------
/**
* @brief Initialize the HAL context and check if DWC_OTG is alive
@ -219,7 +219,7 @@ void usbh_hal_init(usbh_hal_context_t *hal);
* @brief Deinitialize the HAL context
*
* Entry:
* - All channels should be properly disabled, and any pending events handled
* - All channels must be properly disabled, and any pending events handled
* Exit:
* - DWC_OTG global interrupt disabled
* - HAL context deinitialized
@ -231,13 +231,9 @@ void usbh_hal_deinit(usbh_hal_context_t *hal);
/**
* @brief Issue a soft reset to the controller
*
* This should be called when the host port encounters an error event or has
* been disconnected. Before calling this, users are responsible for safely
* freeing all channels as a soft reset will wipe all host port nd channel
* registers.
*
* This function will result in the host port being put back into same state as
* after calling usbh_hal_init().
* This should be called when the host port encounters an error event or has been disconnected. Before calling this,
* users are responsible for safely freeing all channels as a soft reset will wipe all host port and channel registers.
* This function will result in the host port being put back into same state as after calling usbh_hal_init().
*
* @note This has nothing to do with a USB bus reset. It simply resets the peripheral
*
@ -245,18 +241,35 @@ void usbh_hal_deinit(usbh_hal_context_t *hal);
*/
void usbh_hal_core_soft_reset(usbh_hal_context_t *hal);
/* -----------------------------------------------------------------------------
---------------------------------- Host Port ----------------------------------
----------------------------------------------------------------------------- */
/**
* @brief Set FIFO sizes
*
* This function will set the sizes of each of the FIFOs (RX FIFO, Non-periodic TX FIFO, Periodic TX FIFO) and must be
* called at least once before allocating the channel. Based on the type of endpoints (and the endpionts' MPS), there
* may be situations where this function may need to be called again to resize the FIFOs. If resizing FIFOs dynamically,
* it is the user's responsibility to ensure there are no active channels when this function is called.
*
* @note The totol size of all the FIFOs must be less than or equal to USBH_HAL_FIFO_TOTAL_USABLE_LINES
* @note After a port reset, the FIFO size registers will reset to their default values, so this function must be called
* again post reset.
*
* @param hal Context of the HAL layer
* @param fifo_config FIFO configuration
*/
void usbh_hal_set_fifo_size(usbh_hal_context_t *hal, const usbh_hal_fifo_config_t *fifo_config);
// ---------------------------- Host Port Control ------------------------------
// ---------------------------------------------------- Host Port ------------------------------------------------------
// ------------------ Host Port Control --------------------
/**
* @brief Enable the host port's interrupt allowing port and channel events to occur
* @brief Initialize the host port
*
* - Will enable the host port's interrupts allowing port and channel events to occur
*
* @param hal Context of the HAL layer
*/
static inline void usbh_hal_port_start(usbh_hal_context_t *hal)
static inline void usbh_hal_port_init(usbh_hal_context_t *hal)
{
//Configure Host related interrupts
usbh_ll_haintmsk_dis_chan_intr(hal->dev, 0xFFFFFFFF); //Disable interrupts for all channels
@ -264,11 +277,13 @@ static inline void usbh_hal_port_start(usbh_hal_context_t *hal)
}
/**
* @brief Disable the host port's interrupt preventing any further port or channel events
* @brief Deinitialize the host port
*
* - Will disable the host port's interrupts preventing further port aand channel events from ocurring
*
* @param hal Context of the HAL layer
*/
static inline void usbh_hal_port_stop(usbh_hal_context_t *hal)
static inline void usbh_hal_port_deinit(usbh_hal_context_t *hal)
{
//Disable Host port and channel interrupts
usb_ll_dis_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_HCHINT);
@ -298,9 +313,8 @@ static inline void usbh_hal_port_toggle_power(usbh_hal_context_t *hal, bool powe
* Exit:
* - On release of the reset signal, a USBH_HAL_PORT_EVENT_ENABLED will be generated
*
* @note If the host port is already enabled, then issuing a reset will cause
* it be disabled and generate a USBH_HAL_PORT_EVENT_DISABLED event. The
* host port will not be enabled until the reset signal is released (thus
* @note If the host port is already enabled, then issuing a reset will cause it be disabled and generate a
* USBH_HAL_PORT_EVENT_DISABLED event. The host port will not be enabled until the reset signal is released (thus
* generating the USBH_HAL_PORT_EVENT_ENABLED event)
*
* @param hal Context of the HAL layer
@ -353,8 +367,7 @@ static inline void usbh_hal_port_suspend(usbh_hal_context_t *hal)
*
* Hosts should hold the resume signal for at least 20ms
*
* @note If a remote wakeup event occurs, the resume signal is driven
* and cleared automatically.
* @note If a remote wakeup event occurs, the resume signal is driven and cleared automatically.
*
* @param hal Context of the HAL layer
* @param enable Enable/disable resume signal
@ -371,9 +384,8 @@ static inline void usbh_hal_port_toggle_resume(usbh_hal_context_t *hal, bool ena
/**
* @brief Check whether the resume signal is being driven
*
* If a remote wakeup event occurs, the core will automatically drive and clear
* the resume signal for the required amount of time. Call this function to
* check whether the resume signal has completed.
* If a remote wakeup event occurs, the core will automatically drive and clear the resume signal for the required
* amount of time. Call this function to check whether the resume signal has completed.
*
* @param hal Context of the HAL layer
* @return true Resume signal is still being driven
@ -384,18 +396,89 @@ static inline bool usbh_hal_port_check_resume(usbh_hal_context_t *hal)
return usbh_ll_hprt_get_port_resume(hal->dev);
}
// -------------------------- Host Port Status/State ---------------------------
// ---------------- Host Port Scheduling -------------------
/**
* @brief Sets the periodic scheduling frame list
*
* @note This function must be called before attempting configuring any channels to be period via
* usbh_hal_chan_set_ep_char()
*
* @param hal Context of the HAL layer
* @param frame_list Base address of the frame list
* @param frame_list_len Number of entries in the frame list (can only be 8, 16, 32, 64)
*/
static inline void usbh_hal_port_set_frame_list(usbh_hal_context_t *hal, uint32_t *frame_list, usb_hal_frame_list_len_t len)
{
assert(!hal->flags.periodic_sched_enabled);
//Clear and save frame list
hal->periodic_frame_list = frame_list;
hal->frame_list_len = len;
}
/**
* @brief Get the pointer to the periodic scheduling frame list
*
* @param hal Context of the HAL layer
* @return uint32_t* Base address of the periodic scheduling frame list
*/
static inline uint32_t *usbh_hal_port_get_frame_list(usbh_hal_context_t *hal)
{
return hal->periodic_frame_list;
}
/**
* @brief Enable periodic scheduling
*
* @note The periodic frame list must be set via usbh_hal_port_set_frame_list() should be set before calling this
* function
* @note This function must be called before activating any periodic channels
*
* @param hal Context of the HAL layer
*/
static inline void usbh_hal_port_periodic_enable(usbh_hal_context_t *hal)
{
assert(hal->periodic_frame_list != NULL && !hal->flags.periodic_sched_enabled);
usbh_ll_set_frame_list_base_addr(hal->dev, (uint32_t)hal->periodic_frame_list);
usbh_ll_hcfg_set_num_frame_list_entries(hal->dev, hal->frame_list_len);
usbh_ll_hcfg_en_perio_sched(hal->dev);
hal->flags.periodic_sched_enabled = 1;
}
/**
* @brief Disable periodic scheduling
*
* Disabling periodic scheduling will save a bit of DMA bandwith (as the controller will no longer fetch the schedule
* from the frame list).
*
* @note Before disabling periodic scheduling, it is the user's responsibility to ensure that all periodic channels have
* halted safely.
*
* @param hal Context of the HAL layer
*/
static inline void usbh_hal_port_periodic_disable(usbh_hal_context_t *hal)
{
assert(hal->flags.periodic_sched_enabled);
usbh_ll_hcfg_dis_perio_sched(hal->dev);
hal->flags.periodic_sched_enabled = 0;
}
static inline uint32_t usbh_hal_port_get_cur_frame_num(usbh_hal_context_t *hal)
{
return usbh_ll_get_frm_num(hal->dev);
}
// --------------- Host Port Status/State ------------------
/**
* @brief Check if a device is currently connected to the host port
*
* This function is intended to be called after one of the following events
* followed by an adequate debounce delay
* This function is intended to be called after one of the following events followed by an adequate debounce delay
* - USBH_HAL_PORT_EVENT_CONN
* - USBH_HAL_PORT_EVENT_DISCONN
*
* @note No other connection/disconnection event will occur again until the
* debounce lock is disabled via usbh_hal_disable_debounce_lock()
* @note No other connection/disconnection event will occur again until the debounce lock is disabled via
* usbh_hal_disable_debounce_lock()
*
* @param hal Context of the HAL layer
* @return true A device is connected to the host port
@ -409,11 +492,10 @@ static inline bool usbh_hal_port_check_if_connected(usbh_hal_context_t *hal)
/**
* @brief Check the speed (LS/FS) of the device connected to the host port
*
* @note This function should only be called after confirming that a device is
* connected to the host port
* @note This function should only be called after confirming that a device is connected to the host port
*
* @param hal Context of the HAL layer
* @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2)
* @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2 and esp32-s3)
*/
static inline usb_priv_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *hal)
{
@ -423,9 +505,8 @@ static inline usb_priv_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *
/**
* @brief Disable the debounce lock
*
* This function should be called after calling usbh_hal_port_check_if_connected()
* and will allow connection/disconnection events to occur again. Any pending
* connection or disconenction interrupts are cleared.
* This function must be called after calling usbh_hal_port_check_if_connected() and will allow connection/disconnection
* events to occur again. Any pending connection or disconenction interrupts are cleared.
*
* @param hal Context of the HAL layer
*/
@ -439,11 +520,9 @@ static inline void usbh_hal_disable_debounce_lock(usbh_hal_context_t *hal)
usb_ll_en_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_DISCONNINT);
}
/* -----------------------------------------------------------------------------
----------------------------------- Channel ------------------------------------
------------------------------------------------------------------------------*/
// ----------------------------------------------------- Channel -------------------------------------------------------
// --------------------------- Channel Allocation ------------------------------
// ----------------- Channel Allocation --------------------
/**
* @brief Allocate a channel
@ -464,6 +543,8 @@ bool usbh_hal_chan_alloc(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, voi
*/
void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj);
// ---------------- Channel Configuration ------------------
/**
* @brief Get the context variable of the channel
*
@ -475,8 +556,6 @@ static inline void *usbh_hal_chan_get_context(usbh_hal_chan_t *chan_obj)
return chan_obj->chan_ctx;
}
// ---------------------------- Channel Control --------------------------------
/**
* @brief Get the current state of a channel
*
@ -502,10 +581,11 @@ static inline usbh_hal_chan_state_t usbh_hal_chan_get_state(usbh_hal_chan_t *cha
* @note the channel must be in the disabled state in order to change its EP
* information
*
* @param hal Context of the HAL layer
* @param chan_obj Channel object
* @param ep_char Endpoint characteristics
*/
void usbh_hal_chan_set_ep_char(usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep_char);
void usbh_hal_chan_set_ep_char(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep_char);
/**
* @brief Set the direction of the channel
@ -514,8 +594,7 @@ void usbh_hal_chan_set_ep_char(usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep
* needing to reconfigure all of the channel's EP info. This is used primarily
* for control transfers.
*
* @note This function should only be called when the channel is in the disabled
* state or is halted from a USBH_HAL_CHAN_EVENT_SLOT_HALT event
* @note This function should only be called when the channel is halted
*
* @param chan_obj Channel object
* @param is_in Whether the direction is IN
@ -563,6 +642,51 @@ static inline uint32_t usbh_hal_chan_get_pid(usbh_hal_chan_t *chan_obj)
return usbh_ll_chan_get_pid(chan_obj->regs);
}
// ------------------- Channel Control ---------------------
/**
* @brief Activate a channel
*
* Activating a channel will cause the channel to start executing transfer descriptors.
*
* @note This function should only be called on channels that were previously halted
* @note An event will be generated when the channel is halted
*
* @param chan_obj Channel object
* @param xfer_desc_list A filled transfer descriptor list
* @param desc_list_len Transfer descriptor list length
* @param start_idx Index of the starting transfer descriptor in the list
*/
void usbh_hal_chan_activate(usbh_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, int start_idx);
/**
* @brief Get the index of the current transfer descriptor
*
* @param chan_obj Channel object
* @return int Descriptor index
*/
static inline int usbh_hal_chan_get_qtd_idx(usbh_hal_chan_t *chan_obj)
{
return usbh_ll_chan_get_ctd(chan_obj->regs);
}
/**
* @brief Request to halt a channel
*
* This function should be called in order to halt a channel. If the channel is already halted, this function will
* return true. If the channel is still active, this function will return false and users must wait for the
* USBH_HAL_CHAN_EVENT_HALT_REQ event before treating the channel as halted.
*
* @note When a transfer is in progress (i.e., the channel is active) and a halt is requested, the channel will halt
* after the next USB packet is completed. If the transfer has more pending packets, the transfer will just be
* marked as USBH_HAL_XFER_DESC_STS_NOT_EXECUTED.
*
* @param chan_obj Channel object
* @return true The channel is already halted
* @return false The halt was requested, wait for USBH_HAL_CHAN_EVENT_HALT_REQ
*/
bool usbh_hal_chan_request_halt(usbh_hal_chan_t *chan_obj);
/**
* @brief Get a channel's error
*
@ -587,178 +711,74 @@ static inline void usbh_hal_chan_clear_error(usbh_hal_chan_t *chan_obj)
chan_obj->flags.error_pending = 0;
}
/* -----------------------------------------------------------------------------
-------------------------- Transfer Descriptor List ----------------------------
------------------------------------------------------------------------------*/
// -------------------------------------------- Transfer Descriptor List -----------------------------------------------
/**
* @brief Fill a single entry in a transfer descriptor list
*
* - A single entry corresponds to a USB transfer in a particular direction
* (e.g., a BULK OUT).
* - The channel will automatically split the transfer into multiple MPS sized
* packets of the endpoint.
* - For multi direction transfers (such as the various stages of a control transfer),
* the direction and PID of channel must be managed manually. Set the
* USBH_HAL_XFER_DESC_FLAG_HALT flag to halt on each entry to flip the direction
* and PID of the channel.
* - For IN transfer entries, set the USBH_HAL_XFER_DESC_FLAG_IN. The transfer
* size must also be an integer multiple of the endpoint's MPS
* - Depending on the transfer type, a single transfer descriptor may corresponds
* - A stage of a transfer (for control transfers)
* - A frame of a transfer interval (for interrupt and isoc)
* - An entire transfer (for bulk transfers)
* - Check the various USBH_HAL_XFER_DESC_FLAG_ flags for filling a specific type of descriptor
* - For IN transfer entries, set the USBH_HAL_XFER_DESC_FLAG_IN. The transfer size must also be an integer multiple of
* the endpoint's MPS
*
* @note The USBH_HAL_XFER_DESC_FLAG_HALT must be set on the last descriptor of
* the list so that an interrupt is generated at the end of the list
* @note The USBH_HAL_XFER_DESC_FLAG_HALT can be set on every descriptor if users
* prefer to manually step through the list (such as change EP directions in between)
* @note Critical section is not required for this function
*
* @param xfer_desc_list Transfer descriptor list
* @param xfer_desc_idx Transfer descriptor index
* @param desc_list Transfer descriptor list
* @param desc_idx Transfer descriptor index
* @param xfer_data_buff Transfer data buffer
* @param xfer_len Transfer length
* @param flags Transfer flags
*/
static inline void usbh_hal_xfer_desc_fill(void *xfer_desc_list, int xfer_desc_idx, uint8_t *xfer_data_buff, int xfer_len, uint32_t flags)
static inline void usbh_hal_xfer_desc_fill(void *desc_list, uint32_t desc_idx, uint8_t *xfer_data_buff, int xfer_len, uint32_t flags)
{
//Check if the channel should be halted on completion of this xfer descriptor
bool halt_on_xfer_cplt = flags & USBH_HAL_XFER_DESC_FLAG_HALT;
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)xfer_desc_list;
if (flags & USBH_HAL_XFER_DESC_FLAG_NULL) {
usbh_ll_set_qtd_null(&qtd_list[xfer_desc_idx]);
} else if (flags & USBH_HAL_XFER_DESC_FLAG_IN) {
usbh_ll_set_qtd_in(&qtd_list[xfer_desc_idx], xfer_data_buff, xfer_len, halt_on_xfer_cplt);
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)desc_list;
if (flags & USBH_HAL_XFER_DESC_FLAG_IN) {
usbh_ll_set_qtd_in(&qtd_list[desc_idx],
xfer_data_buff, xfer_len,
flags & USBH_HAL_XFER_DESC_FLAG_HOC);
} else {
usbh_ll_set_qtd_out(&qtd_list[xfer_desc_idx], xfer_data_buff, xfer_len, halt_on_xfer_cplt, (flags & USBH_HAL_XFER_DESC_FLAG_SETUP));
usbh_ll_set_qtd_out(&qtd_list[desc_idx],
xfer_data_buff,
xfer_len,
flags & USBH_HAL_XFER_DESC_FLAG_HOC,
flags & USBH_HAL_XFER_DESC_FLAG_SETUP);
}
}
/**
* @brief Parse a transfer decriptors results
* @brief Clear a transfer descriptor (sets all its fields to NULL)
*
* @param xfer_desc_list Transfer descriptor list
* @param xfer_desc_idx Transfer descriptor index
* @param desc_list Transfer descriptor list
* @param desc_idx Transfer descriptor index
*/
static inline void usbh_hal_xfer_desc_clear(void *desc_list, uint32_t desc_idx)
{
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)desc_list;
usbh_ll_set_qtd_null(&qtd_list[desc_idx]);
}
/**
* @brief Parse a transfer decriptor's results
*
* @param desc_list Transfer descriptor list
* @param desc_idx Transfer descriptor index
* @param[out] xfer_rem_len Remaining length of the transfer in bytes
* @param[out] xfer_status Status of the transfer
*
* @note Critical section is not required for this function
*/
static inline void usbh_hal_xfer_desc_parse(void *xfer_desc_list, int xfer_desc_idx, int *xfer_rem_len, int *xfer_status)
static inline void usbh_hal_xfer_desc_parse(void *desc_list, uint32_t desc_idx, int *xfer_rem_len, int *xfer_status)
{
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)xfer_desc_list;
usbh_ll_get_qtd_status(&qtd_list[xfer_desc_idx], xfer_rem_len, xfer_status);
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)desc_list;
usbh_ll_get_qtd_status(&qtd_list[desc_idx], xfer_rem_len, xfer_status);
//Clear the QTD to prevent it from being read again
usbh_ll_set_qtd_null(&qtd_list[desc_idx]);
}
/* -----------------------------------------------------------------------------
-------------------------------- Channel Slot ----------------------------------
------------------------------------------------------------------------------*/
/**
* @brief Acquire a slot
*
* Acquiring a channel's transfer descriptor list slot will cause a give ownership
* of the channel to the acquirer. The transfer descriptor list to be executed
* when the channel is activated.
*
* @param chan_obj Channel object
* @param xfer_desc_list A filled transfer descriptor list
* @param desc_list_len Length of the descriptor list
* @param owner_ctx Context variable of the owner
*/
static inline void usbh_hal_chan_slot_acquire(usbh_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, void *owner_ctx)
{
assert(!chan_obj->slot.flags.slot_acquired);
chan_obj->slot.xfer_desc_list = (usbh_ll_dma_qtd_t *)xfer_desc_list;
chan_obj->slot.owner_ctx = owner_ctx;
chan_obj->slot.flags.cur_qtd_idx = 0; //Start from the first descriptor
chan_obj->slot.flags.qtd_list_len = desc_list_len;
chan_obj->slot.flags.slot_acquired = 1;
//Store the descriptor list length in the HCTSIZ register. Address of desc list is set when channel is activated
usbh_ll_chan_set_qtd_list_len(chan_obj->regs, desc_list_len);
}
/**
* @brief Get current owner of a slot
*
* This function reqturns a slot's context variable that was set when the slot
* was acquired
*
* @param chan_obj Channel object
* @return void* Context variable of the owner of the slot
*/
static inline void *usbh_hal_chan_slot_get_owner(usbh_hal_chan_t *chan_obj)
{
assert(chan_obj->slot.flags.slot_acquired);
return chan_obj->slot.owner_ctx;
}
/**
* @brief Release a slot
*
* @note This should only be called after confirming that the transfer descriptor
* list has completed execution.
* @note Users should parse the completed transfer descriptor list to check the
* results of each transfer.
*
* @param[in] chan_obj Channel object
* @param[out] xfer_desc_list A completed transfer descriptor list
* @param[out] desc_list_len Length of the descriptor list
*/
static inline void usbh_hal_chan_slot_release(usbh_hal_chan_t *chan_obj, void **xfer_desc_list, int *desc_list_len)
{
assert(chan_obj->slot.flags.slot_acquired);
*xfer_desc_list = (void *)chan_obj->slot.xfer_desc_list;
*desc_list_len = chan_obj->slot.flags.qtd_list_len;
chan_obj->slot.flags.slot_acquired = 0;
}
/**
* @brief Activate a channel
*
* Activating a channel will cause it to start executing the transfer descriptor
* list in its slot starting from its next descriptor index. When a transfer
* descriptor completes execution and has the HALT flag set, an event will be
* generated.
*
* @param chan_obj Channel object
* @param num_to_skip Number of transfer descriptors to skip over
*/
void usbh_hal_chan_activate(usbh_hal_chan_t *chan_obj, int num_to_skip);
/**
* @brief Get next transfer descriptor index
*
* This function returns the index of the next descriptor that will be executed
* in the transfer descriptor list.
*
* @param chan_obj Channel object
* @return int Descriptor index
*/
static inline int usbh_hal_chan_get_next_desc_index(usbh_hal_chan_t *chan_obj)
{
return chan_obj->slot.flags.cur_qtd_idx;
}
/**
* @brief Request to halt a channel
*
* This function should be called in order to halt a channel. If the channel is
* already halted, this function will return true. If the channel is still
* active, this function will return false and users must wait for the
* USBH_HAL_CHAN_EVENT_HALT_REQ event before treating the channel as halted.
*
* @note When a transfer is in progress (i.e., the channel is active) and a halt
* is requested, the channel will halt after the next USB packet is completed.
* If the transfer has more pending packets, the transfer will just be
* marked as USBH_HAL_XFER_DESC_STS_NOT_EXECUTED.
*
* @param chan_obj Channel object
* @return true The channel is already halted
* @return false The halt was requested, wait for USBH_HAL_CHAN_EVENT_HALT_REQ
*/
bool usbh_hal_chan_slot_request_halt(usbh_hal_chan_t *chan_obj);
/* -----------------------------------------------------------------------------
-------------------------------- Event Handling --------------------------------
----------------------------------------------------------------------------- */
// ------------------------------------------------- Event Handling ----------------------------------------------------
/**
* @brief Decode global and host port interrupts
@ -776,13 +796,8 @@ usbh_hal_port_event_t usbh_hal_decode_intr(usbh_hal_context_t *hal);
/**
* @brief Gets the next channel with a pending interrupt
*
* If no channel is pending an interrupt, this function will return NULL. If one
* or more channels are pending an interrupt, this function returns one of the
* channel's objects. Call this function repeatedly until it returns NULL.
*
* @note If a channel error event occurs, or a Slot halt/done event occurs, the
* channel is immediately halted and no further channel interrupt or errors
* can occur until it is reactivated.
* If no channel is pending an interrupt, this function will return NULL. If one or more channels are pending an
* interrupt, this function returns one of the channel's objects. Call this function repeatedly until it returns NULL.
*
* @param hal Context of the HAL layer
* @return usbh_hal_chan_t* Channel object. NULL if no channel are pending an interrupt.

View File

@ -159,16 +159,6 @@ typedef struct {
uint8_t *buffer;
} usbh_ll_dma_qtd_t;
/*
* Enumeration of different possible lengths of the periodic frame list
*/
typedef enum {
USBH_LL_FRAME_LIST_LEN_8 = 0,
USBH_LL_FRAME_LIST_LEN_16,
USBH_LL_FRAME_LIST_LEN_32,
USBH_LL_FRAME_LIST_LEN_64,
} usbh_ll_frame_list_len_t;
/* -----------------------------------------------------------------------------
------------------------------ USB Wrap Registers ------------------------------
----------------------------------------------------------------------------- */
@ -249,18 +239,33 @@ static inline bool usb_ll_check_dma_req_in_progress(usbh_dev_t *hw)
return hw->grstctl_reg.dmareq;
}
static inline void usb_ll_flush_tx_fifo(usbh_dev_t *hw, uint32_t chan_num)
static inline void usb_ll_flush_nptx_fifo(usbh_dev_t *hw)
{
usb_grstctl_reg_t grstctl;
grstctl.val = hw->grstctl_reg.val;
grstctl.txfnum = chan_num; //Set channel number to flush
grstctl.txfflsh = 1; //Flush that channel's TX FIFO
hw->grstctl_reg.val = grstctl.val;
hw->grstctl_reg.txfnum = 0; //Set the TX FIFO number to 0 to select the non-periodic TX FIFO
hw->grstctl_reg.txfflsh = 1; //Flush the selected TX FIFO
//Wait for the flushing to complete
while (hw->grstctl_reg.txfflsh) {
;
}
}
static inline void usb_ll_flush_ptx_fifo(usbh_dev_t *hw)
{
hw->grstctl_reg.txfnum = 1; //Set the TX FIFO number to 1 to select the periodic TX FIFO
hw->grstctl_reg.txfflsh = 1; //FLush the select TX FIFO
//Wait for the flushing to complete
while (hw->grstctl_reg.txfflsh) {
;
}
}
static inline void usb_ll_flush_rx_fifo(usbh_dev_t *hw)
{
hw->grstctl_reg.rxfflsh = 1;
//Wait for the flushing to complete
while (hw->grstctl_reg.rxfflsh) {
;
}
}
static inline void usb_ll_reset_frame_counter(usbh_dev_t *hw)
@ -320,20 +325,20 @@ static inline void usb_ll_dis_intrs(usbh_dev_t *hw, uint32_t intr_mask)
// --------------------------- GRXFSIZ Register --------------------------------
static inline void usb_ll_set_rx_fifo_size(usbh_dev_t *hw, uint32_t size)
static inline void usb_ll_set_rx_fifo_size(usbh_dev_t *hw, uint32_t num_lines)
{
//Set size in words
hw->grxfsiz_reg.rxfdep = size;
hw->grxfsiz_reg.rxfdep = num_lines;
}
// -------------------------- GNPTXFSIZ Register -------------------------------
static inline void usb_ll_set_nptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint32_t size)
static inline void usb_ll_set_nptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint32_t num_lines)
{
usb_gnptxfsiz_reg_t gnptxfsiz;
gnptxfsiz.val = hw->gnptxfsiz_reg.val;
gnptxfsiz.nptxfstaddr = addr;
gnptxfsiz.nptxfdep = size;
gnptxfsiz.nptxfdep = num_lines;
hw->gnptxfsiz_reg.val = gnptxfsiz.val;
}
@ -364,12 +369,12 @@ static inline void usb_ll_get_hardware_config(usbh_dev_t *hw, uint32_t *ghwcfg1,
// --------------------------- HPTXFSIZ Register -------------------------------
static inline void usbh_ll_set_ptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint32_t size)
static inline void usbh_ll_set_ptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint32_t num_lines)
{
usb_hptxfsiz_reg_t hptxfsiz;
hptxfsiz.val = hw->hptxfsiz_reg.val;
hptxfsiz.ptxfstaddr = addr;
hptxfsiz.ptxfsize = size;
hptxfsiz.ptxfsize = num_lines;
hw->hptxfsiz_reg.val = hptxfsiz.val;
}
@ -394,9 +399,24 @@ static inline void usbh_ll_hcfg_dis_perio_sched(usbh_dev_t *hw)
*
* @param num_entires Number of entires in the frame list
*/
static inline void usbh_ll_hcfg_set_num_frame_list_entries(usbh_dev_t *hw, usbh_ll_frame_list_len_t num_entries)
static inline void usbh_ll_hcfg_set_num_frame_list_entries(usbh_dev_t *hw, usb_hal_frame_list_len_t num_entries)
{
hw->hcfg_reg.frlisten = num_entries;
uint32_t frlisten;
switch (num_entries) {
case USB_HAL_FRAME_LIST_LEN_8:
frlisten = 0;
break;
case USB_HAL_FRAME_LIST_LEN_16:
frlisten = 1;
break;
case USB_HAL_FRAME_LIST_LEN_32:
frlisten = 2;
break;
default: //USB_HAL_FRAME_LIST_LEN_64
frlisten = 3;
break;
}
hw->hcfg_reg.frlisten = frlisten;
}
static inline void usbh_ll_hcfg_en_scatt_gatt_dma(usbh_dev_t *hw)
@ -417,18 +437,19 @@ static inline void usbh_ll_hcfg_set_fsls_pclk_sel(usbh_dev_t *hw)
/**
* @brief Sets some default values to HCFG to operate in Host mode with scatter/gather DMA
*
* @param hw
* @param hw Start address of the USB Wrap registers
* @param speed Speed to initialize the host port at
*/
static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
{
hw->hcfg_reg.descdma = 1; //Enable scatt/gatt
hw->hcfg_reg.fslssupp = 1; //FS/LS supp only
hw->hcfg_reg.fslssupp = 1; //FS/LS support only
/*
Indicate to the OTG core what speed the PHY clock is at
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
*/
hw->hcfg_reg.fslspclksel = (speed == USB_PRIV_SPEED_FULL) ? 1 : 2; //esp32-s2 only supports FS or LS
hw->hcfg_reg.fslspclksel = (speed == USB_PRIV_SPEED_FULL) ? 1 : 2; //PHY clock on esp32-sx for FS/LS-only
hw->hcfg_reg.perschedena = 0; //Disable perio sched
}
@ -444,7 +465,7 @@ static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_priv_speed_t sp
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
*/
hfir.frint = (speed == USB_PRIV_SPEED_FULL) ? 48000 : 6000; //esp32-s2 only supports FS or LS
hfir.frint = (speed == USB_PRIV_SPEED_FULL) ? 48000 : 6000; //esp32-sx targets only support FS or LS
hw->hfir_reg.val = hfir.val;
}
@ -498,11 +519,27 @@ static inline void usbh_ll_haintmsk_dis_chan_intr(usbh_dev_t *hw, uint32_t mask)
// --------------------------- HFLBAddr Register -------------------------------
/**
* @brief Set the base address of the scheduling frame list
*
* @note For some reason, this address must be 512 bytes aligned or else a bunch of frames will not be scheduled when
* the frame list rolls over. However, according to the databook, there is no mention of the HFLBAddr needing to
* be aligned.
*
* @param hw Start address of the DWC_OTG registers
* @param addr Base address of the scheduling frame list
*/
static inline void usbh_ll_set_frame_list_base_addr(usbh_dev_t *hw, uint32_t addr)
{
hw->hflbaddr_reg.hflbaddr = addr;
}
/**
* @brief Get the base address of the scheduling frame list
*
* @param hw Start address of the DWC_OTG registers
* @return uint32_t Base address of the scheduling frame list
*/
static inline uint32_t usbh_ll_get_frame_list_base_addr(usbh_dev_t *hw)
{
return hw->hflbaddr_reg.hflbaddr;
@ -513,7 +550,7 @@ static inline uint32_t usbh_ll_get_frame_list_base_addr(usbh_dev_t *hw)
static inline usb_priv_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
{
usb_priv_speed_t speed;
//esp32-s2 only supports FS or LS
//esp32-s2 and esp32-s3 only support FS or LS
switch (hw->hprt_reg.prtspd) {
case 1:
speed = USB_PRIV_SPEED_FULL;
@ -529,6 +566,7 @@ static inline uint32_t usbh_ll_hprt_get_test_ctl(usbh_dev_t *hw)
{
return hw->hprt_reg.prttstctl;
}
static inline void usbh_ll_hprt_set_test_ctl(usbh_dev_t *hw, uint32_t test_mode)
{
usb_hprt_reg_t hprt;
@ -604,6 +642,7 @@ static inline bool usbh_ll_hprt_get_port_resume(usbh_dev_t *hw)
{
return hw->hprt_reg.prtres;
}
static inline bool usbh_ll_hprt_get_port_overcur(usbh_dev_t *hw)
{
return hw->hprt_reg.prtovrcurract;
@ -780,9 +819,7 @@ static inline void usbh_ll_chan_set_dma_addr_non_iso(volatile usb_host_chan_regs
static inline void usbh_ll_chan_set_dma_addr_iso(volatile usb_host_chan_regs_t *chan,
void *dmaaddr,
uint32_t ntd,
uint32_t pktcnt,
uint32_t ctd)
uint32_t ntd)
{
int n;
if (ntd == 2) {
@ -861,15 +898,15 @@ static inline usb_host_chan_regs_t *usbh_ll_get_chan_regs(usbh_dev_t *dev, int c
* @param data_buff Pointer to buffer containing the data to transfer
* @param xfer_len Number of bytes in transfer. Setting 0 will do a zero length IN transfer.
* Non zero length must be mulitple of the endpoint's MPS.
* @param halt_on_cplt Generate a channel halted interrupt on completion of QTD
* @param hoc Halt on complete (will generate an interrupt and halt the channel)
*/
static inline void usbh_ll_set_qtd_in(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool halt_on_cplt)
static inline void usbh_ll_set_qtd_in(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool hoc)
{
qtd->buffer = data_buff; //Set pointer to data buffer
qtd->buffer_status_val = 0; //Reset all flags to zero
qtd->in_non_iso.xfer_size = xfer_len;
if (halt_on_cplt) {
qtd->in_non_iso.intr_cplt = 1; //Used to indicate successful completion
if (hoc) {
qtd->in_non_iso.intr_cplt = 1; //We need to set this to distinguish between a halt due to a QTD
qtd->in_non_iso.eol = 1; //Used to halt the channel at this qtd
}
qtd->in_non_iso.active = 1;
@ -882,11 +919,11 @@ static inline void usbh_ll_set_qtd_in(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff
* @param data_buff Pointer to buffer containing the data to transfer
* @param xfer_len Number of bytes to transfer. Setting 0 will do a zero length transfer.
* For ctrl setup packets, this should be set to 8.
* @param halt_on_cplt Generate a channel halted interrupt on completion of QTD.
* @param hoc Halt on complete (will generate an interrupt)
* @param is_setup Indicates whether this is a control transfer setup packet or a normal OUT Data transfer.
* (As per the USB protocol, setup packets cannot be STALLd or NAKd by the device)
*/
static inline void usbh_ll_set_qtd_out(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool halt_on_cplt, bool is_setup)
static inline void usbh_ll_set_qtd_out(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool hoc, bool is_setup)
{
qtd->buffer = data_buff; //Set pointer to data buffer
qtd->buffer_status_val = 0; //Reset all flags to zero
@ -894,9 +931,9 @@ static inline void usbh_ll_set_qtd_out(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buf
if (is_setup) {
qtd->out_non_iso.is_setup = 1;
}
if (halt_on_cplt) {
qtd->out_non_iso.intr_cplt = 1; //Used to indicate successful completion
qtd->out_non_iso.eol = 1; //Used to halt the channel at this qtd
if (hoc) {
qtd->in_non_iso.intr_cplt = 1; //We need to set this to distinguish between a halt due to a QTD
qtd->in_non_iso.eol = 1; //Used to halt the channel at this qtd
}
qtd->out_non_iso.active = 1;
}