summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2025-12-08 10:40:07 +0700
committerGitHub <[email protected]>2025-12-08 10:40:07 +0700
commite9cd4d823fe4cd7de03587c57fc8288ad5711b15 (patch)
tree8089b9f06807ba35f7f6e4325f92deacf81d76bf /src/class
parent0b555fc46d1d41f967ba934a23d2f2de50e6564e (diff)
parentaa3aec00344bf5e723bf27eba406155d133459cc (diff)
Merge pull request #3340 from dinsfire64/hid-enum-fix
remove hid host enumeration assumption
Diffstat (limited to 'src/class')
-rw-r--r--src/class/hid/hid_host.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index da776d04c..fe9a90d33 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -141,7 +141,9 @@ static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) {
static hidh_interface_t* find_new_itf(void) {
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr == 0) return &_hidh_itf[i];
+ if (_hidh_itf[i].daddr == 0) {
+ return &_hidh_itf[i];
+ }
}
return NULL;
}
@@ -152,7 +154,9 @@ static hidh_interface_t* find_new_itf(void) {
uint8_t tuh_hid_itf_get_count(uint8_t daddr) {
uint8_t count = 0;
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr == daddr) count++;
+ if (_hidh_itf[i].daddr == daddr) {
+ count++;
+ }
}
return count;
}
@@ -160,7 +164,9 @@ uint8_t tuh_hid_itf_get_count(uint8_t daddr) {
uint8_t tuh_hid_itf_get_total_count(void) {
uint8_t count = 0;
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr != 0) count++;
+ if (_hidh_itf[i].daddr != 0) {
+ count++;
+ }
}
return count;
}
@@ -520,20 +526,28 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_
TU_ASSERT(max_len >= drv_len);
uint8_t const* p_desc = (uint8_t const*) desc_itf;
- //------------- HID descriptor -------------//
+ // HID descriptor: mostly right after interface descriptor, in some rare case it might be after endpoint descriptors
p_desc = tu_desc_next(p_desc);
- tusb_hid_descriptor_hid_t const* desc_hid = (tusb_hid_descriptor_hid_t const*) p_desc;
- TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType);
+ const tusb_hid_descriptor_hid_t *desc_hid;
+ if (tu_desc_type(p_desc) == HID_DESC_TYPE_HID) {
+ // HID after interface
+ desc_hid = (const tusb_hid_descriptor_hid_t *)p_desc;
+ p_desc = tu_desc_next(p_desc);
+ } else {
+ // HID after endpoint
+ desc_hid = (const tusb_hid_descriptor_hid_t *)(p_desc + sizeof(tusb_desc_endpoint_t) * desc_itf->bNumEndpoints);
+ TU_ASSERT(tu_desc_type(desc_hid) == HID_DESC_TYPE_HID);
+ }
- hidh_interface_t* p_hid = find_new_itf();
+ // Allocate new interface
+ hidh_interface_t *p_hid = find_new_itf();
TU_ASSERT(p_hid); // not enough interface, try to increase CFG_TUH_HID
- p_hid->daddr = daddr;
-
- //------------- Endpoint Descriptors -------------//
- p_desc = tu_desc_next(p_desc);
- tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc;
+ p_hid->daddr = daddr;
+ p_hid->itf_num = desc_itf->bInterfaceNumber;
- for (int i = 0; i < desc_itf->bNumEndpoints; i++) {
+ // Endpoint Descriptors
+ for (uint8_t i = 0; i < desc_itf->bNumEndpoints; i++) {
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType);
TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
@@ -546,11 +560,8 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_
}
p_desc = tu_desc_next(p_desc);
- desc_ep = (tusb_desc_endpoint_t const*) p_desc;
}
- p_hid->itf_num = desc_itf->bInterfaceNumber;
-
// Assume bNumDescriptors = 1
p_hid->report_desc_type = desc_hid->bReportType;
// Use offsetof to avoid pointer to the odd/misaligned address