Merge branch 'ci/usb_host_add_p4_examples_ci' into 'master'

ci(USB): add ESP32-P4 runners to existing USB CI

Closes IDF-9127

See merge request espressif/esp-idf!28795
This commit is contained in:
Tomas Rezucha
2024-02-29 18:43:16 +08:00
18 changed files with 173 additions and 37 deletions

View File

@@ -4,7 +4,7 @@ components/usb/test_apps:
enable: enable:
- if: SOC_USB_OTG_SUPPORTED == 1 - if: SOC_USB_OTG_SUPPORTED == 1
disable_test: disable_test:
- if: IDF_TARGET not in ["esp32s3"] - if: IDF_TARGET not in ["esp32s3", "esp32p4"]
temporary: true temporary: true
reason: lack of runners with usb_host_flash_disk tag reason: lack of runners with usb_host_flash_disk tag
depends_components: depends_components:

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -60,22 +60,42 @@ uint8_t mock_msc_scsi_config_desc[255];
uint16_t mock_msc_scsi_str_desc_manu[128]; uint16_t mock_msc_scsi_str_desc_manu[128];
uint16_t mock_msc_scsi_str_desc_prod[128]; uint16_t mock_msc_scsi_str_desc_prod[128];
uint16_t mock_msc_scsi_str_desc_ser_num[128]; uint16_t mock_msc_scsi_str_desc_ser_num[128];
usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc;
usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc = { const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_fs = {
.bLength = sizeof(usb_ep_desc_t), .bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR, //EP 1 OUT .bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR, //EP 1 OUT
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS, //MPS of 64 bytes .wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_FS, //MPS of 64 bytes
.bInterval = 0, .bInterval = 0,
}; };
const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc = { const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_hs = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR, //EP 1 OUT
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_HS, //MPS of 512 bytes
.bInterval = 0,
};
const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_fs = {
.bLength = sizeof(usb_ep_desc_t), .bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR, .bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR,
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS, //MPS of 64 bytes .wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_FS, //MPS of 64 bytes
.bInterval = 0,
};
const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_hs = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR,
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_HS, //MPS of 512 bytes
.bInterval = 0, .bInterval = 0,
}; };
@@ -130,9 +150,10 @@ void mock_msc_scsi_init_reference_descriptors(void)
dest_ptr += USB_CONFIG_DESC_SIZE; dest_ptr += USB_CONFIG_DESC_SIZE;
memcpy(dest_ptr, (void*)&mock_msc_intf_desc, sizeof(mock_msc_intf_desc)); memcpy(dest_ptr, (void*)&mock_msc_intf_desc, sizeof(mock_msc_intf_desc));
dest_ptr += USB_INTF_DESC_SIZE; dest_ptr += USB_INTF_DESC_SIZE;
memcpy(dest_ptr, (void*)&mock_msc_scsi_bulk_in_ep_desc, sizeof(mock_msc_scsi_bulk_in_ep_desc)); // Set endpoint descriptors with zeroes, FS or HS device has not been connected
memset(dest_ptr, 0, sizeof(usb_ep_desc_t));
dest_ptr += USB_EP_DESC_SIZE; dest_ptr += USB_EP_DESC_SIZE;
memcpy(dest_ptr, (void*)&mock_msc_scsi_bulk_out_ep_desc, sizeof(mock_msc_scsi_bulk_out_ep_desc)); memset(dest_ptr, 0, sizeof(usb_ep_desc_t));
// String descriptors // String descriptors
const char *str = MOCK_MSC_SCSI_STRING_1; const char *str = MOCK_MSC_SCSI_STRING_1;

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -63,7 +63,7 @@ bLength : 0x07 (7 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor) bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x81 (Direction=IN EndpointID=1) bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
bmAttributes : 0x02 (TransferType=Bulk) bmAttributes : 0x02 (TransferType=Bulk)
wMaxPacketSize : 0x0040 (max 64 bytes) wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS)
bInterval : 0x00 (never NAKs) bInterval : 0x00 (never NAKs)
Data (HexDump) : 07 05 81 02 40 00 00 Data (HexDump) : 07 05 81 02 40 00 00
@@ -72,7 +72,7 @@ bLength : 0x07 (7 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor) bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x02 (Direction=OUT EndpointID=2) bEndpointAddress : 0x02 (Direction=OUT EndpointID=2)
bmAttributes : 0x02 (TransferType=Bulk) bmAttributes : 0x02 (TransferType=Bulk)
wMaxPacketSize : 0x0040 (max 64 bytes) wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytest for HS)
bInterval : 0x00 (never NAKs) bInterval : 0x00 (never NAKs)
Data (HexDump) : 07 05 02 02 40 00 00 Data (HexDump) : 07 05 02 02 40 00 00
@@ -85,8 +85,12 @@ extern uint8_t mock_msc_scsi_config_desc[255];
extern uint16_t mock_msc_scsi_str_desc_manu[128]; extern uint16_t mock_msc_scsi_str_desc_manu[128];
extern uint16_t mock_msc_scsi_str_desc_prod[128]; extern uint16_t mock_msc_scsi_str_desc_prod[128];
extern uint16_t mock_msc_scsi_str_desc_ser_num[128]; extern uint16_t mock_msc_scsi_str_desc_ser_num[128];
extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc; extern usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc;
extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc; extern usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_fs;
extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_fs;
extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_hs;
extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_hs;
#define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x0781 // Western Digital, Sandisk #define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x0781 // Western Digital, Sandisk
#define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0x5595 #define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0x5595
@@ -99,7 +103,8 @@ extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
#define MOCK_MSC_SCSI_INTF_ALT_SETTING 0 #define MOCK_MSC_SCSI_INTF_ALT_SETTING 0
#define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x02 #define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x02
#define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x81 #define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x81
#define MOCK_MSC_SCSI_BULK_EP_MPS 64 #define MOCK_MSC_SCSI_BULK_EP_MPS_FS 64 // FS wMaxPacketSize
#define MOCK_MSC_SCSI_BULK_EP_MPS_HS 512 // HS wMaxPacketSize
#define MOCK_MSC_SCSI_STRING_1 (" USB") #define MOCK_MSC_SCSI_STRING_1 (" USB")
#define MOCK_MSC_SCSI_STRING_2 (" SanDisk 3.2Gen1") #define MOCK_MSC_SCSI_STRING_2 (" SanDisk 3.2Gen1")
#define MOCK_MSC_SCSI_STRING_3 ("0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4") // This string is NOT checked by the enum test #define MOCK_MSC_SCSI_STRING_3 ("0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4") // This string is NOT checked by the enum test

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -61,6 +61,7 @@ TEST_CASE("Test HCD bulk pipe URBs", "[bulk][full_speed]")
hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor)
uint8_t dev_addr = test_hcd_enum_device(default_pipe); uint8_t dev_addr = test_hcd_enum_device(default_pipe);
mock_msc_reset_req(default_pipe); mock_msc_reset_req(default_pipe);
test_hcd_set_mock_msc_ep_descriptor(port_speed);
//Create BULK IN and BULK OUT pipes for SCSI //Create BULK IN and BULK OUT pipes for SCSI
hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_out_ep_desc, dev_addr, port_speed); hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_out_ep_desc, dev_addr, port_speed);

