Merge branch 'feature/usb_host_collective_backport_v5.1' into 'release/v5.1'

USB Host: Collective backport to v5.1

See merge request espressif/esp-idf!28096
This commit is contained in:
Marius Vikhammer 2024-03-01 09:28:23 +08:00
commit 929a8449bd
38 changed files with 1486 additions and 1318 deletions

View File

@ -19,7 +19,7 @@
#include "esp32s2/rom/usb/usb_common.h"
#endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "hal/usb_phy_ll.h"
#include "hal/usb_fsls_phy_ll.h"
#endif
#include "esp_rom_gpio.h"
#include "esp_rom_uart.h"
@ -101,8 +101,8 @@ void bootloader_console_init(void)
esp_rom_uart_set_as_console(ESP_ROM_USB_OTG_NUM);
esp_rom_install_channel_putc(1, bootloader_console_write_char_usb);
#if SOC_USB_SERIAL_JTAG_SUPPORTED
usb_phy_ll_usb_wrap_pad_enable(&USB_WRAP, true);
usb_phy_ll_int_otg_enable(&USB_WRAP);
usb_fsls_phy_ll_usb_wrap_pad_enable(&USB_WRAP, true);
usb_fsls_phy_ll_int_otg_enable(&USB_WRAP);
#endif
}
#endif //CONFIG_ESP_CONSOLE_USB_CDC

View File

@ -8,7 +8,7 @@
#include <stdbool.h>
#include "esp_log.h"
#include "hal/usb_serial_jtag_ll.h"
#include "hal/usb_phy_ll.h"
#include "hal/usb_fsls_phy_ll.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/ringbuf.h"
@ -155,7 +155,7 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se
usb_serial_jtag_ll_enable_bus_clock(true);
// Configure PHY
usb_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG);
usb_fsls_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG);
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY|
USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);

View File

@ -107,7 +107,7 @@ menu "PHY"
config ESP_PHY_ENABLE_USB
bool "Enable USB when phy init"
depends on USB_OTG_SUPPORTED || ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
depends on SOC_USB_OTG_SUPPORTED || ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
default n
help

View File

@ -179,6 +179,13 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "ds_hal.c")
endif()
if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs
"usb_hal.c"
"usb_dwc_hal.c"
"usb_fsls_phy_hal.c")
endif()
if(${target} STREQUAL "esp32")
list(APPEND srcs
"touch_sensor_hal.c"
@ -190,24 +197,18 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs
"spi_flash_hal_gpspi.c"
"touch_sensor_hal.c"
"usb_hal.c"
"usb_phy_hal.c"
"xt_wdt_hal.c"
"esp32s2/cp_dma_hal.c"
"esp32s2/touch_sensor_hal.c"
"usb_dwc_hal.c")
"esp32s2/touch_sensor_hal.c")
endif()
if(${target} STREQUAL "esp32s3")
list(APPEND srcs
"spi_flash_hal_gpspi.c"
"touch_sensor_hal.c"
"usb_hal.c"
"usb_phy_hal.c"
"xt_wdt_hal.c"
"esp32s3/touch_sensor_hal.c"
"esp32s3/rtc_cntl_hal.c"
"usb_dwc_hal.c")
"esp32s3/rtc_cntl_hal.c")
endif()
if(${target} STREQUAL "esp32c3")

View File

@ -17,7 +17,7 @@ extern "C" {
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;

View File

@ -17,7 +17,7 @@ extern "C" {
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;

View File

@ -17,7 +17,7 @@ extern "C" {
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;

View File

@ -21,7 +21,7 @@ extern "C" {
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
{
hw->otg_conf.phy_sel = 0;
}
@ -31,7 +31,7 @@ static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
{
//Enable external PHY
hw->otg_conf.phy_sel = 1;
@ -46,7 +46,7 @@ static inline void usb_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
* @param dm_pu D- pullup load
* @param dm_pd D- pulldown load
*/
static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd)
static inline void usb_fsls_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd)
{
usb_wrap_otg_conf_reg_t conf = hw->otg_conf;
conf.pad_pull_override = 1;
@ -62,7 +62,7 @@ static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool
* @param hw Start address of the USB Wrap registers
* @param pad_en Enable the PHY control to D+/D- pad
*/
static inline void usb_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en)
static inline void usb_fsls_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en)
{
hw->otg_conf.pad_enable = pad_en;
}
@ -73,7 +73,7 @@ static inline void usb_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_e
* @param hw Start address of the USB Wrap registers
* @param en Whether to enable the internal PHY's test mode
*/
static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
static inline void usb_fsls_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
{
if (en) {
// Clear USB_WRAP_TEST_CONF_REG
@ -91,7 +91,7 @@ static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
* 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_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
{
REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en);
}
@ -99,7 +99,7 @@ FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_reset_register(void)
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_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);

View File

@ -23,7 +23,7 @@ extern "C" {
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
static inline void usb_fsls_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
{
// USB_OTG use internal PHY
hw->otg_conf.phy_sel = 0;
@ -38,7 +38,7 @@ static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw)
*
* @param hw Start address of the USB Wrap registers
*/
static inline void usb_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
static inline void usb_fsls_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
{
// USB_OTG use external PHY
hw->otg_conf.phy_sel = 1;
@ -53,7 +53,7 @@ static inline void usb_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw)
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
static inline void usb_fsls_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use internal PHY
hw->conf0.phy_sel = 0;
@ -74,7 +74,7 @@ static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw)
*
* @param hw Start address of the USB Serial_JTAG registers
*/
static inline void usb_phy_ll_ext_jtag_enable(usb_serial_jtag_dev_t *hw)
static inline void usb_fsls_phy_ll_ext_jtag_enable(usb_serial_jtag_dev_t *hw)
{
// USB_Serial_JTAG use external PHY
hw->conf0.phy_sel = 1;
@ -93,7 +93,7 @@ static inline void usb_phy_ll_ext_jtag_enable(usb_serial_jtag_dev_t *hw)
* @param dm_pu D- pullup load
* @param dm_pd D- pulldown load
*/
static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd)
static inline void usb_fsls_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd)
{
usb_wrap_otg_conf_reg_t conf = hw->otg_conf;
conf.pad_pull_override = 1;
@ -109,7 +109,7 @@ static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool
* @param hw Start address of the USB Wrap registers
* @param pad_en Enable the PHY control to D+/D- pad
*/
static inline void usb_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en)
static inline void usb_fsls_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_en)
{
hw->otg_conf.pad_enable = pad_en;
}
@ -120,7 +120,7 @@ static inline void usb_phy_ll_usb_wrap_pad_enable(usb_wrap_dev_t *hw, bool pad_e
* @param hw Start address of the USB Wrap registers
* @param en Whether to enable the internal PHY's test mode
*/
static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
static inline void usb_fsls_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
{
if (en) {
// Clear USB_WRAP_TEST_CONF_REG
@ -138,7 +138,7 @@ static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en)
* 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_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
{
SYSTEM.perip_clk_en0.usb_clk_en = clk_en;
}
@ -146,7 +146,7 @@ FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_enable_bus_clock(bool clk_en)
/**
* @brief Reset the USB Wrap module
*/
FORCE_INLINE_ATTR void usb_phy_ll_usb_wrap_reset_register(void)
FORCE_INLINE_ATTR void usb_fsls_phy_ll_usb_wrap_reset_register(void)
{
SYSTEM.perip_rst_en0.usb_rst = 1;
SYSTEM.perip_rst_en0.usb_rst = 0;

View File

@ -6,21 +6,22 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "soc/soc_caps.h"
/*
NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
functions must be called from critical sections unless specified otherwise
This header is shared across all targets. Resolve to an empty header for targets
that don't support USB OTG.
*/
#include <stdlib.h>
#include <stddef.h>
#include "soc/usb_dwc_struct.h"
#if SOC_USB_OTG_SUPPORTED
#include <stdint.h>
#include <stdbool.h>
#include "hal/usb_dwc_ll.h"
#include "hal/usb_dwc_types.h"
#include "hal/assert.h"
#endif // SOC_USB_OTG_SUPPORTED
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_USB_OTG_SUPPORTED
@ -139,7 +140,7 @@ typedef struct {
uint32_t val;
};
struct {
usb_hal_interval_t interval; /**< The interval of the endpoint */
unsigned int interval; /**< The interval of the endpoint in frames (FS) or microframes (HS) */
uint32_t phase_offset_frames; /**< Phase offset in number of frames */
} periodic; /**< Characteristic for periodic (interrupt/isochronous) endpoints only */
} usb_dwc_hal_ep_char_t;
@ -175,7 +176,7 @@ typedef struct {
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 */
//FIFO related
const usb_dwc_hal_fifo_config_t *fifo_config; /**< FIFO sizes configuration */
usb_dwc_hal_fifo_config_t fifo_config; /**< FIFO sizes configuration */
union {
struct {
uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */
@ -190,7 +191,7 @@ typedef struct {
struct {
int num_allocd; /**< Number of channels currently allocated */
uint32_t chan_pend_intrs_msk; /**< Bit mask of channels with pending interrupts */
usb_dwc_hal_chan_t *hdls[USB_DWC_NUM_HOST_CHAN]; /**< Handles of each channel. Set to NULL if channel has not been allocated */
usb_dwc_hal_chan_t *hdls[OTG_NUM_HOST_CHAN]; /**< Handles of each channel. Set to NULL if channel has not been allocated */
} channels;
} usb_dwc_hal_context_t;

View File

@ -1,21 +1,30 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/soc_caps.h"
/*
This header is shared across all targets. Resolve to an empty header for targets
that don't support USB OTG.
*/
#if SOC_USB_OTG_SUPPORTED
#include <stdint.h>
#include <stdbool.h>
#include "soc/usb_dwc_struct.h"
#include "soc/usb_dwc_cfg.h"
#include "hal/usb_dwc_types.h"
#include "hal/misc.h"
#endif // SOC_USB_OTG_SUPPORTED
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "soc/usb_dwc_struct.h"
#include "hal/usb_dwc_types.h"
#include "hal/misc.h"
#if SOC_USB_OTG_SUPPORTED
/* -----------------------------------------------------------------------------
--------------------------------- DWC Constants --------------------------------
@ -23,88 +32,6 @@ extern "C" {
#define USB_DWC_QTD_LIST_MEM_ALIGN 512
#define USB_DWC_FRAME_LIST_MEM_ALIGN 512 // The frame list needs to be 512 bytes aligned (contrary to the databook)
/*
Although we have a 256 lines, only 200 lines are useable due to EPINFO_CTL.
Todo: Check sizes again and express this macro in terms of DWC config options (IDF-7384)
*/
#define USB_DWC_FIFO_TOTAL_USABLE_LINES 200
/* -----------------------------------------------------------------------------
------------------------------ DWC Configuration -------------------------------
----------------------------------------------------------------------------- */
/**
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
*
* RXFIFO
* - Recommended: ((LPS/4) * 2) + 2
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 48 - 48 = 104
* - Worst case can accommodate two packets of 204 bytes, or one packet of 408
* NPTXFIFO
* - Recommended: (LPS/4) * 2
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
* PTXFIFO
* - Recommended: (LPS/4) * 2
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
*/
#define USB_DWC_FIFO_RX_LINES_DEFAULT 104
#define USB_DWC_FIFO_NPTX_LINES_DEFAULT 48
#define USB_DWC_FIFO_PTX_LINES_DEFAULT 48
/**
* @brief FIFO sizes that bias to giving RX FIFO more capacity
*
* RXFIFO
* - Recommended: ((LPS/4) * 2) + 2
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 32 - 16 = 152
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
* NPTXFIFO
* - Recommended: (LPS/4) * 2
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
* - Worst case can accommodate one packet of 64 bytes
* PTXFIFO
* - Recommended: (LPS/4) * 2
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 2 = 32
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
*/
#define USB_DWC_FIFO_RX_LINES_BIASRX 152
#define USB_DWC_FIFO_NPTX_LINES_BIASRX 16
#define USB_DWC_FIFO_PTX_LINES_BIASRX 32
/**
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
*
* RXFIFO
* - Recommended: ((LPS/4) * 2) + 2
* - Actual: Assume LPS is 64, and 2 packets: ((64/4) * 2) + 2 = 34
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
* NPTXFIFO
* - Recommended: (LPS/4) * 2
* - Actual: Assume LPS is 64, and 1 packets: (64/4) * 1 = 16
* - Worst case can accommodate one packet of 64 bytes
* PTXFIFO
* - Recommended: (LPS/4) * 2
* - Actual: Whatever leftover size: USB_DWC_FIFO_TOTAL_USABLE_LINES(200) - 34 - 16 = 150
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
*/
#define USB_DWC_FIFO_RX_LINES_BIASTX 34
#define USB_DWC_FIFO_NPTX_LINES_BIASTX 16
#define USB_DWC_FIFO_PTX_LINES_BIASTX 150
/*
* List of relevant DWC configurations. See DWC OTG databook Chapter 3 for more
* details.
*/
#define USB_DWC_FSPHY_INTERFACE 1
#define USB_DWC_NUM_EPS 6
#define USB_DWC_NUM_IN_EPS 5 // Todo: Add check for when number of IN channels exceeds limit (IDF-8556)
#define USB_DWC_NUM_HOST_CHAN 8
#define USB_DWC_DFIFO_DEPTH 256
#define USB_DWC_RX_DFIFO_DEPTH 256
#define USB_DWC_TX_DFIFO_DEPTH 256 // Same value applies to HNPERIO, NPERIO, HPERIO, and DINEP
/* -----------------------------------------------------------------------------
------------------------------- Global Registers -------------------------------
@ -853,28 +780,48 @@ static inline uint32_t usb_dwc_ll_hctsiz_get_pid(volatile usb_dwc_host_chan_regs
static inline void usb_dwc_ll_hctsiz_set_qtd_list_len(volatile usb_dwc_host_chan_regs_t *chan, int qtd_list_len)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, ntd, qtd_list_len - 1); //Set the length of the descriptor list
usb_dwc_hctsiz_reg_t hctsiz;
hctsiz.val = chan->hctsiz_reg.val;
//Set the length of the descriptor list. NTD occupies xfersize[15:8]
hctsiz.xfersize &= ~(0xFF << 8);
hctsiz.xfersize |= ((qtd_list_len - 1) & 0xFF) << 8;
chan->hctsiz_reg.val = hctsiz.val;
}
static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan)
{
chan->hctsiz_reg.dopng = 0; //Don't do ping
HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, sched_info, 0xFF); //Schedinfo is always 0xFF for fullspeed. Not used in Bulk/Ctrl channels
usb_dwc_hctsiz_reg_t hctsiz;
hctsiz.val = chan->hctsiz_reg.val;
hctsiz.dopng = 0; //Don't do ping
/*
Set SCHED_INFO which occupies xfersize[7:0]
It is always set to 0xFF for full speed and not used in Bulk/Ctrl channels
*/
hctsiz.xfersize |= 0xFF;
chan->hctsiz_reg.val = hctsiz.val;
}
// ---------------------------- HCDMAi Register --------------------------------
static inline void usb_dwc_ll_hcdma_set_qtd_list_addr(volatile usb_dwc_host_chan_regs_t *chan, void *dmaaddr, uint32_t qtd_idx)
{
//Set HCDMAi
chan->hcdma_reg.val = 0;
chan->hcdma_reg.non_iso.dmaaddr = (((uint32_t)dmaaddr) >> 9) & 0x7FFFFF; //MSB of 512 byte aligned address
chan->hcdma_reg.non_iso.ctd = qtd_idx;
usb_dwc_hcdma_reg_t hcdma;
/*
Set the base address portion of the field which is dmaaddr[31:9]. This is
the based address of the QTD list and must be 512 bytes aligned
*/
hcdma.dmaaddr = ((uint32_t)dmaaddr) & 0xFFFFFE00;
//Set the current QTD index in the QTD list which is dmaaddr[8:3]
hcdma.dmaaddr |= (qtd_idx & 0x3F) << 3;
//dmaaddr[2:0] is reserved thus doesn't not need to be set
chan->hcdma_reg.val = hcdma.val;
}
static inline int usb_dwc_ll_hcdam_get_cur_qtd_idx(usb_dwc_host_chan_regs_t *chan)
{
return chan->hcdma_reg.non_iso.ctd;
//The current QTD index is dmaaddr[8:3]
return (chan->hcdma_reg.dmaaddr >> 3) & 0x3F;
}
// ---------------------------- HCDMABi Register -------------------------------
@ -994,6 +941,8 @@ static inline void usb_dwc_ll_qtd_get_status(usb_dwc_ll_dma_qtd_t *qtd, int *rem
qtd->buffer_status_val = 0;
}
#endif // SOC_USB_OTG_SUPPORTED
#ifdef __cplusplus
}
#endif

View File

@ -51,19 +51,6 @@ typedef enum {
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

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -27,14 +27,14 @@ typedef struct {
#if SOC_USB_SERIAL_JTAG_SUPPORTED
usb_serial_jtag_dev_t *jtag_dev; /**< Pointer to base address of USB Serial JTAG registers */
#endif
} usb_phy_hal_context_t;
} usb_fsls_phy_hal_context_t;
/**
* @brief Init the USB PHY hal. This function should be called first before other hal layer function is called
*
* @param hal Context of the HAL layer
*/
void usb_phy_hal_init(usb_phy_hal_context_t *hal);
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal);
/**
* @brief Configure internal/external PHY for USB_OTG
@ -42,7 +42,7 @@ void usb_phy_hal_init(usb_phy_hal_context_t *hal);
* @param hal Context of the HAL layer
* @param phy_target USB PHY target
*/
void usb_phy_hal_otg_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target);
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target);
#if SOC_USB_SERIAL_JTAG_SUPPORTED
/**
@ -51,7 +51,7 @@ void usb_phy_hal_otg_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_targe
* @param hal Context of the HAL layer
* @param phy_target USB PHY target
*/
void usb_phy_hal_jtag_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target);
void usb_fsls_phy_hal_jtag_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target);
#endif
/**
@ -59,7 +59,7 @@ void usb_phy_hal_jtag_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_targ
*
* @param hal Context of the HAL layer
*/
void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal);
void usb_fsls_phy_hal_int_load_conf_host(usb_fsls_phy_hal_context_t *hal);
/**
* @brief Configure pullup/pulldown loads for the D+/D- as a device
@ -67,7 +67,7 @@ void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal);
* @param hal Context of the HAL layer
* @param speed USB speed
*/
void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_phy_speed_t speed);
void usb_fsls_phy_hal_int_load_conf_dev(usb_fsls_phy_hal_context_t *hal, usb_phy_speed_t speed);
/**
* @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection
@ -75,7 +75,7 @@ void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_phy_speed_t s
* @param hal Context of the HAL layer
* @param disconn Whether to disconnect
*/
void usb_phy_hal_int_mimick_disconn(usb_phy_hal_context_t *hal, bool disconn);
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn);
#ifdef __cplusplus
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -9,9 +9,9 @@
#include <string.h>
#include "sdkconfig.h"
#include "soc/chip_revision.h"
#include "hal/efuse_hal.h"
#include "hal/usb_dwc_hal.h"
#include "hal/usb_dwc_ll.h"
#include "hal/efuse_hal.h"
#include "hal/assert.h"
// ------------------------------------------------ Macros and Types ---------------------------------------------------
@ -21,40 +21,7 @@
#define BENDPOINTADDRESS_NUM_MSK 0x0F //Endpoint number mask of the bEndpointAddress field of an endpoint descriptor
#define BENDPOINTADDRESS_DIR_MSK 0x80 //Endpoint direction mask of the bEndpointAddress field of an endpoint descriptor
#define CORE_REG_GSNPSID 0x4F54400A
#define CORE_REG_GHWCFG1 0x00000000
#define CORE_REG_GHWCFG2 0x224DD930
#define CORE_REG_GHWCFG3 0x00C804B5
#define CORE_REG_GHWCFG4 0xD3F0A030
// ----------------------- Configs -------------------------
/**
* @brief Default FIFO sizes (see 2.1.2.4 for programming guide)
*/
const usb_dwc_hal_fifo_config_t fifo_config_default = {
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_DEFAULT,
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_DEFAULT,
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_DEFAULT,
};
/**
* @brief FIFO sizes that bias to giving RX FIFO more capacity
*/
const usb_dwc_hal_fifo_config_t fifo_config_bias_rx = {
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_BIASRX,
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_BIASRX,
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_BIASRX,
};
/**
* @brief FIFO sizes that bias to giving Periodic TX FIFO more capacity (i.e., ISOC OUT)
*/
const usb_dwc_hal_fifo_config_t fifo_config_bias_ptx = {
.rx_fifo_lines = USB_DWC_FIFO_RX_LINES_BIASTX,
.nptx_fifo_lines = USB_DWC_FIFO_NPTX_LINES_BIASTX,
.ptx_fifo_lines = USB_DWC_FIFO_PTX_LINES_BIASTX,
};
#define CORE_REG_GSNPSID 0x4F54400A //Release number of USB_DWC used in Espressif's SoCs
// -------------------- Configurable -----------------------
@ -188,42 +155,69 @@ void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal)
hal->flags.val = 0;
hal->channels.num_allocd = 0;
hal->channels.chan_pend_intrs_msk = 0;
memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * USB_DWC_NUM_HOST_CHAN);
memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * OTG_NUM_HOST_CHAN);
}
void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bias_t fifo_bias)
{
const usb_dwc_hal_fifo_config_t *fifo_config;
/*
* EPINFO_CTL is located at the end of FIFO, its size is fixed in HW.
* The reserved size is always the worst-case, which is device mode that requires 4 locations per EP direction (including EP0).
* Here we just read the FIFO size from HW register, to avoid any ambivalence
*/
uint32_t ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4;
usb_dwc_ll_ghwcfg_get_hw_config(hal->dev, &ghwcfg1, &ghwcfg2, &ghwcfg3, &ghwcfg4);
const uint16_t fifo_size_lines = ((usb_dwc_ghwcfg3_reg_t)ghwcfg3).dfifodepth;
/*
* Recommended FIFO sizes (see 2.1.2.4 for programming guide)
*
* RXFIFO: ((LPS/4) * 2) + 2
* NPTXFIFO: (LPS/4) * 2
* PTXFIFO: (LPS/4) * 2
*
* Recommended sizes fit 2 packets of each type. For S2 and S3 we can't fit even one MPS ISOC packet (1023 FS and 1024 HS).
* So the calculations below are compromises between the available FIFO size and optimal performance.
*/
usb_dwc_hal_fifo_config_t fifo_config;
switch (fifo_bias) {
// Define minimum viable (fits at least 1 MPS) FIFO sizes for non-biased FIFO types
// Allocate the remaining size to the biased FIFO type
case USB_HAL_FIFO_BIAS_DEFAULT:
fifo_config = &fifo_config_default;
fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 4;
fifo_config.ptx_fifo_lines = OTG_DFIFO_DEPTH / 8;
fifo_config.rx_fifo_lines = fifo_size_lines - fifo_config.ptx_fifo_lines - fifo_config.nptx_fifo_lines;
break;
case USB_HAL_FIFO_BIAS_RX:
fifo_config = &fifo_config_bias_rx;
fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 16;
fifo_config.ptx_fifo_lines = OTG_DFIFO_DEPTH / 8;
fifo_config.rx_fifo_lines = fifo_size_lines - fifo_config.ptx_fifo_lines - fifo_config.nptx_fifo_lines;
break;
case USB_HAL_FIFO_BIAS_PTX:
fifo_config = &fifo_config_bias_ptx;
fifo_config.rx_fifo_lines = OTG_DFIFO_DEPTH / 8 + 2; // 2 extra lines are allocated for status information. See USB-OTG Programming Guide, chapter 2.1.2.1
fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 16;
fifo_config.ptx_fifo_lines = fifo_size_lines - fifo_config.nptx_fifo_lines - fifo_config.rx_fifo_lines;
break;
default:
abort();
}
HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USB_DWC_FIFO_TOTAL_USABLE_LINES);
HAL_ASSERT((fifo_config.rx_fifo_lines + fifo_config.nptx_fifo_lines + fifo_config.ptx_fifo_lines) <= fifo_size_lines);
//Check that none of the channels are active
for (int i = 0; i < USB_DWC_NUM_HOST_CHAN; i++) {
for (int i = 0; i < OTG_NUM_HOST_CHAN; i++) {
if (hal->channels.hdls[i] != NULL) {
HAL_ASSERT(!hal->channels.hdls[i]->flags.active);
}
}
//Set the new FIFO lengths
usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines);
usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines, fifo_config->nptx_fifo_lines);
usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines, fifo_config->ptx_fifo_lines);
usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config.rx_fifo_lines);
usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config.rx_fifo_lines, fifo_config.nptx_fifo_lines);
usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config.rx_fifo_lines + fifo_config.nptx_fifo_lines, fifo_config.ptx_fifo_lines);
//Flush the FIFOs
usb_dwc_ll_grstctl_flush_nptx_fifo(hal->dev);
usb_dwc_ll_grstctl_flush_ptx_fifo(hal->dev);
usb_dwc_ll_grstctl_flush_rx_fifo(hal->dev);
hal->fifo_config = fifo_config;
hal->fifo_config = fifo_config; // Implicit struct copy
hal->flags.fifo_sizes_set = 1;
}
@ -232,7 +226,7 @@ void usb_dwc_hal_get_mps_limits(usb_dwc_hal_context_t *hal, usb_hal_fifo_mps_lim
HAL_ASSERT(hal && mps_limits);
HAL_ASSERT(hal->flags.fifo_sizes_set);
const usb_dwc_hal_fifo_config_t *fifo_config = hal->fifo_config;
const usb_dwc_hal_fifo_config_t *fifo_config = &(hal->fifo_config);
mps_limits->in_mps = (fifo_config->rx_fifo_lines - 2) * 4; // Two lines are reserved for status quadlets internally by USB_DWC
mps_limits->non_periodic_out_mps = fifo_config->nptx_fifo_lines * 4;
mps_limits->periodic_out_mps = fifo_config->ptx_fifo_lines * 4;
@ -264,11 +258,11 @@ bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan
{
HAL_ASSERT(hal->flags.fifo_sizes_set); //FIFO sizes should be set befor attempting to allocate a channel
//Attempt to allocate channel
if (hal->channels.num_allocd == USB_DWC_NUM_HOST_CHAN) {
if (hal->channels.num_allocd == OTG_NUM_HOST_CHAN) {
return false; //Out of free channels
}
int chan_idx = -1;
for (int i = 0; i < USB_DWC_NUM_HOST_CHAN; i++) {
for (int i = 0; i < OTG_NUM_HOST_CHAN; i++) {
if (hal->channels.hdls[i] == NULL) {
hal->channels.hdls[i] = chan_obj;
chan_idx = i;

View File

@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/usb_fsls_phy_ll.h"
#include "hal/usb_fsls_phy_hal.h"
void usb_fsls_phy_hal_init(usb_fsls_phy_hal_context_t *hal)
{
hal->wrap_dev = &USB_WRAP;
#if SOC_USB_SERIAL_JTAG_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG;
#endif
}
void usb_fsls_phy_hal_otg_conf(usb_fsls_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_fsls_phy_ll_ext_otg_enable(hal->wrap_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_fsls_phy_ll_usb_wrap_pad_enable(hal->wrap_dev, true);
usb_fsls_phy_ll_int_otg_enable(hal->wrap_dev);
}
}
#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_fsls_phy_ll_ext_jtag_enable(hal->jtag_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_fsls_phy_ll_int_jtag_enable(hal->jtag_dev);
}
}
#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_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true);
}
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_fsls_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false);
} else {
// FS: dp_pu = 1
usb_fsls_phy_ll_int_load_conf(hal->wrap_dev, true, false, false, false);
}
}
void usb_fsls_phy_hal_int_mimick_disconn(usb_fsls_phy_hal_context_t *hal, bool disconn)
{
/*
We mimick 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_fsls_phy_ll_int_enable_test_mode(hal->wrap_dev, disconn);
}

View File

@ -1,64 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/usb_phy_ll.h"
#include "hal/usb_phy_hal.h"
void usb_phy_hal_init(usb_phy_hal_context_t *hal)
{
hal->wrap_dev = &USB_WRAP;
#if SOC_USB_SERIAL_JTAG_SUPPORTED
hal->jtag_dev = &USB_SERIAL_JTAG;
#endif
}
void usb_phy_hal_otg_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_phy_ll_ext_otg_enable(hal->wrap_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_phy_ll_usb_wrap_pad_enable(hal->wrap_dev, true);
usb_phy_ll_int_otg_enable(hal->wrap_dev);
}
}
#if SOC_USB_SERIAL_JTAG_SUPPORTED
void usb_phy_hal_jtag_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target)
{
if (phy_target == USB_PHY_TARGET_EXT) {
usb_phy_ll_ext_jtag_enable(hal->jtag_dev);
} else if (phy_target == USB_PHY_TARGET_INT) {
usb_phy_ll_int_jtag_enable(hal->jtag_dev);
}
}
#endif
void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal)
{
// HOST - upstream: dp_pd = 1, dm_pd = 1
usb_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true);
}
void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_phy_speed_t speed)
{
// DEVICE - downstream
if (speed == USB_PHY_SPEED_LOW) {
// LS: dm_pu = 1
usb_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false);
} else {
// FS: dp_pu = 1
usb_phy_ll_int_load_conf(hal->wrap_dev, true, false, false, false);
}
}
void usb_phy_hal_int_mimick_disconn(usb_phy_hal_context_t *hal, bool disconn)
{
/*
We mimick 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_phy_ll_int_enable_test_mode(hal->wrap_dev, disconn);
}

View File

@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/*
Configuration Set ID: 1
*/
/* 3.1 Basic Config Parameters */
#define OTG_MODE 0
#define OTG_ARCHITECTURE 2
#define OTG_SINGLE_POINT 1
#define OTG_ENABLE_LPM 0
#define OTG_EN_DED_TX_FIFO 1
#define OTG_EN_DESC_DMA 1
#define OTG_MULTI_PROC_INTRPT 0
/* 3.2 USB Physical Layer Interface Parameters */
#define OTG_HSPHY_INTERFACE 0
#define OTG_FSPHY_INTERFACE 1
#define OTG_ENABLE_IC_USB 0
#define OTG_I2C_INTERFACE 0
#define OTG_ADP_SUPPORT 0
#define OTG_BC_SUPPORT 0
/* 3.3 Device Endpoint Configuration Parameters */
#define OTG_NUM_EPS 6
#define OTG_NUM_IN_EPS 5
#define OTG_NUM_CRL_EPS 0
/* 3.4 Host Endpoint Configuration Parameters */
#define OTG_NUM_HOST_CHAN 8
#define OTG_EN_PERIO_HOST 1
/* 3.5 Endpoint Channel FIFO Configuration Parameters */
#define OTG_DFIFO_DEPTH 256
#define OTG_DFIFO_DYNAMIC 1
#define OTG_RX_DFIFO_DEPTH 256
#define OTG_TX_HNPERIO_DFIFO_DEPTH 256
#define OTG_TX_NPERIO_DFIFO_DEPTH 256
#define OTG_TX_HPERIO_DFIFO_DEPTH 256
#define OTG_NPERIO_TX_QUEUE_DEPTH 4
#define OTG_PERIO_TX_QUEUE_DEPTH 8
/* 3.6 Additional Configuration Options Parameters */
#define OTG_TRANS_COUNT_WIDTH 16
#define OTG_PACKET_COUNT_WIDTH 7
#define OTG_RM_OPT_FEATURES 1
#define OTG_EN_PWROPT 1
#define OTG_SYNC_RESET_TYPE 0
#define OTG_EN_IDDIG_FILTER 1
#define OTG_EN_VBUSVALID_FILTER 1
#define OTG_EN_A_VALID_FILTER 1
#define OTG_EN_B_VALID_FILTER 1
#define OTG_EN_SESSIONEND_FILTER 1
#define OTG_EXCP_CNTL_XFER_FLOW 1
#define OTG_PWR_CLAMP 0
#define OTG_PWR_SWITCH_POLARITY 0
/* 3.7 Endpoint Direction Parameters */
#define OTG_EP_DIR_1 0
#define OTG_EP_DIR_2 0
#define OTG_EP_DIR_3 0
#define OTG_EP_DIR_4 0
#define OTG_EP_DIR_5 0
#define OTG_EP_DIR_6 0
/* 3.8 Device Periodic FIFO Depth Parameters */
/* 3.9 Device IN Endpoint FIFO Depth Parameters */
#define OTG_TX_DINEP_DFIFO_DEPTH_1 256
#define OTG_TX_DINEP_DFIFO_DEPTH_2 256
#define OTG_TX_DINEP_DFIFO_DEPTH_3 256
#define OTG_TX_DINEP_DFIFO_DEPTH_4 256
/* 3.10 UTMI-To-UTMI Bridge Component Parameters */
#define U2UB_EN 0
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -153,7 +153,7 @@ typedef union {
* USB D- rx value in test.
*/
uint32_t test_rx_dm:1;
uint32_t reserved:25;
uint32_t reserved_7:25;
};
uint32_t val;
} usb_wrap_test_conf_reg_t;

View File

@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/*
Configuration Set ID: 1
*/
/* 3.1 Basic Config Parameters */
#define OTG_MODE 0
#define OTG_ARCHITECTURE 2
#define OTG_SINGLE_POINT 1
#define OTG_ENABLE_LPM 0
#define OTG_EN_DED_TX_FIFO 1
#define OTG_EN_DESC_DMA 1
#define OTG_MULTI_PROC_INTRPT 0
/* 3.2 USB Physical Layer Interface Parameters */
#define OTG_HSPHY_INTERFACE 0
#define OTG_FSPHY_INTERFACE 1
#define OTG_ENABLE_IC_USB 0
#define OTG_I2C_INTERFACE 0
#define OTG_ADP_SUPPORT 0
#define OTG_BC_SUPPORT 0
/* 3.3 Device Endpoint Configuration Parameters */
#define OTG_NUM_EPS 6
#define OTG_NUM_IN_EPS 5
#define OTG_NUM_CRL_EPS 0
/* 3.4 Host Endpoint Configuration Parameters */
#define OTG_NUM_HOST_CHAN 8
#define OTG_EN_PERIO_HOST 1
/* 3.5 Endpoint Channel FIFO Configuration Parameters */
#define OTG_DFIFO_DEPTH 256
#define OTG_DFIFO_DYNAMIC 1
#define OTG_RX_DFIFO_DEPTH 256
#define OTG_TX_HNPERIO_DFIFO_DEPTH 256
#define OTG_TX_NPERIO_DFIFO_DEPTH 256
#define OTG_TX_HPERIO_DFIFO_DEPTH 256
#define OTG_NPERIO_TX_QUEUE_DEPTH 4
#define OTG_PERIO_TX_QUEUE_DEPTH 8
/* 3.6 Additional Configuration Options Parameters */
#define OTG_TRANS_COUNT_WIDTH 16
#define OTG_PACKET_COUNT_WIDTH 7
#define OTG_RM_OPT_FEATURES 1
#define OTG_EN_PWROPT 1
#define OTG_SYNC_RESET_TYPE 0
#define OTG_EN_IDDIG_FILTER 1
#define OTG_EN_VBUSVALID_FILTER 1
#define OTG_EN_A_VALID_FILTER 1
#define OTG_EN_B_VALID_FILTER 1
#define OTG_EN_SESSIONEND_FILTER 1
#define OTG_EXCP_CNTL_XFER_FLOW 1
#define OTG_PWR_CLAMP 0
#define OTG_PWR_SWITCH_POLARITY 0
/* 3.7 Endpoint Direction Parameters */
#define OTG_EP_DIR_1 0
#define OTG_EP_DIR_2 0
#define OTG_EP_DIR_3 0
#define OTG_EP_DIR_4 0
#define OTG_EP_DIR_5 0
#define OTG_EP_DIR_6 0
/* 3.8 Device Periodic FIFO Depth Parameters */
/* 3.9 Device IN Endpoint FIFO Depth Parameters */
#define OTG_TX_DINEP_DFIFO_DEPTH_1 256
#define OTG_TX_DINEP_DFIFO_DEPTH_2 256
#define OTG_TX_DINEP_DFIFO_DEPTH_3 256
#define OTG_TX_DINEP_DFIFO_DEPTH_4 256
/* 3.10 UTMI-To-UTMI Bridge Component Parameters */
#define U2UB_EN 0
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -154,7 +154,7 @@ typedef union {
* USB D- rx value in test.
*/
uint32_t test_rx_dm:1;
uint32_t reserved7:25;
uint32_t reserved_7:25;
};
uint32_t val;
} usb_wrap_test_conf_reg_t;

