1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
#ifndef __PROTOCOL_USB_USB_H__
#define __PROTOCOL_USB_USB_H__

#include "global.h"

struct usb_instance;

union __attribute__((packed,aligned(4))) usb_ep0_buffer
{
    struct __attribute__((packed,aligned(4)))
    {
        struct __attribute__((packed))
        {
            enum
            {
                USB_SETUP_BMREQUESTTYPE_RECIPIENT_DEVICE = 0,
                USB_SETUP_BMREQUESTTYPE_RECIPIENT_INTERFACE = 1,
                USB_SETUP_BMREQUESTTYPE_RECIPIENT_ENDPOINT = 2,
                USB_SETUP_BMREQUESTTYPE_RECIPIENT_OTHER = 3,
            } recipient : 5;
            enum
            {
                USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD = 0,
                USB_SETUP_BMREQUESTTYPE_TYPE_CLASS = 1,
                USB_SETUP_BMREQUESTTYPE_TYPE_VENDOR = 2,
            } type : 2;
            enum
            {
                USB_SETUP_BMREQUESTTYPE_DIRECTION_OUT = 0,
                USB_SETUP_BMREQUESTTYPE_DIRECTION_IN = 1,
            } direction : 1;
        } bmRequestType;
        enum __attribute__((packed))
        {
            USB_SETUP_BREQUEST_GET_STATUS = 0,
            USB_SETUP_BREQUEST_CLEAR_FEATURE = 1,
            USB_SETUP_BREQUEST_SET_FEATURE = 3,
            USB_SETUP_BREQUEST_SET_ADDRESS = 5,
            USB_SETUP_BREQUEST_GET_DESCRIPTOR = 6,
            USB_SETUP_BREQUEST_SET_DESCRIPTOR = 7,
            USB_SETUP_BREQUEST_GET_CONFIGURATION = 8,
            USB_SETUP_BREQUEST_SET_CONFIGURATION = 9,
            USB_SETUP_BREQUEST_GET_INTERFACE = 10,
            USB_SETUP_BREQUEST_SET_INTERFACE = 11,
            USB_SETUP_BREQUEST_SYNCH_FRAME = 12,
        } bRequest;
        uint16_t wValue;
        uint16_t wIndex;
        uint16_t wLength;
    } setup;
    uint8_t raw[64];
};

enum __attribute__((packed)) usb_descriptor_type
{
    USB_DESCRIPTOR_TYPE_DEVICE = 1,
    USB_DESCRIPTOR_TYPE_CONFIGURATION = 2,
    USB_DESCRIPTOR_TYPE_STRING = 3,
    USB_DESCRIPTOR_TYPE_INTERFACE = 4,
    USB_DESCRIPTOR_TYPE_ENDPOINT = 5,
    USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER = 6,
    USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIG = 7,
    USB_DESCRIPTOR_TYPE_INTERFACE_POWER = 8,
    USB_DESCRIPTOR_TYPE_OTG = 9,
    USB_DESCRIPTOR_TYPE_DEBUG = 10,
    USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION = 11,
};

enum usb_endpoint_direction
{
    USB_ENDPOINT_DIRECTION_OUT = 0,
    USB_ENDPOINT_DIRECTION_IN = 1,
};

union __attribute__((packed)) usb_endpoint_number
{
    struct __attribute__((packed))
    {
        int number : 4;
        int reserved: 3;
        enum usb_endpoint_direction direction : 1;
    };
    uint8_t byte;
};

enum usb_endpoint_type
{
    USB_ENDPOINT_TYPE_CONTROL = 0,
    USB_ENDPOINT_TYPE_ISOCHRONOUS = 1,
    USB_ENDPOINT_TYPE_BULK = 2,
    USB_ENDPOINT_TYPE_INTERRUPT = 3,
};

