1 /*
2  * Copyright (c) 2024, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbd_core.h"
7 #include "usbd_hid.h"
8 
9 #define WINUSB_IN_EP  0x81
10 #define WINUSB_OUT_EP 0x02
11 
12 /*!< endpoint address */
13 #define HID_INT_EP          0x83
14 #define HID_INT_EP_SIZE     4
15 #define HID_INT_EP_INTERVAL 10
16 
17 #define USBD_VID           0xFFFE
18 #define USBD_PID           0xFFFF
19 #define USBD_MAX_POWER     500
20 #define USBD_LANGID_STRING 1033
21 
22 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7 + 9 + 9 + 7)
23 #define INTF_NUM        2
24 
25 /*!< config descriptor size */
26 #define USB_HID_CONFIG_DESC_SIZ 34
27 /*!< report descriptor size */
28 #define HID_MOUSE_REPORT_DESC_SIZE 74
29 
30 #ifdef CONFIG_USB_HS
31 #define WINUSB_EP_MPS 512
32 #else
33 #define WINUSB_EP_MPS 64
34 #endif
35 
36 #define USBD_WINUSB_VENDOR_CODE 0x20
37 
38 #define USBD_WEBUSB_ENABLE 0
39 #define USBD_BULK_ENABLE   1
40 #define USBD_WINUSB_ENABLE 1
41 
42 /* WinUSB Microsoft OS 2.0 descriptor sizes */
43 #define WINUSB_DESCRIPTOR_SET_HEADER_SIZE  10
44 #define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
45 #define WINUSB_FEATURE_COMPATIBLE_ID_SIZE  20
46 
47 #define FUNCTION_SUBSET_LEN                160
48 #define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
49 
50 #define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
51 
52 __ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
53     WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
54     WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
55     0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */  /* dwWindowsVersion*/
56     WBVAL(USBD_WINUSB_DESC_SET_LEN),          /* wDescriptorSetTotalLength */
57 #if (USBD_WEBUSB_ENABLE)
58     WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
59     WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
60     0,                                         // bFirstInterface USBD_WINUSB_IF_NUM
61     0,                                         // bReserved
62     WBVAL(FUNCTION_SUBSET_LEN),                // wSubsetLength
63     WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  // wLength
64     WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  // wDescriptorType
65     'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        // CompatibleId
66     0, 0, 0, 0, 0, 0, 0, 0,                    // SubCompatibleId
67     WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
68     WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   // wDescriptorType
69     WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
70     WBVAL(42),                                 // wPropertyNameLength
71     'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
72     'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
73     'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
74     WBVAL(80), // wPropertyDataLength
75     '{', 0,
76     '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
77     '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
78     '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
79     '9', 0, '3', 0, '3', 0, 'B', 0, '-',
80     0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
81     '}', 0, 0, 0, 0, 0
82 #endif
83 #if USBD_BULK_ENABLE
84     WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
85     WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
86     0,                                         /* bFirstInterface USBD_BULK_IF_NUM*/
87     0,                                         /* bReserved */
88     WBVAL(FUNCTION_SUBSET_LEN),                /* wSubsetLength */
89     WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  /* wLength */
90     WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  /* wDescriptorType */
91     'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        /* CompatibleId*/
92     0, 0, 0, 0, 0, 0, 0, 0,                    /* SubCompatibleId*/
93     WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
94     WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   /* wDescriptorType */
95     WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
96     WBVAL(42),                                 /* wPropertyNameLength */
97     'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
98     'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
99     'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
100     WBVAL(80), /* wPropertyDataLength */
101     '{', 0,
102     'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
103     '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
104     '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
105     'A', 0, 'A', 0, '3', 0, '6', 0, '-',
106     0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
107     '}', 0, 0, 0, 0, 0
108 #endif
109 };
110 
111 #define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
112 
113 #define USBD_WEBUSB_DESC_LEN 24
114 #define USBD_WINUSB_DESC_LEN 28
115 
116 #define USBD_BOS_WTOTALLENGTH (0x05 +                                      \
117                                USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
118                                USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
119 
120 __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
121     0x05,                         /* bLength */
122     0x0f,                         /* bDescriptorType */
123     WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
124     USBD_NUM_DEV_CAPABILITIES,    /* bNumDeviceCaps */
125 #if (USBD_WEBUSB_ENABLE)
126     USBD_WEBUSB_DESC_LEN,           /* bLength */
127     0x10,                           /* bDescriptorType */
128     USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
129     0x00,                           /* bReserved */
130     0x38, 0xB6, 0x08, 0x34,         /* PlatformCapabilityUUID */
131     0xA9, 0x09, 0xA0, 0x47,
132     0x8B, 0xFD, 0xA0, 0x76,
133     0x88, 0x15, 0xB6, 0x65,
134     WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
135     USBD_WINUSB_VENDOR_CODE,  /* bVendorCode */
136     0,                        /* iLandingPage */
137 #endif
138 #if (USBD_WINUSB_ENABLE)
139     USBD_WINUSB_DESC_LEN,           /* bLength */
140     0x10,                           /* bDescriptorType */
141     USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
142     0x00,                           /* bReserved */
143     0xDF, 0x60, 0xDD, 0xD8,         /* PlatformCapabilityUUID */
144     0x89, 0x45, 0xC7, 0x4C,
145     0x9C, 0xD2, 0x65, 0x9D,
146     0x9E, 0x64, 0x8A, 0x9F,
147     0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
148     WBVAL(USBD_WINUSB_DESC_SET_LEN),         /* wDescriptorSetTotalLength */
149     USBD_WINUSB_VENDOR_CODE,                 /* bVendorCode */
150     0,                                       /* bAltEnumCode */
151 #endif
152 };
153 
154 struct usb_msosv2_descriptor msosv2_desc = {
155     .vendor_code = USBD_WINUSB_VENDOR_CODE,
156     .compat_id = USBD_WinUSBDescriptorSetDescriptor,
157     .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
158 };
159 
160 struct usb_bos_descriptor bos_desc = {
161     .string = USBD_BinaryObjectStoreDescriptor,
162     .string_len = USBD_BOS_WTOTALLENGTH
163 };
164 
165 #ifdef CONFIG_USBDEV_ADVANCE_DESC
166 static const uint8_t device_descriptor[] = {
167     USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
168 };
169 
170 static const uint8_t config_descriptor[] = {
171     /* Configuration 0 */
172     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
173     /* Interface 0 */
174     USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
175     /* Endpoint OUT 2 */
176     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
177     /* Endpoint IN 1 */
178     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
179     /************** Descriptor of Joystick Mouse interface ****************/
180     /* 09 */
181     0x09,                          /* bLength: Interface Descriptor size */
182     USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
183     0x01,                          /* bInterfaceNumber: Number of Interface */
184     0x00,                          /* bAlternateSetting: Alternate setting */
185     0x01,                          /* bNumEndpoints */
186     0x03,                          /* bInterfaceClass: HID */
187     0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
188     0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
189     0,                             /* iInterface: Index of string descriptor */
190     /******************** Descriptor of Joystick Mouse HID ********************/
191     /* 18 */
192     0x09,                    /* bLength: HID Descriptor size */
193     HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
194     0x11,                    /* bcdHID: HID Class Spec release number */
195     0x01,
196     0x00,                       /* bCountryCode: Hardware target country */
197     0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
198     0x22,                       /* bDescriptorType */
199     HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
200     0x00,
201     /******************** Descriptor of Mouse endpoint ********************/
202     /* 27 */
203     0x07,                         /* bLength: Endpoint Descriptor size */
204     USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
205     HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
206     0x03,                         /* bmAttributes: Interrupt endpoint */
207     HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
208     0x00,
209     HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
210 };
211 
212 static const uint8_t device_quality_descriptor[] = {
213     ///////////////////////////////////////
214     /// device qualifier descriptor
215     ///////////////////////////////////////
216     0x0a,
217     USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
218     0x10,
219     0x02,
220     0x00,
221     0x00,
222     0x00,
223     0x40,
224     0x00,
225     0x00,
226 };
227 
228 static const char *string_descriptors[] = {
229     (const char[]){ 0x09, 0x04 }, /* Langid */
230     "CherryUSB",                  /* Manufacturer */
231     "CherryUSB WINUSB DEMO",      /* Product */
232     "2022123456",                 /* Serial Number */
233 };
234 
device_descriptor_callback(uint8_t speed)235 static const uint8_t *device_descriptor_callback(uint8_t speed)
236 {
237     return device_descriptor;
238 }
239 
config_descriptor_callback(uint8_t speed)240 static const uint8_t *config_descriptor_callback(uint8_t speed)
241 {
242     return config_descriptor;
243 }
244 
device_quality_descriptor_callback(uint8_t speed)245 static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
246 {
247     return device_quality_descriptor;
248 }
249 
string_descriptor_callback(uint8_t speed,uint8_t index)250 static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
251 {
252     if (index > 3) {
253         return NULL;
254     }
255     return string_descriptors[index];
256 }
257 
258 const struct usb_descriptor winusbv2_descriptor = {
259     .device_descriptor_callback = device_descriptor_callback,
260     .config_descriptor_callback = config_descriptor_callback,
261     .device_quality_descriptor_callback = device_quality_descriptor_callback,
262     .string_descriptor_callback = string_descriptor_callback,
263     .msosv2_descriptor = &msosv2_desc,
264     .bos_descriptor = &bos_desc
265 };
266 #else
267 const uint8_t winusbv2_descriptor[] = {
268     USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
269     /* Configuration 0 */
270     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
271     /* Interface 0 */
272     USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
273     /* Endpoint OUT 2 */
274     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
275     /* Endpoint IN 1 */
276     USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
277     /************** Descriptor of Joystick Mouse interface ****************/
278     /* 09 */
279     0x09,                          /* bLength: Interface Descriptor size */
280     USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
281     0x01,                          /* bInterfaceNumber: Number of Interface */
282     0x00,                          /* bAlternateSetting: Alternate setting */
283     0x01,                          /* bNumEndpoints */
284     0x03,                          /* bInterfaceClass: HID */
285     0x01,                          /* bInterfaceSubClass : 1=BOOT, 0=no boot */
286     0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
287     0,                             /* iInterface: Index of string descriptor */
288     /******************** Descriptor of Joystick Mouse HID ********************/
289     /* 18 */
290     0x09,                    /* bLength: HID Descriptor size */
291     HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
292     0x11,                    /* bcdHID: HID Class Spec release number */
293     0x01,
294     0x00,                       /* bCountryCode: Hardware target country */
295     0x01,                       /* bNumDescriptors: Number of HID class descriptors to follow */
296     0x22,                       /* bDescriptorType */
297     HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
298     0x00,
299     /******************** Descriptor of Mouse endpoint ********************/
300     /* 27 */
301     0x07,                         /* bLength: Endpoint Descriptor size */
302     USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
303     HID_INT_EP,                   /* bEndpointAddress: Endpoint Address (IN) */
304     0x03,                         /* bmAttributes: Interrupt endpoint */
305     HID_INT_EP_SIZE,              /* wMaxPacketSize: 4 Byte max */
306     0x00,
307     HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
308     /* String 0 (LANGID) */
309     USB_LANGID_INIT(USBD_LANGID_STRING),
310     /* String 1 (Manufacturer) */
311     0x14,                       /* bLength */
312     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
313     'C', 0x00,                  /* wcChar0 */
314     'h', 0x00,                  /* wcChar1 */
315     'e', 0x00,                  /* wcChar2 */
316     'r', 0x00,                  /* wcChar3 */
317     'r', 0x00,                  /* wcChar4 */
318     'y', 0x00,                  /* wcChar5 */
319     'U', 0x00,                  /* wcChar6 */
320     'S', 0x00,                  /* wcChar7 */
321     'B', 0x00,                  /* wcChar8 */
322     ///////////////////////////////////////
323     /// string2 descriptor
324     ///////////////////////////////////////
325     0x2C,                       /* bLength */
326     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
327     'C', 0x00,                  /* wcChar0 */
328     'h', 0x00,                  /* wcChar1 */
329     'e', 0x00,                  /* wcChar2 */
330     'r', 0x00,                  /* wcChar3 */
331     'r', 0x00,                  /* wcChar4 */
332     'y', 0x00,                  /* wcChar5 */
333     'U', 0x00,                  /* wcChar6 */
334     'S', 0x00,                  /* wcChar7 */
335     'B', 0x00,                  /* wcChar8 */
336     ' ', 0x00,                  /* wcChar9 */
337     'W', 0x00,                  /* wcChar10 */
338     'I', 0x00,                  /* wcChar11 */
339     'N', 0x00,                  /* wcChar12 */
340     'U', 0x00,                  /* wcChar13 */
341     'S', 0x00,                  /* wcChar14 */
342     'B', 0x00,                  /* wcChar15 */
343     ' ', 0x00,                  /* wcChar16 */
344     'D', 0x00,                  /* wcChar17 */
345     'E', 0x00,                  /* wcChar18 */
346     'M', 0x00,                  /* wcChar19 */
347     'O', 0x00,                  /* wcChar20 */
348     ///////////////////////////////////////
349     /// string3 descriptor
350     ///////////////////////////////////////
351     0x16,                       /* bLength */
352     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
353     '2', 0x00,                  /* wcChar0 */
354     '0', 0x00,                  /* wcChar1 */
355     '2', 0x00,                  /* wcChar2 */
356     '2', 0x00,                  /* wcChar3 */
357     '1', 0x00,                  /* wcChar4 */
358     '2', 0x00,                  /* wcChar5 */
359     '3', 0x00,                  /* wcChar6 */
360     '4', 0x00,                  /* wcChar7 */
361     '5', 0x00,                  /* wcChar8 */
362     '6', 0x00,                  /* wcChar9 */
363 #ifdef CONFIG_USB_HS
364     /* Device Qualifier */
365     0x0a,
366     USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
367     0x10,
368     0x02,
369     0x00,
370     0x00,
371     0x00,
372     0x40,
373     0x00,
374     0x00,
375 #endif
376     /* End */
377     0x00
378 };
379 #endif
380 
381 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
382 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
383 
384 volatile bool ep_tx_busy_flag = false;
385 
usbd_event_handler(uint8_t busid,uint8_t event)386 static void usbd_event_handler(uint8_t busid, uint8_t event)
387 {
388     switch (event) {
389         case USBD_EVENT_RESET:
390             break;
391         case USBD_EVENT_CONNECTED:
392             break;
393         case USBD_EVENT_DISCONNECTED:
394             break;
395         case USBD_EVENT_RESUME:
396             break;
397         case USBD_EVENT_SUSPEND:
398             break;
399         case USBD_EVENT_CONFIGURED:
400             ep_tx_busy_flag = false;
401             /* setup first out ep read transfer */
402             usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
403             break;
404         case USBD_EVENT_SET_REMOTE_WAKEUP:
405             break;
406         case USBD_EVENT_CLR_REMOTE_WAKEUP:
407             break;
408 
409         default:
410             break;
411     }
412 }
413 
usbd_winusb_out(uint8_t busid,uint8_t ep,uint32_t nbytes)414 void usbd_winusb_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
415 {
416     USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
417     // for (int i = 0; i < 100; i++) {
418     //     printf("%02x ", read_buffer[i]);
419     // }
420     // printf("\r\n");
421     usbd_ep_start_write(busid, WINUSB_IN_EP, read_buffer, nbytes);
422     /* setup next out ep read transfer */
423     usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
424 }
425 
usbd_winusb_in(uint8_t busid,uint8_t ep,uint32_t nbytes)426 void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
427 {
428     USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
429 
430     if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
431         /* send zlp */
432         usbd_ep_start_write(busid, WINUSB_IN_EP, NULL, 0);
433     } else {
434         ep_tx_busy_flag = false;
435     }
436 }
437 
438 struct usbd_endpoint winusb_out_ep1 = {
439     .ep_addr = WINUSB_OUT_EP,
440     .ep_cb = usbd_winusb_out
441 };
442 
443 struct usbd_endpoint winusb_in_ep1 = {
444     .ep_addr = WINUSB_IN_EP,
445     .ep_cb = usbd_winusb_in
446 };
447 
448 /*!< hid mouse report descriptor */
449 static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
450     0x05, 0x01, // USAGE_PAGE (Generic Desktop)
451     0x09, 0x02, // USAGE (Mouse)
452     0xA1, 0x01, // COLLECTION (Application)
453     0x09, 0x01, //   USAGE (Pointer)
454 
455     0xA1, 0x00, //   COLLECTION (Physical)
456     0x05, 0x09, //     USAGE_PAGE (Button)
457     0x19, 0x01, //     USAGE_MINIMUM (Button 1)
458     0x29, 0x03, //     USAGE_MAXIMUM (Button 3)
459 
460     0x15, 0x00, //     LOGICAL_MINIMUM (0)
461     0x25, 0x01, //     LOGICAL_MAXIMUM (1)
462     0x95, 0x03, //     REPORT_COUNT (3)
463     0x75, 0x01, //     REPORT_SIZE (1)
464 
465     0x81, 0x02, //     INPUT (Data,Var,Abs)
466     0x95, 0x01, //     REPORT_COUNT (1)
467     0x75, 0x05, //     REPORT_SIZE (5)
468     0x81, 0x01, //     INPUT (Cnst,Var,Abs)
469 
470     0x05, 0x01, //     USAGE_PAGE (Generic Desktop)
471     0x09, 0x30, //     USAGE (X)
472     0x09, 0x31, //     USAGE (Y)
473     0x09, 0x38,
474 
475     0x15, 0x81, //     LOGICAL_MINIMUM (-127)
476     0x25, 0x7F, //     LOGICAL_MAXIMUM (127)
477     0x75, 0x08, //     REPORT_SIZE (8)
478     0x95, 0x03, //     REPORT_COUNT (2)
479 
480     0x81, 0x06, //     INPUT (Data,Var,Rel)
481     0xC0, 0x09,
482     0x3c, 0x05,
483     0xff, 0x09,
484 
485     0x01, 0x15,
486     0x00, 0x25,
487     0x01, 0x75,
488     0x01, 0x95,
489 
490     0x02, 0xb1,
491     0x22, 0x75,
492     0x06, 0x95,
493     0x01, 0xb1,
494 
495     0x01, 0xc0 //   END_COLLECTION
496 };
497 
498 /*!< mouse report struct */
499 struct hid_mouse {
500     uint8_t buttons;
501     int8_t x;
502     int8_t y;
503     int8_t wheel;
504 };
505 
506 /*!< mouse report */
507 static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg;
508 
509 #define HID_STATE_IDLE 0
510 #define HID_STATE_BUSY 1
511 
512 /*!< hid state ! Data can be sent only when state is idle  */
513 static volatile uint8_t hid_state = HID_STATE_IDLE;
514 
515 /* function ------------------------------------------------------------------*/
usbd_hid_int_callback(uint8_t busid,uint8_t ep,uint32_t nbytes)516 static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
517 {
518     hid_state = HID_STATE_IDLE;
519 }
520 
521 /*!< endpoint call back */
522 static struct usbd_endpoint hid_in_ep = {
523     .ep_cb = usbd_hid_int_callback,
524     .ep_addr = HID_INT_EP
525 };
526 
527 struct usbd_interface winusb_intf;
528 struct usbd_interface intf1;
529 
winusbv2_init(uint8_t busid,uintptr_t reg_base)530 void winusbv2_init(uint8_t busid, uintptr_t reg_base)
531 {
532 #ifdef CONFIG_USBDEV_ADVANCE_DESC
533     usbd_desc_register(busid, &winusbv2_descriptor);
534 #else
535     usbd_desc_register(busid, winusbv2_descriptor);
536 #endif
537 #ifndef CONFIG_USBDEV_ADVANCE_DESC
538     usbd_bos_desc_register(busid, &bos_desc);
539     usbd_msosv2_desc_register(busid, &msosv2_desc);
540 #endif
541     /*!< winusb */
542     usbd_add_interface(busid, &winusb_intf);
543     usbd_add_endpoint(busid, &winusb_out_ep1);
544     usbd_add_endpoint(busid, &winusb_in_ep1);
545 
546     usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf1, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
547     usbd_add_endpoint(busid, &hid_in_ep);
548 
549     usbd_initialize(busid, reg_base, usbd_event_handler);
550 }