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 }