M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
hid_parser.c
Go to the documentation of this file.
1/**************************************************************************/
9#include <stdio.h>
10#include <string.h>
11
12#include "NuMicro.h"
13
14#include "usb.h"
15#include "usbh_lib.h"
16#include "usbh_hid.h"
17
18
20
21
22static int hid_parse_item(HID_DEV_T *hdev, uint8_t *buff);
23
24#if ENABLE_DBG_MSG
25struct string_table
26{
27 char string[32];
28 uint8_t code;
29};
30
31static const struct string_table usage_page_list[] =
32{
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,
39 "LEDs", UP_LEDS,
40 "Button", UP_BUTTON,
41 "Digitizer", UP_DIGITIZER,
42 "Bar Code Scanner", UP_BARCODE_SCANNER,
43};
44
45static const struct string_table desktop_page_list[] =
46{
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,
53 "X", USAGE_ID_X,
54 "Y", USAGE_ID_Y,
55 "Z", USAGE_ID_Z,
56 "Rx", 0x33,
57 "Ry", 0x34,
58 "Rz", 0x35,
59 "Slider", 0x36,
60 "Dial", 0x37,
61 "Wheel", USAGE_ID_WHEEL,
62};
63
64#endif
65
66
67/*
68 * Varibles used on parsing HID report descriptor
69 */
70static RP_INFO_T _rp_info; /* describing the current report */
71
72static uint8_t _data_usages[16];
73static int _data_usage_cnt;
74
75static void print_usage_page(void)
76{
77#if ENABLE_DBG_MSG
78 int i;
79
80 for(i = 0; i < sizeof(usage_page_list) / sizeof(struct string_table); i++)
81 {
82 if(usage_page_list[i].code == _rp_info.usage_page)
83 {
84 printf("(%s)", usage_page_list[i].string);
85 return;
86 }
87 }
88 printf("(?? - 0x%x)", _rp_info.usage_page);
89#endif
90}
91
92static void print_usage(uint8_t usage)
93{
94#if ENABLE_DBG_MSG
95 int i, count;
96 struct string_table *p;
97
98 if(_rp_info.usage_page == UP_GENERIC_DESKTOP)
99 {
100 count = sizeof(desktop_page_list) / sizeof(struct string_table);
101 p = (struct string_table *)&desktop_page_list[0];
102 }
103 else
104 return;
105
106 for(i = 0; i < count; i++, p++)
107 {
108 if(p->code == usage)
109 {
110 printf("(%s)", p->string);
111 return;
112 }
113 }
114 printf("(?? - 0x%x)", usage);
115#endif
116}
117
118static void read_main_item_status(uint8_t *buff)
119{
120 HID_DBGMSG("(");
121 if(buff[0] & 0x01)
122 {
123 _rp_info.status.constant = 1;
124 _rp_info.status.variable = 0;
125 HID_DBGMSG("Constant ");
126 }
127 if(buff[0] & 0x02)
128 {
129 _rp_info.status.constant = 0;
130 _rp_info.status.variable = 1;
131 HID_DBGMSG("Variable ");
132 }
133 if(buff[0] & 0x04)
134 {
135 _rp_info.status.relative = 1;
136 HID_DBGMSG("Relative ");
137 }
138 if(buff[0] & 0x08)
139 {
140 _rp_info.status.wrap = 1;
141 HID_DBGMSG("Wrap ");
142 }
143 if(buff[0] & 0x10)
144 {
145 _rp_info.status.non_linear = 1;
146 HID_DBGMSG("Non-linear ");
147 }
148 if(buff[0] & 0x20)
149 {
150 _rp_info.status.no_preferred = 1;
151 HID_DBGMSG("Not-prefered ");
152 }
153 if(buff[0] & 0x40)
154 {
155 _rp_info.status.null_state = 1;
156 HID_DBGMSG("Null-state ");
157 }
158 if(buff[0] & 0x80)
159 {
160 _rp_info.status.is_volatile = 1;
161 HID_DBGMSG("Volatile ");
162 }
163 if(buff[1] & 0x01)
164 {
165 _rp_info.status.buffered_bytes = 1;
166 HID_DBGMSG("Buffered-bytes ");
167 }
168 HID_DBGMSG(")");
169}
170
171
180int hid_parse_report_descriptor(HID_DEV_T *hdev, IFACE_T *iface)
181{
182 UDEV_T *udev = iface->udev;
183 DESC_CONF_T *config;
184 DESC_IF_T *ifd;
185 DESC_HID_T *hidd;
186 uint8_t *bptr;
187 uint8_t *desc_buff;
188 int desc_buff_len, remain_len, size;
189
190 HID_DBGMSG("HID interface %d parsing report descriptor...\n", iface->if_num);
191
192 memset(&_rp_info, 0, sizeof(_rp_info));
193 _data_usage_cnt = 0;
194
195 hdev->rpd.has_report_id = 0;
196
197 bptr = udev->cfd_buff;
198 config = (DESC_CONF_T *)bptr;
199
200 /* step over configuration descritpor */
201 bptr += config->bLength;
202 size = config->wTotalLength - config->bLength;
203
204 /*------------------------------------------------------------------------------------*/
205 /* Find the Interface Descriptor of this HID interface */
206 /*------------------------------------------------------------------------------------*/
207 while(size >= sizeof(DESC_IF_T))
208 {
209 ifd = (DESC_IF_T *)bptr;
210
211 if((ifd->bDescriptorType == USB_DT_INTERFACE) && (ifd->bInterfaceNumber == iface->if_num) &&
212 (ifd->bInterfaceClass == USB_CLASS_HID))
213 break;
214
215 if(ifd->bLength == 0)
216 return -1;
217
218 bptr += ifd->bLength;
219 size -= ifd->bLength;
220 }
221
222 if(size < sizeof(DESC_IF_T))
223 {
224 HID_ERRMSG("Can't find the HID interface!\n");
225 return HID_RET_PARSING;
226 }
227
228 bptr += ifd->bLength;
229 size -= ifd->bLength;
230
231 /*------------------------------------------------------------------------------------*/
232 /* Continue to find the subsequent HID Descriptor */
233 /*------------------------------------------------------------------------------------*/
234 while(size >= sizeof(DESC_HID_T))
235 {
236 hidd = (DESC_HID_T *)bptr;
237
238 if((hidd->bDescriptorType == HID_DESCRIPTOR_TYPE) &&
239 (hidd->bRPDescType == REPORT_DESCRIPTOR_TYPE))
240 break;
241
242 if(hidd->bLength == 0)
243 return HID_RET_PARSING;
244
245 bptr += ifd->bLength;
246 size -= ifd->bLength;
247 }
248
249 if(size < sizeof(DESC_HID_T))
250 {
251 HID_ERRMSG("Can't find the HID interface!\n");
252 return HID_RET_PARSING;
253 }
254
255 hidd = (DESC_HID_T *)bptr;
256
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);
265
266 HID_DBGMSG("Report descriptor found, length=%d. %d\n", hidd->wDescriptorLength, hidd->bLength);
267
268 desc_buff_len = hidd->wDescriptorLength + 8;
269 desc_buff = (uint8_t *)usbh_alloc_mem(desc_buff_len);
270
271 remain_len = usbh_hid_get_report_descriptor(hdev, desc_buff, desc_buff_len);
272 if(remain_len <= 0)
273 {
274 usbh_free_mem(desc_buff, desc_buff_len);
275 return remain_len;
276 }
277
278 //HID_DBGMSG("\nDump report descriptor =>\n");
279 //dump_buff_hex(desc_buff, remain_len);
280
281 /*------------------------------------------------------------------------------------*/
282 /* Parsing items */
283 /*------------------------------------------------------------------------------------*/
284 bptr = desc_buff;
285 while(remain_len > 0)
286 {
287 size = hid_parse_item(hdev, bptr);
288 //printf("size = %d/%d\n", size, remain_len);
289 if(size <= 0)
290 {
291 usbh_free_mem(desc_buff, desc_buff_len);
292 return HID_RET_PARSING;
293 }
294
295 bptr += size;
296 remain_len -= size;
297 }
298
299 usbh_free_mem(desc_buff, desc_buff_len);
300
301 /*------------------------------------------------------------------------------------*/
302 /* For keyboard device, turn on all LEDs for 0.5 seconds and then turn off. */
303 /*------------------------------------------------------------------------------------*/
304 if((hdev->bSubClassCode == HID_SUBCLASS_BOOT_DEVICE) && (hdev->bProtocolCode == HID_PROTOCOL_KEYBOARD))
305 {
306 RP_INFO_T *report;
307
308 for(report = hdev->rpd.report; report != NULL; report = report->next)
309 {
310 if((report->usage_page == UP_LEDS) && (report->report_size == 1) && report->status.variable)
311 {
312 uint8_t i, ret, leds = 0;
313
314 for(i = 0; (i < 8) && (i < report->report_count); i++)
315 leds = (leds << 1) | 0x1;
316
317 /* turn-on keyboard NumLock, CapsLock, ScrollLock LEDs */
318 ret = usbh_hid_set_report(hdev, RT_OUTPUT, 0, &leds, 1);
319 if(ret != 1)
320 {
321 HID_ERRMSG("Failed to turn on LEDs! 0x%x, %d\n", leds, ret);
322 }
323 else
324 {
325 delay_us(500000); /* delay 0.5 conds */
326
327 /* turn-off all LEDs */
328 leds = 0x00;
329 ret = usbh_hid_set_report(hdev, RT_OUTPUT, 0, &leds, 1);
330 if(ret != 1)
331 HID_ERRMSG("Failed to turn off LEDs! %d\n", ret);
332 }
333 }
334 }
335 }
336
337 return 0;
338}
339
340static int hid_add_report(HID_DEV_T *hdev, uint8_t type)
341{
342 RP_INFO_T *report, *p;
343
344 report = (RP_INFO_T *)usbh_alloc_mem(sizeof(RP_INFO_T));
345 if(report == NULL)
346 {
347 HID_ERRMSG("hid_add_report allocate memory failed!!\n");
348 return USBH_ERR_MEMORY_OUT;
349 }
350 memcpy(report, &_rp_info, sizeof(RP_INFO_T));
351 report->type = type;
352
353 HID_DBGMSG("\nCreate a report. %d x %d (%d)\n", report->report_count, report->report_size, report->report_id);
354
355 if(hdev->rpd.report == NULL)
356 hdev->rpd.report = report;
357 else
358 {
359 p = hdev->rpd.report;
360 while(p->next != NULL)
361 p = p->next;
362 p->next = report;
363 }
364 return 0;
365}
366
367static signed int hid_read_item_value(uint8_t bSize, uint8_t *buff)
368{
369 if(bSize == 1)
370 return (signed char)buff[0];
371 else if(bSize == 2)
372 return (signed short)(buff[0] | (buff[1] << 8));
373 else if(bSize == 4)
374 return (signed int)(buff[0] | (buff[1] << 8) | (buff[2] << 16) | (buff[3] << 24));
375 else
376 return 0;
377}
378
379
380static int hid_parse_item(HID_DEV_T *hdev, uint8_t *buff)
381{
382 uint8_t bTag, bSize, tag;
383 int item_len, i;
384
385 bTag = (buff[0] >> 4) & 0xF;
386 //bType = (buff[0] >> 2) & 0x3;
387 bSize = buff[0] & 0x3;
388 tag = (buff[0] & 0xFC);
389
390 if(bTag == 0xF)
391 {
392 bSize = buff[1];
393 item_len = bSize + 3;
394 }
395 else
396 {
397 if(bSize == 0x3)
398 bSize = 4;
399 item_len = bSize + 1;
400 }
401
402#if ENABLE_DBG_MSG
403 for(i = 0; i < item_len; i++)
404 {
405 printf("%02x ", buff[i]);
406 }
407 printf("- ");
408#endif
409
410 switch(tag)
411 {
412 /*------------------------------------------------------------------------------------*/
413 /* Main Item Tags */
414 /*------------------------------------------------------------------------------------*/
415
416 case TAG_INPUT:
417 HID_DBGMSG("Input ");
418 read_main_item_status(&buff[1]);
419 if(_data_usage_cnt > 0)
420 {
421 int report_count = _rp_info.report_count;
422
423 for(i = 0; i < _data_usage_cnt; i++)
424 {
425 _rp_info.report_count = 1;
426 _rp_info.data_usage = _data_usages[i];
427 if(hid_add_report(hdev, TAG_INPUT) != 0)
428 return USBH_ERR_MEMORY_OUT;
429 report_count--;
430 }
431 _rp_info.report_count = report_count;
432 _rp_info.data_usage = 0;
433 _data_usage_cnt = 0;
434 }
435 if(_rp_info.report_count > 0)
436 {
437 if(hid_add_report(hdev, TAG_INPUT) != 0)
438 return USBH_ERR_MEMORY_OUT;
439 }
440 break;
441
442 case TAG_OUTPUT:
443 HID_DBGMSG("Output ");
444 read_main_item_status(&buff[1]);
445 if(_rp_info.report_count > 0)
446 {
447 if(hid_add_report(hdev, TAG_OUTPUT) != 0)
448 return USBH_ERR_MEMORY_OUT;
449 }
450 break;
451
452 case TAG_FEATURE:
453 HID_DBGMSG("Feature ");
454 read_main_item_status(&buff[1]);
455 break;
456
457 case TAG_COLLECTION:
458 HID_DBGMSG("Collection ");
459 if(buff[1] == 0x00)
460 HID_DBGMSG("Physical");
461 else if(buff[1] == 0x01)
462 HID_DBGMSG("Application");
463 else if(buff[1] == 0x02)
464 HID_DBGMSG("Logical");
465 break;
466
467 case TAG_END_COLLECTION:
468 HID_DBGMSG("End Collection");
469 break;
470
471 /*------------------------------------------------------------------------------------*/
472 /* Global Item Tags */
473 /*------------------------------------------------------------------------------------*/
474
475 case TAG_USAGE_PAGE:
476 HID_DBGMSG("Usage Page ");
477 _rp_info.usage_page = buff[1];
478 print_usage_page();
479 break;
480
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);
484 break;
485
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);
489 break;
490
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);
494 break;
495
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);
499 break;
500
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);
504 break;
505
506 case TAG_UNIT:
507 _rp_info.unit = hid_read_item_value(bSize, &buff[1]);
508 HID_DBGMSG("Unit (%d)", _rp_info.unit);
509 break;
510
511 case TAG_REPORT_SIZE:
512 _rp_info.report_size = buff[1];
513 HID_DBGMSG("Report Size (%d)", _rp_info.report_size);
514 break;
515
516 case TAG_REPORT_ID:
517 _rp_info.report_id = buff[1];
518 hdev->rpd.has_report_id = 1;
519 HID_DBGMSG("Report ID (%d)", _rp_info.report_id);
520 break;
521
522 case TAG_REPORT_COUNT:
523 _rp_info.report_count = buff[1];
524 HID_DBGMSG("Report Count (%d)", _rp_info.report_count);
525 break;
526
527 case TAG_PUSH:
528 HID_DBGMSG("PUSH");
529 break;
530
531 case TAG_POP:
532 HID_DBGMSG("POP");
533 break;
534
535 /*------------------------------------------------------------------------------------*/
536 /* Local Item Tags */
537 /*------------------------------------------------------------------------------------*/
538
539 case TAG_USAGE:
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]; /* interested usages */
542 else
543 _rp_info.app_usage = buff[1];
544 HID_DBGMSG("Usage ");
545 print_usage(buff[1]);
546 break;
547
548 case TAG_USAGE_MIN:
549 _rp_info.usage_mim = hid_read_item_value(bSize, &buff[1]);
550 HID_DBGMSG("Usage Mimimum (%d)", _rp_info.usage_mim);
551 break;
552
553 case TAG_USAGE_MAX:
554 _rp_info.usage_max = hid_read_item_value(bSize, &buff[1]);
555 HID_DBGMSG("Usage Maximum (%d)", _rp_info.usage_max);
556 break;
557
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);
561 break;
562
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);
566 break;
567
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);
571 break;
572
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);
576 break;
577
578 case TAG_STRING_MIN:
579 _rp_info.string_min = hid_read_item_value(bSize, &buff[1]);
580 HID_DBGMSG("String Minimum (%d)", _rp_info.string_min);
581 break;
582
583 case TAG_STRING_MAX:
584 _rp_info.string_max = hid_read_item_value(bSize, &buff[1]);
585 HID_DBGMSG("String Maximum (%d)", _rp_info.string_max);
586 break;
587
588 case TAG_DELIMITER:
589 HID_DBGMSG("Delimiter");
590 break;
591
592 default:
593 HID_DBGMSG("Unknow tag: 0x%x\n", tag);
594 break;
595 }
596 HID_DBGMSG("\n");
597
598 return item_len;
599}
600
601
602int hid_parse_keyboard_reports(HID_DEV_T *hdev, uint8_t *data, int data_len)
603{
604 RP_INFO_T *report;
605 int i, bit;
606 int byte_idx = 0, bit_idx = 0;
607 int has_kbd_event = 0;
608 int report_id;
609 static KEYBOARD_EVENT_T _keyboard_event;
610
611 memset(&_keyboard_event, 0, sizeof(_keyboard_event));
612 _keyboard_event.lock_state = hdev->rpd.lock_state;
613
614 /*
615 * Does this device use report ID?
616 */
617 if(hdev->rpd.has_report_id && (byte_idx == 0))
618 {
619 report_id = data[0];
620 bit_idx = 8;
621 byte_idx = 1;
622 }
623
624 for(report = hdev->rpd.report; report != NULL; report = report->next)
625 {
626 if(hdev->rpd.has_report_id && (report->report_id != report_id))
627 continue;
628
629 if(report->type != TAG_INPUT)
630 continue;
631
632 /*----------------------------------------------------------------------*/
633 /* Extract keyboard report; only KeyCode reports are interested */
634 /*----------------------------------------------------------------------*/
635 if((report->usage_page == UP_KEYCODE) && (report->app_usage == USAGE_ID_KEYBOARD))
636 {
637 uint32_t usage_val;
638
639 if((report->report_size != 1) && (report->report_size != 8))
640 {
641 /* unlikely! seems violate HID spec. */
642 HID_ERRMSG("Keycode report size %d is not supported!\n", report->report_size);
644 }
645
646 if(report->report_size == 1)
647 {
648 usage_val = 0;
649 for(i = 0; i < report->report_count; i++)
650 {
651 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
652 usage_val |= (bit << i);
653
654 if(bit_idx < 8) /* is in the first byte */
655 {
656 _keyboard_event.modifier |= usage_val;
657 }
658 else if(bit_idx < 16) /* is in the second byte (reserved) */
659 {
660 }
661 else
662 {
663 if(bit_idx < 8 * 8)
664 _keyboard_event.keycode[(bit_idx - 16) / 8] |= usage_val;
665 }
666 bit_idx++;
667 }
668 byte_idx = (bit_idx / 8);
669 }
670 else /* report->report_size == 8 */
671 {
672 for(i = 0; i < report->report_count; i++)
673 {
674 if(byte_idx == 0)
675 {
676 _keyboard_event.modifier = data[byte_idx];
677 }
678 else if(byte_idx == 1)
679 {
680 /* reserved byte */
681 }
682 else
683 {
684 if(byte_idx < 8)
685 {
686 _keyboard_event.keycode[byte_idx - 2] = data[byte_idx];
687 }
688 }
689 byte_idx++;
690 }
691 }
692 has_kbd_event = 1;
693 }
694 else
695 {
696 /* not interested, just skip it */
697 bit_idx += report->report_size * report->report_count;
698 byte_idx = (bit_idx / 8);
699 }
700
701 if(byte_idx >= data_len)
702 break;
703 }
704
705 if((has_kbd_event) && (_keyboard_callback != NULL))
706 {
707 uint8_t pressed_lock_keys = 0;
708 char update_LEDs = 0;
709
710 /*----------------------------------------------------------------------*/
711 /* Scan received key code sequence */
712 /*----------------------------------------------------------------------*/
713 for(i = 0; i < 6; i++)
714 {
715 switch(_keyboard_event.keycode[i])
716 {
717 case KEYCODE_NUM_LOCK:
718 pressed_lock_keys |= STATE_MASK_NUM_LOCK;
719 break;
720 case KEYCODE_CAPS_LOCK:
721 pressed_lock_keys |= STATE_MASK_CAPS_LOCK;
722 break;
723 case KEYCODE_SCROLL_LOCK:
724 pressed_lock_keys |= STATE_MASK_SCROLL_LOCK;
725 break;
726 case 0: /* empty */
727 case 1: /* error */
728 break;
729
730 default:
731 _keyboard_event.keycode[_keyboard_event.key_cnt++] = _keyboard_event.keycode[i];
732 }
733 }
734
735 /*----------------------------------------------------------------------*/
736 /* Update lock keys (Num Lock, Caps Lock, Scroll Lock) */
737 /*----------------------------------------------------------------------*/
738 for(i = 0; i < 3; i++)
739 {
740 if((pressed_lock_keys & (1 << i)) && (!(hdev->rpd.last_pressed_lock_keys & (1 << i))))
741 {
742 /*
743 * A lock key pressed and it is not pressed in the last time.
744 * It should be a press down of the lock key.
745 */
746 _keyboard_event.lock_state ^= (1 << i); /* switch on/off the corresponding lock state */
747 update_LEDs = 1;
748 }
749 }
750 hdev->rpd.last_pressed_lock_keys = pressed_lock_keys; /* record the lock key press state for next time. */
751 hdev->rpd.lock_state = _keyboard_event.lock_state;
752
753 if(update_LEDs)
754 {
755 usbh_hid_set_report_non_blocking(hdev, RT_OUTPUT, 0, &_keyboard_event.lock_state, 1);
756 }
757
758 _keyboard_callback(hdev, &_keyboard_event);
759 }
760 return 0;
761}
762
763int hid_parse_mouse_reports(HID_DEV_T *hdev, uint8_t *data, int data_len)
764{
765 int byte_idx = 0, bit_idx = 0;
766 RP_INFO_T *report;
767 int i, bit;
768 int has_mouse_event = 0;
769 int report_id;
770 static MOUSE_EVENT_T _mouse_event;
771
772 memset(&_mouse_event, 0, sizeof(_mouse_event));
773
774 /*
775 * Does this device use report ID?
776 */
777 if(hdev->rpd.has_report_id && (byte_idx == 0))
778 {
779 report_id = data[0];
780 bit_idx = 8;
781 byte_idx = 1;
782 }
783
784 for(report = hdev->rpd.report; report != NULL; report = report->next)
785 {
786 if(hdev->rpd.has_report_id && (report->report_id != report_id))
787 continue;
788
789 if(report->type != TAG_INPUT)
790 continue;
791
792 /*----------------------------------------------------------------------*/
793 /* Extract mouse button report */
794 /*----------------------------------------------------------------------*/
795 if((report->usage_page == UP_BUTTON) &&
796 ((report->app_usage == USAGE_ID_MOUSE) || (report->app_usage == USAGE_ID_POINTER)))
797 {
798 /* Get button data */
799 if(report->status.variable)
800 {
801 _mouse_event.button_cnt = report->report_count;
802 for(i = 0; i < report->report_count; i++)
803 {
804 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
805 _mouse_event.button_map |= (bit << i);
806 bit_idx += report->report_size;
807 byte_idx = (bit_idx / 8);
808 }
809 }
810 else
811 {
812 /* ignore constant padding bits */
813 bit_idx += report->report_count * report->report_size;
814 byte_idx = (bit_idx / 8);
815 }
816 has_mouse_event = 1;
817 }
818
819 /*----------------------------------------------------------------------*/
820 /* Extract mouse X, Y, and WHEEL reports */
821 /*----------------------------------------------------------------------*/
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)))
825 {
826 signed int usage_val = 0;
827
828 for(i = 0; i < report->report_size; i++)
829 {
830 bit = (data[byte_idx] >> (bit_idx % 8)) & 0x1;
831 usage_val |= (bit << i);
832 bit_idx++;
833 byte_idx = (bit_idx / 8);
834 }
835
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;
840
841 if(report->data_usage == USAGE_ID_X)
842 {
843 _mouse_event.X = usage_val;
844 _mouse_event.axis_relative = report->status.relative;
845 _mouse_event.axis_min = report->logical_min;
846 _mouse_event.axis_max = report->logical_max;
847 }
848 else if(report->data_usage == USAGE_ID_Y)
849 {
850 _mouse_event.Y = usage_val;
851 }
852 else if(report->data_usage == USAGE_ID_WHEEL)
853 {
854 _mouse_event.wheel = usage_val;
855 _mouse_event.wheel_relative = report->status.relative;
856 _mouse_event.wheel_min = report->logical_min;
857 _mouse_event.wheel_max = report->logical_max;
858 }
859 has_mouse_event = 1;
860 }
861 else
862 {
863 /* not supported, just skip it */
864 bit_idx += report->report_size;
865 byte_idx = (bit_idx / 8);
866 }
867
868 if(byte_idx >= data_len)
869 break;
870 }
871
872 if((has_mouse_event) && (_mouse_callback != NULL))
873 {
874 _mouse_callback(hdev, &_mouse_event);
875 // HID_DBGMSG("X: %d, Y: %d, W: %d, button: 0x%x\n", _mouse_event.X, _mouse_event.Y, _mouse_event.wheel, _mouse_event.button_map);
876 }
877
878 return 0;
879}
880
881
883
884
NuMicro peripheral access layer header file.
#define NULL
Definition: M471M_R1_S.h:13908
#define USBH_ERR_NOT_SUPPORTED
Definition: usbh_lib.h:34
#define RT_OUTPUT
Definition: usbh_hid.h:164
#define USBH_ERR_MEMORY_OUT
Definition: usbh_lib.h:31
#define HID_RET_PARSING
Definition: usbh_lib.h:91
signed int wheel_min
Definition: usbh_hid.h:307
signed int Y
Definition: usbh_hid.h:306
uint8_t keycode[6]
Definition: usbh_hid.h:288
uint32_t button_map
Definition: usbh_hid.h:302
int32_t usbh_hid_get_report_descriptor(struct usbhid_dev *hdev, uint8_t *desc_buf, int buf_max_len)
uint8_t button_cnt
Definition: usbh_hid.h:301
uint8_t wheel_relative
Definition: usbh_hid.h:300
signed int wheel
Definition: usbh_hid.h:309
signed int axis_min
Definition: usbh_hid.h:303
signed int wheel_max
Definition: usbh_hid.h:308
uint8_t axis_relative
Definition: usbh_hid.h:299
int32_t usbh_hid_set_report(struct usbhid_dev *hdev, int rtp_typ, int rtp_id, uint8_t *data, int len)
signed int axis_max
Definition: usbh_hid.h:304
signed int X
Definition: usbh_hid.h:305
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.