@@ -247,33 +247,37 @@ static bool config_set_protocol (uint8_t dev_addr, tusb_control_requ
247247static bool config_get_report_desc (uint8_t dev_addr , tusb_control_request_t const * request , xfer_result_t result );
248248static bool config_get_report_desc_complete (uint8_t dev_addr , tusb_control_request_t const * request , xfer_result_t result );
249249
250- uint16_t hidh_open (uint8_t rhport , uint8_t dev_addr , tusb_desc_interface_t const * desc_itf , uint16_t max_len )
250+ static void config_driver_mount_complete (uint8_t dev_addr , uint8_t instance , uint8_t const * desc_report , uint16_t desc_len );
251+
252+ bool hidh_open (uint8_t rhport , uint8_t dev_addr , tusb_desc_interface_t const * desc_itf , uint16_t max_len )
251253{
252254 (void ) max_len ;
253255
254- TU_VERIFY (TUSB_CLASS_HID == desc_itf -> bInterfaceClass , 0 );
256+ TU_VERIFY (TUSB_CLASS_HID == desc_itf -> bInterfaceClass );
257+
258+ // len = interface + hid + n*endpoints
259+ uint16_t const drv_len = sizeof (tusb_desc_interface_t ) + sizeof (tusb_hid_descriptor_hid_t ) + desc_itf -> bNumEndpoints * sizeof (tusb_desc_endpoint_t );
260+ TU_ASSERT (max_len >= drv_len );
255261
256- uint16_t drv_len = sizeof (tusb_desc_interface_t );
257262 uint8_t const * p_desc = (uint8_t const * ) desc_itf ;
258263
259264 //------------- HID descriptor -------------//
260265 p_desc = tu_desc_next (p_desc );
261266 tusb_hid_descriptor_hid_t const * desc_hid = (tusb_hid_descriptor_hid_t const * ) p_desc ;
262- TU_ASSERT (HID_DESC_TYPE_HID == desc_hid -> bDescriptorType , 0 );
267+ TU_ASSERT (HID_DESC_TYPE_HID == desc_hid -> bDescriptorType );
263268
264269 // not enough interface, try to increase CFG_TUH_HID
265270 // TODO multiple devices
266271 hidh_device_t * hid_dev = get_dev (dev_addr );
267272 TU_ASSERT (hid_dev -> inst_count < CFG_TUH_HID , 0 );
268273
269274 //------------- Endpoint Descriptor -------------//
270- drv_len += tu_desc_len (p_desc );
271275 p_desc = tu_desc_next (p_desc );
272276 tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const * ) p_desc ;
273- TU_ASSERT (TUSB_DESC_ENDPOINT == desc_ep -> bDescriptorType , 0 );
277+ TU_ASSERT (TUSB_DESC_ENDPOINT == desc_ep -> bDescriptorType );
274278
275279 // TODO also open endpoint OUT
276- TU_ASSERT ( usbh_edpt_open (rhport , dev_addr , desc_ep ), 0 );
280+ TU_ASSERT ( usbh_edpt_open (rhport , dev_addr , desc_ep ) );
277281
278282 hidh_interface_t * hid_itf = get_instance (dev_addr , hid_dev -> inst_count );
279283 hid_dev -> inst_count ++ ;
@@ -290,9 +294,7 @@ uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const
290294 hid_itf -> protocol_mode = HID_PROTOCOL_BOOT ;
291295 if ( HID_SUBCLASS_BOOT == desc_itf -> bInterfaceSubClass ) hid_itf -> itf_protocol = desc_itf -> bInterfaceProtocol ;
292296
293- drv_len += desc_itf -> bNumEndpoints * sizeof (tusb_desc_endpoint_t );
294-
295- return drv_len ;
297+ return true;
296298}
297299
298300bool hidh_set_config (uint8_t dev_addr , uint8_t itf_num )
@@ -367,50 +369,64 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons
367369 uint8_t const instance = get_instance_id_by_itfnum (dev_addr , itf_num );
368370 hidh_interface_t * hid_itf = get_instance (dev_addr , instance );
369371
370- // Get Report Descriptor
372+ // Get Report Descriptor if possible
371373 // using usbh enumeration buffer since report descriptor can be very long
372- TU_ASSERT ( hid_itf -> report_desc_len <= CFG_TUH_ENUMERATION_BUFSIZE );
374+ if ( hid_itf -> report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE )
375+ {
376+ TU_LOG2 ("HID Skip Report Descriptor since it is too large %u bytes\r\n" , hid_itf -> report_desc_len );
373377
374- TU_LOG2 ("HID Get Report Descriptor\r\n" );
375- tusb_control_request_t const new_request =
378+ // Driver is mounted without report descriptor
379+ config_driver_mount_complete (dev_addr , instance , NULL , 0 );
380+ }else
376381 {
377- .bmRequestType_bit =
382+ TU_LOG2 ("HID Get Report Descriptor\r\n" );
383+ tusb_control_request_t const new_request =
378384 {
379- .recipient = TUSB_REQ_RCPT_INTERFACE ,
380- .type = TUSB_REQ_TYPE_STANDARD ,
381- .direction = TUSB_DIR_IN
382- },
383- .bRequest = TUSB_REQ_GET_DESCRIPTOR ,
384- .wValue = tu_u16 (hid_itf -> report_desc_type , 0 ),
385- .wIndex = itf_num ,
386- .wLength = hid_itf -> report_desc_len
387- };
385+ .bmRequestType_bit =
386+ {
387+ .recipient = TUSB_REQ_RCPT_INTERFACE ,
388+ .type = TUSB_REQ_TYPE_STANDARD ,
389+ .direction = TUSB_DIR_IN
390+ },
391+ .bRequest = TUSB_REQ_GET_DESCRIPTOR ,
392+ .wValue = tu_u16 (hid_itf -> report_desc_type , 0 ),
393+ .wIndex = itf_num ,
394+ .wLength = hid_itf -> report_desc_len
395+ };
396+
397+ TU_ASSERT (tuh_control_xfer (dev_addr , & new_request , usbh_get_enum_buf (), config_get_report_desc_complete ));
398+ }
388399
389- TU_ASSERT (tuh_control_xfer (dev_addr , & new_request , usbh_get_enum_buf (), config_get_report_desc_complete ));
390400 return true;
391401}
392402
393403static bool config_get_report_desc_complete (uint8_t dev_addr , tusb_control_request_t const * request , xfer_result_t result )
394404{
395405 TU_ASSERT (XFER_RESULT_SUCCESS == result );
396406
397- uint8_t const itf_num = (uint8_t ) request -> wIndex ;
398- uint8_t const instance = get_instance_id_by_itfnum (dev_addr , itf_num );
399- hidh_interface_t * hid_itf = get_instance (dev_addr , instance );
407+ uint8_t const itf_num = (uint8_t ) request -> wIndex ;
408+ uint8_t const instance = get_instance_id_by_itfnum (dev_addr , itf_num );
400409
401410 uint8_t const * desc_report = usbh_get_enum_buf ();
402411 uint16_t const desc_len = request -> wLength ;
403412
413+ config_driver_mount_complete (dev_addr , instance , desc_report , desc_len );
414+
415+ return true;
416+ }
417+
418+ static void config_driver_mount_complete (uint8_t dev_addr , uint8_t instance , uint8_t const * desc_report , uint16_t desc_len )
419+ {
420+ hidh_interface_t * hid_itf = get_instance (dev_addr , instance );
421+
404422 // enumeration is complete
405423 tuh_hid_mount_cb (dev_addr , instance , desc_report , desc_len );
406424
407425 // queue transfer for IN endpoint
408426 hidh_get_report (dev_addr , hid_itf );
409427
410428 // notify usbh that driver enumeration is complete
411- usbh_driver_set_config_complete (dev_addr , itf_num );
412-
413- return true;
429+ usbh_driver_set_config_complete (dev_addr , hid_itf -> itf_num );
414430}
415431
416432//--------------------------------------------------------------------+
0 commit comments