View File

@@ -19,6 +19,7 @@
#include "usb/usb_types_ch9.h" #include "usb/usb_types_ch9.h"
#include "test_hcd_common.h" #include "test_hcd_common.h"
#include "test_usb_common.h" #include "test_usb_common.h"
#include "test_usb_mock_msc.h"
#include "unity.h" #include "unity.h"
#include "esp_dma_utils.h" #include "esp_dma_utils.h"
@@ -328,3 +329,14 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe)
test_hcd_free_urb(urb); test_hcd_free_urb(urb);
return ENUM_ADDR; return ENUM_ADDR;
} }
void test_hcd_set_mock_msc_ep_descriptor(usb_speed_t port_speed)
{
if (port_speed == USB_SPEED_HIGH) {
mock_msc_scsi_bulk_out_ep_desc = mock_msc_scsi_bulk_out_ep_desc_hs; // HS wMaxPacketSize = 512
mock_msc_scsi_bulk_in_ep_desc = mock_msc_scsi_bulk_in_ep_desc_hs;
} else {
mock_msc_scsi_bulk_out_ep_desc = mock_msc_scsi_bulk_out_ep_desc_fs; // FS wMaxPacketSize = 64
mock_msc_scsi_bulk_in_ep_desc = mock_msc_scsi_bulk_in_ep_desc_fs;
}
}

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -136,3 +136,12 @@ void test_hcd_free_urb(urb_t *urb);
* @return uint8_t The address of the device after enumeration * @return uint8_t The address of the device after enumeration
*/ */
uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe); uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe);
/**
* @brief Set endpoint descriptor
*
* Set endpoint descriptor of the mock device with different wMaxPacketSize according to the connected device's speed
*
* @param port_speed Port speed after the device is connected
*/
void test_hcd_set_mock_msc_ep_descriptor(usb_speed_t port_speed);