View File

@ -1,12 +1,12 @@
set(srcs)
set(include)
set(priv_include)
# As CONFIG_USB_OTG_SUPPORTED comes from Kconfig, it is not evaluated yet
set(priv_includes)
# As CONFIG_SOC_USB_OTG_SUPPORTED comes from Kconfig, it is not evaluated yet
# when components are being registered.
# Thus, always add the (private) requirements, regardless of Kconfig
set(priv_require driver) # usb_phy driver relies on gpio driver API
set(priv_requires driver) # usb_phy driver relies on gpio driver API
if(CONFIG_USB_OTG_SUPPORTED)
if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs "hcd_dwc.c"
"hub.c"
"usb_helpers.c"
@ -15,11 +15,11 @@ if(CONFIG_USB_OTG_SUPPORTED)
"usbh.c"
"usb_phy.c")
list(APPEND include "include")
list(APPEND priv_include "private_include")
list(APPEND priv_includes "private_include")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${include}
PRIV_INCLUDE_DIRS ${priv_include}
PRIV_REQUIRES ${priv_require}
PRIV_INCLUDE_DIRS ${priv_includes}
PRIV_REQUIRES ${priv_requires}
)

View File

@ -1,13 +1,7 @@
menu "USB-OTG"
visible if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
# Invisible item, enabled when USB_OTG peripheral does exist
config USB_OTG_SUPPORTED
bool
default y if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
depends on SOC_USB_OTG_SUPPORTED
config USB_HOST_CONTROL_TRANSFER_MAX_SIZE
depends on USB_OTG_SUPPORTED
int "Largest size (in bytes) of transfers to/from default endpoints"
default 256
help
@ -18,7 +12,6 @@ menu "USB-OTG"
- Device's with configuration descriptors larger than this limit cannot be supported
choice USB_HOST_HW_BUFFER_BIAS
depends on USB_OTG_SUPPORTED
prompt "Hardware FIFO size biasing"
default USB_HOST_HW_BUFFER_BIAS_BALANCED
help
@ -56,7 +49,6 @@ menu "USB-OTG"
menu "Root Hub configuration"
config USB_HOST_DEBOUNCE_DELAY_MS
depends on USB_OTG_SUPPORTED
int "Debounce delay in ms"
default 250
help
@ -67,7 +59,6 @@ menu "USB-OTG"
The default value is set to 250 ms to be safe.
config USB_HOST_RESET_HOLD_MS
depends on USB_OTG_SUPPORTED
int "Reset hold in ms"
default 30
help
@ -79,7 +70,6 @@ menu "USB-OTG"
The default value is set to 30 ms to be safe.
config USB_HOST_RESET_RECOVERY_MS
depends on USB_OTG_SUPPORTED
int "Reset recovery delay in ms"
default 30
help
@ -92,7 +82,6 @@ menu "USB-OTG"
config USB_HOST_SET_ADDR_RECOVERY_MS
depends on USB_OTG_SUPPORTED
int "SetAddress() recovery time in ms"
default 10
help
@ -107,4 +96,12 @@ menu "USB-OTG"
endmenu #Root Hub configuration
# Hidden or compatibility options
config USB_OTG_SUPPORTED
# Invisible config kept for compatibility
# Todo: Remove in v6.0 (IDF-8936)
bool
default y
endmenu #USB-OTG

View File

