1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include "usb/usb_types_ch9.h"
11 #include "test_usb_mock_classes.h"
12 
13 // ---------------------------------------------------- MSC SCSI -------------------------------------------------------
14 
15 const char *MSC_CLIENT_TAG = "MSC Client";
16 
17 const uint8_t mock_msc_scsi_dev_desc[] = {
18     0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x12, 0x8A, 0xC0, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
19 };
20 
21 const uint8_t mock_msc_scsi_config_desc[] = {
22     0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0xF0, 0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50, 0x00, 0x07,
23     0x05, 0x01, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01,
24 };
25 
26 
27 const uint8_t mock_msc_scsi_str_desc_manu[] = {
28     0x0c, 0x03, 0x41, 0x00, 0x44, 0x00, 0x41, 0x00, 0x54, 0x00, 0x41, 0x00,
29 };
30 
31 const uint8_t mock_msc_scsi_str_desc_prod[] = {
32     0x2c, 0x03, 0x41, 0x00, 0x44, 0x00, 0x41, 0x00, 0x54, 0x00, 0x41, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42,
33     0x00, 0x20, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x20, 0x00, 0x44, 0x00, 0x72, 0x00,
34     0x69, 0x00, 0x76, 0x00, 0x65, 0x00,
35 };
36 
37 const uint8_t mock_msc_scsi_str_desc_ser_num[] = {
38     0x22, 0x03, 0x31, 0x00, 0x33, 0x00, 0x43, 0x00, 0x32, 0x00, 0x38, 0x00, 0x31, 0x00, 0x36, 0x00, 0x35, 0x00, 0x38,
39     0x00, 0x32, 0x00, 0x31, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0x00, 0x45, 0x00,
40 };
41 
42 const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc = {
43     .bLength = sizeof(usb_ep_desc_t),
44     .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
45     .bEndpointAddress = 0x01,       //EP 1 OUT
46     .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
47     .wMaxPacketSize = 64,           //MPS of 64 bytes
48     .bInterval = 1,
49 };
50 
51 const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc = {
52     .bLength = sizeof(usb_ep_desc_t),
53     .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
54     .bEndpointAddress = 0x82,       //EP 2 IN
55     .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
56     .wMaxPacketSize = 64,           //MPS of 64 bytes
57     .bInterval = 1,
58 };
59 
mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t * cbw,bool is_read,int offset,int num_sectors,uint32_t tag)60 void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag)
61 {
62     cbw->dCBWSignature = 0x43425355;    //Fixed value
63     cbw->dCBWTag = tag; //Random value that is echoed back
64     cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE;
65     cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; //If this is a read, set the direction flag
66     cbw->bCBWLUN = MOCK_MSC_SCSI_LUN;
67     cbw->bCBWCBLength = 10;     //The length of the SCSI command
68     //Initialize SCSI CMD as READ10 or WRITE 10
69     cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A;  //SCSI CMD READ10 or WRITE10
70     cbw->CBWCB.flags = 0;
71     cbw->CBWCB.lba_3 = (offset >> 24);
72     cbw->CBWCB.lba_2 = (offset >> 16);
73     cbw->CBWCB.lba_1 = (offset >> 8);
74     cbw->CBWCB.lba_0 = (offset >> 0);
75     cbw->CBWCB.group = 0;
76     cbw->CBWCB.len_1 = (num_sectors >> 8);
77     cbw->CBWCB.len_0 = (num_sectors >> 0);
78     cbw->CBWCB.control = 0;
79 }
80 
mock_msc_scsi_check_csw(mock_msc_bulk_csw_t * csw,uint32_t tag_expect)81 bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect)
82 {
83     bool no_issues = true;
84     if (csw->dCSWSignature != 0x53425355) {
85         no_issues = false;
86         printf("Warning: csw signature corrupt (0x%X)\n", csw->dCSWSignature);
87     }
88     if (csw->dCSWTag != tag_expect) {
89         no_issues = false;
90         printf("Warning: csw tag unexpected! Expected %d got %d\n", tag_expect, csw->dCSWTag);
91     }
92     if (csw->dCSWDataResidue) {
93         no_issues = false;
94         printf("Warning: csw indicates data residue of %d bytes!\n", csw->dCSWDataResidue);
95     }
96     if (csw->bCSWStatus) {
97         no_issues = false;
98         printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus);
99     }
100     return no_issues;
101 }
102 
103 
104 // ---------------------------------------------------- HID Mouse ------------------------------------------------------
105 
106 const usb_ep_desc_t mock_hid_mouse_in_ep_desc = {
107     .bLength = sizeof(usb_ep_desc_t),
108     .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
109     .bEndpointAddress = 0x81,       //EP 1 IN
110     .bmAttributes = USB_BM_ATTRIBUTES_XFER_INT,
111     .wMaxPacketSize = 4,            //MPS of 4 bytes
112     .bInterval = 10,                //Interval of 10ms
113 };
114 
mock_hid_process_report(mock_hid_mouse_report_t * report,int iter)115 void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter)
116 {
117     static int x_pos = 0;
118     static int y_pos = 0;
119     //Update X position
120     if (report->x_movement & 0x80) {    //Positive movement
121         x_pos += report->x_movement & 0x7F;
122     } else {    //Negative movement
123         x_pos -= report->x_movement & 0x7F;
124     }
125     //Update Y position
126     if (report->y_movement & 0x80) {    //Positive movement
127         y_pos += report->y_movement & 0x7F;
128     } else {    //Negative movement
129         y_pos -= report->y_movement & 0x7F;
130     }
131     printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter);
132 }
133