struct __attribute__((packed)) usb_devicedescriptor
{
    uint8_t bLength;
    enum usb_descriptor_type bDescriptorType;
    uint16_t bcdUSB;
    uint8_t bDeviceClass;
    uint8_t bDeviceSubClass;
    uint8_t bDeviceProtocol;
    uint8_t bMaxPacketSize0;
    uint16_t idVendor;
    uint16_t idProduct;
    uint16_t bcdDevice;
    uint8_t iManufacturer;
    uint8_t iProduct;
    uint8_t iSerialNumber;
    uint8_t bNumConfigurations;
};

struct __attribute__((packed)) usb_configurationdescriptor
{
    uint8_t bLength;
    enum usb_descriptor_type bDescriptorType;
    uint16_t wTotalLength;
    uint8_t bNumInterfaces;
    uint8_t bConfigurationValue;
    uint8_t iConfiguration;
    struct __attribute__((packed))
    {
        unsigned int reserved : 5;
        unsigned int remotewakeup : 1;
        unsigned int selfpowered : 1;
        unsigned int buspowered : 1;
    } bmAttributes;
    uint8_t bMaxPower;
};

struct __attribute__((packed)) usb_interfacedescriptor
{
    uint8_t bLength;
    enum usb_descriptor_type bDescriptorType;
    uint8_t bInterfaceNumber;
    uint8_t bAlternateSetting;
    uint8_t bNumEndpoints;
    uint8_t bInterfaceClass;
    uint8_t bInterfaceSubClass;
    uint8_t bInterfaceProtocol;
    uint8_t iInterface;
};

struct __attribute__((packed)) usb_endpointdescriptor
{
    uint8_t bLength;
    enum usb_descriptor_type bDescriptorType;
    union usb_endpoint_number bEndpointAddress;
    struct __attribute__((packed))
    {
        enum
        {
            USB_ENDPOINT_ATTRIBUTE_TYPE_CONTROL = 0,
            USB_ENDPOINT_ATTRIBUTE_TYPE_ISOCHRONOUS = 1,
            USB_ENDPOINT_ATTRIBUTE_TYPE_BULK = 2,
            USB_ENDPOINT_ATTRIBUTE_TYPE_INTERRUPT = 3,
        } type : 2;
        enum
        {
            USB_ENDPOINT_ATTRIBUTE_SYNCTYPE_NOSYNC = 0,
            USB_ENDPOINT_ATTRIBUTE_SYNCTYPE_ASYNC = 1,
            USB_ENDPOINT_ATTRIBUTE_SYNCTYPE_ADAPTIVE = 2,
            USB_ENDPOINT_ATTRIBUTE_SYNCTYPE_SYNC = 3,
        } synctype : 2;
        enum
        {
            USB_ENDPOINT_ATTRIBUTE_USAGE_DATA = 0,
            USB_ENDPOINT_ATTRIBUTE_USAGE_FEEDBACK = 1,
            USB_ENDPOINT_ATTRIBUTE_USAGE_EXPLICIT = 2,
        } usage : 2;
        unsigned int reserved : 2;
    } bmAttributes;
    uint16_t wMaxPacketSize;
    uint8_t bInterval;
};

struct __attribute__((packed)) usb_stringdescriptor
{
    uint8_t bLength;
    enum usb_descriptor_type bDescriptorType;
    uint16_t wString[];
};

struct __attribute__((packed,aligned(4))) usb_endpoint
{
    union usb_endpoint_number number;
    uint8_t reserved1;
    uint8_t reserved2;
    uint8_t reserved3;
    void (*xfer_complete)(const struct usb_instance* data, int interface, int endpoint, int bytesleft);
    union __attribute__((packed))
    {
        void (*setup_received)(const struct usb_instance* data, int interface, int endpoint, int back2back);
        void (*timeout)(const struct usb_instance* data, int interface, int endpoint, int bytesleft);
    };
};

struct __attribute__((packed,aligned(4))) usb_altsetting
{
    void (*set_altsetting)(const struct usb_instance* data, int interface, int altsetting);
    void (*unset_altsetting)(const struct usb_instance* data, int interface, int altsetting);
    uint8_t reserved1;
    uint8_t reserved2;
    uint8_t reserved3;
    uint8_t endpoint_count;
    const struct usb_endpoint* endpoints[];
};

struct __attribute__((packed,aligned(4))) usb_interface
{
    uint8_t reserved1;
    uint8_t reserved2;
    uint8_t current_altsetting;
    uint8_t altsetting_count;
    const struct usb_altsetting* altsettings[];
};

struct __attribute__((packed,aligned(4))) usb_configuration
{
    const struct usb_configurationdescriptor* descriptor;
    void (*set_configuration)(const struct usb_instance* data, int configuration);
    void (*unset_configuration)(const struct usb_instance* data, int configuration);
    uint8_t reserved1;
    uint8_t reserved2;
    uint8_t reserved3;
    uint8_t interface_count;
    struct usb_interface* interfaces[];
};

struct __attribute__((packed,aligned(4))) usb_state
{
    uint8_t current_address;
    uint8_t current_configuration;
    uint8_t reserved1;
    uint8_t reserved2;
};

struct __attribute__((packed,aligned(4))) usb_driver
{
    void (*init)(const struct usb_instance* data);
    void (*ep0_start_rx)(const struct usb_instance* data, int non_setup);
    void (*ep0_start_tx)(const struct usb_instance* data, const void* buf, int len);
    void (*start_rx)(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size);
    void (*start_tx)(const struct usb_instance* data, union usb_endpoint_number ep, const void* buf, int size);
    void (*set_stall)(const struct usb_instance* data, union usb_endpoint_number ep, int stall);
    void (*set_address)(const struct usb_instance* data, uint8_t address);
    void (*configure_ep)(const struct usb_instance* data, union usb_endpoint_number ep, enum usb_endpoint_type type, int maxpacket);
    void (*unconfigure_ep)(const struct usb_instance* data, union usb_endpoint_number ep);
};

struct __attribute__((packed,aligned(4))) usb_instance
{
    const struct usb_driver* driver;
    const void* driver_config;
    void* driver_state;
    struct usb_state* state;
    union usb_ep0_buffer* buffer;
    void (*bus_reset)(const struct usb_instance* data, int highspeed);
    int (*ep0_setup_hook)(const struct usb_instance* data, union usb_ep0_buffer* buf);
    int (*ep0_data_hook)(const struct usb_instance* data, union usb_ep0_buffer* buf, int size);
    uint8_t configuration_count;
    uint8_t stringdescriptor_count;
    uint8_t reserved1;
    uint8_t reserved2;
    const struct usb_devicedescriptor* devicedescriptor;
    const struct usb_stringdescriptor** stringdescriptors;
    const struct usb_configuration* configurations[];
};

extern void usb_init(const struct usb_instance* data);
extern void usb_handle_bus_reset(const struct usb_instance* data, int highspeed);
extern void usb_handle_timeout(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
extern void usb_handle_xfer_complete(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft);
extern void usb_handle_setup_received(const struct usb_instance* data, union usb_endpoint_number epnum, int back2back);
extern void usb_ep0_start_rx(const struct usb_instance* data, int non_setup);
extern void usb_ep0_start_tx(const struct usb_instance* data, const void* buf, int len);
extern void usb_ep0_expect_setup(const struct usb_instance* data);
extern void usb_start_rx(const struct usb_instance* data, union usb_endpoint_number ep, void* buf, int size);
extern void usb_start_tx(const struct usb_instance* data, union usb_endpoint_number ep, const void* buf, int size);
extern void usb_set_stall(const struct usb_instance* data, union usb_endpoint_number ep, int stall);
extern void usb_configure_ep(const struct usb_instance* data, union usb_endpoint_number ep, enum usb_endpoint_type type, int maxpacket);
extern void usb_unconfigure_ep(const struct usb_instance* data, union usb_endpoint_number ep);


#endif