1 /* 2 * File : hid.c 3 * COPYRIGHT (C) 2008 - 2018, RT-Thread Development Team 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Change Logs: 8 * Date Author Notes 9 * 2017-03-13 Urey the first version 10 * 2017-11-16 ZYH Update to common hid 11 */ 12 13 #include <rthw.h> 14 #include <rtthread.h> 15 #include <rtservice.h> 16 #include <rtdevice.h> 17 18 #include "drivers/usb_common.h" 19 #include "drivers/usb_device.h" 20 21 #include "hid.h" 22 23 #ifdef RT_USB_DEVICE_HID 24 25 struct hid_s 26 { 27 struct rt_device parent; 28 struct ufunction *func; 29 uep_t ep_in; 30 uep_t ep_out; 31 int status; 32 rt_uint16_t protocol; 33 rt_uint8_t report_buf[MAX_REPORT_SIZE]; 34 struct rt_messagequeue hid_mq; 35 }; 36 37 /* CustomHID_ConfigDescriptor */ 38 ALIGN(4) 39 const rt_uint8_t _report_desc[]= 40 { 41 #ifdef RT_USB_DEVICE_HID_KEYBOARD 42 USAGE_PAGE(1), 0x01, 43 USAGE(1), 0x06, 44 COLLECTION(1), 0x01, 45 REPORT_ID(1), HID_REPORT_ID_KEYBOARD1, 46 47 USAGE_PAGE(1), 0x07, 48 USAGE_MINIMUM(1), 0xE0, 49 USAGE_MAXIMUM(1), 0xE7, 50 LOGICAL_MINIMUM(1), 0x00, 51 LOGICAL_MAXIMUM(1), 0x01, 52 REPORT_SIZE(1), 0x01, 53 REPORT_COUNT(1), 0x08, 54 INPUT(1), 0x02, 55 REPORT_COUNT(1), 0x01, 56 REPORT_SIZE(1), 0x08, 57 INPUT(1), 0x01, 58 59 60 REPORT_COUNT(1), 0x05, 61 REPORT_SIZE(1), 0x01, 62 USAGE_PAGE(1), 0x08, 63 USAGE_MINIMUM(1), 0x01, 64 USAGE_MAXIMUM(1), 0x05, 65 OUTPUT(1), 0x02, 66 REPORT_COUNT(1), 0x01, 67 REPORT_SIZE(1), 0x03, 68 OUTPUT(1), 0x01, 69 70 71 REPORT_COUNT(1), 0x06, 72 REPORT_SIZE(1), 0x08, 73 LOGICAL_MINIMUM(1), 0x00, 74 LOGICAL_MAXIMUM(1), 0x65, 75 USAGE_PAGE(1), 0x07, 76 USAGE_MINIMUM(1), 0x00, 77 USAGE_MAXIMUM(1), 0x65, 78 INPUT(1), 0x00, 79 END_COLLECTION(0), 80 #if RT_USB_DEVICE_HID_KEYBOARD_NUMBER>1 81 /****keyboard2*****/ 82 USAGE_PAGE(1), 0x01, 83 USAGE(1), 0x06, 84 COLLECTION(1), 0x01, 85 REPORT_ID(1), HID_REPORT_ID_KEYBOARD2, 86 87 USAGE_PAGE(1), 0x07, 88 USAGE_MINIMUM(1), 0xE0, 89 USAGE_MAXIMUM(1), 0xE7, 90 LOGICAL_MINIMUM(1), 0x00, 91 LOGICAL_MAXIMUM(1), 0x01, 92 REPORT_SIZE(1), 0x01, 93 REPORT_COUNT(1), 0x08, 94 INPUT(1), 0x02, 95 REPORT_COUNT(1), 0x01, 96 REPORT_SIZE(1), 0x08, 97 INPUT(1), 0x01, 98 99 REPORT_COUNT(1), 0x06, 100 REPORT_SIZE(1), 0x08, 101 LOGICAL_MINIMUM(1), 0x00, 102 LOGICAL_MAXIMUM(1), 0x65, 103 USAGE_PAGE(1), 0x07, 104 USAGE_MINIMUM(1), 0x00, 105 USAGE_MAXIMUM(1), 0x65, 106 INPUT(1), 0x00, 107 END_COLLECTION(0), 108 #if RT_USB_DEVICE_HID_KEYBOARD_NUMBER>2 109 USAGE_PAGE(1), 0x01, 110 USAGE(1), 0x06, 111 COLLECTION(1), 0x01, 112 REPORT_ID(1), HID_REPORT_ID_KEYBOARD3, 113 114 USAGE_PAGE(1), 0x07, 115 USAGE_MINIMUM(1), 0xE0, 116 USAGE_MAXIMUM(1), 0xE7, 117 LOGICAL_MINIMUM(1), 0x00, 118 LOGICAL_MAXIMUM(1), 0x01, 119 REPORT_SIZE(1), 0x01, 120 REPORT_COUNT(1), 0x08, 121 INPUT(1), 0x02, 122 REPORT_COUNT(1), 0x01, 123 REPORT_SIZE(1), 0x08, 124 INPUT(1), 0x01, 125 126 REPORT_COUNT(1), 0x06, 127 REPORT_SIZE(1), 0x08, 128 LOGICAL_MINIMUM(1), 0x00, 129 LOGICAL_MAXIMUM(1), 0x65, 130 USAGE_PAGE(1), 0x07, 131 USAGE_MINIMUM(1), 0x00, 132 USAGE_MAXIMUM(1), 0x65, 133 INPUT(1), 0x00, 134 END_COLLECTION(0), 135 #if RT_USB_DEVICE_HID_KEYBOARD_NUMBER>3 136 USAGE_PAGE(1), 0x01, 137 USAGE(1), 0x06, 138 COLLECTION(1), 0x01, 139 REPORT_ID(1), HID_REPORT_ID_KEYBOARD4, 140 141 USAGE_PAGE(1), 0x07, 142 USAGE_MINIMUM(1), 0xE0, 143 USAGE_MAXIMUM(1), 0xE7, 144 LOGICAL_MINIMUM(1), 0x00, 145 LOGICAL_MAXIMUM(1), 0x01, 146 REPORT_SIZE(1), 0x01, 147 REPORT_COUNT(1), 0x08, 148 INPUT(1), 0x02, 149 REPORT_COUNT(1), 0x01, 150 REPORT_SIZE(1), 0x08, 151 INPUT(1), 0x01, 152 153 REPORT_COUNT(1), 0x06, 154 REPORT_SIZE(1), 0x08, 155 LOGICAL_MINIMUM(1), 0x00, 156 LOGICAL_MAXIMUM(1), 0x65, 157 USAGE_PAGE(1), 0x07, 158 USAGE_MINIMUM(1), 0x00, 159 USAGE_MAXIMUM(1), 0x65, 160 INPUT(1), 0x00, 161 END_COLLECTION(0), 162 #endif 163 #endif 164 #endif 165 #endif 166 // Media Control 167 #ifdef RT_USB_DEVICE_HID_MEDIA 168 USAGE_PAGE(1), 0x0C, 169 USAGE(1), 0x01, 170 COLLECTION(1), 0x01, 171 REPORT_ID(1), HID_REPORT_ID_MEDIA, 172 USAGE_PAGE(1), 0x0C, 173 LOGICAL_MINIMUM(1), 0x00, 174 LOGICAL_MAXIMUM(1), 0x01, 175 REPORT_SIZE(1), 0x01, 176 REPORT_COUNT(1), 0x07, 177 USAGE(1), 0xB5, // Next Track 178 USAGE(1), 0xB6, // Previous Track 179 USAGE(1), 0xB7, // Stop 180 USAGE(1), 0xCD, // Play / Pause 181 USAGE(1), 0xE2, // Mute 182 USAGE(1), 0xE9, // Volume Up 183 USAGE(1), 0xEA, // Volume Down 184 INPUT(1), 0x02, // Input (Data, Variable, Absolute) 185 REPORT_COUNT(1), 0x01, 186 INPUT(1), 0x01, 187 END_COLLECTION(0), 188 #endif 189 190 #ifdef RT_USB_DEVICE_HID_GENERAL 191 USAGE_PAGE(1), 0x8c, 192 USAGE(1), 0x01, 193 COLLECTION(1), 0x01, 194 REPORT_ID(1), HID_REPORT_ID_GENERAL, 195 196 REPORT_COUNT(1), RT_USB_DEVICE_HID_GENERAL_IN_REPORT_LENGTH, 197 USAGE(1), 0x03, 198 REPORT_SIZE(1), 0x08, 199 LOGICAL_MINIMUM(1), 0x00, 200 LOGICAL_MAXIMUM(1), 0xFF, 201 INPUT(1), 0x02, 202 203 REPORT_COUNT(1), RT_USB_DEVICE_HID_GENERAL_OUT_REPORT_LENGTH, 204 USAGE(1), 0x04, 205 REPORT_SIZE(1), 0x08, 206 LOGICAL_MINIMUM(1), 0x00, 207 LOGICAL_MAXIMUM(1), 0xFF, 208 OUTPUT(1), 0x02, 209 END_COLLECTION(0), 210 #endif 211 #ifdef RT_USB_DEVICE_HID_MOUSE 212 USAGE_PAGE(1), 0x01, // Generic Desktop 213 USAGE(1), 0x02, // Mouse 214 COLLECTION(1), 0x01, // Application 215 USAGE(1), 0x01, // Pointer 216 COLLECTION(1), 0x00, // Physical 217 REPORT_ID(1), HID_REPORT_ID_MOUSE, 218 REPORT_COUNT(1), 0x03, 219 REPORT_SIZE(1), 0x01, 220 USAGE_PAGE(1), 0x09, // Buttons 221 USAGE_MINIMUM(1), 0x1, 222 USAGE_MAXIMUM(1), 0x3, 223 LOGICAL_MINIMUM(1), 0x00, 224 LOGICAL_MAXIMUM(1), 0x01, 225 INPUT(1), 0x02, 226 REPORT_COUNT(1), 0x01, 227 REPORT_SIZE(1), 0x05, 228 INPUT(1), 0x01, 229 REPORT_COUNT(1), 0x03, 230 REPORT_SIZE(1), 0x08, 231 USAGE_PAGE(1), 0x01, 232 USAGE(1), 0x30, // X 233 USAGE(1), 0x31, // Y 234 USAGE(1), 0x38, // scroll 235 LOGICAL_MINIMUM(1), 0x81, 236 LOGICAL_MAXIMUM(1), 0x7f, 237 INPUT(1), 0x06, 238 END_COLLECTION(0), 239 END_COLLECTION(0), 240 #endif 241 }; /* CustomHID_ReportDescriptor */ 242 243 ALIGN(4) 244 static struct udevice_descriptor _dev_desc = 245 { 246 USB_DESC_LENGTH_DEVICE, //bLength; 247 USB_DESC_TYPE_DEVICE, //type; 248 USB_BCD_VERSION, //bcdUSB; 249 USB_CLASS_HID, //bDeviceClass; 250 0x00, //bDeviceSubClass; 251 0x00, //bDeviceProtocol; 252 64, //bMaxPacketSize0; 253 _VENDOR_ID, //idVendor; 254 _PRODUCT_ID, //idProduct; 255 USB_BCD_DEVICE, //bcdDevice; 256 USB_STRING_MANU_INDEX, //iManufacturer; 257 USB_STRING_PRODUCT_INDEX, //iProduct; 258 USB_STRING_SERIAL_INDEX, //iSerialNumber; 259 USB_DYNAMIC, //bNumConfigurations; 260 }; 261 262 //FS and HS needed 263 ALIGN(4) 264 static struct usb_qualifier_descriptor dev_qualifier = 265 { 266 sizeof(dev_qualifier), //bLength 267 USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType 268 0x0200, //bcdUSB 269 USB_CLASS_MASS_STORAGE, //bDeviceClass 270 0x06, //bDeviceSubClass 271 0x50, //bDeviceProtocol 272 64, //bMaxPacketSize0 273 0x01, //bNumConfigurations 274 0, 275 }; 276 277 278 /* hid interface descriptor */ 279 ALIGN(4) 280 const static struct uhid_comm_descriptor _hid_comm_desc = 281 { 282 #ifdef RT_USB_DEVICE_COMPOSITE 283 /* Interface Association Descriptor */ 284 { 285 USB_DESC_LENGTH_IAD, 286 USB_DESC_TYPE_IAD, 287 USB_DYNAMIC, 288 0x01, 289 0x03, /* bInterfaceClass: HID */ 290 #if defined(RT_USB_DEVICE_HID_KEYBOARD)||defined(RT_USB_DEVICE_HID_MOUSE) 291 USB_HID_SUBCLASS_BOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 292 #else 293 USB_HID_SUBCLASS_NOBOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 294 #endif 295 #if !defined(RT_USB_DEVICE_HID_KEYBOARD)||!defined(RT_USB_DEVICE_HID_MOUSE)||!defined(RT_USB_DEVICE_HID_MEDIA) 296 USB_HID_PROTOCOL_NONE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 297 #elif !defined(RT_USB_DEVICE_HID_MOUSE) 298 USB_HID_PROTOCOL_KEYBOARD, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 299 #else 300 USB_HID_PROTOCOL_MOUSE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 301 #endif 302 0x00, 303 }, 304 #endif 305 /* Interface Descriptor */ 306 { 307 USB_DESC_LENGTH_INTERFACE, 308 USB_DESC_TYPE_INTERFACE, 309 USB_DYNAMIC, /* bInterfaceNumber: Number of Interface */ 310 0x00, /* bAlternateSetting: Alternate setting */ 311 0x02, /* bNumEndpoints */ 312 0x03, /* bInterfaceClass: HID */ 313 #if defined(RT_USB_DEVICE_HID_KEYBOARD)||defined(RT_USB_DEVICE_HID_MOUSE) 314 USB_HID_SUBCLASS_BOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 315 #else 316 USB_HID_SUBCLASS_NOBOOT, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 317 #endif 318 #if !defined(RT_USB_DEVICE_HID_KEYBOARD)||!defined(RT_USB_DEVICE_HID_MOUSE)||!defined(RT_USB_DEVICE_HID_MEDIA) 319 USB_HID_PROTOCOL_NONE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 320 #elif !defined(RT_USB_DEVICE_HID_MOUSE) 321 USB_HID_PROTOCOL_KEYBOARD, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 322 #else 323 USB_HID_PROTOCOL_MOUSE, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 324 #endif 325 0, /* iInterface: Index of string descriptor */ 326 }, 327 328 /* HID Descriptor */ 329 { 330 HID_DESCRIPTOR_SIZE, /* bLength: HID Descriptor size */ 331 HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ 332 0x0110, /* bcdHID: HID Class Spec release number */ 333 0x00, /* bCountryCode: Hardware target country */ 334 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ 335 { 336 { 337 0x22, /* bDescriptorType */ 338 sizeof(_report_desc), /* wItemLength: Total length of Report descriptor */ 339 }, 340 }, 341 }, 342 343 /* Endpoint Descriptor IN */ 344 { 345 USB_DESC_LENGTH_ENDPOINT, 346 USB_DESC_TYPE_ENDPOINT, 347 USB_DYNAMIC | USB_DIR_IN, 348 USB_EP_ATTR_INT, 349 0x40, 350 0x01, 351 }, 352 353 /* Endpoint Descriptor OUT */ 354 { 355 USB_DESC_LENGTH_ENDPOINT, 356 USB_DESC_TYPE_ENDPOINT, 357 USB_DYNAMIC | USB_DIR_OUT, 358 USB_EP_ATTR_INT, 359 0x40, 360 0x01, 361 }, 362 }; 363 364 ALIGN(4) 365 const static char* _ustring[] = 366 { 367 "Language", 368 "RT-Thread Team.", 369 "RTT HID-Device", 370 "32021919830108", 371 "Configuration", 372 "Interface", 373 }; 374 375 static void dump_data(uint8_t *data, rt_size_t size) 376 { 377 rt_size_t i; 378 for (i = 0; i < size; i++) 379 { 380 rt_kprintf("%02x ", *data++); 381 if ((i + 1) % 8 == 0) 382 { 383 rt_kprintf("\n"); 384 }else if ((i + 1) % 4 == 0){ 385 rt_kprintf(" "); 386 } 387 } 388 } 389 static void dump_report(struct hid_report * report) 390 { 391 rt_kprintf("\nHID Recived:"); 392 rt_kprintf("\nReport ID %02x \n", report->report_id); 393 dump_data(report->report,report->size); 394 } 395 396 static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) 397 { 398 struct hid_s *data; 399 struct hid_report report; 400 RT_ASSERT(func != RT_NULL); 401 RT_ASSERT(func->device != RT_NULL); 402 data = (struct hid_s *) func->user_data; 403 404 if(size != 0) 405 { 406 rt_memcpy((void *)&report,(void*)data->ep_out->buffer,size); 407 report.size = size-1; 408 rt_mq_send(&data->hid_mq,(void *)&report,sizeof(report)); 409 } 410 411 data->ep_out->request.buffer = data->ep_out->buffer; 412 data->ep_out->request.size = EP_MAXPACKET(data->ep_out); 413 data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; 414 rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); 415 return RT_EOK; 416 } 417 418 static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) 419 { 420 struct hid_s *data; 421 RT_ASSERT(func != RT_NULL); 422 RT_ASSERT(func->device != RT_NULL); 423 424 data = (struct hid_s *) func->user_data; 425 if(data->parent.tx_complete != RT_NULL) 426 { 427 data->parent.tx_complete(&data->parent,RT_NULL); 428 } 429 return RT_EOK; 430 } 431 432 static rt_err_t _hid_set_report_callback(udevice_t device, rt_size_t size) 433 { 434 RT_DEBUG_LOG(RT_DEBUG_USB, ("_hid_set_report_callback\n")); 435 436 if(size != 0) 437 { 438 } 439 440 dcd_ep0_send_status(device->dcd); 441 442 return RT_EOK; 443 } 444 445 /** 446 * This function will handle hid interface bRequest. 447 * 448 * @param device the usb device object. 449 * @param setup the setup bRequest. 450 * 451 * @return RT_EOK on successful. 452 */ 453 static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) 454 { 455 RT_ASSERT(func != RT_NULL); 456 RT_ASSERT(func->device != RT_NULL); 457 RT_ASSERT(setup != RT_NULL); 458 459 struct hid_s *data = (struct hid_s *) func->user_data; 460 461 if(setup->wIndex != 0) 462 return -RT_EIO; 463 464 switch (setup->bRequest) 465 { 466 case USB_REQ_GET_DESCRIPTOR: 467 if((setup->wValue >> 8) == USB_DESC_TYPE_REPORT) 468 { 469 rt_usbd_ep0_write(func->device, (void *)(&_report_desc[0]), sizeof(_report_desc)); 470 } 471 else if((setup->wValue >> 8) == USB_DESC_TYPE_HID) 472 { 473 474 rt_usbd_ep0_write(func->device, (void *)(&_hid_comm_desc.hid_desc), sizeof(struct uhid_descriptor)); 475 } 476 break; 477 case USB_HID_REQ_GET_REPORT: 478 if(setup->wLength == 0) 479 { 480 rt_usbd_ep0_set_stall(func->device); 481 break; 482 } 483 if((setup->wLength == 0) || (setup->wLength > MAX_REPORT_SIZE)) 484 setup->wLength = MAX_REPORT_SIZE; 485 rt_usbd_ep0_write(func->device, data->report_buf,setup->wLength); 486 break; 487 case USB_HID_REQ_GET_IDLE: 488 489 dcd_ep0_send_status(func->device->dcd); 490 break; 491 case USB_HID_REQ_GET_PROTOCOL: 492 rt_usbd_ep0_write(func->device, &data->protocol,2); 493 break; 494 case USB_HID_REQ_SET_REPORT: 495 496 if((setup->wLength == 0) || (setup->wLength > MAX_REPORT_SIZE)) 497 rt_usbd_ep0_set_stall(func->device); 498 499 rt_usbd_ep0_read(func->device, data->report_buf, setup->wLength, _hid_set_report_callback); 500 break; 501 case USB_HID_REQ_SET_IDLE: 502 dcd_ep0_send_status(func->device->dcd); 503 break; 504 case USB_HID_REQ_SET_PROTOCOL: 505 data->protocol = setup->wValue; 506 507 dcd_ep0_send_status(func->device->dcd); 508 break; 509 } 510 511 return RT_EOK; 512 } 513 514 515 /** 516 * This function will run cdc function, it will be called on handle set configuration bRequest. 517 * 518 * @param func the usb function object. 519 * 520 * @return RT_EOK on successful. 521 */ 522 static rt_err_t _function_enable(ufunction_t func) 523 { 524 struct hid_s *data; 525 526 RT_ASSERT(func != RT_NULL); 527 RT_ASSERT(func->device != RT_NULL); 528 data = (struct hid_s *) func->user_data; 529 530 RT_DEBUG_LOG(RT_DEBUG_USB, ("hid function enable\n")); 531 // 532 // _vcom_reset_state(func); 533 // 534 if(data->ep_out->buffer == RT_NULL) 535 { 536 data->ep_out->buffer = rt_malloc(HID_RX_BUFSIZE); 537 } 538 data->ep_out->request.buffer = data->ep_out->buffer; 539 data->ep_out->request.size = EP_MAXPACKET(data->ep_out); 540 data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; 541 542 rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); 543 544 return RT_EOK; 545 } 546 547 /** 548 * This function will stop cdc function, it will be called on handle set configuration bRequest. 549 * 550 * @param func the usb function object. 551 * 552 * @return RT_EOK on successful. 553 */ 554 static rt_err_t _function_disable(ufunction_t func) 555 { 556 struct hid_s *data; 557 558 RT_ASSERT(func != RT_NULL); 559 RT_ASSERT(func->device != RT_NULL); 560 data = (struct hid_s *) func->user_data; 561 562 RT_DEBUG_LOG(RT_DEBUG_USB, ("hid function disable\n")); 563 564 if(data->ep_out->buffer != RT_NULL) 565 { 566 rt_free(data->ep_out->buffer); 567 data->ep_out->buffer = RT_NULL; 568 } 569 570 return RT_EOK; 571 } 572 573 static struct ufunction_ops ops = 574 { 575 _function_enable, 576 _function_disable, 577 RT_NULL, 578 }; 579 580 581 582 583 /** 584 * This function will configure hid descriptor. 585 * 586 * @param comm the communication interface number. 587 * @param data the data interface number. 588 * 589 * @return RT_EOK on successful. 590 */ 591 static rt_err_t _hid_descriptor_config(uhid_comm_desc_t hid, rt_uint8_t cintf_nr) 592 { 593 #ifdef RT_USB_DEVICE_COMPOSITE 594 hid->iad_desc.bFirstInterface = cintf_nr; 595 #endif 596 597 return RT_EOK; 598 } 599 static rt_size_t _hid_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) 600 { 601 struct hid_s *hiddev = (struct hid_s *)dev; 602 struct hid_report report; 603 if (hiddev->func->device->state == USB_STATE_CONFIGURED) 604 { 605 report.report_id = pos; 606 rt_memcpy((void *)report.report,(void *)buffer,size); 607 report.size = size; 608 hiddev->ep_in->request.buffer = (void *)&report; 609 hiddev->ep_in->request.size = (size+1) > 64 ? 64 : size+1; 610 hiddev->ep_in->request.req_type = UIO_REQUEST_WRITE; 611 rt_usbd_io_request(hiddev->func->device, hiddev->ep_in, &hiddev->ep_in->request); 612 return size; 613 } 614 615 return 0; 616 } 617 RT_WEAK void HID_Report_Received(hid_report_t report) 618 { 619 dump_report(report); 620 } 621 ALIGN(RT_ALIGN_SIZE) 622 static rt_uint8_t hid_thread_stack[512]; 623 static struct rt_thread hid_thread; 624 625 static void hid_thread_entry(void* parameter) 626 { 627 struct hid_report report; 628 struct hid_s *hiddev; 629 hiddev = (struct hid_s *)parameter; 630 while(1) 631 { 632 if(rt_mq_recv(&hiddev->hid_mq, &report, sizeof(report),RT_WAITING_FOREVER) != RT_EOK ) 633 continue; 634 HID_Report_Received(&report); 635 } 636 } 637 638 #ifdef RT_USING_DEVICE_OPS 639 const static struct rt_device_ops hid_device_ops = 640 { 641 RT_NULL, 642 RT_NULL, 643 RT_NULL, 644 RT_NULL, 645 _hid_write, 646 RT_NULL, 647 }; 648 #endif 649 650 static rt_uint8_t hid_mq_pool[(sizeof(struct hid_report)+sizeof(void*))*8]; 651 static void rt_usb_hid_init(struct ufunction *func) 652 { 653 struct hid_s *hiddev; 654 hiddev = (struct hid_s *)func->user_data; 655 rt_memset(&hiddev->parent, 0, sizeof(hiddev->parent)); 656 657 #ifdef RT_USING_DEVICE_OPS 658 hiddev->parent.ops = &hid_device_ops; 659 #else 660 hiddev->parent.write = _hid_write; 661 #endif 662 hiddev->func = func; 663 664 rt_device_register(&hiddev->parent, "hidd", RT_DEVICE_FLAG_RDWR); 665 rt_mq_init(&hiddev->hid_mq, "hiddmq", hid_mq_pool, sizeof(struct hid_report), 666 sizeof(hid_mq_pool), RT_IPC_FLAG_FIFO); 667 668 rt_thread_init(&hid_thread, "hidd", hid_thread_entry, hiddev, 669 hid_thread_stack, sizeof(hid_thread_stack), RT_USBD_THREAD_PRIO, 20); 670 rt_thread_startup(&hid_thread); 671 } 672 673 674 /** 675 * This function will create a hid function instance. 676 * 677 * @param device the usb device object. 678 * 679 * @return RT_EOK on successful. 680 */ 681 ufunction_t rt_usbd_function_hid_create(udevice_t device) 682 { 683 ufunction_t func; 684 struct hid_s *data; 685 686 uintf_t hid_intf; 687 ualtsetting_t hid_setting; 688 uhid_comm_desc_t hid_desc; 689 690 /* parameter check */ 691 RT_ASSERT(device != RT_NULL); 692 693 /* set usb device string description */ 694 rt_usbd_device_set_string(device, _ustring); 695 696 /* create a cdc function */ 697 func = rt_usbd_function_new(device, &_dev_desc, &ops); 698 //not support hs 699 //rt_usbd_device_set_qualifier(device, &_dev_qualifier); 700 701 /* allocate memory for cdc vcom data */ 702 data = (struct hid_s*)rt_malloc(sizeof(struct hid_s)); 703 rt_memset(data, 0, sizeof(struct hid_s)); 704 func->user_data = (void*)data; 705 706 /* create an interface object */ 707 hid_intf = rt_usbd_interface_new(device, _interface_handler); 708 709 /* create an alternate setting object */ 710 hid_setting = rt_usbd_altsetting_new(sizeof(struct uhid_comm_descriptor)); 711 712 /* config desc in alternate setting */ 713 rt_usbd_altsetting_config_descriptor(hid_setting, &_hid_comm_desc, (rt_off_t)&((uhid_comm_desc_t)0)->intf_desc); 714 715 /* configure the hid interface descriptor */ 716 _hid_descriptor_config(hid_setting->desc, hid_intf->intf_num); 717 718 /* create endpoint */ 719 hid_desc = (uhid_comm_desc_t)hid_setting->desc; 720 data->ep_out = rt_usbd_endpoint_new(&hid_desc->ep_out_desc, _ep_out_handler); 721 data->ep_in = rt_usbd_endpoint_new(&hid_desc->ep_in_desc, _ep_in_handler); 722 723 /* add the int out and int in endpoint to the alternate setting */ 724 rt_usbd_altsetting_add_endpoint(hid_setting, data->ep_out); 725 rt_usbd_altsetting_add_endpoint(hid_setting, data->ep_in); 726 727 /* add the alternate setting to the interface, then set default setting */ 728 rt_usbd_interface_add_altsetting(hid_intf, hid_setting); 729 rt_usbd_set_altsetting(hid_intf, 0); 730 731 /* add the interface to the mass storage function */ 732 rt_usbd_function_add_interface(func, hid_intf); 733 734 /* initilize hid */ 735 rt_usb_hid_init(func); 736 return func; 737 } 738 struct udclass hid_class = 739 { 740 .rt_usbd_function_create = rt_usbd_function_hid_create 741 }; 742 743 int rt_usbd_hid_class_register(void) 744 { 745 rt_usbd_class_register(&hid_class); 746 return 0; 747 } 748 INIT_PREV_EXPORT(rt_usbd_hid_class_register); 749 #endif /* RT_USB_DEVICE_HID */ 750