1 /* 2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /* 8 This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB 9 Host stack. 10 */ 11 12 #pragma once 13 14 #include <stdint.h> 15 #include <stdbool.h> 16 #include "usb/usb_types_ch9.h" 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 // ---------------------------------------------------- MSC SCSI ------------------------------------------------------- 23 24 const char *MSC_CLIENT_TAG; 25 26 /* 27 Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should... 28 29 - Be implement the Mass Storage class supporting BULK only transfers using SCSI commands 30 - It's configuration 1 should have the following endpoints 31 32 Device Descriptor: 33 bLength 18 34 bDescriptorType 1 35 bcdUSB 2.00 36 bDeviceClass 0 37 bDeviceSubClass 0 38 bDeviceProtocol 0 39 bMaxPacketSize0 64 40 idVendor 0x125f 41 idProduct 0xc08a 42 bcdDevice 1.00 43 iManufacturer 1 44 iProduct 2 45 iSerial 3 46 bNumConfigurations 1 47 Configuration Descriptor: 48 bLength 9 49 bDescriptorType 2 50 wTotalLength 0x0020 51 bNumInterfaces 1 52 bConfigurationValue 1 53 iConfiguration 0 54 bmAttributes 0x80 55 (Bus Powered) 56 MaxPower 480mA 57 Interface Descriptor: 58 bLength 9 59 bDescriptorType 4 60 bInterfaceNumber 0 61 bAlternateSetting 0 62 bNumEndpoints 2 63 bInterfaceClass 8 Mass Storage 64 bInterfaceSubClass 6 SCSI 65 bInterfaceProtocol 80 Bulk-Only 66 iInterface 0 67 Endpoint Descriptor: 68 bLength 7 69 bDescriptorType 5 70 bEndpointAddress 0x01 EP 1 OUT 71 bmAttributes 2 72 Transfer Type Bulk 73 Synch Type None 74 Usage Type Data 75 wMaxPacketSize 0x0040 1x 64 bytes 76 bInterval 1 77 Endpoint Descriptor: 78 bLength 7 79 bDescriptorType 5 80 bEndpointAddress 0x82 EP 2 IN 81 bmAttributes 2 82 Transfer Type Bulk 83 Synch Type None 84 Usage Type Data 85 wMaxPacketSize 0x0040 1x 64 bytes 86 bInterval 1 87 88 If you're using a flash driver with different endpoints, modify the endpoint descriptors below. 89 */ 90 91 //Constant descriptors 92 extern const uint8_t mock_msc_scsi_dev_desc[]; 93 extern const uint8_t mock_msc_scsi_config_desc[]; 94 extern const uint8_t mock_msc_scsi_str_desc_manu[]; 95 extern const uint8_t mock_msc_scsi_str_desc_prod[]; 96 extern const uint8_t mock_msc_scsi_str_desc_ser_num[]; 97 extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc; 98 extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc; 99 100 #define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x125F 101 #define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0xc08A 102 #define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64 103 #define MOCK_MSC_SCSI_SECTOR_SIZE 512 104 #define MOCK_MSC_SCSI_LUN 0 105 #define MOCK_MSC_SCSI_INTF_NUMBER 0 106 #define MOCK_MSC_SCSI_INTF_ALT_SETTING 0 107 #define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x01 108 #define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x82 109 #define MOCK_MSC_SCSI_BULK_EP_MPS 64 110 111 #define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \ 112 (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \ 113 (setup_pkt_ptr)->bRequest = 0xFF; \ 114 (setup_pkt_ptr)->wValue = 0; \ 115 (setup_pkt_ptr)->wIndex = (intf_num); \ 116 (setup_pkt_ptr)->wLength = 0; \ 117 }) 118 119 typedef struct __attribute__((packed)) { 120 uint8_t opcode; //0x28 = read(10), 0x2A=write(10) 121 uint8_t flags; 122 uint8_t lba_3; 123 uint8_t lba_2; 124 uint8_t lba_1; 125 uint8_t lba_0; 126 uint8_t group; 127 uint8_t len_1; 128 uint8_t len_0; 129 uint8_t control; 130 } mock_scsi_cmd10_t; 131 132 typedef struct __attribute__((packed)) { 133 uint32_t dCBWSignature; 134 uint32_t dCBWTag; 135 uint32_t dCBWDataTransferLength; 136 uint8_t bmCBWFlags; 137 uint8_t bCBWLUN; 138 uint8_t bCBWCBLength; 139 mock_scsi_cmd10_t CBWCB; 140 uint8_t padding[6]; 141 } mock_msc_bulk_cbw_t; 142 143 // USB Bulk Transfer Command Status Wrapper data 144 typedef struct __attribute__((packed)) { 145 uint32_t dCSWSignature; 146 uint32_t dCSWTag; 147 uint32_t dCSWDataResidue; 148 uint8_t bCSWStatus; 149 } mock_msc_bulk_csw_t; 150 151 /** 152 * @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command 153 * 154 * @param cbw CBW structure 155 * @param is_read Is a read command 156 * @param offset Block offset 157 * @param num_sectors Number of sectors to read 158 * @param tag Tag (this is simply echoed back 159 */ 160 void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag); 161 162 /** 163 * @brief Check that returned Command Status Wrapper (CSW) is valid 164 * 165 * @param csw CSW structure 166 * @param tag_expect Expected tag 167 * @return true CSW is valid 168 * @return false CSW is not valid 169 */ 170 bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect); 171 172 // ---------------------------------------------------- HID Mouse ------------------------------------------------------ 173 174 175 /* 176 Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should... 177 178 - Be implement the HID with standard report format used by mice 179 - It's configuration 1 should have the following endpoint 180 181 Device Descriptor: 182 bLength 18 183 bDescriptorType 1 184 bcdUSB 2.00 185 bDeviceClass 0 186 bDeviceSubClass 0 187 bDeviceProtocol 0 188 bMaxPacketSize0 8 189 idVendor 0x413c Dell Computer Corp. 190 idProduct 0x301a 191 bcdDevice 1.00 192 iManufacturer 1 193 iProduct 2 194 iSerial 0 195 bNumConfigurations 1 196 Configuration Descriptor: 197 bLength 9 198 bDescriptorType 2 199 wTotalLength 0x0022 200 bNumInterfaces 1 201 bConfigurationValue 1 202 iConfiguration 0 203 bmAttributes 0xa0 204 (Bus Powered) 205 Remote Wakeup 206 MaxPower 100mA 207 Interface Descriptor: 208 bLength 9 209 bDescriptorType 4 210 bInterfaceNumber 0 211 bAlternateSetting 0 212 bNumEndpoints 1 213 bInterfaceClass 3 Human Interface Device 214 bInterfaceSubClass 1 Boot Interface Subclass 215 bInterfaceProtocol 2 Mouse 216 iInterface 0 217 HID Device Descriptor: 218 bLength 9 219 bDescriptorType 33 220 bcdHID 1.11 221 bCountryCode 0 Not supported 222 bNumDescriptors 1 223 bDescriptorType 34 Report 224 wDescriptorLength 46 225 Report Descriptors: 226 ** UNAVAILABLE ** 227 Endpoint Descriptor: 228 bLength 7 229 bDescriptorType 5 230 bEndpointAddress 0x81 EP 1 IN 231 bmAttributes 3 232 Transfer Type Interrupt 233 Synch Type None 234 Usage Type Data 235 wMaxPacketSize 0x0004 1x 4 bytes 236 bInterval 10 237 238 If you're using another mice with different endpoints, modify the endpoint descriptor below 239 */ 240 241 extern const usb_ep_desc_t mock_hid_mouse_in_ep_desc; 242 243 #define MOCK_HID_MOUSE_DEV_ID_VENDOR 0x413C 244 #define MOCK_HID_MOUSE_DEV_ID_PRODUCT 0x301A 245 #define MOCK_HID_MOUSE_DEV_DFLT_EP_MPS 8 246 #define MOCK_HID_MOUSE_INTF_NUMBER 0 247 #define MOCK_HID_MOUSE_INTF_ALT_SETTING 0 248 #define MOCK_HID_MOUSE_INTR_IN_EP_ADDR 0x81 249 #define MOCK_HID_MOUSE_INTR_IN_MPS 0x04 250 251 typedef union { 252 struct { 253 uint32_t left_button: 1; 254 uint32_t right_button: 1; 255 uint32_t middle_button: 1; 256 uint32_t reserved5: 5; 257 uint8_t x_movement; 258 uint8_t y_movement; 259 } __attribute__((packed)); 260 uint8_t val[3]; 261 } mock_hid_mouse_report_t; 262 _Static_assert(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect"); 263 264 void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter); 265 266 // ---------------------------------------------------- Mock ISOC ------------------------------------------------------ 267 268 /* 269 Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for 270 ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below: 271 */ 272 273 #define MOCK_ISOC_EP_NUM 2 274 #define MOCK_ISOC_EP_MPS 512 275 276 277 static const usb_ep_desc_t mock_isoc_out_ep_desc = { 278 .bLength = sizeof(usb_ep_desc_t), 279 .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, 280 .bEndpointAddress = MOCK_ISOC_EP_NUM, 281 .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC, 282 .wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes 283 .bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms 284 }; 285 286 287 #ifdef __cplusplus 288 } 289 #endif 290