• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }