mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 06:11:06 +00:00 
			
		
		
		
	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.
		
			
				
	
	
		
			355 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			355 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier: Apache-2.0
 | 
						|
 */
 | 
						|
 | 
						|
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#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;
 | 
						|
}
 |