22static int hid_parse_item(
HID_DEV_T *hdev, uint8_t *buff);
31static const struct string_table usage_page_list[] =
33 "Generic Desktop", UP_GENERIC_DESKTOP,
34 "Simulation Controls", UP_SIMULATION_CONTROLS,
35 "VR Controls", UP_VR_CONTROLS,
36 "Sport Controls", UP_SPORT_CONTROLS,
37 "Game Controls", UP_GAME_CONTROLS,
38 "KeyCode", UP_KEYCODE,
41 "Digitizer", UP_DIGITIZER,
42 "Bar Code Scanner", UP_BARCODE_SCANNER,
45static const struct string_table desktop_page_list[] =
47 "Pointer", USAGE_ID_POINTER,
48 "Mouse", USAGE_ID_MOUSE,
49 "Joystick", USAGE_ID_JOYSTICK,
50 "Game Pad", USAGE_ID_GAMEPAD,
51 "Keyboard", USAGE_ID_KEYBOARD,
52 "Keypad", USAGE_ID_KEYPAD,
61 "Wheel", USAGE_ID_WHEEL,
70static RP_INFO_T _rp_info;
72static uint8_t _data_usages[16];
73static int _data_usage_cnt;
75static void print_usage_page(
void)
80 for(i = 0; i <
sizeof(usage_page_list) /
sizeof(
struct string_table); i++)
82 if(usage_page_list[i].code == _rp_info.usage_page)
84 printf(
"(%s)", usage_page_list[i].
string);
88 printf(
"(?? - 0x%x)", _rp_info.usage_page);
92static void print_usage(uint8_t usage)
96 struct string_table *p;
98 if(_rp_info.usage_page == UP_GENERIC_DESKTOP)
100 count =
sizeof(desktop_page_list) /
sizeof(
struct string_table);
101 p = (
struct string_table *)&desktop_page_list[0];
106 for(i = 0; i < count; i++, p++)
110 printf(
"(%s)", p->string);
114 printf(
"(?? - 0x%x)", usage);
118static void read_main_item_status(uint8_t *buff)
123 _rp_info.status.constant = 1;
124 _rp_info.status.variable = 0;
125 HID_DBGMSG(
"Constant ");
129 _rp_info.status.constant = 0;
130 _rp_info.status.variable = 1;
131 HID_DBGMSG(
"Variable ");
135 _rp_info.status.relative = 1;
136 HID_DBGMSG(
"Relative ");
140 _rp_info.status.wrap = 1;
145 _rp_info.status.non_linear = 1;
146 HID_DBGMSG(
"Non-linear ");
150 _rp_info.status.no_preferred = 1;
151 HID_DBGMSG(
"Not-prefered ");
155 _rp_info.status.null_state = 1;
156 HID_DBGMSG(
"Null-state ");
160 _rp_info.status.is_volatile = 1;
161 HID_DBGMSG(
"Volatile ");
165 _rp_info.status.buffered_bytes = 1;
166 HID_DBGMSG(
"Buffered-bytes ");
180int hid_parse_report_descriptor(
HID_DEV_T *hdev, IFACE_T *iface)
182 UDEV_T *udev = iface->udev;
188 int desc_buff_len, remain_len, size;
190 HID_DBGMSG(
"HID interface %d parsing report descriptor...\n", iface->if_num);
192 memset(&_rp_info, 0,
sizeof(_rp_info));
195 hdev->rpd.has_report_id = 0;
197 bptr = udev->cfd_buff;
198 config = (DESC_CONF_T *)bptr;
201 bptr += config->bLength;
202 size = config->wTotalLength - config->bLength;
207 while(size >=
sizeof(DESC_IF_T))
209 ifd = (DESC_IF_T *)bptr;
211 if((ifd->bDescriptorType == USB_DT_INTERFACE) && (ifd->bInterfaceNumber == iface->if_num) &&
212 (ifd->bInterfaceClass == USB_CLASS_HID))
215 if(ifd->bLength == 0)
218 bptr += ifd->bLength;
219 size -= ifd->bLength;
222 if(size <
sizeof(DESC_IF_T))
224 HID_ERRMSG(
"Can't find the HID interface!\n");
228 bptr += ifd->bLength;
229 size -= ifd->bLength;
234 while(size >=
sizeof(DESC_HID_T))
236 hidd = (DESC_HID_T *)bptr;
238 if((hidd->bDescriptorType == HID_DESCRIPTOR_TYPE) &&
239 (hidd->bRPDescType == REPORT_DESCRIPTOR_TYPE))
242 if(hidd->bLength == 0)
245 bptr += ifd->bLength;
246 size -= ifd->bLength;
249 if(size <
sizeof(DESC_HID_T))
251 HID_ERRMSG(
"Can't find the HID interface!\n");
255 hidd = (DESC_HID_T *)bptr;
257 HID_DBGMSG(
"[HID Descriptor]\n");
258 HID_DBGMSG(
"bLength = %d\n", hidd->bLength);
259 HID_DBGMSG(
"bDescriptorType = 0x%x\n", hidd->bDescriptorType);
260 HID_DBGMSG(
"bcdHID = 0x%x\n", hidd->bcdHID);
261 HID_DBGMSG(
"bCountryCode = 0x%x\n", hidd->bCountryCode);
262 HID_DBGMSG(
"bNumDescriptors = %d\n", hidd->bNumDescriptors);
263 HID_DBGMSG(
"bRPDescType = 0x%x\n", hidd->bRPDescType);
264 HID_DBGMSG(
"wDescriptorLength = %d\n", hidd->wDescriptorLength);
266 HID_DBGMSG(
"Report descriptor found, length=%d. %d\n", hidd->wDescriptorLength, hidd->bLength);
268 desc_buff_len = hidd->wDescriptorLength + 8;
269 desc_buff = (uint8_t *)usbh_alloc_mem(desc_buff_len);
274 usbh_free_mem(desc_buff, desc_buff_len);
285 while(remain_len > 0)
287 size = hid_parse_item(hdev, bptr);
291 usbh_free_mem(desc_buff, desc_buff_len);
299 usbh_free_mem(desc_buff, desc_buff_len);
304 if((hdev->bSubClassCode == HID_SUBCLASS_BOOT_DEVICE) && (hdev->bProtocolCode == HID_PROTOCOL_KEYBOARD))
308 for(report = hdev->rpd.report; report !=
NULL; report = report->next)
310 if((report->usage_page == UP_LEDS) && (report->report_size == 1) && report->status.variable)
312 uint8_t i, ret, leds = 0;
314 for(i = 0; (i < 8) && (i < report->report_count); i++)
315 leds = (leds << 1) | 0x1;
321 HID_ERRMSG(
"Failed to turn on LEDs! 0x%x, %d\n", leds, ret);
331 HID_ERRMSG(
"Failed to turn off LEDs! %d\n", ret);
340static int hid_add_report(
HID_DEV_T *hdev, uint8_t type)
342 RP_INFO_T *report, *p;
344 report = (RP_INFO_T *)usbh_alloc_mem(
sizeof(RP_INFO_T));
347 HID_ERRMSG(
"hid_add_report allocate memory failed!!\n");
350 memcpy(report, &_rp_info,
sizeof(RP_INFO_T));
353 HID_DBGMSG(
"\nCreate a report. %d x %d (%d)\n", report->report_count, report->report_size, report->report_id);
355 if(hdev->rpd.report ==
NULL)
356 hdev->rpd.report = report;
359 p = hdev->rpd.report;
360 while(p->next !=
NULL)
367static signed int hid_read_item_value(uint8_t bSize, uint8_t *buff)
370 return (
signed char)buff[0];
372 return (
signed short)(buff[0] | (buff[1] << 8));
374 return (
signed int)(buff[0] | (buff[1] << 8) | (buff[2] << 16) | (buff[3] << 24));
380static int hid_parse_item(
HID_DEV_T *hdev, uint8_t *buff)
382 uint8_t bTag, bSize, tag;
385 bTag = (buff[0] >> 4) & 0xF;
387 bSize = buff[0] & 0x3;
388 tag = (buff[0] & 0xFC);
393 item_len = bSize + 3;
399 item_len = bSize + 1;
403 for(i = 0; i < item_len; i++)
405 printf(
"%02x ", buff[i]);
417 HID_DBGMSG(
"Input ");
418 read_main_item_status(&buff[1]);
419 if(_data_usage_cnt > 0)
421 int report_count = _rp_info.report_count;
423 for(i = 0; i < _data_usage_cnt; i++)
425 _rp_info.report_count = 1;
426 _rp_info.data_usage = _data_usages[i];
427 if(hid_add_report(hdev, TAG_INPUT) != 0)
431 _rp_info.report_count = report_count;
432 _rp_info.data_usage = 0;
435 if(_rp_info.report_count > 0)
437 if(hid_add_report(hdev, TAG_INPUT) != 0)
443 HID_DBGMSG(
"Output ");
444 read_main_item_status(&buff[1]);
445 if(_rp_info.report_count > 0)
447 if(hid_add_report(hdev, TAG_OUTPUT) != 0)
453 HID_DBGMSG(
"Feature ");
454 read_main_item_status(&buff[1]);
458 HID_DBGMSG(
"Collection ");
460 HID_DBGMSG(
"Physical");
461 else if(buff[1] == 0x01)
462 HID_DBGMSG(
"Application");
463 else if(buff[1] == 0x02)
464 HID_DBGMSG(
"Logical");
467 case TAG_END_COLLECTION:
468 HID_DBGMSG(
"End Collection");
476 HID_DBGMSG(
"Usage Page ");
477 _rp_info.usage_page = buff[1];
481 case TAG_LOGICAL_MIN:
482 _rp_info.logical_min = hid_read_item_value(bSize, &buff[1]);
483 HID_DBGMSG(
"Logical Minimum (%d)", _rp_info.logical_min);
486 case TAG_LOGICAL_MAX:
487 _rp_info.logical_max = hid_read_item_value(bSize, &buff[1]);
488 HID_DBGMSG(
"Logical Maximum (%d)", _rp_info.logical_max);
491 case TAG_PHYSICAL_MIN:
492 _rp_info.physical_min = hid_read_item_value(bSize, &buff[1]);
493 HID_DBGMSG(
"Physical Minimum (%d)", _rp_info.physical_min);
496 case TAG_PHYSICAL_MAX:
497 _rp_info.physical_max = hid_read_item_value(bSize, &buff[1]);
498 HID_DBGMSG(
"Physical Maximum (%d)", _rp_info.physical_max);
501 case TAG_UNIT_EXPONENT:
502 _rp_info.unit_exponent = hid_read_item_value(bSize, &buff[1]);
503 HID_DBGMSG(
"Unit Exponent (%d)", _rp_info.unit_exponent);
507 _rp_info.unit = hid_read_item_value(bSize, &buff[1]);
508 HID_DBGMSG(
"Unit (%d)", _rp_info.unit);
511 case TAG_REPORT_SIZE:
512 _rp_info.report_size = buff[1];
513 HID_DBGMSG(
"Report Size (%d)", _rp_info.report_size);
517 _rp_info.report_id = buff[1];
518 hdev->rpd.has_report_id = 1;
519 HID_DBGMSG(
"Report ID (%d)", _rp_info.report_id);
522 case TAG_REPORT_COUNT:
523 _rp_info.report_count = buff[1];
524 HID_DBGMSG(
"Report Count (%d)", _rp_info.report_count);
540 if((buff[1] == USAGE_ID_X) || (buff[1] == USAGE_ID_Y) || (buff[1] == USAGE_ID_WHEEL))
541 _data_usages[_data_usage_cnt++] = buff[1];
543 _rp_info.app_usage = buff[1];
544 HID_DBGMSG(
"Usage ");
545 print_usage(buff[1]);
549 _rp_info.usage_mim = hid_read_item_value(bSize, &buff[1]);
550 HID_DBGMSG(
"Usage Mimimum (%d)", _rp_info.usage_mim);
554 _rp_info.usage_max = hid_read_item_value(bSize, &buff[1]);
555 HID_DBGMSG(
"Usage Maximum (%d)", _rp_info.usage_max);
558 case TAG_DESIGNATOR_INDEX:
559 _rp_info.designator_index = hid_read_item_value(bSize, &buff[1]);
560 HID_DBGMSG(
"Designator Index (%d)", _rp_info.designator_index);
563 case TAG_DESIGNATOR_MIN:
564 _rp_info.designator_min = hid_read_item_value(bSize, &buff[1]);
565 HID_DBGMSG(
"Designator Minimum (%d)", _rp_info.designator_min);
568 case TAG_DESIGNATOR_MAX:
569 _rp_info.designator_max = hid_read_item_value(bSize, &buff[1]);
570 HID_DBGMSG(
"Designator Maximum (%d)", _rp_info.designator_max);
573 case TAG_STRING_INDEX:
574 _rp_info.string_index = hid_read_item_value(bSize, &buff[1]);
575 HID_DBGMSG(
"String Index (%d)", _rp_info.string_index);
579 _rp_info.string_min = hid_read_item_value(bSize, &buff[1]);
580 HID_DBGMSG(
"String Minimum (%d)", _rp_info.string_min);
584 _rp_info.string_max = hid_read_item_value(bSize, &buff[1]);
585 HID_DBGMSG(
"String Maximum (%d)", _rp_info.string_max);
589 HID_DBGMSG(
"Delimiter");
593 HID_DBGMSG(
"Unknow tag: 0x%x\n", tag);
602int hid_parse_keyboard_reports(
HID_DEV_T *hdev, uint8_t *data,
int data_len)
606 int byte_idx = 0, bit_idx = 0;
607 int has_kbd_event = 0;
611 memset(&_keyboard_event, 0,
sizeof(_keyboard_event));
612 _keyboard_event.
lock_state = hdev->rpd.lock_state;
617 if(hdev->rpd.has_report_id && (byte_idx == 0))
624 for(report = hdev->rpd.report; report !=
NULL; report = report->next)
626 if(hdev->rpd.has_report_id && (report->report_id != report_id))
629 if(report->type != TAG_INPUT)
635 if((report->usage_page == UP_KEYCODE) && (report->app_usage == USAGE_ID_KEYBOARD))
639 if((report->report_size != 1) && (report->report_size != 8))
642 HID_ERRMSG(
"Keycode report size %d is not supported!\n", report->report_size);
646 if(report->report_size == 1)
649 for(i = 0; i < report->report_count; i++)
651 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
652 usage_val |= (bit << i);
656 _keyboard_event.
modifier |= usage_val;
658 else if(bit_idx < 16)
664 _keyboard_event.
keycode[(bit_idx - 16) / 8] |= usage_val;
668 byte_idx = (bit_idx / 8);
672 for(i = 0; i < report->report_count; i++)
676 _keyboard_event.
modifier = data[byte_idx];
678 else if(byte_idx == 1)
686 _keyboard_event.
keycode[byte_idx - 2] = data[byte_idx];
697 bit_idx += report->report_size * report->report_count;
698 byte_idx = (bit_idx / 8);
701 if(byte_idx >= data_len)
705 if((has_kbd_event) && (_keyboard_callback !=
NULL))
707 uint8_t pressed_lock_keys = 0;
708 char update_LEDs = 0;
713 for(i = 0; i < 6; i++)
715 switch(_keyboard_event.
keycode[i])
717 case KEYCODE_NUM_LOCK:
718 pressed_lock_keys |= STATE_MASK_NUM_LOCK;
720 case KEYCODE_CAPS_LOCK:
721 pressed_lock_keys |= STATE_MASK_CAPS_LOCK;
723 case KEYCODE_SCROLL_LOCK:
724 pressed_lock_keys |= STATE_MASK_SCROLL_LOCK;
738 for(i = 0; i < 3; i++)
740 if((pressed_lock_keys & (1 << i)) && (!(hdev->rpd.last_pressed_lock_keys & (1 << i))))
750 hdev->rpd.last_pressed_lock_keys = pressed_lock_keys;
751 hdev->rpd.lock_state = _keyboard_event.
lock_state;
758 _keyboard_callback(hdev, &_keyboard_event);
763int hid_parse_mouse_reports(
HID_DEV_T *hdev, uint8_t *data,
int data_len)
765 int byte_idx = 0, bit_idx = 0;
768 int has_mouse_event = 0;
772 memset(&_mouse_event, 0,
sizeof(_mouse_event));
777 if(hdev->rpd.has_report_id && (byte_idx == 0))
784 for(report = hdev->rpd.report; report !=
NULL; report = report->next)
786 if(hdev->rpd.has_report_id && (report->report_id != report_id))
789 if(report->type != TAG_INPUT)
795 if((report->usage_page == UP_BUTTON) &&
796 ((report->app_usage == USAGE_ID_MOUSE) || (report->app_usage == USAGE_ID_POINTER)))
799 if(report->status.variable)
801 _mouse_event.
button_cnt = report->report_count;
802 for(i = 0; i < report->report_count; i++)
804 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
806 bit_idx += report->report_size;
807 byte_idx = (bit_idx / 8);
813 bit_idx += report->report_count * report->report_size;
814 byte_idx = (bit_idx / 8);
822 else if((report->usage_page == UP_GENERIC_DESKTOP) &&
823 ((report->app_usage == USAGE_ID_MOUSE) || (report->app_usage == USAGE_ID_POINTER) ||
824 (report->data_usage == USAGE_ID_WHEEL)))
826 signed int usage_val = 0;
828 for(i = 0; i < report->report_size; i++)
830 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
831 usage_val |= (bit << i);
833 byte_idx = (bit_idx / 8);
836 if(report->report_size <= 8)
837 usage_val = (
signed char)usage_val;
838 else if(report->report_size <= 16)
839 usage_val = (
signed short)usage_val;
841 if(report->data_usage == USAGE_ID_X)
843 _mouse_event.
X = usage_val;
845 _mouse_event.
axis_min = report->logical_min;
846 _mouse_event.
axis_max = report->logical_max;
848 else if(report->data_usage == USAGE_ID_Y)
850 _mouse_event.
Y = usage_val;
852 else if(report->data_usage == USAGE_ID_WHEEL)
854 _mouse_event.
wheel = usage_val;
856 _mouse_event.
wheel_min = report->logical_min;
857 _mouse_event.
wheel_max = report->logical_max;
864 bit_idx += report->report_size;
865 byte_idx = (bit_idx / 8);
868 if(byte_idx >= data_len)
872 if((has_mouse_event) && (_mouse_callback !=
NULL))
874 _mouse_callback(hdev, &_mouse_event);
NuMicro peripheral access layer header file.
#define USBH_ERR_NOT_SUPPORTED
#define USBH_ERR_MEMORY_OUT
int32_t usbh_hid_get_report_descriptor(struct usbhid_dev *hdev, uint8_t *desc_buf, int buf_max_len)
int32_t usbh_hid_set_report(struct usbhid_dev *hdev, int rtp_typ, int rtp_id, uint8_t *data, int len)
HIDDEN_SYMBOLS struct usbhid_dev HID_DEV_T
USB Host library header file.
USB Host HID class driver header file.
USB Host library exported header file.