1 #include "usbd_core.h"
2 #include "usbd_cdc.h"
3
4 #define WCID_VENDOR_CODE 0x17
5
6 #define DOUBLE_WINUSB 0
7
8 __ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
9 ///////////////////////////////////////
10 /// MS OS string descriptor
11 ///////////////////////////////////////
12 0x12, /* bLength */
13 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
14 /* MSFT100 */
15 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
16 '1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
17 WCID_VENDOR_CODE, /* bVendorCode */
18 0x00, /* bReserved */
19 };
20
21 #if DOUBLE_WINUSB == 0
22 __ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
23 ///////////////////////////////////////
24 /// WCID descriptor
25 ///////////////////////////////////////
26 0x28, 0x00, 0x00, 0x00, /* dwLength */
27 0x00, 0x01, /* bcdVersion */
28 0x04, 0x00, /* wIndex */
29 0x01, /* bCount */
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
31
32 ///////////////////////////////////////
33 /// WCID function descriptor
34 ///////////////////////////////////////
35 0x00, /* bFirstInterfaceNumber */
36 0x01, /* bReserved */
37 /* WINUSB */
38 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
39 /* */
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
42 };
43 #else
44 __ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[64] __ALIGN_END = {
45 ///////////////////////////////////////
46 /// WCID descriptor
47 ///////////////////////////////////////
48 0x40, 0x00, 0x00, 0x00, /* dwLength */
49 0x00, 0x01, /* bcdVersion */
50 0x04, 0x00, /* wIndex */
51 0x02, /* bCount */
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
53
54 ///////////////////////////////////////
55 /// WCID function descriptor
56 ///////////////////////////////////////
57 0x00, /* bFirstInterfaceNumber */
58 0x01, /* bReserved */
59 /* WINUSB */
60 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
61 /* */
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
64
65 ///////////////////////////////////////
66 /// WCID function descriptor
67 ///////////////////////////////////////
68 0x01, /* bFirstInterfaceNumber */
69 0x01, /* bReserved */
70 /* WINUSB */
71 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
72 /* */
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
75 };
76 #endif
77 __ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties [142] __ALIGN_END = {
78 ///////////////////////////////////////
79 /// WCID property descriptor
80 ///////////////////////////////////////
81 0x8e, 0x00, 0x00, 0x00, /* dwLength */
82 0x00, 0x01, /* bcdVersion */
83 0x05, 0x00, /* wIndex */
84 0x01, 0x00, /* wCount */
85
86 ///////////////////////////////////////
87 /// registry propter descriptor
88 ///////////////////////////////////////
89 0x84, 0x00, 0x00, 0x00, /* dwSize */
90 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
91 0x28, 0x00, /* wPropertyNameLength */
92 /* DeviceInterfaceGUID */
93 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
94 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
95 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
96 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
97 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
98 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
99 /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
100 '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
101 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
102 '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
103 '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
104 '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
105 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
106 '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
107 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
108 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
109 '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
110 };
111 #define WINUSB_IF1_WCID_PROPERTIES_SIZE (142)
112 __ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = {
113 ///////////////////////////////////////
114 /// WCID property descriptor
115 ///////////////////////////////////////
116 0x8e, 0x00, 0x00, 0x00, /* dwLength */
117 0x00, 0x01, /* bcdVersion */
118 0x05, 0x00, /* wIndex */
119 0x01, 0x00, /* wCount */
120
121 ///////////////////////////////////////
122 /// registry propter descriptor
123 ///////////////////////////////////////
124 0x84, 0x00, 0x00, 0x00, /* dwSize */
125 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
126 0x28, 0x00, /* wPropertyNameLength */
127 /* DeviceInterfaceGUID */
128 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
129 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
130 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
131 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
132 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
133 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
134 /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
135 '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
136 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
137 '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
138 '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
139 '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
140 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
141 '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
142 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
143 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
144 '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
145 };
146
147 const uint8_t *WINUSB_IFx_WCIDProperties[] = {
148 WINUSB_IF0_WCIDProperties,
149 WINUSB_IF1_WCIDProperties,
150 };
151
152 struct usb_msosv1_descriptor msosv1_desc = {
153 .string = WCID_StringDescriptor_MSOS,
154 .vendor_code = WCID_VENDOR_CODE,
155 .compat_id = WINUSB_WCIDDescriptor,
156 #if DOUBLE_WINUSB == 0
157 .comp_id_property = &WINUSB_IF0_WCIDProperties,
158 #else
159 .comp_id_property = WINUSB_IFx_WCIDProperties,
160 #endif
161 };
162
163 #define WINUSB_IN_EP 0x81
164 #define WINUSB_OUT_EP 0x02
165
166 #define USBD_VID 0xefff
167 #define USBD_PID 0xffff
168 #define USBD_MAX_POWER 100
169 #define USBD_LANGID_STRING 1033
170
171 #if DOUBLE_WINUSB == 0
172 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
173 #define INTF_NUM 1
174 #else
175 #define WINUSB_IN_EP2 0x83
176 #define WINUSB_OUT_EP2 0x04
177
178 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 7 + 7)
179 #define INTF_NUM 2
180 #endif
181
182 #ifdef CONFIG_USB_HS
183 #define WINUSB_EP_MPS 512
184 #else
185 #define WINUSB_EP_MPS 64
186 #endif
187
188 const uint8_t winusb_descriptor[] = {
189 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
190 USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
191 USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04),
192 USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00),
193 USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00),
194 #if DOUBLE_WINUSB == 1
195 USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05),
196 USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00),
197 USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00),
198 #endif
199 ///////////////////////////////////////
200 /// string0 descriptor
201 ///////////////////////////////////////
202 USB_LANGID_INIT(USBD_LANGID_STRING),
203 ///////////////////////////////////////
204 /// string1 descriptor
205 ///////////////////////////////////////
206 0x14, /* bLength */
207 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
208 'C', 0x00, /* wcChar0 */
209 'h', 0x00, /* wcChar1 */
210 'e', 0x00, /* wcChar2 */
211 'r', 0x00, /* wcChar3 */
212 'r', 0x00, /* wcChar4 */
213 'y', 0x00, /* wcChar5 */
214 'U', 0x00, /* wcChar6 */
215 'S', 0x00, /* wcChar7 */
216 'B', 0x00, /* wcChar8 */
217 ///////////////////////////////////////
218 /// string2 descriptor
219 ///////////////////////////////////////
220 0x2C, /* bLength */
221 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
222 'C', 0x00, /* wcChar0 */
223 'h', 0x00, /* wcChar1 */
224 'e', 0x00, /* wcChar2 */
225 'r', 0x00, /* wcChar3 */
226 'r', 0x00, /* wcChar4 */
227 'y', 0x00, /* wcChar5 */
228 'U', 0x00, /* wcChar6 */
229 'S', 0x00, /* wcChar7 */
230 'B', 0x00, /* wcChar8 */
231 ' ', 0x00, /* wcChar9 */
232 'W', 0x00, /* wcChar10 */
233 'I', 0x00, /* wcChar11 */
234 'N', 0x00, /* wcChar12 */
235 'U', 0x00, /* wcChar13 */
236 'S', 0x00, /* wcChar14 */
237 'B', 0x00, /* wcChar15 */
238 ' ', 0x00, /* wcChar16 */
239 'D', 0x00, /* wcChar17 */
240 'E', 0x00, /* wcChar18 */
241 'M', 0x00, /* wcChar19 */
242 'O', 0x00, /* wcChar20 */
243 ///////////////////////////////////////
244 /// string3 descriptor
245 ///////////////////////////////////////
246 0x16, /* bLength */
247 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
248 '2', 0x00, /* wcChar0 */
249 '0', 0x00, /* wcChar1 */
250 '2', 0x00, /* wcChar2 */
251 '1', 0x00, /* wcChar3 */
252 '0', 0x00, /* wcChar4 */
253 '3', 0x00, /* wcChar5 */
254 '1', 0x00, /* wcChar6 */
255 '0', 0x00, /* wcChar7 */
256 '0', 0x00, /* wcChar8 */
257 '0', 0x00, /* wcChar9 */
258 ///////////////////////////////////////
259 /// string4 descriptor
260 ///////////////////////////////////////
261 0x30, /* bLength */
262 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
263 'C', 0x00, /* wcChar0 */
264 'h', 0x00, /* wcChar1 */
265 'e', 0x00, /* wcChar2 */
266 'r', 0x00, /* wcChar3 */
267 'r', 0x00, /* wcChar4 */
268 'y', 0x00, /* wcChar5 */
269 'U', 0x00, /* wcChar6 */
270 'S', 0x00, /* wcChar7 */
271 'B', 0x00, /* wcChar8 */
272 ' ', 0x00, /* wcChar9 */
273 'W', 0x00, /* wcChar10 */
274 'I', 0x00, /* wcChar11 */
275 'N', 0x00, /* wcChar12 */
276 'U', 0x00, /* wcChar13 */
277 'S', 0x00, /* wcChar14 */
278 'B', 0x00, /* wcChar15 */
279 ' ', 0x00, /* wcChar16 */
280 'D', 0x00, /* wcChar17 */
281 'E', 0x00, /* wcChar18 */
282 'M', 0x00, /* wcChar19 */
283 'O', 0x00, /* wcChar20 */
284 ' ', 0x00, /* wcChar16 */
285 '1', 0x00, /* wcChar21 */
286 ///////////////////////////////////////
287 /// string5 descriptor
288 ///////////////////////////////////////
289 0x30, /* bLength */
290 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
291 'C', 0x00, /* wcChar0 */
292 'h', 0x00, /* wcChar1 */
293 'e', 0x00, /* wcChar2 */
294 'r', 0x00, /* wcChar3 */
295 'r', 0x00, /* wcChar4 */
296 'y', 0x00, /* wcChar5 */
297 'U', 0x00, /* wcChar6 */
298 'S', 0x00, /* wcChar7 */
299 'B', 0x00, /* wcChar8 */
300 ' ', 0x00, /* wcChar9 */
301 'W', 0x00, /* wcChar10 */
302 'I', 0x00, /* wcChar11 */
303 'N', 0x00, /* wcChar12 */
304 'U', 0x00, /* wcChar13 */
305 'S', 0x00, /* wcChar14 */
306 'B', 0x00, /* wcChar15 */
307 ' ', 0x00, /* wcChar16 */
308 'D', 0x00, /* wcChar17 */
309 'E', 0x00, /* wcChar18 */
310 'M', 0x00, /* wcChar19 */
311 'O', 0x00, /* wcChar20 */
312 ' ', 0x00, /* wcChar16 */
313 '2', 0x00, /* wcChar21 */
314 #ifdef CONFIG_USB_HS
315 ///////////////////////////////////////
316 /// device qualifier descriptor
317 ///////////////////////////////////////
318 0x0a,
319 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
320 0x00,
321 0x02,
322 0x02,
323 0x02,
324 0x01,
325 0x40,
326 0x01,
327 0x00,
328 #endif
329 0x00
330 };
331
332 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
333 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
334
335 volatile bool ep_tx_busy_flag = false;
336
usbd_event_handler(uint8_t event)337 void usbd_event_handler(uint8_t event)
338 {
339 switch (event) {
340 case USBD_EVENT_RESET:
341 break;
342 case USBD_EVENT_CONNECTED:
343 break;
344 case USBD_EVENT_DISCONNECTED:
345 break;
346 case USBD_EVENT_RESUME:
347 break;
348 case USBD_EVENT_SUSPEND:
349 break;
350 case USBD_EVENT_CONFIGURED:
351 /* setup first out ep read transfer */
352 usbd_ep_start_read(WINUSB_OUT_EP, read_buffer, 2048);
353 #if DOUBLE_WINUSB == 1
354 usbd_ep_start_read(WINUSB_OUT_EP2, read_buffer, 2048);
355 #endif
356 break;
357 case USBD_EVENT_SET_REMOTE_WAKEUP:
358 break;
359 case USBD_EVENT_CLR_REMOTE_WAKEUP:
360 break;
361
362 default:
363 break;
364 }
365 }
366
usbd_winusb_out(uint8_t ep,uint32_t nbytes)367 void usbd_winusb_out(uint8_t ep, uint32_t nbytes)
368 {
369 USB_LOG_RAW("actual out len:%d\r\n", nbytes);
370 // for (int i = 0; i < 100; i++) {
371 // printf("%02x ", read_buffer[i]);
372 // }
373 // printf("\r\n");
374 usbd_ep_start_write(WINUSB_IN_EP, read_buffer, nbytes);
375 /* setup next out ep read transfer */
376 usbd_ep_start_read(WINUSB_OUT_EP, read_buffer, 2048);
377 }
378
usbd_winusb_in(uint8_t ep,uint32_t nbytes)379 void usbd_winusb_in(uint8_t ep, uint32_t nbytes)
380 {
381 USB_LOG_RAW("actual in len:%d\r\n", nbytes);
382
383 if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) {
384 /* send zlp */
385 usbd_ep_start_write(WINUSB_IN_EP, NULL, 0);
386 } else {
387 ep_tx_busy_flag = false;
388 }
389 }
390
391 struct usbd_endpoint winusb_out_ep1 = {
392 .ep_addr = WINUSB_OUT_EP,
393 .ep_cb = usbd_winusb_out
394 };
395
396 struct usbd_endpoint winusb_in_ep1 = {
397 .ep_addr = WINUSB_IN_EP,
398 .ep_cb = usbd_winusb_in
399 };
400
401 struct usbd_interface intf0;
402
403 #if DOUBLE_WINUSB == 1
404
usbd_winusb_out2(uint8_t ep,uint32_t nbytes)405 void usbd_winusb_out2(uint8_t ep, uint32_t nbytes)
406 {
407 USB_LOG_RAW("actual out len:%d\r\n", nbytes);
408 // for (int i = 0; i < 100; i++) {
409 // printf("%02x ", read_buffer[i]);
410 // }
411 // printf("\r\n");
412 usbd_ep_start_write(WINUSB_IN_EP2, read_buffer, nbytes);
413 /* setup next out ep read transfer */
414 usbd_ep_start_read(WINUSB_OUT_EP2, read_buffer, 2048);
415 }
416
usbd_winusb_in2(uint8_t ep,uint32_t nbytes)417 void usbd_winusb_in2(uint8_t ep, uint32_t nbytes)
418 {
419 USB_LOG_RAW("actual in len:%d\r\n", nbytes);
420
421 if ((nbytes % WINUSB_EP_MPS) == 0 && nbytes) {
422 /* send zlp */
423 usbd_ep_start_write(WINUSB_IN_EP2, NULL, 0);
424 } else {
425 ep_tx_busy_flag = false;
426 }
427 }
428
429 struct usbd_endpoint winusb_out_ep2 = {
430 .ep_addr = WINUSB_OUT_EP2,
431 .ep_cb = usbd_winusb_out2
432 };
433
434 struct usbd_endpoint winusb_in_ep2 = {
435 .ep_addr = WINUSB_IN_EP2,
436 .ep_cb = usbd_winusb_in2
437 };
438
439 struct usbd_interface intf1;
440
441 #endif
442
winusb_init(void)443 void winusb_init(void)
444 {
445 usbd_desc_register(winusb_descriptor);
446 usbd_msosv1_desc_register(&msosv1_desc);
447 usbd_add_interface(&intf0);
448 usbd_add_endpoint(&winusb_out_ep1);
449 usbd_add_endpoint(&winusb_in_ep1);
450 #if DOUBLE_WINUSB == 1
451 usbd_add_interface(&intf1);
452 usbd_add_endpoint(&winusb_out_ep2);
453 usbd_add_endpoint(&winusb_in_ep2);
454 #endif
455 usbd_initialize();
456 }