@ -668,20 +668,20 @@ static bool _internal_pipe_event_notify(pipe_t *pipe, bool from_isr)
static usb_speed_t get_usb_port_speed(usb_dwc_speed_t priv)
{
switch (priv) {
case USB_DWC_SPEED_LOW: return USB_SPEED_LOW;
case USB_DWC_SPEED_FULL: return USB_SPEED_FULL;
case USB_DWC_SPEED_HIGH: return USB_SPEED_HIGH;
default: abort();
case USB_DWC_SPEED_LOW: return USB_SPEED_LOW;
case USB_DWC_SPEED_FULL: return USB_SPEED_FULL;
case USB_DWC_SPEED_HIGH: return USB_SPEED_HIGH;
default: abort();
}
}
static usb_hal_fifo_bias_t get_hal_fifo_bias(hcd_port_fifo_bias_t public)
{
switch (public) {
case HCD_PORT_FIFO_BIAS_BALANCED: return USB_HAL_FIFO_BIAS_DEFAULT;
case HCD_PORT_FIFO_BIAS_RX: return USB_HAL_FIFO_BIAS_RX;
case HCD_PORT_FIFO_BIAS_PTX: return USB_HAL_FIFO_BIAS_PTX;
default: abort();
case HCD_PORT_FIFO_BIAS_BALANCED: return USB_HAL_FIFO_BIAS_DEFAULT;
case HCD_PORT_FIFO_BIAS_RX: return USB_HAL_FIFO_BIAS_RX;
case HCD_PORT_FIFO_BIAS_PTX: return USB_HAL_FIFO_BIAS_PTX;
default: abort();
}
}
@ -1536,9 +1536,9 @@ static bool pipe_alloc_hcd_support_verification(usb_dwc_hal_context_t *hal, cons
}
}
if (ep_desc->wMaxPacketSize > limit) {
if (USB_EP_DESC_GET_MPS(ep_desc) > limit) {
ESP_LOGE(HCD_DWC_TAG, "EP MPS (%d) exceeds supported limit (%d)",
ep_desc->wMaxPacketSize,
USB_EP_DESC_GET_MPS(ep_desc),
limit);
return false;
}
@ -1571,38 +1571,38 @@ static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_
ep_char->mps = (pipe_config->dev_speed == USB_SPEED_LOW) ? CTRL_EP_MAX_MPS_LS : CTRL_EP_MAX_MPS_HSFS;
} else {
ep_char->bEndpointAddress = pipe_config->ep_desc->bEndpointAddress;
ep_char->mps = pipe_config->ep_desc->wMaxPacketSize;
ep_char->mps = USB_EP_DESC_GET_MPS(pipe_config->ep_desc);
}
ep_char->dev_addr = pipe_config->dev_addr;
ep_char->ls_via_fs_hub = (port_speed == USB_SPEED_FULL && pipe_config->dev_speed == USB_SPEED_LOW);
// Calculate the pipe's interval in terms of USB frames
// @see USB-OTG programming guide chapter 6.5 for more information
if (type == USB_TRANSFER_TYPE_INTR || type == USB_TRANSFER_TYPE_ISOCHRONOUS) {
unsigned int interval_frames;
unsigned int xfer_list_len;
if (type == USB_TRANSFER_TYPE_INTR) {
interval_frames = pipe_config->ep_desc->bInterval;
xfer_list_len = XFER_LIST_LEN_INTR;
// Convert bInterval field to real value
// @see USB 2.0 specs, Table 9-13
unsigned int interval_value;
if (type == USB_TRANSFER_TYPE_INTR && pipe_config->dev_speed != USB_SPEED_HIGH) {
interval_value = pipe_config->ep_desc->bInterval;
} else {
interval_frames = (1 << (pipe_config->ep_desc->bInterval - 1));
xfer_list_len = XFER_LIST_LEN_ISOC;
interval_value = (1 << (pipe_config->ep_desc->bInterval - 1));
}
// Round down interval to nearest power of 2
if (interval_frames >= 32) {
interval_frames = 32;
} else if (interval_frames >= 16) {
interval_frames = 16;
} else if (interval_frames >= 8) {
interval_frames = 8;
} else if (interval_frames >= 4) {
interval_frames = 4;
} else if (interval_frames >= 2) {
interval_frames = 2;
} else if (interval_frames >= 1) {
interval_frames = 1;
if (interval_value >= 32) {
interval_value = 32;
} else if (interval_value >= 16) {
interval_value = 16;
} else if (interval_value >= 8) {
interval_value = 8;
} else if (interval_value >= 4) {
interval_value = 4;
} else if (interval_value >= 2) {
interval_value = 2;
} else if (interval_value >= 1) {
interval_value = 1;
}
ep_char->periodic.interval = interval_frames;
ep_char->periodic.interval = interval_value;
// We are the Nth pipe to be allocated. Use N as a phase offset
unsigned int xfer_list_len = (type == USB_TRANSFER_TYPE_INTR) ? XFER_LIST_LEN_INTR : XFER_LIST_LEN_ISOC;
ep_char->periodic.phase_offset_frames = pipe_idx & (xfer_list_len - 1);
} else {
ep_char->periodic.interval = 0;
@ -2130,7 +2130,7 @@ static void _buffer_fill(pipe_t *pipe)
start_idx = (next_interval_idx_no_offset + pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1);
} else {
// Not enough time until the next schedule, add another interval to it.
start_idx = (next_interval_idx_no_offset + pipe->ep_char.periodic.interval + pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1);
start_idx = (next_interval_idx_no_offset + pipe->ep_char.periodic.interval + pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1);
}
} else {
// Start index is based on previously filled buffer

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -435,6 +435,12 @@ ESP_STATIC_ASSERT(sizeof(usb_ep_desc_t) == USB_EP_DESC_SIZE, "Size of usb_ep_des
#define USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK 0x0f
#define USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK 0x80
/**
* @brief Bit masks belonging to the wMaxPacketSize field of endpoint descriptor
*/
#define USB_W_MAX_PACKET_SIZE_MPS_MASK 0x07ff
#define USB_W_MAX_PACKET_SIZE_MULT_MASK 0x1800
/**
* @brief Bit masks belonging to the bmAttributes field of an endpoint descriptor
*/
@ -459,7 +465,8 @@ ESP_STATIC_ASSERT(sizeof(usb_ep_desc_t) == USB_EP_DESC_SIZE, "Size of usb_ep_des
#define USB_EP_DESC_GET_XFERTYPE(desc_ptr) ((usb_transfer_type_t) ((desc_ptr)->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK))
#define USB_EP_DESC_GET_EP_NUM(desc_ptr) ((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK)
#define USB_EP_DESC_GET_EP_DIR(desc_ptr) (((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) ? 1 : 0)
#define USB_EP_DESC_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & 0x7FF)
#define USB_EP_DESC_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & USB_W_MAX_PACKET_SIZE_MPS_MASK)
#define USB_EP_DESC_GET_MULT(desc_ptr) (((desc_ptr)->wMaxPacketSize & USB_W_MAX_PACKET_SIZE_MULT_MASK) >> 11)
// ------------------ String Descriptor --------------------

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -137,21 +137,21 @@ void mock_msc_scsi_init_reference_descriptors(void)
// String descriptors
const char *str = MOCK_MSC_SCSI_STRING_1;
uint8_t chr_count = strlen(str);
mock_msc_scsi_str_desc_manu[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8 ) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
mock_msc_scsi_str_desc_manu[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
for (uint8_t i = 0; i < chr_count; i++) {
mock_msc_scsi_str_desc_manu[1 + i] = str[i];
}
str = MOCK_MSC_SCSI_STRING_2;
chr_count = strlen(str);
mock_msc_scsi_str_desc_prod[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8 ) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
mock_msc_scsi_str_desc_prod[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
for (uint8_t i = 0; i < chr_count; i++) {
mock_msc_scsi_str_desc_prod[1 + i] = str[i];
}
str = MOCK_MSC_SCSI_STRING_3;
chr_count = strlen(str);
mock_msc_scsi_str_desc_ser_num[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8 ) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
mock_msc_scsi_str_desc_ser_num[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
for (uint8_t i = 0; i < chr_count; i++) {
mock_msc_scsi_str_desc_ser_num[1 + i] = str[i];
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -112,7 +112,8 @@ extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
(setup_pkt_ptr)->wLength = 0; \
})
typedef struct __attribute__((packed)) {
typedef struct __attribute__((packed))
{
uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
uint8_t flags;
uint8_t lba_3;
@ -125,7 +126,8 @@ typedef struct __attribute__((packed)) {
uint8_t control;
} mock_scsi_cmd10_t;
typedef struct __attribute__((packed)) {
typedef struct __attribute__((packed))
{
uint32_t dCBWSignature;
uint32_t dCBWTag;
uint32_t dCBWDataTransferLength;
@ -137,7 +139,8 @@ typedef struct __attribute__((packed)) {
} mock_msc_bulk_cbw_t;
// USB Bulk Transfer Command Status Wrapper data
typedef struct __attribute__((packed)) {
typedef struct __attribute__((packed))
{
uint32_t dCSWSignature;
uint32_t dCSWTag;
uint32_t dCSWDataResidue;
@ -180,7 +183,6 @@ ISOC, transferring to a non-existent endpoint should work. The non-existent endp
#define MOCK_ISOC_EP_NUM 2
#define MOCK_ISOC_EP_MPS 512
static const usb_ep_desc_t mock_isoc_out_ep_desc = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
@ -190,7 +192,6 @@ static const usb_ep_desc_t mock_isoc_out_ep_desc = {
.bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
};
#ifdef __cplusplus
}
#endif

View File

@ -68,10 +68,11 @@ TEST_CASE("Test HCD bulk pipe URBs", "[bulk][full_speed]")
//Create URBs for CBW, Data, and CSW transport. IN Buffer sizes are rounded up to nearest MPS
urb_t *urb_cbw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_cbw_t));
urb_t *urb_data = test_hcd_alloc_urb(0, TEST_NUM_SECTORS_PER_XFER * MOCK_MSC_SCSI_SECTOR_SIZE);
urb_t *urb_csw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_csw_t) + (mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize - (sizeof(mock_msc_bulk_csw_t) % mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize)));
const uint16_t mps = USB_EP_DESC_GET_MPS(&mock_msc_scsi_bulk_in_ep_desc) ;
urb_t *urb_csw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_csw_t) + (mps - (sizeof(mock_msc_bulk_csw_t) % mps)));
urb_cbw->transfer.num_bytes = sizeof(mock_msc_bulk_cbw_t);
urb_data->transfer.num_bytes = TEST_NUM_SECTORS_PER_XFER * MOCK_MSC_SCSI_SECTOR_SIZE;
urb_csw->transfer.num_bytes = sizeof(mock_msc_bulk_csw_t) + (mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize - (sizeof(mock_msc_bulk_csw_t) % mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize));
urb_csw->transfer.num_bytes = sizeof(mock_msc_bulk_csw_t) + (mps - (sizeof(mock_msc_bulk_csw_t) % mps));
for (int block_num = 0; block_num < TEST_NUM_SECTORS_TOTAL; block_num += TEST_NUM_SECTORS_PER_XFER) {
//Initialize CBW URB, then send it on the BULK OUT pipe

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -68,7 +68,7 @@ TEST_CASE("Test HCD control pipe URBs", "[ctrl][low_speed][full_speed]")
TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes);
TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes);
usb_config_desc_t *config_desc = (usb_config_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t));
TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION , config_desc->bDescriptorType);
TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION, config_desc->bDescriptorType);
printf("Config Desc wTotalLength %d\n", config_desc->wTotalLength);
}
@ -201,7 +201,7 @@ TEST_CASE("Test HCD control pipe STALL", "[ctrl][full_speed]")
TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes);
TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes);
usb_config_desc_t *config_desc = (usb_config_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t));
TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION , config_desc->bDescriptorType);
TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION, config_desc->bDescriptorType);
printf("Config Desc wTotalLength %d\n", config_desc->wTotalLength);
}
@ -270,11 +270,11 @@ TEST_CASE("Test HCD control pipe runtime halt and clear", "[ctrl][low_speed][ful
TEST_ASSERT_EQUAL_PTR(urb_list[i], urb);
TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || urb->transfer.status == USB_TRANSFER_STATUS_CANCELED);
if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) {
//We must have transmitted at least the setup packet, but device may return less than bytes requested
//We must have transmitted at least the setup packet, but device may return less than bytes requested
TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes);
TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes);
usb_config_desc_t *config_desc = (usb_config_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t));
TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION , config_desc->bDescriptorType);
TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION, config_desc->bDescriptorType);
printf("Config Desc wTotalLength %d\n", config_desc->wTotalLength);
} else {
//A failed transfer should 0 actual number of bytes transmitted

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -76,14 +76,14 @@ static void ctrl_client_event_cb(const usb_host_client_event_msg_t *event_msg, v
{
ctrl_client_obj_t *ctrl_obj = (ctrl_client_obj_t *)arg;
switch (event_msg->event) {
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, ctrl_obj->cur_stage);
ctrl_obj->next_stage = TEST_STAGE_DEV_OPEN;
ctrl_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
default:
abort(); //Should never occur in this test
break;
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, ctrl_obj->cur_stage);
ctrl_obj->next_stage = TEST_STAGE_DEV_OPEN;
ctrl_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
default:
abort(); //Should never occur in this test
break;
}
}
@ -100,7 +100,7 @@ void ctrl_client_async_seq_task(void *arg)
.max_num_event_msg = CTRL_CLIENT_MAX_EVENT_MSGS,
.async = {
.client_event_callback = ctrl_client_event_cb,
.callback_arg = (void *)&ctrl_obj,
.callback_arg = (void *) &ctrl_obj,
},
};
TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &ctrl_obj.client_hdl));
@ -130,52 +130,52 @@ void ctrl_client_async_seq_task(void *arg)
ctrl_obj.cur_stage = ctrl_obj.next_stage;
switch (ctrl_obj.next_stage) {
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(CTRL_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr_to_open, &ctrl_obj.dev_hdl), "Failed to open the device");
//Target our transfers to the device
for (int i = 0; i < NUM_TRANSFER_OBJ; i++) {
ctrl_xfer[i]->device_handle = ctrl_obj.dev_hdl;
}
//Check the VID/PID of the opened device
const usb_device_desc_t *device_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(ctrl_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(ctrl_obj.test_param.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(ctrl_obj.test_param.idProduct, device_desc->idProduct);
//Cache the active configuration descriptor for later comparison
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(ctrl_obj.dev_hdl, &ctrl_obj.config_desc_cached));
ctrl_obj.next_stage = TEST_STAGE_CTRL_XFER;
skip_event_handling = true;
break;
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(CTRL_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr_to_open, &ctrl_obj.dev_hdl), "Failed to open the device");
//Target our transfers to the device
for (int i = 0; i < NUM_TRANSFER_OBJ; i++) {
ctrl_xfer[i]->device_handle = ctrl_obj.dev_hdl;
}
case TEST_STAGE_CTRL_XFER: {
ESP_LOGD(CTRL_CLIENT_TAG, "Transfer");
//Send a control transfer to get the device's configuration descriptor
usb_transfer_t *transfer = ctrl_xfer[ctrl_obj.num_xfer_sent % NUM_TRANSFER_OBJ];
USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)transfer->data_buffer, 0, MAX_TRANSFER_BYTES);
transfer->num_bytes = sizeof(usb_setup_packet_t) + MAX_TRANSFER_BYTES;
transfer->bEndpointAddress = 0x80;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(ctrl_obj.client_hdl, transfer));
ctrl_obj.num_xfer_sent++;
ctrl_obj.next_stage = TEST_STAGE_CTRL_XFER_WAIT;
skip_event_handling = true;
break;
}
case TEST_STAGE_CTRL_XFER_WAIT: {
//Nothing to do but wait
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(CTRL_CLIENT_TAG, "Close");
vTaskDelay(10); // Give USB Host Lib some time to process all trnsfers
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(ctrl_obj.client_hdl, ctrl_obj.dev_hdl));
exit_loop = true;
break;
}
default:
abort();
break;
//Check the VID/PID of the opened device
const usb_device_desc_t *device_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(ctrl_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(ctrl_obj.test_param.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(ctrl_obj.test_param.idProduct, device_desc->idProduct);
//Cache the active configuration descriptor for later comparison
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(ctrl_obj.dev_hdl, &ctrl_obj.config_desc_cached));
ctrl_obj.next_stage = TEST_STAGE_CTRL_XFER;
skip_event_handling = true;
break;
}
case TEST_STAGE_CTRL_XFER: {
ESP_LOGD(CTRL_CLIENT_TAG, "Transfer");
//Send a control transfer to get the device's configuration descriptor
usb_transfer_t *transfer = ctrl_xfer[ctrl_obj.num_xfer_sent % NUM_TRANSFER_OBJ];
USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)transfer->data_buffer, 0, MAX_TRANSFER_BYTES);
transfer->num_bytes = sizeof(usb_setup_packet_t) + MAX_TRANSFER_BYTES;
transfer->bEndpointAddress = 0x80;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(ctrl_obj.client_hdl, transfer));
ctrl_obj.num_xfer_sent++;
ctrl_obj.next_stage = TEST_STAGE_CTRL_XFER_WAIT;
skip_event_handling = true;
break;
}
case TEST_STAGE_CTRL_XFER_WAIT: {
//Nothing to do but wait
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(CTRL_CLIENT_TAG, "Close");
vTaskDelay(10); // Give USB Host Lib some time to process all trnsfers
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(ctrl_obj.client_hdl, ctrl_obj.dev_hdl));
exit_loop = true;
break;
}
default:
abort();
break;
}
}
//Free transfers and deregister client

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -64,15 +64,15 @@ static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer)
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes);
switch (msc_obj->cur_stage) {
case TEST_STAGE_MSC_RESET:
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
break;
case TEST_STAGE_MSC_CBW:
msc_obj->next_stage = TEST_STAGE_MSC_DATA_DCONN;
break;
default:
abort();
break;
case TEST_STAGE_MSC_RESET:
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
break;
case TEST_STAGE_MSC_CBW:
msc_obj->next_stage = TEST_STAGE_MSC_DATA_DCONN;
break;
default:
abort();
break;
}
}
@ -97,21 +97,21 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo
{
msc_client_obj_t *msc_obj = (msc_client_obj_t *)arg;
switch (event_msg->event) {
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage);
msc_obj->next_stage = TEST_STAGE_DEV_OPEN;
msc_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
case USB_HOST_CLIENT_EVENT_DEV_GONE:
msc_obj->event_count++;
//If all transfers dequeued and device gone event occurred. Go to next stage
if (msc_obj->event_count >= msc_obj->num_data_transfers + 1) {
msc_obj->next_stage = TEST_STAGE_DEV_CLOSE;
}
break;
default:
abort(); //Should never occur in this test
break;
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage);
msc_obj->next_stage = TEST_STAGE_DEV_OPEN;
msc_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
case USB_HOST_CLIENT_EVENT_DEV_GONE:
msc_obj->event_count++;
//If all transfers dequeued and device gone event occurred. Go to next stage
if (msc_obj->event_count >= msc_obj->num_data_transfers + 1) {
msc_obj->next_stage = TEST_STAGE_DEV_CLOSE;
}
break;
default:
abort(); //Should never occur in this test
break;
}
}
@ -133,7 +133,7 @@ void msc_client_async_dconn_task(void *arg)
.max_num_event_msg = MSC_ASYNC_CLIENT_MAX_EVENT_MSGS,
.async = {
.client_event_callback = msc_client_event_cb,
.callback_arg = (void *)&msc_obj,
.callback_arg = (void *) &msc_obj,
},
};
TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl));
@ -168,85 +168,85 @@ void msc_client_async_dconn_task(void *arg)
msc_obj.cur_stage = msc_obj.next_stage;
switch (msc_obj.cur_stage) {
case TEST_STAGE_WAIT_CONN: {
//Nothing to do while waiting for connection
break;
case TEST_STAGE_WAIT_CONN: {
//Nothing to do while waiting for connection
break;
}
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(MSC_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl));
//Target our transfers to the device
xfer_out->device_handle = msc_obj.dev_hdl;
xfer_out->callback = msc_reset_cbw_transfer_cb;
for (int i = 0; i < msc_obj.num_data_transfers; i++) {
xfer_in[i]->device_handle = msc_obj.dev_hdl;
xfer_in[i]->callback = msc_data_transfer_cb;
}
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(MSC_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl));
//Target our transfers to the device
xfer_out->device_handle = msc_obj.dev_hdl;
xfer_out->callback = msc_reset_cbw_transfer_cb;
for (int i = 0; i < msc_obj.num_data_transfers; i++) {
xfer_in[i]->device_handle = msc_obj.dev_hdl;
xfer_in[i]->callback = msc_data_transfer_cb;
}
//Check the VID/PID of the opened device
const usb_device_desc_t *device_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(msc_obj.test_param.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct);
//Claim the MSC interface
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
msc_obj.next_stage = TEST_STAGE_MSC_RESET;
skip_event_handling = true; //Need to execute TEST_STAGE_MSC_RESET
break;
//Check the VID/PID of the opened device
const usb_device_desc_t *device_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(msc_obj.test_param.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct);
//Claim the MSC interface
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
msc_obj.next_stage = TEST_STAGE_MSC_RESET;
skip_event_handling = true; //Need to execute TEST_STAGE_MSC_RESET
break;
}
case TEST_STAGE_MSC_RESET: {
ESP_LOGD(MSC_CLIENT_TAG, "MSC Reset");
//Send an MSC SCSI interface reset
MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, MOCK_MSC_SCSI_INTF_NUMBER);
xfer_out->num_bytes = sizeof(usb_setup_packet_t);
xfer_out->bEndpointAddress = 0;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_CBW: {
ESP_LOGD(MSC_CLIENT_TAG, "CBW");
mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, true, 0, msc_obj.test_param.num_sectors_per_xfer, msc_obj.test_param.msc_scsi_xfer_tag);
xfer_out->num_bytes = sizeof(mock_msc_bulk_cbw_t);
xfer_out->bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_DATA_DCONN: {
ESP_LOGD(MSC_CLIENT_TAG, "Data and disconnect");
//Setup the Data IN transfers
for (int i = 0; i < msc_obj.num_data_transfers; i++) {
xfer_in[i]->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE, MOCK_MSC_SCSI_BULK_EP_MPS);
xfer_in[i]->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
}
case TEST_STAGE_MSC_RESET: {
ESP_LOGD(MSC_CLIENT_TAG, "MSC Reset");
//Send an MSC SCSI interface reset
MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, MOCK_MSC_SCSI_INTF_NUMBER);
xfer_out->num_bytes = sizeof(usb_setup_packet_t);
xfer_out->bEndpointAddress = 0;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out));
//Next stage set from transfer callback
break;
//Submit those transfers
for (int i = 0; i < msc_obj.num_data_transfers; i++) {
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in[i]));
}
case TEST_STAGE_MSC_CBW: {
ESP_LOGD(MSC_CLIENT_TAG, "CBW");
mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, true, 0, msc_obj.test_param.num_sectors_per_xfer, msc_obj.test_param.msc_scsi_xfer_tag);
xfer_out->num_bytes = sizeof(mock_msc_bulk_cbw_t);
xfer_out->bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out));
//Next stage set from transfer callback
break;
//Trigger a disconnect
test_usb_set_phy_state(false, 0);
//Next stage set from transfer callback
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(MSC_CLIENT_TAG, "Close");
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER));
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl));
dconn_iter++;
if (dconn_iter < TEST_DCONN_ITERATIONS) {
//Start the next test iteration by going back to TEST_STAGE_WAIT_CONN and reenabling connections
msc_obj.next_stage = TEST_STAGE_WAIT_CONN;
skip_event_handling = true; //Need to execute TEST_STAGE_WAIT_CONN
test_usb_set_phy_state(true, 0);
} else {
exit_loop = true;
}
case TEST_STAGE_MSC_DATA_DCONN: {
ESP_LOGD(MSC_CLIENT_TAG, "Data and disconnect");
//Setup the Data IN transfers
for (int i = 0; i < msc_obj.num_data_transfers; i++) {
xfer_in[i]->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE, MOCK_MSC_SCSI_BULK_EP_MPS);
xfer_in[i]->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
}
//Submit those transfers
for (int i = 0; i < msc_obj.num_data_transfers; i++) {
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in[i]));
}
//Trigger a disconnect
test_usb_set_phy_state(false, 0);
//Next stage set from transfer callback
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(MSC_CLIENT_TAG, "Close");
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER));
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl));
dconn_iter++;
if (dconn_iter < TEST_DCONN_ITERATIONS) {
//Start the next test iteration by going back to TEST_STAGE_WAIT_CONN and reenabling connections
msc_obj.next_stage = TEST_STAGE_WAIT_CONN;
skip_event_handling = true; //Need to execute TEST_STAGE_WAIT_CONN
test_usb_set_phy_state(true, 0);
} else {
exit_loop = true;
}
break;
}
default:
abort();
break;
break;
}
default:
abort();
break;
}
}
//Free transfers

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -54,14 +54,14 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo
{
msc_client_obj_t *msc_obj = (msc_client_obj_t *)arg;
switch (event_msg->event) {
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage);
msc_obj->next_stage = TEST_STAGE_DEV_OPEN;
msc_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
default:
abort(); //Should never occur in this test
break;
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage);
msc_obj->next_stage = TEST_STAGE_DEV_OPEN;
msc_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
default:
abort(); //Should never occur in this test
break;
}
}
@ -81,7 +81,7 @@ void msc_client_async_enum_task(void *arg)
.max_num_event_msg = MSC_ASYNC_CLIENT_MAX_EVENT_MSGS,
.async = {
.client_event_callback = msc_client_event_cb,
.callback_arg = (void *)&msc_obj,
.callback_arg = (void *) &msc_obj,
},
};
TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl));
@ -104,78 +104,78 @@ void msc_client_async_enum_task(void *arg)
msc_obj.cur_stage = msc_obj.next_stage;
switch (msc_obj.cur_stage) {
case TEST_STAGE_WAIT_CONN: {
//Wait for connection, nothing to do
break;
}
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(MSC_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl));
msc_obj.next_stage = TEST_STAGE_CHECK_DEV_DESC;
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_DEV_DESC
break;
}
case TEST_STAGE_CHECK_DEV_DESC: {
//Check the device descriptor
const usb_device_desc_t *device_desc;
const usb_device_desc_t *device_desc_ref = &mock_msc_scsi_dev_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength);
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, device_desc_ref->bLength, "Device descriptors do not match.");
msc_obj.next_stage = TEST_STAGE_CHECK_CONFIG_DESC;
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_CONFIG_DESC
break;
}
case TEST_STAGE_WAIT_CONN: {
//Wait for connection, nothing to do
break;
}
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(MSC_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl));
msc_obj.next_stage = TEST_STAGE_CHECK_DEV_DESC;
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_DEV_DESC
break;
}
case TEST_STAGE_CHECK_DEV_DESC: {
//Check the device descriptor
const usb_device_desc_t *device_desc;
const usb_device_desc_t *device_desc_ref = &mock_msc_scsi_dev_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength);
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, device_desc_ref->bLength, "Device descriptors do not match.");
msc_obj.next_stage = TEST_STAGE_CHECK_CONFIG_DESC;
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_CONFIG_DESC
break;
}
case TEST_STAGE_CHECK_CONFIG_DESC: {
//Check the configuration descriptor
const usb_config_desc_t *config_desc;
const usb_config_desc_t *config_desc_ref = (const usb_config_desc_t *)mock_msc_scsi_config_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(msc_obj.dev_hdl, &config_desc));
TEST_ASSERT_EQUAL_MESSAGE(config_desc_ref->wTotalLength, config_desc->wTotalLength, "Incorrent length of CFG descriptor");
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, config_desc_ref->wTotalLength, "Configuration descriptors do not match");
msc_obj.next_stage = TEST_STAGE_CHECK_STR_DESC;
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_STR_DESC
break;
}
case TEST_STAGE_CHECK_STR_DESC: {
usb_device_info_t dev_info;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info));
//Check manufacturer string descriptors
const usb_str_desc_t *manu_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_manu;
const usb_str_desc_t *product_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_prod;
const usb_str_desc_t *ser_num_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_ser_num;
TEST_ASSERT_EQUAL(manu_str_desc_ref->bLength, dev_info.str_desc_manufacturer->bLength);
TEST_ASSERT_EQUAL(product_str_desc_ref->bLength, dev_info.str_desc_product->bLength);
TEST_ASSERT_EQUAL(ser_num_str_desc_ref->bLength, dev_info.str_desc_serial_num->bLength);
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(manu_str_desc_ref, dev_info.str_desc_manufacturer , manu_str_desc_ref->bLength, "Manufacturer string descriptors do not match.");
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(product_str_desc_ref, dev_info.str_desc_product , manu_str_desc_ref->bLength, "Product string descriptors do not match.");
//TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ser_num_str_desc_ref, dev_info.str_desc_serial_num , manu_str_desc_ref->bLength, "Serial number string descriptors do not match.");
//Get dev info and compare
msc_obj.next_stage = TEST_STAGE_DEV_CLOSE;
skip_event_handling = true; //Need to execute TEST_STAGE_DEV_CLOSE
break;
}
case TEST_STAGE_CHECK_CONFIG_DESC: {
//Check the configuration descriptor
const usb_config_desc_t *config_desc;
const usb_config_desc_t *config_desc_ref = (const usb_config_desc_t *)mock_msc_scsi_config_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(msc_obj.dev_hdl, &config_desc));
TEST_ASSERT_EQUAL_MESSAGE(config_desc_ref->wTotalLength, config_desc->wTotalLength, "Incorrent length of CFG descriptor");
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, config_desc_ref->wTotalLength, "Configuration descriptors do not match");
msc_obj.next_stage = TEST_STAGE_CHECK_STR_DESC;
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_STR_DESC
break;
}
case TEST_STAGE_CHECK_STR_DESC: {
usb_device_info_t dev_info;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info));
//Check manufacturer string descriptors
const usb_str_desc_t *manu_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_manu;
const usb_str_desc_t *product_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_prod;
const usb_str_desc_t *ser_num_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_ser_num;
TEST_ASSERT_EQUAL(manu_str_desc_ref->bLength, dev_info.str_desc_manufacturer->bLength);
TEST_ASSERT_EQUAL(product_str_desc_ref->bLength, dev_info.str_desc_product->bLength);
TEST_ASSERT_EQUAL(ser_num_str_desc_ref->bLength, dev_info.str_desc_serial_num->bLength);
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(manu_str_desc_ref, dev_info.str_desc_manufacturer, manu_str_desc_ref->bLength, "Manufacturer string descriptors do not match.");
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(product_str_desc_ref, dev_info.str_desc_product, manu_str_desc_ref->bLength, "Product string descriptors do not match.");
//TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ser_num_str_desc_ref, dev_info.str_desc_serial_num , manu_str_desc_ref->bLength, "Serial number string descriptors do not match.");
//Get dev info and compare
msc_obj.next_stage = TEST_STAGE_DEV_CLOSE;
skip_event_handling = true; //Need to execute TEST_STAGE_DEV_CLOSE
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(MSC_CLIENT_TAG, "Close");
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl));
enum_iter++;
if (enum_iter < TEST_ENUM_ITERATIONS) {
//Start the next test iteration by disconnecting the device, then going back to TEST_STAGE_WAIT_CONN stage
test_usb_set_phy_state(false, 0);
test_usb_set_phy_state(true, 0);
msc_obj.next_stage = TEST_STAGE_WAIT_CONN;
skip_event_handling = true; //Need to execute TEST_STAGE_WAIT_CONN
} else {
exit_loop = true;
}
break;
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(MSC_CLIENT_TAG, "Close");
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl));
enum_iter++;
if (enum_iter < TEST_ENUM_ITERATIONS) {
//Start the next test iteration by disconnecting the device, then going back to TEST_STAGE_WAIT_CONN stage
test_usb_set_phy_state(false, 0);
test_usb_set_phy_state(true, 0);
msc_obj.next_stage = TEST_STAGE_WAIT_CONN;
skip_event_handling = true; //Need to execute TEST_STAGE_WAIT_CONN
} else {
exit_loop = true;
}
default:
abort();
break;
break;
}
default:
abort();
break;
}
}
//Free transfers and deregister the client

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -59,43 +59,43 @@ static void msc_transfer_cb(usb_transfer_t *transfer)
{
msc_client_obj_t *msc_obj = (msc_client_obj_t *)transfer->context;
switch (msc_obj->cur_stage) {
case TEST_STAGE_MSC_RESET: {
//Check MSC SCSI interface reset
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes);
case TEST_STAGE_MSC_RESET: {
//Check MSC SCSI interface reset
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes);
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
break;
}
case TEST_STAGE_MSC_CBW: {
//Check MSC SCSI CBW transfer
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(sizeof(mock_msc_bulk_cbw_t), transfer->actual_num_bytes);
msc_obj->next_stage = TEST_STAGE_MSC_DATA;
break;
}
case TEST_STAGE_MSC_DATA: {
//Check MSC SCSI data IN transfer
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj->test_param.num_sectors_per_xfer, transfer->actual_num_bytes);
msc_obj->next_stage = TEST_STAGE_MSC_CSW;
break;
}
case TEST_STAGE_MSC_CSW: {
//Check MSC SCSI CSW transfer
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_TRUE(mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)transfer->data_buffer, msc_obj->test_param.msc_scsi_xfer_tag));
msc_obj->num_sectors_read += msc_obj->test_param.num_sectors_per_xfer;
if (msc_obj->num_sectors_read < msc_obj->test_param.num_sectors_to_read) {
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
break;
}
case TEST_STAGE_MSC_CBW: {
//Check MSC SCSI CBW transfer
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(sizeof(mock_msc_bulk_cbw_t), transfer->actual_num_bytes);
msc_obj->next_stage = TEST_STAGE_MSC_DATA;
break;
}
case TEST_STAGE_MSC_DATA: {
//Check MSC SCSI data IN transfer
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_EQUAL(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj->test_param.num_sectors_per_xfer, transfer->actual_num_bytes);
msc_obj->next_stage = TEST_STAGE_MSC_CSW;
break;
}
case TEST_STAGE_MSC_CSW: {
//Check MSC SCSI CSW transfer
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
TEST_ASSERT_TRUE(mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)transfer->data_buffer, msc_obj->test_param.msc_scsi_xfer_tag));
msc_obj->num_sectors_read += msc_obj->test_param.num_sectors_per_xfer;
if (msc_obj->num_sectors_read < msc_obj->test_param.num_sectors_to_read) {
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
} else {
msc_obj->next_stage = TEST_STAGE_DEV_CLOSE;
}
break;
}
default: {
abort();
break;
} else {
msc_obj->next_stage = TEST_STAGE_DEV_CLOSE;
}
break;
}
default: {
abort();
break;
}
}
}
@ -103,14 +103,14 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo
{
msc_client_obj_t *msc_obj = (msc_client_obj_t *)arg;
switch (event_msg->event) {
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage);
msc_obj->next_stage = TEST_STAGE_DEV_OPEN;
msc_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
default:
abort(); //Should never occur in this test
break;
case USB_HOST_CLIENT_EVENT_NEW_DEV:
TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage);
msc_obj->next_stage = TEST_STAGE_DEV_OPEN;
msc_obj->dev_addr_to_open = event_msg->new_dev.address;
break;
default:
abort(); //Should never occur in this test
break;
}
}
@ -132,7 +132,7 @@ void msc_client_async_seq_task(void *arg)
.max_num_event_msg = MSC_ASYNC_CLIENT_MAX_EVENT_MSGS,
.async = {
.client_event_callback = msc_client_event_cb,
.callback_arg = (void *)&msc_obj,
.callback_arg = (void *) &msc_obj,
},
};
TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl));
@ -166,77 +166,77 @@ void msc_client_async_seq_task(void *arg)
msc_obj.cur_stage = msc_obj.next_stage;
switch (msc_obj.cur_stage) {
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(MSC_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl));
//Target our transfers to the device
xfer_out->device_handle = msc_obj.dev_hdl;
xfer_in->device_handle = msc_obj.dev_hdl;
//Check the VID/PID of the opened device
const usb_device_desc_t *device_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(msc_obj.test_param.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct);
//Claim the MSC interface
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
msc_obj.next_stage = TEST_STAGE_MSC_RESET;
skip_event_handling = true; //Need to execute TEST_STAGE_MSC_RESET
break;
}
case TEST_STAGE_MSC_RESET: {
ESP_LOGD(MSC_CLIENT_TAG, "MSC Reset");
//Send an MSC SCSI interface reset
MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, MOCK_MSC_SCSI_INTF_NUMBER);
xfer_out->num_bytes = sizeof(usb_setup_packet_t);
xfer_out->bEndpointAddress = 0;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out));
//Test that an inflight control transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_CBW: {
ESP_LOGD(MSC_CLIENT_TAG, "CBW");
mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, true, msc_obj.next_stage, msc_obj.test_param.num_sectors_per_xfer, msc_obj.test_param.msc_scsi_xfer_tag);
xfer_out->num_bytes = sizeof(mock_msc_bulk_cbw_t);
xfer_out->bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out));
//Test that an inflight transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_out));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_DATA: {
ESP_LOGD(MSC_CLIENT_TAG, "Data");
xfer_in->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, MOCK_MSC_SCSI_BULK_EP_MPS);
xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in));
//Test that an inflight transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_in));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_CSW: {
ESP_LOGD(MSC_CLIENT_TAG, "CSW");
xfer_in->num_bytes = usb_round_up_to_mps(sizeof(mock_msc_bulk_csw_t), MOCK_MSC_SCSI_BULK_EP_MPS);
xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in));
//Test that an inflight transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_in));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(MSC_CLIENT_TAG, "Close");
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER));
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl));
exit_loop = true;
break;
}
default:
abort();
break;
case TEST_STAGE_DEV_OPEN: {
ESP_LOGD(MSC_CLIENT_TAG, "Open");
//Open the device
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl));
//Target our transfers to the device
xfer_out->device_handle = msc_obj.dev_hdl;
xfer_in->device_handle = msc_obj.dev_hdl;
//Check the VID/PID of the opened device
const usb_device_desc_t *device_desc;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
TEST_ASSERT_EQUAL(msc_obj.test_param.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct);
//Claim the MSC interface
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
msc_obj.next_stage = TEST_STAGE_MSC_RESET;
skip_event_handling = true; //Need to execute TEST_STAGE_MSC_RESET
break;
}
case TEST_STAGE_MSC_RESET: {
ESP_LOGD(MSC_CLIENT_TAG, "MSC Reset");
//Send an MSC SCSI interface reset
MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, MOCK_MSC_SCSI_INTF_NUMBER);
xfer_out->num_bytes = sizeof(usb_setup_packet_t);
xfer_out->bEndpointAddress = 0;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out));
//Test that an inflight control transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_CBW: {
ESP_LOGD(MSC_CLIENT_TAG, "CBW");
mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, true, msc_obj.next_stage, msc_obj.test_param.num_sectors_per_xfer, msc_obj.test_param.msc_scsi_xfer_tag);
xfer_out->num_bytes = sizeof(mock_msc_bulk_cbw_t);
xfer_out->bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out));
//Test that an inflight transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_out));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_DATA: {
ESP_LOGD(MSC_CLIENT_TAG, "Data");
xfer_in->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, MOCK_MSC_SCSI_BULK_EP_MPS);
xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in));
//Test that an inflight transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_in));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_MSC_CSW: {
ESP_LOGD(MSC_CLIENT_TAG, "CSW");
xfer_in->num_bytes = usb_round_up_to_mps(sizeof(mock_msc_bulk_csw_t), MOCK_MSC_SCSI_BULK_EP_MPS);
xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in));
//Test that an inflight transfer cannot be resubmitted
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_in));
//Next stage set from transfer callback
break;
}
case TEST_STAGE_DEV_CLOSE: {
ESP_LOGD(MSC_CLIENT_TAG, "Close");
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER));
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl));
exit_loop = true;
break;
}
default:
abort();
break;
}
}
//Free transfers and deregister the client

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -169,20 +169,20 @@ static void test_async_client_cb(const usb_host_client_event_msg_t *event_msg, v
client_test_stage_t *stage = (client_test_stage_t *)arg;
switch (event_msg->event) {
case USB_HOST_CLIENT_EVENT_NEW_DEV:
if (dev_addr == 0) {
dev_addr = event_msg->new_dev.address;
} else {
TEST_ASSERT_EQUAL(dev_addr, event_msg->new_dev.address);
}
*stage = CLIENT_TEST_STAGE_CONN;
break;
case USB_HOST_CLIENT_EVENT_DEV_GONE:
*stage = CLIENT_TEST_STAGE_DCONN;
break;
default:
abort();
break;
case USB_HOST_CLIENT_EVENT_NEW_DEV:
if (dev_addr == 0) {
dev_addr = event_msg->new_dev.address;
} else {
TEST_ASSERT_EQUAL(dev_addr, event_msg->new_dev.address);
}
*stage = CLIENT_TEST_STAGE_CONN;
break;
case USB_HOST_CLIENT_EVENT_DEV_GONE:
*stage = CLIENT_TEST_STAGE_DCONN;
break;
default:
abort();
break;
}
}
@ -197,7 +197,7 @@ TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]")
.max_num_event_msg = 5,
.async = {
.client_event_callback = test_async_client_cb,
.callback_arg = (void *)&client0_stage,
.callback_arg = (void *) &client0_stage,
},
};
usb_host_client_handle_t client0_hdl;

