diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 420600f9..5e3ac6a7 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -61,6 +61,8 @@ void hid_app_task(void) // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 40b6f563..a39ac8be 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -247,6 +247,8 @@ static bool config_set_protocol (uint8_t dev_addr, tusb_control_requ static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); + uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { (void) max_len; @@ -367,26 +369,34 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - // Get Report Descriptor + // Get Report Descriptor if possible // using usbh enumeration buffer since report descriptor can be very long - TU_ASSERT( hid_itf->report_desc_len <= CFG_TUH_ENUMERATION_BUFSIZE ); - - TU_LOG2("HID Get Report Descriptor\r\n"); - tusb_control_request_t const new_request = + if( hid_itf->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_u16(hid_itf->report_desc_type, 0), - .wIndex = itf_num, - .wLength = hid_itf->report_desc_len - }; + TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); + + // Driver is mounted without report descriptor + config_driver_mount_complete(dev_addr, instance, NULL, 0); + }else + { + TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const new_request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_u16(hid_itf->report_desc_type, 0), + .wIndex = itf_num, + .wLength = hid_itf->report_desc_len + }; + + TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); + } - TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); return true; } @@ -394,13 +404,21 @@ static bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_reque { TU_ASSERT(XFER_RESULT_SUCCESS == result); - uint8_t const itf_num = (uint8_t) request->wIndex; - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); uint8_t const* desc_report = usbh_get_enum_buf(); uint16_t const desc_len = request->wLength; + config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); + + return true; +} + +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + // enumeration is complete tuh_hid_mount_cb(dev_addr, instance, desc_report, desc_len); @@ -408,9 +426,7 @@ static bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_reque hidh_get_report(dev_addr, hid_itf); // notify usbh that driver enumeration is complete - usbh_driver_set_config_complete(dev_addr, itf_num); - - return true; + usbh_driver_set_config_complete(dev_addr, hid_itf->itf_num); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index ef203123..bbef05e2 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -97,6 +97,8 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report_desc, uint16_t desc_len); // Invoked when device with hid interface is un-mounted diff --git a/src/host/usbh.c b/src/host/usbh.c index 36c2ea7c..979fc506 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -892,8 +892,6 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura p_desc = tu_desc_next(p_desc); } - TU_LOG_INT(2, p_desc - (uint8_t*) desc_cfg); - TU_LOG_INT(2, tu_desc_type(p_desc)); TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc;