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