2022-10-06 17:16:54 -04:00
/*
2024-01-30 06:13:46 -05:00
* SPDX - FileCopyrightText : 2015 - 2024 Espressif Systems ( Shanghai ) CO LTD
2022-10-06 17:16:54 -04:00
*
* 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 <stdint.h>
# include <stdbool.h>
# include "esp_assert.h"
# include "usb/usb_types_ch9.h"
# 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 )
2024-01-30 06:13:46 -05:00
wMaxPacketSize : 0x0040 ( max 64 bytes for FS , 512 bytes for HS )
2022-10-06 17:16:54 -04:00
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 )
2024-01-30 06:13:46 -05:00
wMaxPacketSize : 0x0040 ( max 64 bytes for FS , 512 bytest for HS )
2022-10-06 17:16:54 -04:00
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 ] ;
2024-01-30 06:13:46 -05:00
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 ;
2022-10-06 17:16:54 -04:00
# 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
2024-01-30 06:13:46 -05:00
# define MOCK_MSC_SCSI_BULK_EP_MPS_FS 64 // FS wMaxPacketSize
# define MOCK_MSC_SCSI_BULK_EP_MPS_HS 512 // HS wMaxPacketSize
2022-10-06 17:16:54 -04:00
# 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 ; \
( setup_pkt_ptr ) - > wValue = 0 ; \
( setup_pkt_ptr ) - > wIndex = ( intf_num ) ; \
( setup_pkt_ptr ) - > wLength = 0 ; \
} )
2023-12-14 04:14:39 -05:00
typedef struct __attribute__ ( ( packed ) )
{
2022-10-06 17:16:54 -04:00
uint8_t opcode ; //0x28 = read(10), 0x2A=write(10)
uint8_t flags ;
uint8_t lba_3 ;
uint8_t lba_2 ;
uint8_t lba_1 ;
uint8_t lba_0 ;
uint8_t group ;
uint8_t len_1 ;
uint8_t len_0 ;
uint8_t control ;
} mock_scsi_cmd10_t ;
2023-12-14 04:14:39 -05:00
typedef struct __attribute__ ( ( packed ) )
{
2022-10-06 17:16:54 -04:00
uint32_t dCBWSignature ;
uint32_t dCBWTag ;
uint32_t dCBWDataTransferLength ;
uint8_t bmCBWFlags ;
uint8_t bCBWLUN ;
uint8_t bCBWCBLength ;
mock_scsi_cmd10_t CBWCB ;
uint8_t padding [ 6 ] ;
} mock_msc_bulk_cbw_t ;
// USB Bulk Transfer Command Status Wrapper data
2023-12-14 04:14:39 -05:00
typedef struct __attribute__ ( ( packed ) )
{
2022-10-06 17:16:54 -04:00
uint32_t dCSWSignature ;
uint32_t dCSWTag ;
uint32_t dCSWDataResidue ;
uint8_t bCSWStatus ;
} mock_msc_bulk_csw_t ;
/**
* @ 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
*/
void mock_msc_scsi_init_cbw ( mock_msc_bulk_cbw_t * cbw , bool is_read , int offset , int num_sectors , 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
*/
bool mock_msc_scsi_check_csw ( mock_msc_bulk_csw_t * csw , uint32_t tag_expect ) ;
/**
* @ brief Construct configuration and string descriptors
*/
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