View File

@@ -428,7 +428,7 @@ static void test_parse_ep_by_address(const usb_config_desc_t *config_desc)
TEST_ASSERT_NULL(ep_desc); TEST_ASSERT_NULL(ep_desc);
} }
TEST_CASE("Test USB Helpers descriptor parsing", "[helpers][full_speed]") TEST_CASE("Test USB Helpers descriptor parsing", "[helpers][full_speed][high_speed]")
{ {
const usb_config_desc_t *config_desc = (const usb_config_desc_t *)config_desc_bytes; const usb_config_desc_t *config_desc = (const usb_config_desc_t *)config_desc_bytes;
test_walk_desc(config_desc); test_walk_desc(config_desc);

View File

@@ -7,7 +7,10 @@ from pytest_embedded import Dut
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
@pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32p4'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag')
@pytest.mark.usb_host_flash_disk @pytest.mark.usb_host_flash_disk
def test_usb_hcd(dut: Dut) -> None: def test_usb_hcd(dut: Dut) -> None:
dut.run_all_single_board_cases(group='full_speed') if (dut.target == 'esp32s3'):
dut.run_all_single_board_cases(group='full_speed')
else:
dut.run_all_single_board_cases(group='high_speed')

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -55,6 +55,7 @@ typedef struct {
usb_device_handle_t dev_hdl; usb_device_handle_t dev_hdl;
int num_data_transfers; int num_data_transfers;
int event_count; int event_count;
usb_speed_t dev_speed;
} msc_client_obj_t; } msc_client_obj_t;
static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer) static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer)
@@ -188,6 +189,10 @@ void msc_client_async_dconn_task(void *arg)
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &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.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct); TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct);
//Get device info to get device speed
usb_device_info_t dev_info;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info));
msc_obj.dev_speed = dev_info.speed;
//Claim the MSC interface //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)); 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; msc_obj.next_stage = TEST_STAGE_MSC_RESET;
@@ -216,8 +221,11 @@ void msc_client_async_dconn_task(void *arg)
case TEST_STAGE_MSC_DATA_DCONN: { case TEST_STAGE_MSC_DATA_DCONN: {
ESP_LOGD(MSC_CLIENT_TAG, "Data and disconnect"); ESP_LOGD(MSC_CLIENT_TAG, "Data and disconnect");
//Setup the Data IN transfers //Setup the Data IN transfers
const int bulk_ep_mps = (msc_obj.dev_speed == USB_SPEED_HIGH)
? MOCK_MSC_SCSI_BULK_EP_MPS_HS
: MOCK_MSC_SCSI_BULK_EP_MPS_FS;
for (int i = 0; i < msc_obj.num_data_transfers; i++) { 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]->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE, bulk_ep_mps);
xfer_in[i]->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; xfer_in[i]->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
} }
//Submit those transfers //Submit those transfers

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -48,6 +48,7 @@ typedef struct {
uint8_t dev_addr_to_open; uint8_t dev_addr_to_open;
usb_host_client_handle_t client_hdl; usb_host_client_handle_t client_hdl;
usb_device_handle_t dev_hdl; usb_device_handle_t dev_hdl;
usb_speed_t dev_speed;
} msc_client_obj_t; } msc_client_obj_t;
static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg) static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg)
@@ -66,6 +67,24 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo
} }
} }
static void mock_msc_scsi_init_reference_ep_descriptors(const msc_client_obj_t *msc_obj)
{
uint8_t *dest_ptr = mock_msc_scsi_config_desc;
dest_ptr += USB_CONFIG_DESC_SIZE;
dest_ptr += USB_INTF_DESC_SIZE;
const usb_ep_desc_t en_desc_in = (msc_obj->dev_speed == USB_SPEED_HIGH)
? mock_msc_scsi_bulk_in_ep_desc_hs
: mock_msc_scsi_bulk_in_ep_desc_fs;
const usb_ep_desc_t en_desc_out = (msc_obj->dev_speed == USB_SPEED_HIGH)
? mock_msc_scsi_bulk_out_ep_desc_hs
: mock_msc_scsi_bulk_out_ep_desc_fs;
memcpy(dest_ptr, (void*)&en_desc_in, sizeof(en_desc_in));
dest_ptr += USB_EP_DESC_SIZE;
memcpy(dest_ptr, (void*)&en_desc_out, sizeof(en_desc_out));
}
void msc_client_async_enum_task(void *arg) void msc_client_async_enum_task(void *arg)
{ {
msc_client_obj_t msc_obj; msc_client_obj_t msc_obj;
@@ -113,6 +132,11 @@ void msc_client_async_enum_task(void *arg)
//Open the device //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)); 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; msc_obj.next_stage = TEST_STAGE_CHECK_DEV_DESC;
//Get device info to get device speed
usb_device_info_t dev_info;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info));
msc_obj.dev_speed = dev_info.speed;
mock_msc_scsi_init_reference_ep_descriptors(&msc_obj);
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_DEV_DESC skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_DEV_DESC
break; break;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -53,6 +53,7 @@ typedef struct {
usb_host_client_handle_t client_hdl; usb_host_client_handle_t client_hdl;
usb_device_handle_t dev_hdl; usb_device_handle_t dev_hdl;
int num_sectors_read; int num_sectors_read;
usb_speed_t dev_speed;
} msc_client_obj_t; } msc_client_obj_t;
static void msc_transfer_cb(usb_transfer_t *transfer) static void msc_transfer_cb(usb_transfer_t *transfer)
@@ -141,7 +142,7 @@ void msc_client_async_seq_task(void *arg)
usb_transfer_t *xfer_out = NULL; //Must be large enough to contain CBW and MSC reset control transfer usb_transfer_t *xfer_out = NULL; //Must be large enough to contain CBW and MSC reset control transfer
usb_transfer_t *xfer_in = NULL; //Must be large enough to contain CSW and Data usb_transfer_t *xfer_in = NULL; //Must be large enough to contain CSW and Data
size_t out_worst_case_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t)); size_t out_worst_case_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t));
size_t in_worst_case_size = usb_round_up_to_mps(MAX(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, sizeof(mock_msc_bulk_csw_t)), MOCK_MSC_SCSI_BULK_EP_MPS); size_t in_worst_case_size = usb_round_up_to_mps(MAX(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, sizeof(mock_msc_bulk_csw_t)), MOCK_MSC_SCSI_BULK_EP_MPS_HS);
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(out_worst_case_size, 0, &xfer_out)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(out_worst_case_size, 0, &xfer_out));
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(in_worst_case_size, 0, &xfer_in)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(in_worst_case_size, 0, &xfer_in));
xfer_out->callback = msc_transfer_cb; xfer_out->callback = msc_transfer_cb;
@@ -178,6 +179,10 @@ void msc_client_async_seq_task(void *arg)
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &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.idVendor, device_desc->idVendor);
TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct); TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct);
//Get device info to get device speed
usb_device_info_t dev_info;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info));
msc_obj.dev_speed = dev_info.speed;
//Claim the MSC interface //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)); 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; msc_obj.next_stage = TEST_STAGE_MSC_RESET;
@@ -209,7 +214,10 @@ void msc_client_async_seq_task(void *arg)
} }
case TEST_STAGE_MSC_DATA: { case TEST_STAGE_MSC_DATA: {
ESP_LOGD(MSC_CLIENT_TAG, "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); const int bulk_ep_mps = (msc_obj.dev_speed == USB_SPEED_HIGH)
? MOCK_MSC_SCSI_BULK_EP_MPS_HS
: MOCK_MSC_SCSI_BULK_EP_MPS_FS;
xfer_in->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, bulk_ep_mps);
xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in));
//Test that an inflight transfer cannot be resubmitted //Test that an inflight transfer cannot be resubmitted
@@ -219,7 +227,10 @@ void msc_client_async_seq_task(void *arg)
} }
case TEST_STAGE_MSC_CSW: { case TEST_STAGE_MSC_CSW: {
ESP_LOGD(MSC_CLIENT_TAG, "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); const int bulk_ep_mps = (msc_obj.dev_speed == USB_SPEED_HIGH)
? MOCK_MSC_SCSI_BULK_EP_MPS_HS
: MOCK_MSC_SCSI_BULK_EP_MPS_FS;
xfer_in->num_bytes = usb_round_up_to_mps(sizeof(mock_msc_bulk_csw_t), bulk_ep_mps);
xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR;
TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in));
//Test that an inflight transfer cannot be resubmitted //Test that an inflight transfer cannot be resubmitted

View File

@@ -44,7 +44,7 @@ Procedure:
- Uninstall USB Host Library - Uninstall USB Host Library
*/ */
TEST_CASE("Test USB Host async client (single client)", "[usb_host][full_speed]") TEST_CASE("Test USB Host async client (single client)", "[usb_host][full_speed][high_speed]")
{ {
//Create task to run client that communicates with MSC SCSI interface //Create task to run client that communicates with MSC SCSI interface
msc_client_test_param_t params = { msc_client_test_param_t params = {
@@ -94,7 +94,7 @@ Procedure:
- Free all devices - Free all devices
- Uninstall USB Host Library - Uninstall USB Host Library
*/ */
TEST_CASE("Test USB Host async client (multi client)", "[usb_host][full_speed]") TEST_CASE("Test USB Host async client (multi client)", "[usb_host][full_speed][high_speed]")
{ {
//Create task to run the MSC client //Create task to run the MSC client
msc_client_test_param_t msc_params = { msc_client_test_param_t msc_params = {

View File

@@ -7,7 +7,10 @@ from pytest_embedded import Dut
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
@pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32p4'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag')
@pytest.mark.usb_host_flash_disk @pytest.mark.usb_host_flash_disk
def test_usb_host(dut: Dut) -> None: def test_usb_host(dut: Dut) -> None:
dut.run_all_single_board_cases(group='full_speed') if (dut.target == 'esp32s3'):
dut.run_all_single_board_cases(group='full_speed')
else:
dut.run_all_single_board_cases(group='high_speed')

View File

@@ -450,7 +450,7 @@ examples/peripherals/usb/host:
disable: disable:
- if: SOC_USB_OTG_SUPPORTED != 1 - if: SOC_USB_OTG_SUPPORTED != 1
disable_test: disable_test:
- if: IDF_TARGET not in ["esp32s3"] - if: IDF_TARGET not in ["esp32s3", "esp32p4"]
temporary: true temporary: true
reason: lack of runners with usb_host_flash_disk tag reason: lack of runners with usb_host_flash_disk tag
depends_components: depends_components:

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
import pytest import pytest
from pytest_embedded import Dut from pytest_embedded import Dut
@@ -13,6 +13,6 @@ def test_usb_device_msc_example(dut: Dut) -> None:
dut.expect('Mount storage') dut.expect('Mount storage')
dut.expect('TinyUSB Driver installed') dut.expect('TinyUSB Driver installed')
dut.expect('USB MSC initialization DONE') dut.expect('USB MSC initialization DONE')
dut.expect('esp32s2>') dut.expect(dut.target + '>')
dut.write('status') dut.write('status')
dut.expect('storage exposed over USB') dut.expect('storage exposed over USB')

View File

@@ -7,9 +7,12 @@ from pytest_embedded import Dut
@pytest.mark.esp32s2 @pytest.mark.esp32s2
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
@pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32p4'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag')
@pytest.mark.usb_host_flash_disk @pytest.mark.usb_host_flash_disk
def test_usb_host_msc_example(dut: Dut) -> None: def test_usb_host_msc_example(dut: Dut) -> None:
# Get wMaxPacketSize to get USB device speed
max_packet_size = int(dut.expect(r'wMaxPacketSize (\d{2,3})')[1].decode())
# Check result of file_operations() # Check result of file_operations()
dut.expect_exact("example: Read from file '/usb/esp/test.txt': 'Hello World!'") dut.expect_exact("example: Read from file '/usb/esp/test.txt': 'Hello World!'")
@@ -17,12 +20,20 @@ def test_usb_host_msc_example(dut: Dut) -> None:
write_throughput = float(dut.expect(r'example: Write speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) write_throughput = float(dut.expect(r'example: Write speed ([0-9]*[.]?[0-9]+) MiB')[1].decode())
read_throughput = float(dut.expect(r'example: Read speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) read_throughput = float(dut.expect(r'example: Read speed ([0-9]*[.]?[0-9]+) MiB')[1].decode())
# Set write and read throughput limits
if (max_packet_size == 512): # wMaxPacketSize = 512 for HS
write_throughput_limit = 4.9
read_throughput_limit = 11.5
else: # wMaxPacketSize = 64 for FS
write_throughput_limit = 0.9
read_throughput_limit = 1.0
# These values should be updated for HS targets # These values should be updated for HS targets
if write_throughput > 0.9: if write_throughput > write_throughput_limit:
print('Write throughput put OK') print('Write throughput put OK')
else: else:
print('write throughput too slow!') print('write throughput too slow!')
if read_throughput > 1.0: if read_throughput > read_throughput_limit:
print('Read throughput put OK') print('Read throughput put OK')
else: else:
print('Read throughput too slow!') print('Read throughput too slow!')

View File

@@ -72,7 +72,9 @@ static void action_get_info(class_driver_t *driver_obj)
ESP_LOGI(TAG, "Getting device information"); ESP_LOGI(TAG, "Getting device information");
usb_device_info_t dev_info; usb_device_info_t dev_info;
ESP_ERROR_CHECK(usb_host_device_info(driver_obj->dev_hdl, &dev_info)); ESP_ERROR_CHECK(usb_host_device_info(driver_obj->dev_hdl, &dev_info));
ESP_LOGI(TAG, "\t%s speed", (dev_info.speed == USB_SPEED_LOW) ? "Low" : "Full"); ESP_LOGI(TAG, "\t%s speed", (char *[]) {
"Low", "Full", "High"
}[dev_info.speed]);
ESP_LOGI(TAG, "\tbConfigurationValue %d", dev_info.bConfigurationValue); ESP_LOGI(TAG, "\tbConfigurationValue %d", dev_info.bConfigurationValue);
//Get the device descriptor next //Get the device descriptor next

View File

@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag')
@pytest.mark.usb_host_flash_disk
def test_usb_host_lib_example(dut: Dut) -> None:
# register client
dut.expect_exact('CLASS: Registering Client')
# expect device descriptor
dut.expect_exact('CLASS: Getting device descriptor')
# confirm device descriptor
dut.expect_exact('*** Device descriptor ***')
# expect configuration descriptor
dut.expect_exact('CLASS: Getting config descriptor')
# confirm configuration descriptor
dut.expect_exact('*** Configuration descriptor ***')