Skip to content

Commit d9be4fc

Browse files
committed
feat(class/hid/usbh_hid): add usbh_hid_report_convert api
Signed-off-by: sakumisu <1203593632@qq.com>
1 parent 904b4ca commit d9be4fc

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

class/hid/usbh_hid.c

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -435,11 +435,58 @@ int usbh_hid_parse_report_descriptor(const uint8_t *report_data, uint32_t report
435435
return -1;
436436
}
437437

438+
int usbh_hid_report_convert(struct usbh_hid_report_item *item, const uint8_t *report_buf, uint32_t *output1, uint8_t **output2, uint32_t *output_len)
439+
{
440+
const uint8_t *src;
441+
uint32_t bits_len = item->attribute.report_size * item->attribute.report_count;
442+
443+
if(bits_len == 0) {
444+
return -1;
445+
}
446+
447+
if (item->report_flags & HID_MAINITEM_CONSTANT) {
448+
return -1;
449+
}
450+
451+
if (item->attribute.report_id > 0) {
452+
if (report_buf[0] != item->attribute.report_id) {
453+
return -2; /* report id mismatch */
454+
}
455+
456+
src = report_buf + 1; /* skip report id */
457+
} else {
458+
src = report_buf;
459+
}
460+
461+
if ((bits_len < 32) && (bits_len % 8 != 0)) {
462+
*output1 = 0;
463+
464+
for (uint32_t i = 0; i < bits_len; i++) {
465+
*output1 |= ((src[item->report_bit_offset / 8] >> ((item->report_bit_offset % 8) + i)) & 0x01) << i;
466+
}
467+
468+
*output2 = NULL;
469+
*output_len = 1;
470+
return 0;
471+
} else if (bits_len % 8 == 0) {
472+
if (item->report_bit_offset % 8 != 0) {
473+
/* currently do not support item that is not byte aligned */
474+
return -3;
475+
}
476+
477+
uint32_t byte_len = bits_len / 8;
478+
*output2 = (uint8_t *)src + item->report_bit_offset / 8;
479+
*output_len = byte_len;
480+
return 0;
481+
}
482+
return -4;
483+
}
484+
438485
static void usbh_hid_item_info_print(struct usbh_hid_report_item *item)
439486
{
440487
USB_LOG_RAW("Item Type: %s\r\n", (unsigned int)item->report_type == HID_REPORT_INPUT ? "Input" :
441488
(unsigned int)item->report_type == HID_REPORT_OUTPUT ? "Output" :
442-
"Feature");
489+
"Feature");
443490
USB_LOG_RAW("Usage Page: 0x%04x\r\n", (unsigned int)item->attribute.usage_page);
444491
USB_LOG_RAW("Report ID: 0x%04x\r\n", (unsigned int)item->attribute.report_id);
445492
USB_LOG_RAW("Report Size: %ubit\r\n", (unsigned int)item->attribute.report_size);
@@ -452,7 +499,7 @@ static void usbh_hid_item_info_print(struct usbh_hid_report_item *item)
452499
USB_LOG_RAW("\r\n");
453500
}
454501

455-
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_buf[2048];
502+
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_desc_buf[2048];
456503

457504
int lshid(int argc, char **argv)
458505
{
@@ -471,18 +518,18 @@ int lshid(int argc, char **argv)
471518
return -1;
472519
}
473520

474-
if (hid_class->report_size > sizeof(g_hid_report_buf)) {
521+
if (hid_class->report_size > sizeof(g_hid_report_desc_buf)) {
475522
USB_LOG_ERR("hid report buffer is too small\r\n");
476523
return -1;
477524
}
478525

479-
ret = usbh_hid_get_report_descriptor(hid_class, g_hid_report_buf, hid_class->report_size);
526+
ret = usbh_hid_get_report_descriptor(hid_class, g_hid_report_desc_buf, hid_class->report_size);
480527
if (ret < 0) {
481528
USB_LOG_ERR("get hid report descriptor failed, errcode: %d\r\n", ret);
482529
return -1;
483530
}
484531

485-
ret = usbh_hid_parse_report_descriptor(g_hid_report_buf, hid_class->report_size, &report_info);
532+
ret = usbh_hid_parse_report_descriptor(g_hid_report_desc_buf, hid_class->report_size, &report_info);
486533
if (ret < 0) {
487534
USB_LOG_ERR("parse hid report descriptor failed\r\n");
488535
return -1;

class/hid/usbh_hid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
7070
int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen);
7171

7272
int usbh_hid_parse_report_descriptor(const uint8_t *report_data, uint32_t report_size, struct usbh_hid_report_info *report_info);
73+
int usbh_hid_report_convert(struct usbh_hid_report_item *item, const uint8_t *report_buf, uint32_t *output1, uint8_t **output2, uint32_t *output_len);
7374

7475
void usbh_hid_run(struct usbh_hid *hid_class);
7576
void usbh_hid_stop(struct usbh_hid *hid_class);

0 commit comments

Comments
 (0)