View File

@ -198,7 +198,7 @@ static void print_ep_desc(const usb_ep_desc_t *ep_desc)
USB_EP_DESC_GET_EP_NUM(ep_desc),
USB_EP_DESC_GET_EP_DIR(ep_desc) ? "IN" : "OUT");
printf("\t\tbmAttributes 0x%x\t%s\n", ep_desc->bmAttributes, ep_type_str);
printf("\t\twMaxPacketSize %d\n", ep_desc->wMaxPacketSize);
printf("\t\twMaxPacketSize %d\n", USB_EP_DESC_GET_MPS(ep_desc));
printf("\t\tbInterval %d\n", ep_desc->bInterval);
}

View File

@ -12,8 +12,8 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/usb_phy.h"
#include "soc/usb_otg_periph.h"
#include "hal/usb_phy_hal.h"
#include "hal/usb_phy_ll.h"
#include "hal/usb_fsls_phy_hal.h"
#include "hal/usb_fsls_phy_ll.h"
#include "esp_rom_gpio.h"
#include "driver/gpio.h"
#include "hal/gpio_ll.h"
@ -33,7 +33,7 @@ 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_phy_hal_context_t hal_context; /**< USB_PHY hal context */
usb_fsls_phy_hal_context_t hal_context; /**< USB_PHY hal context */
};
typedef struct {
@ -120,7 +120,7 @@ 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_phy_hal_int_load_conf_host(&(handle->hal_context));
usb_fsls_phy_hal_int_load_conf_host(&(handle->hal_context));
}
} 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
@ -141,7 +141,7 @@ 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_phy_hal_int_load_conf_dev(&(handle->hal_context), speed);
usb_fsls_phy_hal_int_load_conf_dev(&(handle->hal_context), speed);
return ESP_OK;
}
@ -157,7 +157,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_phy_hal_int_mimick_disconn(&(handle->hal_context), false);
usb_fsls_phy_hal_int_mimick_disconn(&(handle->hal_context), false);
} else {
if (!handle->iopins) {
ret = ESP_FAIL;
@ -174,7 +174,7 @@ 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_phy_hal_int_mimick_disconn(&(handle->hal_context), true);
usb_fsls_phy_hal_int_mimick_disconn(&(handle->hal_context), true);
} else {
/*
Disable connections on the external PHY by connecting the VP and VM signals to the constant LOW signal.
@ -214,8 +214,8 @@ static esp_err_t usb_phy_install(void)
portEXIT_CRITICAL(&phy_spinlock);
goto cleanup;
}
usb_phy_ll_usb_wrap_enable_bus_clock(true);
usb_phy_ll_usb_wrap_reset_register();
usb_fsls_phy_ll_usb_wrap_enable_bus_clock(true);
usb_fsls_phy_ll_usb_wrap_reset_register();
// Enable USB peripheral and reset the register
portEXIT_CRITICAL(&phy_spinlock);
return ESP_OK;
@ -255,13 +255,13 @@ 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_phy_hal_init(&(phy_context->hal_context));
usb_fsls_phy_hal_init(&(phy_context->hal_context));
if (config->controller == USB_PHY_CTRL_OTG) {
usb_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT);
usb_fsls_phy_hal_otg_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT);
}
#if SOC_USB_SERIAL_JTAG_SUPPORTED
else if (config->controller == USB_PHY_CTRL_SERIAL_JTAG) {
usb_phy_hal_jtag_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT);
usb_fsls_phy_hal_jtag_conf(&(phy_context->hal_context), config->target == USB_PHY_TARGET_EXT);
phy_context->otg_mode = USB_OTG_MODE_DEVICE;
phy_context->otg_speed = USB_PHY_SPEED_FULL;
}
@ -308,7 +308,7 @@ static void phy_uninstall(void)
p_phy_ctrl_obj_free = p_phy_ctrl_obj;
p_phy_ctrl_obj = NULL;
// Disable USB peripheral without reset the module
usb_phy_ll_usb_wrap_enable_bus_clock(false);
usb_fsls_phy_ll_usb_wrap_enable_bus_clock(false);
}
portEXIT_CRITICAL(&phy_spinlock);
free(p_phy_ctrl_obj_free);
@ -324,8 +324,8 @@ 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_phy_ll_int_load_conf(handle->hal_context.wrap_dev, false, false, false, false);
usb_phy_ll_usb_wrap_pad_enable(handle->hal_context.wrap_dev, false);
usb_fsls_phy_ll_int_load_conf(handle->hal_context.wrap_dev, false, false, false, false);
usb_fsls_phy_ll_usb_wrap_pad_enable(handle->hal_context.wrap_dev, false);
p_phy_ctrl_obj->internal_phy = NULL;
}
portEXIT_CRITICAL(&phy_spinlock);

View File

@ -1081,11 +1081,11 @@ esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb)
endpoint_t *ep_obj = (endpoint_t *)ep_hdl;
USBH_CHECK( transfer_check_usb_compliance(&(urb->transfer),
USB_EP_DESC_GET_XFERTYPE(ep_obj->constant.ep_desc),
USB_EP_DESC_GET_MPS(ep_obj->constant.ep_desc),
USB_EP_DESC_GET_EP_DIR(ep_obj->constant.ep_desc)),
ESP_ERR_INVALID_ARG);
USBH_CHECK(transfer_check_usb_compliance(&(urb->transfer),
USB_EP_DESC_GET_XFERTYPE(ep_obj->constant.ep_desc),
USB_EP_DESC_GET_MPS(ep_obj->constant.ep_desc),
USB_EP_DESC_GET_EP_DIR(ep_obj->constant.ep_desc)),
ESP_ERR_INVALID_ARG);
// Check that the EP's underlying pipe is in the active state before submitting the URB
if (hcd_pipe_get_state(ep_obj->constant.pipe_hdl) != HCD_PIPE_STATE_ACTIVE) {
return ESP_ERR_INVALID_STATE;