23static int hid_parse_item(
HID_DEV_T *hdev, uint8_t *buff);
32static const struct string_table usage_page_list[] =
34 "Generic Desktop", UP_GENERIC_DESKTOP,
35 "Simulation Controls", UP_SIMULATION_CONTROLS,
36 "VR Controls", UP_VR_CONTROLS,
37 "Sport Controls", UP_SPORT_CONTROLS,
38 "Game Controls", UP_GAME_CONTROLS,
39 "KeyCode", UP_KEYCODE,
42 "Digitizer", UP_DIGITIZER,
43 "Bar Code Scanner", UP_BARCODE_SCANNER,
46static const struct string_table desktop_page_list[] =
48 "Pointer", USAGE_ID_POINTER,
49 "Mouse", USAGE_ID_MOUSE,
50 "Joystick", USAGE_ID_JOYSTICK,
51 "Game Pad", USAGE_ID_GAMEPAD,
52 "Keyboard", USAGE_ID_KEYBOARD,
53 "Keypad", USAGE_ID_KEYPAD,
62 "Wheel", USAGE_ID_WHEEL,
71static RP_INFO_T _rp_info;
73static uint8_t _data_usages[16];
74static int _data_usage_cnt;
76static void print_usage_page(
void)
81 for (i = 0; i <
sizeof(usage_page_list)/
sizeof(
struct string_table); i++)
83 if (usage_page_list[i].code == _rp_info.usage_page)
85 printf(
"(%s)", usage_page_list[i].
string);
89 printf(
"(?? - 0x%x)", _rp_info.usage_page);
93static void print_usage(uint8_t usage)
97 struct string_table *p;
99 if (_rp_info.usage_page == UP_GENERIC_DESKTOP)
101 count =
sizeof(desktop_page_list)/
sizeof(
struct string_table);
102 p = (
struct string_table *)&desktop_page_list[0];
107 for (i = 0; i < count; i++, p++)
109 if (p->code == usage)
111 printf(
"(%s)", p->string);
115 printf(
"(?? - 0x%x)", usage);
119static void read_main_item_status(uint8_t *buff)
124 _rp_info.status.constant = 1;
125 _rp_info.status.variable = 0;
126 HID_DBGMSG(
"Constant ");
130 _rp_info.status.constant = 0;
131 _rp_info.status.variable = 1;
132 HID_DBGMSG(
"Variable ");
136 _rp_info.status.relative = 1;
137 HID_DBGMSG(
"Relative ");
141 _rp_info.status.wrap = 1;
146 _rp_info.status.non_linear = 1;
147 HID_DBGMSG(
"Non-linear ");
151 _rp_info.status.no_preferred = 1;
152 HID_DBGMSG(
"Not-prefered ");
156 _rp_info.status.null_state = 1;
157 HID_DBGMSG(
"Null-state ");
161 _rp_info.status.is_volatile = 1;
162 HID_DBGMSG(
"Volatile ");
166 _rp_info.status.buffered_bytes = 1;
167 HID_DBGMSG(
"Buffered-bytes ");
181int hid_parse_report_descriptor(
HID_DEV_T *hdev, IFACE_T *iface)
183 UDEV_T *udev = iface->udev;
189 int desc_buff_len, remain_len, size;
191 HID_DBGMSG(
"HID interface %d parsing report descriptor...\n", iface->if_num);
193 memset(&_rp_info, 0,
sizeof(_rp_info));
196 hdev->rpd.has_report_id = 0;
198 bptr = udev->cfd_buff;
199 config = (DESC_CONF_T *)bptr;
202 bptr += config->bLength;
203 size = config->wTotalLength - config->bLength;
208 while (size >=
sizeof(DESC_IF_T))
210 ifd = (DESC_IF_T *)bptr;
212 if ((ifd->bDescriptorType == USB_DT_INTERFACE) && (ifd->bInterfaceNumber == iface->if_num) &&
213 (ifd->bInterfaceClass == USB_CLASS_HID))
216 if (ifd->bLength == 0)
219 bptr += ifd->bLength;
220 size -= ifd->bLength;
223 if (size <
sizeof(DESC_IF_T))
225 HID_ERRMSG(
"Can't find the HID interface!\n");
229 bptr += ifd->bLength;
230 size -= ifd->bLength;
235 while (size >=
sizeof(DESC_HID_T))
237 hidd = (DESC_HID_T *)bptr;
239 if ((hidd->bDescriptorType == HID_DESCRIPTOR_TYPE) &&
240 (hidd->bRPDescType == REPORT_DESCRIPTOR_TYPE))
243 if (hidd->bLength == 0)
246 bptr += ifd->bLength;
247 size -= ifd->bLength;
250 if (size <
sizeof(DESC_HID_T))
252 HID_ERRMSG(
"Can't find the HID interface!\n");
256 hidd = (DESC_HID_T *)bptr;
258 HID_DBGMSG(
"[HID Descriptor]\n");
259 HID_DBGMSG(
"bLength = %d\n", hidd->bLength);
260 HID_DBGMSG(
"bDescriptorType = 0x%x\n", hidd->bDescriptorType);
261 HID_DBGMSG(
"bcdHID = 0x%x\n", hidd->bcdHID);
262 HID_DBGMSG(
"bCountryCode = 0x%x\n", hidd->bCountryCode);
263 HID_DBGMSG(
"bNumDescriptors = %d\n", hidd->bNumDescriptors);
264 HID_DBGMSG(
"bRPDescType = 0x%x\n", hidd->bRPDescType);
265 HID_DBGMSG(
"wDescriptorLength = %d\n", hidd->wDescriptorLength);
267 HID_DBGMSG(
"Report descriptor found, length=%d. %d\n", hidd->wDescriptorLength, hidd->bLength);
269 desc_buff_len = hidd->wDescriptorLength+8;
270 desc_buff = (uint8_t *)usbh_alloc_mem(desc_buff_len);
275 usbh_free_mem(desc_buff, desc_buff_len);
286 while (remain_len > 0)
288 size = hid_parse_item(hdev, bptr);
292 usbh_free_mem(desc_buff, desc_buff_len);
300 usbh_free_mem(desc_buff, desc_buff_len);
305 if ((hdev->bSubClassCode == HID_SUBCLASS_BOOT_DEVICE) && (hdev->bProtocolCode == HID_PROTOCOL_KEYBOARD))
309 for (report = hdev->rpd.report; report !=
NULL; report = report->next)
311 if ((report->usage_page == UP_LEDS) && (report->report_size == 1) && report->status.variable)
313 uint8_t i, ret, leds = 0;
315 for (i = 0; (i < 8) && (i < report->report_count); i++)
316 leds = (leds << 1) | 0x1;
322 HID_ERRMSG(
"Failed to turn on LEDs! 0x%x, %d\n", leds, ret);
332 HID_ERRMSG(
"Failed to turn off LEDs! %d\n", ret);
341static int hid_add_report(
HID_DEV_T *hdev, uint8_t type)
343 RP_INFO_T *report, *p;
345 report = (RP_INFO_T *)usbh_alloc_mem(
sizeof(RP_INFO_T));
348 HID_ERRMSG(
"hid_add_report allocate memory failed!!\n");
351 memcpy(report, &_rp_info,
sizeof(RP_INFO_T));
354 HID_DBGMSG(
"\nCreate a report. %d x %d (%d)\n", report->report_count, report->report_size, report->report_id);
356 if (hdev->rpd.report ==
NULL)
357 hdev->rpd.report = report;
360 p = hdev->rpd.report;
361 while (p->next !=
NULL)
368static signed int hid_read_item_value(uint8_t bSize, uint8_t *buff)
371 return (
signed char)buff[0];
373 return (
signed short)(buff[0] | (buff[1]<<8));
375 return (
signed int)(buff[0] | (buff[1]<<8) | (buff[2]<<16) | (buff[3]<<24));
381static int hid_parse_item(
HID_DEV_T *hdev, uint8_t *buff)
383 uint8_t bTag, bSize, tag;
386 bTag = (buff[0] >> 4) & 0xF;
388 bSize = buff[0] & 0x3;
389 tag = (buff[0] & 0xFC);
404 for (i = 0; i < item_len; i++)
406 printf(
"%02x ", buff[i]);
418 HID_DBGMSG(
"Input ");
419 read_main_item_status(&buff[1]);
420 if (_data_usage_cnt > 0)
422 int report_count = _rp_info.report_count;
424 for (i = 0; i < _data_usage_cnt; i++)
426 _rp_info.report_count = 1;
427 _rp_info.data_usage = _data_usages[i];
428 if (hid_add_report(hdev, TAG_INPUT) != 0)
432 _rp_info.report_count = report_count;
433 _rp_info.data_usage = 0;
436 if (_rp_info.report_count > 0)
438 if (hid_add_report(hdev, TAG_INPUT) != 0)
444 HID_DBGMSG(
"Output ");
445 read_main_item_status(&buff[1]);
446 if (_rp_info.report_count > 0)
448 if (hid_add_report(hdev, TAG_OUTPUT) != 0)
454 HID_DBGMSG(
"Feature ");
455 read_main_item_status(&buff[1]);
459 HID_DBGMSG(
"Collection ");
461 HID_DBGMSG(
"Physical");
462 else if (buff[1] == 0x01)
463 HID_DBGMSG(
"Application");
464 else if (buff[1] == 0x02)
465 HID_DBGMSG(
"Logical");
468 case TAG_END_COLLECTION:
469 HID_DBGMSG(
"End Collection");
477 HID_DBGMSG(
"Usage Page ");
478 _rp_info.usage_page = buff[1];
482 case TAG_LOGICAL_MIN:
483 _rp_info.logical_min = hid_read_item_value(bSize, &buff[1]);
484 HID_DBGMSG(
"Logical Minimum (%d)", _rp_info.logical_min);
487 case TAG_LOGICAL_MAX:
488 _rp_info.logical_max = hid_read_item_value(bSize, &buff[1]);
489 HID_DBGMSG(
"Logical Maximum (%d)", _rp_info.logical_max);
492 case TAG_PHYSICAL_MIN:
493 _rp_info.physical_min = hid_read_item_value(bSize, &buff[1]);
494 HID_DBGMSG(
"Physical Minimum (%d)", _rp_info.physical_min);
497 case TAG_PHYSICAL_MAX:
498 _rp_info.physical_max = hid_read_item_value(bSize, &buff[1]);
499 HID_DBGMSG(
"Physical Maximum (%d)", _rp_info.physical_max);
502 case TAG_UNIT_EXPONENT:
503 _rp_info.unit_exponent = hid_read_item_value(bSize, &buff[1]);
504 HID_DBGMSG(
"Unit Exponent (%d)", _rp_info.unit_exponent);
508 _rp_info.unit = hid_read_item_value(bSize, &buff[1]);
509 HID_DBGMSG(
"Unit (%d)", _rp_info.unit);
512 case TAG_REPORT_SIZE:
513 _rp_info.report_size = buff[1];
514 HID_DBGMSG(
"Report Size (%d)", _rp_info.report_size);
518 _rp_info.report_id = buff[1];
519 hdev->rpd.has_report_id = 1;
520 HID_DBGMSG(
"Report ID (%d)", _rp_info.report_id);
523 case TAG_REPORT_COUNT:
524 _rp_info.report_count = buff[1];
525 HID_DBGMSG(
"Report Count (%d)", _rp_info.report_count);
541 if ((buff[1] == USAGE_ID_X) || (buff[1] == USAGE_ID_Y) || (buff[1] == USAGE_ID_WHEEL))
542 _data_usages[_data_usage_cnt++] = buff[1];
544 _rp_info.app_usage = buff[1];
545 HID_DBGMSG(
"Usage ");
546 print_usage(buff[1]);
550 _rp_info.usage_mim = hid_read_item_value(bSize, &buff[1]);
551 HID_DBGMSG(
"Usage Mimimum (%d)", _rp_info.usage_mim);
555 _rp_info.usage_max = hid_read_item_value(bSize, &buff[1]);
556 HID_DBGMSG(
"Usage Maximum (%d)", _rp_info.usage_max);
559 case TAG_DESIGNATOR_INDEX:
560 _rp_info.designator_index = hid_read_item_value(bSize, &buff[1]);
561 HID_DBGMSG(
"Designator Index (%d)", _rp_info.designator_index);
564 case TAG_DESIGNATOR_MIN:
565 _rp_info.designator_min = hid_read_item_value(bSize, &buff[1]);
566 HID_DBGMSG(
"Designator Minimum (%d)", _rp_info.designator_min);
569 case TAG_DESIGNATOR_MAX:
570 _rp_info.designator_max = hid_read_item_value(bSize, &buff[1]);
571 HID_DBGMSG(
"Designator Maximum (%d)", _rp_info.designator_max);
574 case TAG_STRING_INDEX:
575 _rp_info.string_index = hid_read_item_value(bSize, &buff[1]);
576 HID_DBGMSG(
"String Index (%d)", _rp_info.string_index);
580 _rp_info.string_min = hid_read_item_value(bSize, &buff[1]);
581 HID_DBGMSG(
"String Minimum (%d)", _rp_info.string_min);
585 _rp_info.string_max = hid_read_item_value(bSize, &buff[1]);
586 HID_DBGMSG(
"String Maximum (%d)", _rp_info.string_max);
590 HID_DBGMSG(
"Delimiter");
594 HID_DBGMSG(
"Unknow tag: 0x%x\n", tag);
603int hid_parse_keyboard_reports(
HID_DEV_T *hdev, uint8_t *data,
int data_len)
607 int byte_idx = 0, bit_idx = 0;
608 int has_kbd_event = 0;
612 memset(&_keyboard_event, 0,
sizeof(_keyboard_event));
613 _keyboard_event.
lock_state = hdev->rpd.lock_state;
618 if (hdev->rpd.has_report_id && (byte_idx == 0))
625 for (report = hdev->rpd.report; report !=
NULL; report = report->next)
627 if (hdev->rpd.has_report_id && (report->report_id != report_id))
630 if (report->type != TAG_INPUT)
636 if ((report->usage_page == UP_KEYCODE) && (report->app_usage == USAGE_ID_KEYBOARD))
640 if ((report->report_size != 1) && (report->report_size != 8))
643 HID_ERRMSG(
"Keycode report size %d is not supported!\n", report->report_size);
647 if (report->report_size == 1)
650 for (i = 0; i < report->report_count; i++)
652 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
653 usage_val |= (bit << i);
657 _keyboard_event.
modifier |= usage_val;
659 else if (bit_idx < 16)
665 _keyboard_event.
keycode[(bit_idx-16)/8] |= usage_val;
669 byte_idx = (bit_idx / 8);
673 for (i = 0; i < report->report_count; i++)
677 _keyboard_event.
modifier = data[byte_idx];
679 else if (byte_idx == 1)
687 _keyboard_event.
keycode[byte_idx-2] = data[byte_idx];
698 bit_idx += report->report_size * report->report_count;
699 byte_idx = (bit_idx / 8);
702 if (byte_idx >= data_len)
706 if ((has_kbd_event) && (_keyboard_callback !=
NULL))
708 uint8_t pressed_lock_keys = 0;
709 char update_LEDs = 0;
714 for (i = 0; i < 6; i++)
716 switch (_keyboard_event.
keycode[i])
718 case KEYCODE_NUM_LOCK:
719 pressed_lock_keys |= STATE_MASK_NUM_LOCK;
721 case KEYCODE_CAPS_LOCK:
722 pressed_lock_keys |= STATE_MASK_CAPS_LOCK;
724 case KEYCODE_SCROLL_LOCK:
725 pressed_lock_keys |= STATE_MASK_SCROLL_LOCK;
739 for (i = 0; i < 3; i++)
741 if ((pressed_lock_keys & (1<<i)) && (!(hdev->rpd.last_pressed_lock_keys & (1<<i))))
751 hdev->rpd.last_pressed_lock_keys = pressed_lock_keys;
752 hdev->rpd.lock_state = _keyboard_event.
lock_state;
759 _keyboard_callback(hdev, &_keyboard_event);
764int hid_parse_mouse_reports(
HID_DEV_T *hdev, uint8_t *data,
int data_len)
766 int byte_idx = 0, bit_idx = 0;
769 int has_mouse_event = 0;
773 memset(&_mouse_event, 0,
sizeof(_mouse_event));
778 if (hdev->rpd.has_report_id && (byte_idx == 0))
785 for (report = hdev->rpd.report; report !=
NULL; report = report->next)
787 if (hdev->rpd.has_report_id && (report->report_id != report_id))
790 if (report->type != TAG_INPUT)
796 if ((report->usage_page == UP_BUTTON) &&
797 ((report->app_usage == USAGE_ID_MOUSE) || (report->app_usage == USAGE_ID_POINTER)))
800 if (report->status.variable)
802 _mouse_event.
button_cnt = report->report_count;
803 for (i = 0; i < report->report_count; i++)
805 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
807 bit_idx += report->report_size;
808 byte_idx = (bit_idx / 8);
814 bit_idx += report->report_count * report->report_size;
815 byte_idx = (bit_idx / 8);
823 else if ((report->usage_page == UP_GENERIC_DESKTOP) &&
824 ((report->app_usage == USAGE_ID_MOUSE) || (report->app_usage == USAGE_ID_POINTER) ||
825 (report->data_usage == USAGE_ID_WHEEL)))
827 uint32_t usage_val = 0;
830 for (i = 0; i < report->report_size; i++)
832 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
833 usage_val |= (bit << i);
835 byte_idx = (bit_idx / 8);
838 if (report->report_size <= 8)
839 s_val = (
signed char)usage_val;
840 else if (report->report_size <= 16)
841 s_val = (
signed short)usage_val;
843 if (report->data_usage == USAGE_ID_X)
845 _mouse_event.
X = s_val;
846 _mouse_event.
X_raw = usage_val;
847 _mouse_event.
X_bits = report->report_size;
849 _mouse_event.
axis_min = report->logical_min;
850 _mouse_event.
axis_max = report->logical_max;
852 else if (report->data_usage == USAGE_ID_Y)
854 _mouse_event.
Y = s_val;
855 _mouse_event.
Y_raw = usage_val;
856 _mouse_event.
Y_bits = report->report_size;
858 else if (report->data_usage == USAGE_ID_WHEEL)
860 _mouse_event.
wheel = s_val;
862 _mouse_event.
wheel_bits = report->report_size;
864 _mouse_event.
wheel_min = report->logical_min;
865 _mouse_event.
wheel_max = report->logical_max;
872 bit_idx += report->report_size;
873 byte_idx = (bit_idx / 8);
876 if (byte_idx >= data_len)
880 if ((has_mouse_event) && (_mouse_callback !=
NULL))
882 _mouse_callback(hdev, &_mouse_event);
NuMicro peripheral access layer header file.
#define NULL
NULL pointer.
#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.