From 6a3bb3294d51065d06b6ca766b7b2abf4071ba07 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Wed, 8 May 2024 02:56:16 +0800 Subject: [PATCH] refactor(usb): Split test device descriptors from mock class files Previously, descriptors of the test devices were stored direclty in the mock device files (e.g., "mock_[hid|msc].[h|c]"). This commit splits out the device descriptors to separate files (e.g., "dev_[hid|msc].c") along with getter functions. Users that want to run the tests locally on a different device simply need to update the "dev_[hid|msc].c" file for their device. --- .../usb/test_apps/common/CMakeLists.txt | 4 +- components/usb/test_apps/common/dev_hid.c | 232 ++++++++++++ components/usb/test_apps/common/dev_hid.h | 80 ++++ components/usb/test_apps/common/dev_isoc.c | 27 ++ components/usb/test_apps/common/dev_isoc.h | 36 ++ components/usb/test_apps/common/dev_msc.c | 354 ++++++++++++++++++ components/usb/test_apps/common/dev_msc.h | 118 ++++++ components/usb/test_apps/common/mock_hid.c | 42 --- components/usb/test_apps/common/mock_hid.h | 112 ------ components/usb/test_apps/common/mock_msc.c | 131 +------ components/usb/test_apps/common/mock_msc.h | 140 +------ .../usb/test_apps/hcd/main/test_app_main.c | 5 +- .../usb/test_apps/hcd/main/test_hcd_bulk.c | 28 +- .../usb/test_apps/hcd/main/test_hcd_common.c | 11 - .../usb/test_apps/hcd/main/test_hcd_intr.c | 17 +- .../usb/test_apps/hcd/main/test_hcd_isoc.c | 48 +-- .../usb/test_apps/usb_host/main/ctrl_client.h | 2 - .../usb_host/main/ctrl_client_async_seq.c | 29 +- .../usb/test_apps/usb_host/main/msc_client.h | 2 - .../usb_host/main/msc_client_async_dconn.c | 71 ++-- .../usb_host/main/msc_client_async_enum.c | 36 +- .../usb_host/main/msc_client_async_seq.c | 114 +++--- .../test_apps/usb_host/main/test_app_main.c | 7 +- .../usb_host/main/test_usb_host_async.c | 34 +- .../usb_host/main/test_usb_host_plugging.c | 8 +- 25 files changed, 1107 insertions(+), 581 deletions(-) create mode 100644 components/usb/test_apps/common/dev_hid.c create mode 100644 components/usb/test_apps/common/dev_hid.h create mode 100644 components/usb/test_apps/common/dev_isoc.c create mode 100644 components/usb/test_apps/common/dev_isoc.h create mode 100644 components/usb/test_apps/common/dev_msc.c create mode 100644 components/usb/test_apps/common/dev_msc.h delete mode 100644 components/usb/test_apps/common/mock_hid.c delete mode 100644 components/usb/test_apps/common/mock_hid.h diff --git a/components/usb/test_apps/common/CMakeLists.txt b/components/usb/test_apps/common/CMakeLists.txt index ce2bfb32b3..047989446d 100644 --- a/components/usb/test_apps/common/CMakeLists.txt +++ b/components/usb/test_apps/common/CMakeLists.txt @@ -1,4 +1,6 @@ -idf_component_register(SRCS "mock_hid.c" +idf_component_register(SRCS "dev_hid.c" + "dev_isoc.c" + "dev_msc.c" "mock_msc.c" "test_usb_common.c" INCLUDE_DIRS "." diff --git a/components/usb/test_apps/common/dev_hid.c b/components/usb/test_apps/common/dev_hid.c new file mode 100644 index 0000000000..91d52a67b7 --- /dev/null +++ b/components/usb/test_apps/common/dev_hid.c @@ -0,0 +1,232 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" +#include "dev_hid.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as an HID mouse be connected. That test device's information and descriptors are defined in this file. + +If you are connecting a different HID mouse, please update the descriptor and +getter functions accordingly. + +------------------------------ Device Descriptor ------------------------------- +bLength : 0x12 (18 bytes) +bDescriptorType : 0x01 (Device Descriptor) +bcdUSB : 0x0210 (2.00) +bDeviceClass : 0x00 +bDeviceSubClass : 0x00 +bDeviceProtocol : 0x00 +bMaxPacketSize0 : 0x08 (8 bytes) +idVendor : 0x413C (Dell Computer Corp) +idProduct : 0x301A (Dell MS116 Optical Mouse) +bcdDevice : 0x0100 (1.00) +iManufacturer : 1 +iProduct : 2 +iSerial : 0 +bNumConfigurations : 1 + +--------------------------- Configuration Descriptor --------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x02 (Configuration Descriptor) +wTotalLength : 0x0022 (34 bytes) +bNumInterfaces : 0x01 (1 Interface) +bConfigurationValue : 0x01 (Configuration 1) +iConfiguration : 0x00 (No String Descriptor) +bmAttributes : 0xA0 + D7: Reserved, set 1 : 0x01 + D6: Self Powered : 0x00 (no) + D5: Remote Wakeup : 0x01 (yes) + D4..0: Reserved, set 0 : 0x00 +MaxPower : 0x32 (100 mA) + +Data (HexDump) : 09 02 3B 00 02 01 00 A0 32 09 04 00 00 01 03 01 + 02 00 09 21 00 02 00 01 22 4D 00 07 05 81 03 08 + 00 0A 09 04 01 00 01 03 01 01 00 09 21 00 02 00 + 01 22 31 00 07 05 82 03 08 00 0A + +----------------------------- Interface Descriptor ----------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x04 (Interface Descriptor) +bInterfaceNumber : 0x00 +bAlternateSetting : 0x00 +bNumEndpoints : 0x01 (1 Endpoint) +bInterfaceClass : 0x03 (HID - Human Interface Device) +bInterfaceSubClass : 0x01 (Boot Interface) +bInterfaceProtocol : 0x02 (Mouse) +iInterface : 0x00 (No String Descriptor) + +-------------------------------- HID Descriptor -------------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x21 (HID Descriptor) +bcdHID : 0x0200 (HID Version 2.00) +bCountryCode : 0x00 (00 = not localized) +bNumDescriptors : 0x01 +Descriptor 1: +bDescriptorType : 0x22 (Class=Report) +wDescriptorLength : 0x004D (77 bytes) + +------------------------------ Endpoint Descriptor ----------------------------- +bLength : 0x07 (7 bytes) +bDescriptorType : 0x05 (Endpoint Descriptor) +bEndpointAddress : 0x81 (Direction=IN EndpointID=1) +bmAttributes : 0x03 (TransferType=Interrupt) +wMaxPacketSize : 0x0008 +bInterval : 0x0A (10 ms) + +---------------------------- String Descriptor Manu ---------------------------- +bLength : 0x0E (14 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : "PixArt" + +---------------------------- String Descriptor Prod ---------------------------- +bLength : 0x3A (58 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : "Dell MS116 USB Optical Mouse" +*/ + +// ------------------------------- Descriptors --------------------------------- + +static const usb_device_desc_t dev_desc = { + .bLength = USB_DEVICE_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE, + .bcdUSB = 0x0210, // 2.10 + .bDeviceClass = USB_CLASS_PER_INTERFACE, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x413C, // Dell Computer Corp + .idProduct = 0x301A, // Dell MS116 Optical Mouse + .bcdDevice = 0x0100, // 1.00 + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 0, + .bNumConfigurations = 1, +}; + +static const usb_config_desc_t config_desc = { + .bLength = USB_CONFIG_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = 0x0022, // 34 bytes + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0xA0, + .bMaxPower = 0x32, // 100 mA +}; + +static const usb_intf_desc_t intf_desc = { + .bLength = USB_INTF_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0x01, // Boot Interface + .bInterfaceProtocol = 0x02, // Mouse + .iInterface = 0, // (No String Descriptor) +}; + +const usb_ep_desc_t in_ep_desc = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, // EP 1 IN + .bmAttributes = USB_BM_ATTRIBUTES_XFER_INT, + .wMaxPacketSize = 0x0008, + .bInterval = 0x0A, // 10 ms +}; + +/* +String descriptors are dynamically initialized due to issues with static +initialization of variable length array members. See IDF-9886. +*/ + +static const usb_str_desc_t str_desc_manu_base = { + .bLength = sizeof(usb_str_desc_t) + (6 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_manu_data[] = { + 0x0050, // 'P' + 0x0069, // 'i' + 0x0078, // 'x' + 0x0041, // 'A' + 0x0072, // 'r' + 0x0074, // 't' +}; +static uint8_t *str_desc_manu[sizeof(str_desc_manu_base) + sizeof(str_desc_manu_data)]; + +static const usb_str_desc_t str_desc_prod_base = { + .bLength = sizeof(usb_str_desc_t) + (28 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_prod_data[] = { + /* + The following string encoded in UTF-16LE + + "Dell MS116 USB Optical Mouse" + */ + 0x0044, 0x0065, 0x006c, 0x006c, 0x0020, 0x004d, 0x0053, 0x0031, 0x0031, + 0x0036, 0x0020, 0x0055, 0x0053, 0x0042, 0x0020, 0x004f, 0x0070, 0x0074, + 0x0069, 0x0063, 0x0061, 0x006c, 0x0020, 0x004d, 0x006f, 0x0075, 0x0073, + 0x0065, +}; +static uint8_t *str_desc_prod[sizeof(str_desc_prod_base) + sizeof(str_desc_prod_data)]; + +// -------------------------------- Functions ---------------------------------- + +void dev_hid_init(void) +{ + // Dynamically initialize string descriptors due to compiler limitations (see IDF-9886) + uint8_t *ptr; + + // Initialize manufacturer string descriptor + ptr = (uint8_t *)str_desc_manu; + memcpy(ptr, &str_desc_manu_base, sizeof(str_desc_manu_base)); + ptr += sizeof(str_desc_manu_base); + memcpy(ptr, &str_desc_manu_data, sizeof(str_desc_manu_data)); + + // Initialize product string descriptor + ptr = (uint8_t *)str_desc_prod; + memcpy(ptr, &str_desc_prod_base, sizeof(str_desc_prod_base)); + ptr += sizeof(str_desc_prod_base); + memcpy(ptr, &str_desc_prod_data, sizeof(str_desc_prod_data)); + + // No serial string descriptor +} + +const usb_device_desc_t *dev_hid_get_dev_desc(usb_speed_t speed) +{ + return &dev_desc; +} + +const usb_config_desc_t *dev_hid_get_config_desc(usb_speed_t speed) +{ + return &config_desc; +} + +const usb_intf_desc_t *dev_hid_get_intf_desc(usb_speed_t speed) +{ + return &intf_desc; +} + +const usb_ep_desc_t *dev_hid_get_in_ep_desc(usb_speed_t speed) +{ + return &in_ep_desc; +} + +const usb_str_desc_t *dev_hid_get_str_desc_manu(void) +{ + return (const usb_str_desc_t *)str_desc_manu; +} + +const usb_str_desc_t *dev_hid_get_str_desc_prod(void) +{ + return (const usb_str_desc_t *)str_desc_prod; +} diff --git a/components/usb/test_apps/common/dev_hid.h b/components/usb/test_apps/common/dev_hid.h new file mode 100644 index 0000000000..a0eb581e3d --- /dev/null +++ b/components/usb/test_apps/common/dev_hid.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as an HID mouse be connected. That test device's information and descriptors are defined in this file. + +If you are connecting a different device, please update the descriptors in +dev_hid.c accordingly. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the test device + * + * @note Call this before running tests. This is necessary due to IDF-9886 + */ +void dev_hid_init(void); + +/** + * @brief Get the test device's descriptor + * + * @param[in] speed Test device's current speed + * @return Device descriptor + */ +const usb_device_desc_t *dev_hid_get_dev_desc(usb_speed_t speed); + +/** + * @brief Get the test device's configuration descriptor + * + * @param[in] speed Test device's current speed + * @return Configuration descriptor + */ +const usb_config_desc_t *dev_hid_get_config_desc(usb_speed_t speed); + +/** + * @brief Get the test device's HID interface descriptor + * + * @param[in] speed Test device's current speed + * @return HID interface descriptor + */ +const usb_intf_desc_t *dev_hid_get_intf_desc(usb_speed_t speed); + +/** + * @brief Get the test device's HID interrupt IN endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return Interrupt IN endpoint descriptor + */ +const usb_ep_desc_t *dev_hid_get_in_ep_desc(usb_speed_t speed); + +/** + * @brief Get the test device's manufacturer string descriptor + * + * @return Manufacturer string descriptor + */ +const usb_str_desc_t *dev_hid_get_str_desc_manu(void); + +/** + * @brief Get the test device's product string descriptor + * + * @return Product string descriptor + */ +const usb_str_desc_t *dev_hid_get_str_desc_prod(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/dev_isoc.c b/components/usb/test_apps/common/dev_isoc.c new file mode 100644 index 0000000000..6cf1eb52f6 --- /dev/null +++ b/components/usb/test_apps/common/dev_isoc.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" +#include "dev_isoc.h" + +// ------------------------------- Descriptors --------------------------------- + +static const usb_ep_desc_t isoc_out_ep_desc = { + .bLength = sizeof(usb_ep_desc_t), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x02, // EP 2 OUT + .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC, + .wMaxPacketSize = 512, + .bInterval = 1, // Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms +}; + +// -------------------------------- Functions ---------------------------------- + +const usb_ep_desc_t *dev_isoc_get_out_ep_desc(usb_speed_t speed) +{ + return &isoc_out_ep_desc; +} diff --git a/components/usb/test_apps/common/dev_isoc.h b/components/usb/test_apps/common/dev_isoc.h new file mode 100644 index 0000000000..9096179ac3 --- /dev/null +++ b/components/usb/test_apps/common/dev_isoc.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device containing an ISOC endpoint be connected. This header contains +functions to get information and descriptors about that test device. + +If you are connecting a different device, please update the descriptors in +dev_isoc.c accordingly. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get the test device's ISOC OUT endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return ISOC OUT endpoint descriptor + */ +const usb_ep_desc_t *dev_isoc_get_out_ep_desc(usb_speed_t speed); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/dev_msc.c b/components/usb/test_apps/common/dev_msc.c new file mode 100644 index 0000000000..6d5d93d224 --- /dev/null +++ b/components/usb/test_apps/common/dev_msc.c @@ -0,0 +1,354 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "usb/usb_types_ch9.h" +#include "dev_msc.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as a MSC SCSI flash drive be connected. That test device's +information and descriptors are defined in this file. + +If you are connecting a different MSC SCSI flash drive, please update +the descriptor and getter functions accordingly. + +------------------------------ Device Descriptor ------------------------------- +bLength : 0x12 (18 bytes) +bDescriptorType : 0x01 (Device Descriptor) +bcdUSB : 0x0210 (2.10) +bDeviceClass : 0x00 +bDeviceSubClass : 0x00 +bDeviceProtocol : 0x00 +bMaxPacketSize0 : 0x40 (64 bytes) +idVendor : 0x0781 (SanDisk Corp) +idProduct : 0x5595 +bcdDevice : 0x0100 (1.00) +iManufacturer : 1 +iProduct : 2 +iSerial : 3 +bNumConfigurations : 1 + +--------------------------- Configuration Descriptor --------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x02 (Configuration Descriptor) +wTotalLength : 0x0020 (32 bytes) +bNumInterfaces : 0x01 (1 Interface) +bConfigurationValue : 0x01 (Configuration 1) +iConfiguration : 0x00 (No String Descriptor) +bmAttributes : 0x80 + D7: Reserved, set 1 : 0x01 + D6: Self Powered : 0x00 (no) + D5: Remote Wakeup : 0x00 (no) + D4..0: Reserved, set 0 : 0x00 +MaxPower : 0x70 (224 mA) + +Data (HexDump) : 09 02 20 00 01 01 00 80 70 09 04 00 00 02 08 06 + 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00 + +----------------------------- Interface Descriptor ----------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x04 (Interface Descriptor) +bInterfaceNumber : 0x00 +bAlternateSetting : 0x00 +bNumEndpoints : 0x02 (2 Endpoints) +bInterfaceClass : 0x08 (Mass Storage) +bInterfaceSubClass : 0x06 (SCSI transparent command set) +bInterfaceProtocol : 0x50 (Bulk-Only Transport) +iInterface : 0x00 (No String Descriptor) + +------------------------------ Endpoint Descriptor ----------------------------- +bLength : 0x07 (7 bytes) +bDescriptorType : 0x05 (Endpoint Descriptor) +bEndpointAddress : 0x81 (Direction=IN EndpointID=1) +bmAttributes : 0x02 (TransferType=Bulk) +wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS) +bInterval : 0x00 (never NAKs) + +------------------------------ Endpoint Descriptor ----------------------------- +bLength : 0x07 (7 bytes) +bDescriptorType : 0x05 (Endpoint Descriptor) +bEndpointAddress : 0x02 (Direction=OUT EndpointID=2) +bmAttributes : 0x02 (TransferType=Bulk) +wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS) +bInterval : 0x00 (never NAKs) + +---------------------------- String Descriptor Manu ---------------------------- +bLength : 0x0A (10 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : " USB" + +---------------------------- String Descriptor Prod ---------------------------- +bLength : 0x22 (34 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : " SanDisk 3.2Gen1" + +----------------------------- String Descriptor Ser ---------------------------- +bLength : 0xF2 (242 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : "0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4" +*/ + +// --------------------------- Device Information ------------------------------ + +static const dev_msc_info_t dev_info = { + .bInterfaceNumber = 0x00, + .bAlternateSetting = 0x00, + .in_ep_addr = 0x81, + .out_up_addr = 0x02, + .scsi_sector_size = 512, +}; + +// ------------------------------- Descriptors --------------------------------- + +static const usb_device_desc_t dev_desc = { + .bLength = USB_DEVICE_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE, + .bcdUSB = 0x0210, // 2.10 + .bDeviceClass = USB_CLASS_PER_INTERFACE, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x0781, // SanDisk Corp + .idProduct = 0x5595, + .bcdDevice = 0x0100, // 1.00 + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +static const usb_config_desc_t config_desc = { + .bLength = USB_CONFIG_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = 0x0020, // 32 bytes + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x70, // 224 mA +}; + +static const usb_intf_desc_t intf_desc = { + .bLength = USB_INTF_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = 0x06, //SCSI + .bInterfaceProtocol = 0x50, //Bulk only + .iInterface = 0, +}; + +static const usb_ep_desc_t in_ep_desc_fs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, // EP 1 IN + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 64, + .bInterval = 0, +}; + +static const usb_ep_desc_t in_ep_desc_hs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, // EP 1 IN + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 512, + .bInterval = 0, +}; + +static const usb_ep_desc_t out_ep_desc_fs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x02, // EP 2 OUT + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 64, + .bInterval = 0, +}; + +static const usb_ep_desc_t out_ep_desc_hs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x02, // EP 2 OUT + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 512, + .bInterval = 0, +}; + +/* +String descriptors are dynamically initialized due to issues with static +initialization of variable length array members. See IDF-9886. +*/ + +static const usb_str_desc_t str_desc_manu_base = { + .bLength = sizeof(usb_str_desc_t) + (4 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_manu_data[] = { + 0x0020, // ' ' + 0x0055, // 'U' + 0x0053, // 'S' + 0x0042, // 'B' +}; +static uint8_t *str_desc_manu[sizeof(str_desc_manu_base) + sizeof(str_desc_manu_data)]; + +static const usb_str_desc_t str_desc_prod_base = { + .bLength = sizeof(usb_str_desc_t) + (16 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_prod_data[] = { + 0x0020, // ' ' + 0x0053, // 'S' + 0x0061, // 'a' + 0x006e, // 'n' + 0x0044, // 'D' + 0x0069, // 'i' + 0x0073, // 's' + 0x006b, // 'k' + 0x0020, // ' ' + 0x0033, // '3' + 0x002e, // '.' + 0x0032, // '2' + 0x0047, // 'G' + 0x0065, // 'e' + 0x006e, // 'n' + 0x0031, // '1' +}; +static uint8_t *str_desc_prod[sizeof(str_desc_prod_base) + sizeof(str_desc_prod_data)]; + +static const usb_str_desc_t str_desc_ser_base = { + .bLength = sizeof(usb_str_desc_t) + (120 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_ser_data[] = { + /* + The following string encoded in UTF-16LE + + "0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000 + 000000000000096abe1a3ff83610095558107aea948b4" + */ + 0x0030, 0x0031, 0x0030, 0x0031, 0x0063, 0x0064, 0x0064, 0x0031, 0x0065, + 0x0038, 0x0035, 0x0036, 0x0062, 0x0034, 0x0032, 0x0037, 0x0062, 0x0062, + 0x0062, 0x0037, 0x0039, 0x0036, 0x0066, 0x0038, 0x0037, 0x0030, 0x0035, + 0x0036, 0x0031, 0x0061, 0x0034, 0x0062, 0x0032, 0x0062, 0x0038, 0x0031, + 0x0037, 0x0061, 0x0066, 0x0039, 0x0064, 0x0061, 0x0039, 0x0038, 0x0037, + 0x0032, 0x0063, 0x0038, 0x0064, 0x0037, 0x0035, 0x0032, 0x0031, 0x0037, + 0x0063, 0x0063, 0x0063, 0x0064, 0x0064, 0x0035, 0x0064, 0x0035, 0x0065, + 0x0063, 0x0063, 0x0062, 0x0033, 0x0061, 0x0030, 0x0030, 0x0030, 0x0030, + 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, + 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0039, 0x0036, + 0x0061, 0x0062, 0x0065, 0x0031, 0x0061, 0x0033, 0x0066, 0x0066, 0x0038, + 0x0033, 0x0036, 0x0031, 0x0030, 0x0030, 0x0039, 0x0035, 0x0035, 0x0035, + 0x0038, 0x0031, 0x0030, 0x0037, 0x0061, 0x0065, 0x0061, 0x0039, 0x0034, + 0x0038, 0x0062, 0x0034, +}; +static uint8_t *str_desc_ser[sizeof(str_desc_ser_base) + sizeof(str_desc_ser_data)]; + +// -------------------------------- Functions ---------------------------------- + +void dev_msc_init(void) +{ + // Dynamically initialize string descriptors due to compiler limitations (see IDF-9886) + uint8_t *ptr; + + // Initialize manufacturer string descriptor + ptr = (uint8_t *)str_desc_manu; + memcpy(ptr, &str_desc_manu_base, sizeof(str_desc_manu_base)); + ptr += sizeof(str_desc_manu_base); + memcpy(ptr, &str_desc_manu_data, sizeof(str_desc_manu_data)); + + // Initialize product string descriptor + ptr = (uint8_t *)str_desc_prod; + memcpy(ptr, &str_desc_prod_base, sizeof(str_desc_prod_base)); + ptr += sizeof(str_desc_prod_base); + memcpy(ptr, &str_desc_prod_data, sizeof(str_desc_prod_data)); + + // Initialize serial string descriptor + ptr = (uint8_t *)str_desc_ser; + memcpy(ptr, &str_desc_ser_base, sizeof(str_desc_ser_base)); + ptr += sizeof(str_desc_ser_base); + memcpy(ptr, &str_desc_ser_data, sizeof(str_desc_ser_data)); +} + +const dev_msc_info_t *dev_msc_get_info(void) +{ + return &dev_info; +} + +const usb_device_desc_t *dev_msc_get_dev_desc(usb_speed_t speed) +{ + return &dev_desc; +} + +const usb_config_desc_t *dev_msc_get_config_desc(usb_speed_t speed) +{ + return &config_desc; +} + +const usb_intf_desc_t *dev_msc_get_intf_desc(usb_speed_t speed) +{ + return &intf_desc; +} + +const usb_ep_desc_t *dev_msc_get_in_ep_desc(usb_speed_t speed) +{ + const usb_ep_desc_t *ret; + + // EP descriptor differs by speed due to MPS + switch (speed) { + case USB_SPEED_FULL: + ret = &in_ep_desc_fs; + break; + case USB_SPEED_HIGH: + ret = &in_ep_desc_hs; + break; + default: + ret = NULL; + abort(); // Should never occur + break; + } + + return ret; +} + +const usb_ep_desc_t *dev_msc_get_out_ep_desc(usb_speed_t speed) +{ + const usb_ep_desc_t *ret; + + // EP descriptor differs by speed due to MPS + switch (speed) { + case USB_SPEED_FULL: + ret = &out_ep_desc_fs; + break; + case USB_SPEED_HIGH: + ret = &out_ep_desc_hs; + break; + default: + ret = NULL; + abort(); // Should never occur + break; + } + + return ret; +} + +const usb_str_desc_t *dev_msc_get_str_desc_manu(void) +{ + return (const usb_str_desc_t *)str_desc_manu; +} + +const usb_str_desc_t *dev_msc_get_str_desc_prod(void) +{ + return (const usb_str_desc_t *)str_desc_prod; +} + +const usb_str_desc_t *dev_msc_get_str_desc_ser(void) +{ + return (const usb_str_desc_t *)str_desc_ser; +} diff --git a/components/usb/test_apps/common/dev_msc.h b/components/usb/test_apps/common/dev_msc.h new file mode 100644 index 0000000000..ac21ca952e --- /dev/null +++ b/components/usb/test_apps/common/dev_msc.h @@ -0,0 +1,118 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as a MSC SCSI flash drive be connected. This header contains +functions to get information and descriptors about that test device. + +If you are connecting a different MSC SCSI flash drive, please update +the descriptors in dev_msc.c accordingly. +*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief MSC SCSI test device information + * + * Structure containing basic information about the the MSC SCSI interface on + * the test device. + */ +typedef struct { + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t in_ep_addr; + uint8_t out_up_addr; + unsigned int scsi_sector_size; +} dev_msc_info_t; + +/** + * @brief Initialize the test device + * + * @note Call this before running tests. This is necessary due to IDF-9886 + */ +void dev_msc_init(void); + +/** + * @brief Get information about the test device's MSC SCSI interface + * + * @return Information object + */ +const dev_msc_info_t *dev_msc_get_info(void); + +/** + * @brief Get the test device's descriptor + * + * @param[in] speed Test device's current speed + * @return Device descriptor + */ +const usb_device_desc_t *dev_msc_get_dev_desc(usb_speed_t speed); + +/** + * @brief Get the test device's configuration descriptor + * + * @param[in] speed Test device's current speed + * @return Configuration descriptor + */ +const usb_config_desc_t *dev_msc_get_config_desc(usb_speed_t speed); + +/** + * @brief Get the test device's MSC interface descriptor + * + * @param[in] speed Test device's current speed + * @return MSC interface descriptor + */ +const usb_intf_desc_t *dev_msc_get_intf_desc(usb_speed_t speed); + +/** + * @brief Get the test device's MSC IN endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return MSC IN endpoint descriptor + */ +const usb_ep_desc_t *dev_msc_get_in_ep_desc(usb_speed_t speed); + +/** + * @brief Get the test device's MSC OUT endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return MSC OUT endpoint descriptor + */ +const usb_ep_desc_t *dev_msc_get_out_ep_desc(usb_speed_t speed); + +/** + * @brief Get the test device's manufacturer string descriptor + * + * @return Manufacturer string descriptor + */ +const usb_str_desc_t *dev_msc_get_str_desc_manu(void); + +/** + * @brief Get the test device's product string descriptor + * + * @return Product string descriptor + */ +const usb_str_desc_t *dev_msc_get_str_desc_prod(void); + +/** + * @brief Get the test device's serial number string descriptor + * + * @return Serial number string descriptor + */ +const usb_str_desc_t *dev_msc_get_str_desc_ser(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/mock_hid.c b/components/usb/test_apps/common/mock_hid.c deleted file mode 100644 index 4f91e7b294..0000000000 --- a/components/usb/test_apps/common/mock_hid.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include "usb/usb_types_ch9.h" -#include "mock_hid.h" - -// ---------------------------------------------------- HID Mouse ------------------------------------------------------ - -const usb_ep_desc_t mock_hid_mouse_in_ep_desc = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_HID_MOUSE_INTR_IN_EP_ADDR, // EP 1 IN - .bmAttributes = USB_BM_ATTRIBUTES_XFER_INT, - .wMaxPacketSize = MOCK_HID_MOUSE_INTR_IN_MPS, - .bInterval = 10, // Interval of 10ms -}; - -void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter) -{ - static int x_pos = 0; - static int y_pos = 0; - // Update X position - if (report->x_movement & 0x80) { // Positive movement - x_pos += report->x_movement & 0x7F; - } else { // Negative movement - x_pos -= report->x_movement & 0x7F; - } - // Update Y position - if (report->y_movement & 0x80) { // Positive movement - y_pos += report->y_movement & 0x7F; - } else { // Negative movement - y_pos -= report->y_movement & 0x7F; - } - printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter); -} diff --git a/components/usb/test_apps/common/mock_hid.h b/components/usb/test_apps/common/mock_hid.h deleted file mode 100644 index a9a145fbdf..0000000000 --- a/components/usb/test_apps/common/mock_hid.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* -This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB -Host stack. -*/ - -#pragma once - -#include -#include -#include "esp_assert.h" -#include "usb/usb_types_ch9.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// ---------------------------------------------------- HID Mouse ------------------------------------------------------ - -/* -Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should... - -- Be implement the HID with standard report format used by mice -- It's configuration 1 should have the following endpoint - - ------------------ Configuration Descriptor ------------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x02 (Configuration Descriptor) -wTotalLength : 0x003B (59 bytes) -bNumInterfaces : 0x02 (2 Interfaces) -bConfigurationValue : 0x01 (Configuration 1) -iConfiguration : 0x00 (No String Descriptor) -bmAttributes : 0xA0 - D7: Reserved, set 1 : 0x01 - D6: Self Powered : 0x00 (no) - D5: Remote Wakeup : 0x01 (yes) - D4..0: Reserved, set 0 : 0x00 -MaxPower : 0x32 (100 mA) -Data (HexDump) : 09 02 3B 00 02 01 00 A0 32 09 04 00 00 01 03 01 - 02 00 09 21 00 02 00 01 22 4D 00 07 05 81 03 08 - 00 0A 09 04 01 00 01 03 01 01 00 09 21 00 02 00 - 01 22 31 00 07 05 82 03 08 00 0A - - ---------------- Interface Descriptor ----------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x04 (Interface Descriptor) -bInterfaceNumber : 0x00 -bAlternateSetting : 0x00 -bNumEndpoints : 0x01 (1 Endpoint) -bInterfaceClass : 0x03 (HID - Human Interface Device) -bInterfaceSubClass : 0x01 (Boot Interface) -bInterfaceProtocol : 0x02 (Mouse) -iInterface : 0x00 (No String Descriptor) -Data (HexDump) : 09 04 00 00 01 03 01 02 00 - - ------------------- HID Descriptor -------------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x21 (HID Descriptor) -bcdHID : 0x0200 (HID Version 2.00) -bCountryCode : 0x00 (00 = not localized) -bNumDescriptors : 0x01 -Data (HexDump) : 09 21 00 02 00 01 22 4D 00 -Descriptor 1: -bDescriptorType : 0x22 (Class=Report) -wDescriptorLength : 0x004D (77 bytes) -Error reading descriptor : ERROR_INVALID_PARAMETER (due to a obscure limitation of the Win32 USB API, see UsbTreeView.txt) - - ----------------- Endpoint Descriptor ----------------- -bLength : 0x07 (7 bytes) -bDescriptorType : 0x05 (Endpoint Descriptor) -bEndpointAddress : 0x81 (Direction=IN EndpointID=1) -bmAttributes : 0x03 (TransferType=Interrupt) -wMaxPacketSize : 0x0008 -bInterval : 0x0A (10 ms) -Data (HexDump) : 07 05 81 03 08 00 0A - -If you're using another mice with different endpoints, modify the endpoint descriptor below -*/ - -extern const usb_ep_desc_t mock_hid_mouse_in_ep_desc; - -#define MOCK_HID_MOUSE_DEV_ID_VENDOR 0x03F0 -#define MOCK_HID_MOUSE_DEV_ID_PRODUCT 0x1198 -#define MOCK_HID_MOUSE_DEV_DFLT_EP_MPS 8 -#define MOCK_HID_MOUSE_INTF_NUMBER 0 -#define MOCK_HID_MOUSE_INTF_ALT_SETTING 0 -#define MOCK_HID_MOUSE_INTR_IN_EP_ADDR 0x81 -#define MOCK_HID_MOUSE_INTR_IN_MPS 8 - -typedef union { - struct { - uint32_t left_button: 1; - uint32_t right_button: 1; - uint32_t middle_button: 1; - uint32_t reserved5: 5; - uint8_t x_movement; - uint8_t y_movement; - } __attribute__((packed)); - uint8_t val[3]; -} mock_hid_mouse_report_t; -ESP_STATIC_ASSERT(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect"); - -void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter); - -#ifdef __cplusplus -} -#endif diff --git a/components/usb/test_apps/common/mock_msc.c b/components/usb/test_apps/common/mock_msc.c index fd276d6b5b..30538f0f7f 100644 --- a/components/usb/test_apps/common/mock_msc.c +++ b/components/usb/test_apps/common/mock_msc.c @@ -15,97 +15,18 @@ const char *MSC_CLIENT_TAG = "MSC Client"; -const usb_device_desc_t mock_msc_scsi_dev_desc = { - .bLength = USB_DEVICE_DESC_SIZE, - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE, - .bcdUSB = MOCK_MSC_SCSI_USB_VERSION, - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = MOCK_MSC_SCSI_DEV_DFLT_EP_MPS, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, - .bcdDevice = MOCK_MSC_SCSI_DEV_VERSION, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1, -}; - -#define MOCK_MSC_SCSI_WTOTALLENGTH (USB_CONFIG_DESC_SIZE + USB_INTF_DESC_SIZE + 2*USB_EP_DESC_SIZE) -static const usb_config_desc_t mock_msc_config_desc = { - .bLength = USB_CONFIG_DESC_SIZE, - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION, - .wTotalLength = MOCK_MSC_SCSI_WTOTALLENGTH, - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 0x70, // 224mA -}; - -static const usb_intf_desc_t mock_msc_intf_desc = { - .bLength = USB_INTF_DESC_SIZE, - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE, - .bInterfaceNumber = MOCK_MSC_SCSI_INTF_NUMBER, - .bAlternateSetting = MOCK_MSC_SCSI_INTF_ALT_SETTING, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = 0x06, // SCSI - .bInterfaceProtocol = 0x50, // Bulk only - .iInterface = 0, -}; - -uint8_t mock_msc_scsi_config_desc[255]; -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_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_fs = { - .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_FS, // MPS of 64 bytes - .bInterval = 0, -}; - -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), - .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_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, -}; - -void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag) +void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, + bool is_read, + unsigned int offset, + unsigned int num_sectors, + unsigned int sector_size, + uint32_t tag) { cbw->dCBWSignature = 0x43425355; // Fixed value cbw->dCBWTag = tag; // Random value that is echoed back - cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE; + cbw->dCBWDataTransferLength = num_sectors * sector_size; cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; // If this is a read, set the direction flag - cbw->bCBWLUN = MOCK_MSC_SCSI_LUN; + cbw->bCBWLUN = 0; cbw->bCBWCBLength = 10; // The length of the SCSI command // Initialize SCSI CMD as READ10 or WRITE 10 cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; // SCSI CMD READ10 or WRITE10 @@ -141,39 +62,3 @@ bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect) } return no_issues; } - -void mock_msc_scsi_init_reference_descriptors(void) -{ - // Configuration descriptor - uint8_t *dest_ptr = mock_msc_scsi_config_desc; - memcpy(dest_ptr, (void*)&mock_msc_config_desc, sizeof(mock_msc_config_desc)); - dest_ptr += USB_CONFIG_DESC_SIZE; - memcpy(dest_ptr, (void*)&mock_msc_intf_desc, sizeof(mock_msc_intf_desc)); - dest_ptr += USB_INTF_DESC_SIZE; - // 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; - memset(dest_ptr, 0, sizeof(usb_ep_desc_t)); - - // 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 - 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 - 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 - for (uint8_t i = 0; i < chr_count; i++) { - mock_msc_scsi_str_desc_ser_num[1 + i] = str[i]; - } -} diff --git a/components/usb/test_apps/common/mock_msc.h b/components/usb/test_apps/common/mock_msc.h index 466decf2be..17e347d49a 100644 --- a/components/usb/test_apps/common/mock_msc.h +++ b/components/usb/test_apps/common/mock_msc.h @@ -4,11 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* -This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB -Host stack. -*/ - #pragma once #include @@ -16,99 +11,16 @@ Host stack. #include "esp_assert.h" #include "usb/usb_types_ch9.h" +/* +This header contains bare-bone mock implementations of the MSC SCSI class +*/ + #ifdef __cplusplus extern "C" { #endif -// ---------------------------------------------------- MSC SCSI ------------------------------------------------------- - extern const char *MSC_CLIENT_TAG; -/* -Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should... - -- Be implement the Mass Storage class supporting BULK only transfers using SCSI commands -- It's configuration 1 should have the following endpoints - - ------------------ Configuration Descriptor ------------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x02 (Configuration Descriptor) -wTotalLength : 0x0020 (32 bytes) -bNumInterfaces : 0x01 (1 Interface) -bConfigurationValue : 0x01 (Configuration 1) -iConfiguration : 0x00 (No String Descriptor) -bmAttributes : 0x80 - D7: Reserved, set 1 : 0x01 - D6: Self Powered : 0x00 (no) - D5: Remote Wakeup : 0x00 (no) - D4..0: Reserved, set 0 : 0x00 -MaxPower : 0x70 (224 mA) -Data (HexDump) : 09 02 20 00 01 01 00 80 70 09 04 00 00 02 08 06 - 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00 - - ---------------- Interface Descriptor ----------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x04 (Interface Descriptor) -bInterfaceNumber : 0x00 -bAlternateSetting : 0x00 -bNumEndpoints : 0x02 (2 Endpoints) -bInterfaceClass : 0x08 (Mass Storage) -bInterfaceSubClass : 0x06 (SCSI transparent command set) -bInterfaceProtocol : 0x50 (Bulk-Only Transport) -iInterface : 0x00 (No String Descriptor) -Data (HexDump) : 09 04 00 00 02 08 06 50 00 - - ----------------- Endpoint Descriptor ----------------- -bLength : 0x07 (7 bytes) -bDescriptorType : 0x05 (Endpoint Descriptor) -bEndpointAddress : 0x81 (Direction=IN EndpointID=1) -bmAttributes : 0x02 (TransferType=Bulk) -wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS) -bInterval : 0x00 (never NAKs) -Data (HexDump) : 07 05 81 02 40 00 00 - - ----------------- Endpoint Descriptor ----------------- -bLength : 0x07 (7 bytes) -bDescriptorType : 0x05 (Endpoint Descriptor) -bEndpointAddress : 0x02 (Direction=OUT EndpointID=2) -bmAttributes : 0x02 (TransferType=Bulk) -wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytest for HS) -bInterval : 0x00 (never NAKs) -Data (HexDump) : 07 05 02 02 40 00 00 - -If you're using a flash driver with different endpoints, modify the endpoint descriptors below. -*/ - -//Constant descriptors -extern const usb_device_desc_t mock_msc_scsi_dev_desc; -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_prod[128]; -extern uint16_t mock_msc_scsi_str_desc_ser_num[128]; -extern usb_ep_desc_t mock_msc_scsi_bulk_out_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_PRODUCT 0x5595 -#define MOCK_MSC_SCSI_DEV_VERSION 0x0100 //1.00 -#define MOCK_MSC_SCSI_USB_VERSION 0x0210 //2.10 -#define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64 -#define MOCK_MSC_SCSI_SECTOR_SIZE 512 -#define MOCK_MSC_SCSI_LUN 0 -#define MOCK_MSC_SCSI_INTF_NUMBER 0 -#define MOCK_MSC_SCSI_INTF_ALT_SETTING 0 -#define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x02 -#define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x81 -#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_2 (" SanDisk 3.2Gen1") -#define MOCK_MSC_SCSI_STRING_3 ("0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4") // This string is NOT checked by the enum test - #define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \ (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \ (setup_pkt_ptr)->bRequest = 0xFF; \ @@ -155,21 +67,26 @@ typedef struct __attribute__((packed)) /** * @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command * - * @param cbw CBW structure - * @param is_read Is a read command - * @param offset Block offset - * @param num_sectors Number of sectors to read - * @param tag Tag (this is simply echoed back + * @param[in] cbw CBW structure + * @param[in] is_read Is a read command + * @param[in] offset Block offset + * @param[in] num_sectors Number of sectors to read + * @param[in] sector_size Size of each sector in bytes + * @param[in] tag Tag (this is simply echoed back */ -void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag); +void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, + bool is_read, + unsigned int offset, + unsigned int num_sectors, + unsigned int sector_size, + uint32_t tag); /** * @brief Check that returned Command Status Wrapper (CSW) is valid * - * @param csw CSW structure - * @param tag_expect Expected tag - * @return true CSW is valid - * @return false CSW is not valid + * @param[in] csw CSW structure + * @param[in] tag_expect Expected tag + * @return True if CSW is valid, false otherwise */ bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect); @@ -178,25 +95,6 @@ bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect); */ void mock_msc_scsi_init_reference_descriptors(void); -// ---------------------------------------------------- Mock ISOC ------------------------------------------------------ - -/* -Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for -ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below: -*/ - -#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, - .bEndpointAddress = MOCK_ISOC_EP_NUM, - .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC, - .wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes - .bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms -}; - #ifdef __cplusplus } #endif diff --git a/components/usb/test_apps/hcd/main/test_app_main.c b/components/usb/test_apps/hcd/main/test_app_main.c index d9a01d71e8..9137bfe469 100644 --- a/components/usb/test_apps/hcd/main/test_app_main.c +++ b/components/usb/test_apps/hcd/main/test_app_main.c @@ -7,14 +7,17 @@ #include "unity.h" #include "unity_test_runner.h" #include "unity_test_utils_memory.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "dev_msc.h" +#include "dev_hid.h" #include "test_hcd_common.h" void setUp(void) { unity_utils_record_free_mem(); + dev_msc_init(); + dev_hid_init(); port_hdl = test_hcd_setup(); } diff --git a/components/usb/test_apps/hcd/main/test_hcd_bulk.c b/components/usb/test_apps/hcd/main/test_hcd_bulk.c index f5034dc66a..8d72020012 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_bulk.c +++ b/components/usb/test_apps/hcd/main/test_hcd_bulk.c @@ -10,16 +10,17 @@ #include "freertos/semphr.h" #include "unity.h" #include "mock_msc.h" +#include "dev_msc.h" #include "test_hcd_common.h" // --------------------------------------------------- Test Cases ------------------------------------------------------ -static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe) +static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe, uint8_t bInterfaceNumber) { // Create URB urb_t *urb = test_hcd_alloc_urb(0, sizeof(usb_setup_packet_t)); usb_setup_packet_t *setup_pkt = (usb_setup_packet_t *)urb->transfer.data_buffer; - MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt, MOCK_MSC_SCSI_INTF_NUMBER); + MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt, bInterfaceNumber); urb->transfer.num_bytes = sizeof(usb_setup_packet_t); // Enqueue, wait, dequeue, and check URB TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb)); @@ -60,24 +61,31 @@ TEST_CASE("Test HCD bulk pipe URBs", "[bulk][full_speed]") // Enumerate and reset MSC SCSI device 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); - mock_msc_reset_req(default_pipe); - test_hcd_set_mock_msc_ep_descriptor(port_speed); + const dev_msc_info_t *dev_info = dev_msc_get_info(); + mock_msc_reset_req(default_pipe, dev_info->bInterfaceNumber); // 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_in_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_in_ep_desc, dev_addr, port_speed); + const usb_ep_desc_t *out_ep_desc = dev_msc_get_out_ep_desc(port_speed); + const usb_ep_desc_t *in_ep_desc = dev_msc_get_in_ep_desc(port_speed); + const uint16_t mps = USB_EP_DESC_GET_MPS(in_ep_desc) ; + hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr, port_speed); + hcd_pipe_handle_t bulk_in_pipe = test_hcd_pipe_alloc(port_hdl, in_ep_desc, dev_addr, port_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); - const uint16_t mps = USB_EP_DESC_GET_MPS(&mock_msc_scsi_bulk_in_ep_desc) ; + urb_t *urb_data = test_hcd_alloc_urb(0, TEST_NUM_SECTORS_PER_XFER * dev_info->scsi_sector_size); 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_data->transfer.num_bytes = TEST_NUM_SECTORS_PER_XFER * dev_info->scsi_sector_size; 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 - mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)urb_cbw->transfer.data_buffer, true, block_num, TEST_NUM_SECTORS_PER_XFER, 0xAAAAAAAA); + mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)urb_cbw->transfer.data_buffer, + true, + block_num, + TEST_NUM_SECTORS_PER_XFER, + dev_info->scsi_sector_size, + 0xAAAAAAAA); TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_out_pipe, urb_cbw)); test_hcd_expect_pipe_event(bulk_out_pipe, HCD_PIPE_EVENT_URB_DONE); TEST_ASSERT_EQUAL_PTR(urb_cbw, hcd_urb_dequeue(bulk_out_pipe)); diff --git a/components/usb/test_apps/hcd/main/test_hcd_common.c b/components/usb/test_apps/hcd/main/test_hcd_common.c index 0d69c183c1..293f6ca21f 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_common.c +++ b/components/usb/test_apps/hcd/main/test_hcd_common.c @@ -330,14 +330,3 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe) test_hcd_free_urb(urb); 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; - } -} diff --git a/components/usb/test_apps/hcd/main/test_hcd_intr.c b/components/usb/test_apps/hcd/main/test_hcd_intr.c index 7c772c9ee3..4416967c1b 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_intr.c +++ b/components/usb/test_apps/hcd/main/test_hcd_intr.c @@ -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 */ @@ -8,8 +8,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "unity.h" -#include "mock_msc.h" -#include "mock_hid.h" +#include "dev_hid.h" #include "test_hcd_common.h" // --------------------------------------------------- Test Cases ------------------------------------------------------ @@ -36,7 +35,6 @@ Note: Some mice will NAK until it is moved, so try moving the mouse around if th #define TEST_HID_DEV_SPEED USB_SPEED_LOW #define NUM_URBS 3 -#define URB_DATA_BUFF_SIZE MOCK_HID_MOUSE_INTR_IN_MPS #define NUM_URB_ITERS (NUM_URBS * 100) TEST_CASE("Test HCD interrupt pipe URBs", "[intr][low_speed]") @@ -49,11 +47,13 @@ TEST_CASE("Test HCD interrupt pipe URBs", "[intr][low_speed]") uint8_t dev_addr = test_hcd_enum_device(default_pipe); // Allocate interrupt pipe and URBS - hcd_pipe_handle_t intr_pipe = test_hcd_pipe_alloc(port_hdl, &mock_hid_mouse_in_ep_desc, dev_addr, port_speed); + const usb_ep_desc_t *in_ep_desc = dev_hid_get_in_ep_desc(port_speed); + const int data_buff_size = USB_EP_DESC_GET_MPS(in_ep_desc); + hcd_pipe_handle_t intr_pipe = test_hcd_pipe_alloc(port_hdl, in_ep_desc, dev_addr, port_speed); urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { - urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - urb_list[i]->transfer.num_bytes = URB_DATA_BUFF_SIZE; + urb_list[i] = test_hcd_alloc_urb(0, data_buff_size); + urb_list[i]->transfer.num_bytes = data_buff_size; urb_list[i]->transfer.context = URB_CONTEXT_VAL; } @@ -69,7 +69,8 @@ TEST_CASE("Test HCD interrupt pipe URBs", "[intr][low_speed]") urb_t *urb = hcd_urb_dequeue(intr_pipe); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - mock_hid_process_report((mock_hid_mouse_report_t *)urb->transfer.data_buffer, iter_count); + // Byte 1 and 2 contains x and y movement respectively + printf("X mov %d, Y mov %d\n", urb->transfer.data_buffer[1], urb->transfer.data_buffer[2]); // Requeue URB if (iter_count > NUM_URBS) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(intr_pipe, urb)); diff --git a/components/usb/test_apps/hcd/main/test_hcd_isoc.c b/components/usb/test_apps/hcd/main/test_hcd_isoc.c index 87364c44d1..20c4c63ab5 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_isoc.c +++ b/components/usb/test_apps/hcd/main/test_hcd_isoc.c @@ -10,14 +10,13 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "unity.h" -#include "mock_msc.h" +#include "dev_isoc.h" +#include "usb/usb_types_ch9.h" #include "test_usb_common.h" #include "test_hcd_common.h" #define NUM_URBS 3 #define NUM_PACKETS_PER_URB 3 -#define ISOC_PACKET_SIZE MOCK_ISOC_EP_MPS -#define URB_DATA_BUFF_SIZE (NUM_PACKETS_PER_URB * ISOC_PACKET_SIZE) #define POST_ENQUEUE_DELAY_US 20 #define ENQUEUE_DELAY (OTG_HSPHY_INTERFACE ? 100 : 500) // With this delay we want to enqueue the URBs at different times @@ -53,18 +52,20 @@ TEST_CASE("Test HCD isochronous pipe URBs", "[isoc][full_speed]") uint8_t dev_addr = test_hcd_enum_device(default_pipe); // Create ISOC OUT pipe to non-existent device - hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); + const usb_ep_desc_t *out_ep_desc = dev_isoc_get_out_ep_desc(port_speed); + const int isoc_packet_size = USB_EP_DESC_GET_MPS(out_ep_desc); + hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr + 1, port_speed); // Create URBs urb_t *urb_list[NUM_URBS]; // Initialize URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { - urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, URB_DATA_BUFF_SIZE); - urb_list[urb_idx]->transfer.num_bytes = URB_DATA_BUFF_SIZE; + urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, NUM_PACKETS_PER_URB * isoc_packet_size); + urb_list[urb_idx]->transfer.num_bytes = NUM_PACKETS_PER_URB * isoc_packet_size; urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) { - urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = isoc_packet_size; // Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) - memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * NUM_URBS) + pkt_idx, ISOC_PACKET_SIZE); + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * isoc_packet_size], (urb_idx * NUM_URBS) + pkt_idx, isoc_packet_size); } } // Enqueue URBs @@ -81,7 +82,7 @@ TEST_CASE("Test HCD isochronous pipe URBs", "[isoc][full_speed]") TEST_ASSERT_EQUAL(urb_list[urb_idx], urb); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); // Overall URB status and overall number of bytes - TEST_ASSERT_EQUAL(URB_DATA_BUFF_SIZE, urb->transfer.actual_num_bytes); + TEST_ASSERT_EQUAL(NUM_PACKETS_PER_URB * isoc_packet_size, urb->transfer.actual_num_bytes); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) { TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status, "Transfer NOT completed"); @@ -127,12 +128,14 @@ TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") urb_t *urb_list[NUM_URBS]; hcd_pipe_handle_t unused_pipes[OTG_NUM_HOST_CHAN]; + const usb_ep_desc_t *out_ep_desc = dev_isoc_get_out_ep_desc(port_speed); + const int isoc_packet_size = USB_EP_DESC_GET_MPS(out_ep_desc); // For all channels for (int channel = 0; channel < OTG_NUM_HOST_CHAN - 1; channel++) { // Allocate unused pipes, so the active isoc_out_pipe uses different channel index for (int ch = 0; ch < channel; ch++) { - unused_pipes[ch] = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); + unused_pipes[ch] = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr + 1, port_speed); } // For all intervals @@ -142,20 +145,21 @@ TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") unsigned num_packets_per_urb = 32; // This is maximum number of packets if interval = 1. This is limited by FRAME_LIST_LEN num_packets_per_urb >>= (interval - 1); // Create ISOC OUT pipe - usb_ep_desc_t isoc_out_ep = mock_isoc_out_ep_desc; // Implicit copy + usb_ep_desc_t isoc_out_ep; + memcpy(&isoc_out_ep, out_ep_desc, sizeof(usb_ep_desc_t)); isoc_out_ep.bInterval = interval; isoc_out_ep.bEndpointAddress = interval; // So you can see the bInterval value in trace hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &isoc_out_ep, channel + 1, port_speed); // Channel number represented in dev_num, so you can see it in trace // Initialize URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { - urb_list[urb_idx] = test_hcd_alloc_urb(num_packets_per_urb, num_packets_per_urb * ISOC_PACKET_SIZE); - urb_list[urb_idx]->transfer.num_bytes = num_packets_per_urb * ISOC_PACKET_SIZE; + urb_list[urb_idx] = test_hcd_alloc_urb(num_packets_per_urb, num_packets_per_urb * isoc_packet_size); + urb_list[urb_idx]->transfer.num_bytes = num_packets_per_urb * isoc_packet_size; urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; for (int pkt_idx = 0; pkt_idx < num_packets_per_urb; pkt_idx++) { - urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = isoc_packet_size; // Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) - memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * num_packets_per_urb) + pkt_idx, ISOC_PACKET_SIZE); + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * isoc_packet_size], (urb_idx * num_packets_per_urb) + pkt_idx, isoc_packet_size); } } @@ -176,7 +180,7 @@ TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") TEST_ASSERT_EQUAL(urb_list[urb_idx], urb); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); // Overall URB status and overall number of bytes - TEST_ASSERT_EQUAL(num_packets_per_urb * ISOC_PACKET_SIZE, urb->transfer.actual_num_bytes); + TEST_ASSERT_EQUAL(num_packets_per_urb * isoc_packet_size, urb->transfer.actual_num_bytes); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); for (int pkt_idx = 0; pkt_idx < num_packets_per_urb; pkt_idx++) { TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status, "Transfer NOT completed"); @@ -235,18 +239,20 @@ TEST_CASE("Test HCD isochronous pipe sudden disconnect", "[isoc][full_speed]") uint8_t dev_addr = test_hcd_enum_device(default_pipe); // Create ISOC OUT pipe to non-existent device - hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); + const usb_ep_desc_t *out_ep_desc = dev_isoc_get_out_ep_desc(port_speed); + const int isoc_packet_size = USB_EP_DESC_GET_MPS(out_ep_desc); + hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr + 1, port_speed); // Create URBs urb_t *urb_list[NUM_URBS]; // Initialize URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { - urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, URB_DATA_BUFF_SIZE); - urb_list[urb_idx]->transfer.num_bytes = URB_DATA_BUFF_SIZE; + urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, NUM_PACKETS_PER_URB * isoc_packet_size); + urb_list[urb_idx]->transfer.num_bytes = NUM_PACKETS_PER_URB * isoc_packet_size; urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) { - urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = isoc_packet_size; // Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) - memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * NUM_URBS) + pkt_idx, ISOC_PACKET_SIZE); + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * isoc_packet_size], (urb_idx * NUM_URBS) + pkt_idx, isoc_packet_size); } } // Enqueue URBs diff --git a/components/usb/test_apps/usb_host/main/ctrl_client.h b/components/usb/test_apps/usb_host/main/ctrl_client.h index 4cfeccc53d..b780571f6b 100644 --- a/components/usb/test_apps/usb_host/main/ctrl_client.h +++ b/components/usb/test_apps/usb_host/main/ctrl_client.h @@ -8,8 +8,6 @@ typedef struct { int num_ctrl_xfer_to_send; - uint16_t idVendor; - uint16_t idProduct; } ctrl_client_test_param_t; void ctrl_client_async_seq_task(void *arg); diff --git a/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c b/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c index 48b0937739..657cf87595 100644 --- a/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c +++ b/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c @@ -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 */ @@ -11,6 +11,7 @@ #include "esp_err.h" #include "esp_log.h" #include "test_usb_common.h" +#include "dev_msc.h" #include "ctrl_client.h" #include "usb/usb_host.h" #include "unity.h" @@ -47,14 +48,19 @@ typedef enum { } test_stage_t; typedef struct { + // Test parameters ctrl_client_test_param_t test_param; + // MSC device info + uint8_t dev_addr; + usb_speed_t dev_speed; + // Client variables + usb_host_client_handle_t client_hdl; + usb_device_handle_t dev_hdl; + // Test state test_stage_t cur_stage; test_stage_t next_stage; uint8_t num_xfer_done; uint8_t num_xfer_sent; - uint8_t dev_addr_to_open; - usb_host_client_handle_t client_hdl; - usb_device_handle_t dev_hdl; const usb_config_desc_t *config_desc_cached; } ctrl_client_obj_t; @@ -79,7 +85,7 @@ static void ctrl_client_event_cb(const usb_host_client_event_msg_t *event_msg, v 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; + ctrl_obj->dev_addr = event_msg->new_dev.address; break; default: abort(); // Should never occur in this test @@ -133,16 +139,21 @@ void ctrl_client_async_seq_task(void *arg) 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"); + TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr, &ctrl_obj.dev_hdl), "Failed to open the device"); + // Get device info to get device speed + usb_device_info_t dev_info; + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(ctrl_obj.dev_hdl, &dev_info)); + ctrl_obj.dev_speed = dev_info.speed; // 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 + // Check that the device descriptor matches our expected MSC device const usb_device_desc_t *device_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(ctrl_obj.dev_speed); 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); + TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, sizeof(usb_device_desc_t), "Device descriptors do not match."); // 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; diff --git a/components/usb/test_apps/usb_host/main/msc_client.h b/components/usb/test_apps/usb_host/main/msc_client.h index c3bf2063f2..6a816547bd 100644 --- a/components/usb/test_apps/usb_host/main/msc_client.h +++ b/components/usb/test_apps/usb_host/main/msc_client.h @@ -12,8 +12,6 @@ typedef struct { int num_sectors_to_read; int num_sectors_per_xfer; uint32_t msc_scsi_xfer_tag; - uint16_t idVendor; - uint16_t idProduct; } msc_client_test_param_t; void msc_client_async_seq_task(void *arg); diff --git a/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c b/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c index b1b4364906..5f1df1cf15 100644 --- a/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c +++ b/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c @@ -13,8 +13,10 @@ #include "esp_err.h" #include "esp_log.h" #include "mock_msc.h" +#include "dev_msc.h" #include "test_usb_common.h" #include "msc_client.h" +#include "usb/usb_types_ch9.h" #include "usb/usb_host.h" #include "unity.h" @@ -47,15 +49,20 @@ typedef enum { } test_stage_t; typedef struct { + // Test parameters msc_client_test_param_t test_param; - test_stage_t cur_stage; - test_stage_t next_stage; - uint8_t dev_addr_to_open; + // MSC device info + const dev_msc_info_t *dev_info; + usb_speed_t dev_speed; + uint8_t dev_addr; + // Client variables usb_host_client_handle_t client_hdl; usb_device_handle_t dev_hdl; + // Test state + test_stage_t cur_stage; + test_stage_t next_stage; int num_data_transfers; int event_count; - usb_speed_t dev_speed; } msc_client_obj_t; static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer) @@ -101,7 +108,7 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo 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; + msc_obj->dev_addr = event_msg->new_dev.address; break; case USB_HOST_CLIENT_EVENT_DEV_GONE: msc_obj->event_count++; @@ -119,13 +126,17 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo void msc_client_async_dconn_task(void *arg) { msc_client_obj_t msc_obj; + // Initialize test params memcpy(&msc_obj.test_param, arg, sizeof(msc_client_test_param_t)); - msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; - msc_obj.next_stage = TEST_STAGE_WAIT_CONN; - msc_obj.dev_addr_to_open = 0; + // Initialize MSC device info + msc_obj.dev_info = dev_msc_get_info(); + // Initialize client variables msc_obj.client_hdl = NULL; msc_obj.dev_hdl = NULL; - msc_obj.num_data_transfers = msc_obj.test_param.num_sectors_per_xfer / MOCK_MSC_SCSI_SECTOR_SIZE; + // Initialize test state + msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; + msc_obj.next_stage = TEST_STAGE_WAIT_CONN; + msc_obj.num_data_transfers = msc_obj.test_param.num_sectors_per_xfer / msc_obj.dev_info->scsi_sector_size; msc_obj.event_count = 0; // Register client @@ -143,7 +154,7 @@ void msc_client_async_dconn_task(void *arg) usb_transfer_t *xfer_out; // Must be large enough to contain CBW and MSC reset control transfer usb_transfer_t *xfer_in[msc_obj.num_data_transfers]; // We manually split the data stage into multiple transfers size_t xfer_out_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t)); - size_t xfer_in_size = MOCK_MSC_SCSI_SECTOR_SIZE; + size_t xfer_in_size = msc_obj.dev_info->scsi_sector_size; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(xfer_out_size, 0, &xfer_out)); xfer_out->context = (void *)&msc_obj; for (int i = 0; i < msc_obj.num_data_transfers; i++) { @@ -176,7 +187,7 @@ void msc_client_async_dconn_task(void *arg) 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)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr, &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; @@ -184,17 +195,21 @@ void msc_client_async_dconn_task(void *arg) 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); // 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; + // Check the device descriptor of the opened device + const usb_device_desc_t *device_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(msc_obj.dev_speed); + 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."); // 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, + msc_obj.dev_info->bInterfaceNumber, + msc_obj.dev_info->bAlternateSetting)); msc_obj.next_stage = TEST_STAGE_MSC_RESET; skip_event_handling = true; // Need to execute TEST_STAGE_MSC_RESET break; @@ -202,7 +217,7 @@ void msc_client_async_dconn_task(void *arg) 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); + MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, msc_obj.dev_info->bInterfaceNumber); 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)); @@ -211,9 +226,14 @@ void msc_client_async_dconn_task(void *arg) } 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); + 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.dev_info->scsi_sector_size, + 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; + xfer_out->bEndpointAddress = msc_obj.dev_info->out_up_addr; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out)); // Next stage set from transfer callback break; @@ -221,12 +241,11 @@ void msc_client_async_dconn_task(void *arg) case TEST_STAGE_MSC_DATA_DCONN: { ESP_LOGD(MSC_CLIENT_TAG, "Data and disconnect"); // 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; + const usb_ep_desc_t *in_ep_desc = dev_msc_get_in_ep_desc(msc_obj.dev_speed); + const int bulk_ep_mps = USB_EP_DESC_GET_MPS(in_ep_desc); 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, bulk_ep_mps); - xfer_in[i]->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; + xfer_in[i]->num_bytes = usb_round_up_to_mps(msc_obj.dev_info->scsi_sector_size, bulk_ep_mps); + xfer_in[i]->bEndpointAddress = msc_obj.dev_info->in_ep_addr; } // Submit those transfers for (int i = 0; i < msc_obj.num_data_transfers; i++) { @@ -239,7 +258,7 @@ void msc_client_async_dconn_task(void *arg) } 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_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, msc_obj.dev_info->bInterfaceNumber)); 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) { diff --git a/components/usb/test_apps/usb_host/main/msc_client_async_enum.c b/components/usb/test_apps/usb_host/main/msc_client_async_enum.c index 2d4135515f..e33ad0ad36 100644 --- a/components/usb/test_apps/usb_host/main/msc_client_async_enum.c +++ b/components/usb/test_apps/usb_host/main/msc_client_async_enum.c @@ -12,6 +12,7 @@ #include "freertos/task.h" #include "esp_err.h" #include "esp_log.h" +#include "dev_msc.h" #include "mock_msc.h" #include "test_usb_common.h" #include "msc_client.h" @@ -67,24 +68,6 @@ 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) { msc_client_obj_t msc_obj; @@ -136,17 +119,16 @@ void msc_client_async_enum_task(void *arg) 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 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; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(msc_obj.dev_speed); 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."); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, sizeof(usb_device_desc_t), "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; @@ -155,10 +137,10 @@ void msc_client_async_enum_task(void *arg) 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; + const usb_config_desc_t *config_desc_ref = dev_msc_get_config_desc(msc_obj.dev_speed); 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, "Incorrect length of CFG descriptor"); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, config_desc_ref->wTotalLength, "Configuration descriptors do not match"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, sizeof(usb_config_desc_t), "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; @@ -167,15 +149,15 @@ void msc_client_async_enum_task(void *arg) 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; + const usb_str_desc_t *manu_str_desc_ref = dev_msc_get_str_desc_manu(); + const usb_str_desc_t *product_str_desc_ref = dev_msc_get_str_desc_prod(); + const usb_str_desc_t *ser_num_str_desc_ref = dev_msc_get_str_desc_ser(); 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."); + 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 diff --git a/components/usb/test_apps/usb_host/main/msc_client_async_seq.c b/components/usb/test_apps/usb_host/main/msc_client_async_seq.c index 7bb41f3919..192012fb34 100644 --- a/components/usb/test_apps/usb_host/main/msc_client_async_seq.c +++ b/components/usb/test_apps/usb_host/main/msc_client_async_seq.c @@ -14,6 +14,7 @@ #include "esp_log.h" #include "test_usb_common.h" #include "mock_msc.h" +#include "dev_msc.h" #include "msc_client.h" #include "usb/usb_host.h" #include "unity.h" @@ -46,14 +47,19 @@ typedef enum { } test_stage_t; typedef struct { + // Test parameters msc_client_test_param_t test_param; - test_stage_t cur_stage; - test_stage_t next_stage; - uint8_t dev_addr_to_open; + // MSC device info + const dev_msc_info_t *dev_info; + usb_speed_t dev_speed; + uint8_t dev_addr; + // Client variables usb_host_client_handle_t client_hdl; usb_device_handle_t dev_hdl; + // Test state + test_stage_t cur_stage; + test_stage_t next_stage; int num_sectors_read; - usb_speed_t dev_speed; } msc_client_obj_t; static void msc_transfer_cb(usb_transfer_t *transfer) @@ -77,7 +83,7 @@ static void msc_transfer_cb(usb_transfer_t *transfer) 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); + TEST_ASSERT_EQUAL(msc_obj->dev_info->scsi_sector_size * msc_obj->test_param.num_sectors_per_xfer, transfer->actual_num_bytes); msc_obj->next_stage = TEST_STAGE_MSC_CSW; break; } @@ -107,7 +113,7 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo 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; + msc_obj->dev_addr = event_msg->new_dev.address; break; default: abort(); // Should never occur in this test @@ -119,12 +125,17 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo void msc_client_async_seq_task(void *arg) { msc_client_obj_t msc_obj; + // Initialize test params memcpy(&msc_obj.test_param, arg, sizeof(msc_client_test_param_t)); + // Initialize MSC device info + msc_obj.dev_info = dev_msc_get_info(); + // Initialize client variables + msc_obj.client_hdl = NULL; + msc_obj.dev_hdl = NULL; + // Initialize test state msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; msc_obj.next_stage = TEST_STAGE_WAIT_CONN; - msc_obj.client_hdl = NULL; - msc_obj.dev_addr_to_open = 0; - msc_obj.dev_hdl = NULL; + msc_obj.dev_addr = 0; msc_obj.num_sectors_read = 0; // Register client @@ -138,17 +149,10 @@ void msc_client_async_seq_task(void *arg) }; TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl)); - // Allocate transfers - 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 - 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_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(in_worst_case_size, 0, &xfer_in)); - xfer_out->callback = msc_transfer_cb; - xfer_in->callback = msc_transfer_cb; - xfer_out->context = (void *)&msc_obj; - xfer_in->context = (void *)&msc_obj; + // IN MPS and transfers to be set/allocated later (after device connects and MPS is determined) + int in_ep_mps = 0; + usb_transfer_t *xfer_in = NULL; + usb_transfer_t *xfer_out = NULL; // Wait to be started by main thread ulTaskNotifyTake(pdTRUE, portMAX_DELAY); @@ -170,21 +174,44 @@ void msc_client_async_seq_task(void *arg) 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); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr, &msc_obj.dev_hdl)); // 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; + // Check that the device descriptor matches our expected MSC device + const usb_device_desc_t *device_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(msc_obj.dev_speed); + 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, sizeof(usb_device_desc_t), "Device descriptors do not match."); // 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, + msc_obj.dev_info->bInterfaceNumber, + msc_obj.dev_info->bAlternateSetting)); + /* + Allocate transfers + + IN transfer must be large enough to contain CSW and Data + OUT transfer must be large enough to contain CBW and MSC reset control transfer + */ + const usb_ep_desc_t *in_ep_desc = dev_msc_get_in_ep_desc(msc_obj.dev_speed); + in_ep_mps = USB_EP_DESC_GET_MPS(in_ep_desc); + const size_t in_worst_case_size = usb_round_up_to_mps(MAX(msc_obj.dev_info->scsi_sector_size * msc_obj.test_param.num_sectors_per_xfer, + sizeof(mock_msc_bulk_csw_t)), + in_ep_mps); + const size_t out_worst_case_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t)); + 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)); + xfer_out->callback = msc_transfer_cb; + xfer_in->callback = msc_transfer_cb; + xfer_out->context = (void *)&msc_obj; + xfer_in->context = (void *)&msc_obj; + // Target our transfers to the device + xfer_out->device_handle = msc_obj.dev_hdl; + xfer_in->device_handle = msc_obj.dev_hdl; + // Set next stage msc_obj.next_stage = TEST_STAGE_MSC_RESET; skip_event_handling = true; // Need to execute TEST_STAGE_MSC_RESET break; @@ -192,7 +219,7 @@ void msc_client_async_seq_task(void *arg) 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); + MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, msc_obj.dev_info->bInterfaceNumber); 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)); @@ -203,9 +230,14 @@ void msc_client_async_seq_task(void *arg) } 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); + 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.dev_info->scsi_sector_size, + 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; + xfer_out->bEndpointAddress = msc_obj.dev_info->out_up_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)); @@ -214,11 +246,8 @@ void msc_client_async_seq_task(void *arg) } case TEST_STAGE_MSC_DATA: { ESP_LOGD(MSC_CLIENT_TAG, "Data"); - 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->num_bytes = usb_round_up_to_mps(msc_obj.dev_info->scsi_sector_size * msc_obj.test_param.num_sectors_per_xfer, in_ep_mps); + xfer_in->bEndpointAddress = msc_obj.dev_info->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)); @@ -227,11 +256,8 @@ void msc_client_async_seq_task(void *arg) } case TEST_STAGE_MSC_CSW: { ESP_LOGD(MSC_CLIENT_TAG, "CSW"); - 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->num_bytes = usb_round_up_to_mps(sizeof(mock_msc_bulk_csw_t), in_ep_mps); + xfer_in->bEndpointAddress = msc_obj.dev_info->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)); @@ -240,7 +266,7 @@ void msc_client_async_seq_task(void *arg) } 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_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, msc_obj.dev_info->bInterfaceNumber)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl)); exit_loop = true; break; diff --git a/components/usb/test_apps/usb_host/main/test_app_main.c b/components/usb/test_apps/usb_host/main/test_app_main.c index 3301425ab1..93e2510374 100644 --- a/components/usb/test_apps/usb_host/main/test_app_main.c +++ b/components/usb/test_apps/usb_host/main/test_app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -7,17 +7,16 @@ #include "unity.h" #include "unity_test_runner.h" #include "unity_test_utils_memory.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "test_usb_common.h" -#include "mock_msc.h" +#include "dev_msc.h" #include "usb/usb_host.h" void setUp(void) { - mock_msc_scsi_init_reference_descriptors(); unity_utils_record_free_mem(); + dev_msc_init(); test_usb_init_phy(); // Initialize the internal USB PHY and USB Controller for testing // Install USB Host usb_host_config_t host_config = { diff --git a/components/usb/test_apps/usb_host/main/test_usb_host_async.c b/components/usb/test_apps/usb_host/main/test_usb_host_async.c index b132bcfc84..c7329d91fa 100644 --- a/components/usb/test_apps/usb_host/main/test_usb_host_async.c +++ b/components/usb/test_apps/usb_host/main/test_usb_host_async.c @@ -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 */ @@ -11,7 +11,7 @@ #include "esp_err.h" #include "esp_intr_alloc.h" #include "test_usb_common.h" -#include "mock_msc.h" +#include "dev_msc.h" #include "msc_client.h" #include "ctrl_client.h" #include "usb/usb_host.h" @@ -51,8 +51,6 @@ TEST_CASE("Test USB Host async client (single client)", "[usb_host][full_speed][ .num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL, .num_sectors_per_xfer = TEST_MSC_NUM_SECTORS_PER_XFER, .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t task_hdl; xTaskCreatePinnedToCore(msc_client_async_seq_task, "async", 4096, (void *)¶ms, 2, &task_hdl, 0); @@ -101,8 +99,6 @@ TEST_CASE("Test USB Host async client (multi client)", "[usb_host][full_speed][h .num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL, .num_sectors_per_xfer = TEST_MSC_NUM_SECTORS_PER_XFER, .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t msc_task_hdl; xTaskCreatePinnedToCore(msc_client_async_seq_task, "msc", 4096, (void *)&msc_params, 2, &msc_task_hdl, 0); @@ -111,8 +107,6 @@ TEST_CASE("Test USB Host async client (multi client)", "[usb_host][full_speed][h // Create task a control transfer client ctrl_client_test_param_t ctrl_params = { .num_ctrl_xfer_to_send = TEST_CTRL_NUM_TRANSFERS, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t ctrl_task_hdl; xTaskCreatePinnedToCore(ctrl_client_async_seq_task, "ctrl", 4096, (void *)&ctrl_params, 2, &ctrl_task_hdl, 0); @@ -226,21 +220,35 @@ TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]") TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, 0, &client0_dev_hdl)); // Check that the device cannot be opened again by the same client + const dev_msc_info_t *dev_info = dev_msc_get_info(); usb_device_handle_t dummy_dev_hdl; TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, dev_addr, &dummy_dev_hdl)); TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client1_hdl, dev_addr, &dummy_dev_hdl)); printf("Claiming interface\n"); // Check that both clients cannot claim the same interface - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); - TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client1_hdl, client1_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber, + dev_info->bAlternateSetting)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client1_hdl, + client1_dev_hdl, + dev_info->bInterfaceNumber, + dev_info->bAlternateSetting)); // Check that client0 cannot claim the same interface multiple times - TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber, + dev_info->bAlternateSetting)); printf("Releasing interface\n"); // Check that client0 can release the interface - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber)); // Check that client0 cannot release interface it has not claimed - TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber)); // Wait until the device disconnects and the clients receive the event test_usb_set_phy_state(false, 0); diff --git a/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c b/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c index 6be17aa848..263898c0de 100644 --- a/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c +++ b/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c @@ -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 */ @@ -11,6 +11,7 @@ #include "esp_intr_alloc.h" #include "test_usb_common.h" #include "mock_msc.h" +#include "dev_msc.h" #include "msc_client.h" #include "ctrl_client.h" #include "usb/usb_host.h" @@ -84,12 +85,11 @@ Procedure: TEST_CASE("Test USB Host sudden disconnection (single client)", "[usb_host][full_speed]") { // Create task to run client that communicates with MSC SCSI interface + const dev_msc_info_t *dev_info = dev_msc_get_info(); msc_client_test_param_t params = { .num_sectors_to_read = 1, // Unused by disconnect MSC client - .num_sectors_per_xfer = TEST_FORCE_DCONN_NUM_TRANSFERS * MOCK_MSC_SCSI_SECTOR_SIZE, + .num_sectors_per_xfer = TEST_FORCE_DCONN_NUM_TRANSFERS * dev_info->scsi_sector_size, .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t task_hdl; xTaskCreatePinnedToCore(msc_client_async_dconn_task, "async", 4096, (void *)¶ms, 2, &task_hdl, 0);