@@ -180,7 +180,7 @@ static usbh_class_driver_t const usbh_class_drivers[] =
180180 #endif
181181};
182182
183- enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE (usbh_class_drivers ) };
183+ enum { USBH_BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE (usbh_class_drivers ) };
184184enum { CONFIG_NUM = 1 }; // default to use configuration 1
185185
186186
@@ -246,6 +246,21 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
246246static bool usbh_edpt_control_open (uint8_t dev_addr , uint8_t max_packet_size );
247247static bool usbh_control_xfer_cb (uint8_t daddr , uint8_t ep_addr , xfer_result_t result , uint32_t xferred_bytes );
248248
249+ // Additional class drivers implemented by application
250+ tu_static usbh_class_driver_t const * _app_driver = NULL ;
251+ tu_static uint8_t _app_driver_count = 0 ;
252+ tu_static uint8_t _total_driver_count = USBH_BUILTIN_DRIVER_COUNT ;
253+
254+ static usbh_class_driver_t const * usbh_get_driver (uint8_t drv_id )
255+ {
256+ usbh_class_driver_t const * driver = NULL ;
257+ if ( drv_id < _app_driver_count )
258+ driver = & _app_driver [drv_id ];
259+ else if ( drv_id < _total_driver_count )
260+ driver = & usbh_class_drivers [drv_id - _app_driver_count ];
261+ return driver ;
262+ }
263+
249264#if CFG_TUSB_OS == OPT_OS_NONE
250265// TODO rework time-related function later
251266// weak and overridable
@@ -339,6 +354,12 @@ bool tuh_init(uint8_t controller_id) {
339354 _usbh_mutex = osal_mutex_create (& _usbh_mutexdef );
340355 TU_ASSERT (_usbh_mutex );
341356#endif
357+ // Get application driver if available
358+ if ( usbh_app_driver_get_cb )
359+ {
360+ _app_driver = usbh_app_driver_get_cb (& _app_driver_count );
361+ _total_driver_count = USBH_BUILTIN_DRIVER_COUNT + _app_driver_count ;
362+ }
342363
343364 // Device
344365 tu_memclr (& _dev0 , sizeof (_dev0 ));
@@ -351,10 +372,14 @@ bool tuh_init(uint8_t controller_id) {
351372 }
352373
353374 // Class drivers
354- for (uint8_t drv_id = 0 ; drv_id < USBH_CLASS_DRIVER_COUNT ; drv_id ++ )
375+ for (uint8_t drv_id = 0 ; drv_id < _total_driver_count ; drv_id ++ )
355376 {
356- TU_LOG_USBH ("%s init\r\n" , usbh_class_drivers [drv_id ].name );
357- usbh_class_drivers [drv_id ].init ();
377+ usbh_class_driver_t const * driver = usbh_get_driver (drv_id );
378+ if ( driver )
379+ {
380+ TU_LOG_USBH ("%s init\r\n" , driver -> name );
381+ driver -> init ();
382+ }
358383 }
359384
360385 _usbh_controller = controller_id ;;
@@ -482,12 +507,16 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
482507 }else
483508 #endif
484509 {
485- uint8_t const drv_id = dev -> ep2drv [epnum ][ep_dir ];
486- if ( drv_id < USBH_CLASS_DRIVER_COUNT ) {
487- TU_LOG_USBH ("%s xfer callback\r\n" , usbh_class_drivers [drv_id ].name );
488- usbh_class_drivers [drv_id ].xfer_cb (event .dev_addr , ep_addr , (xfer_result_t ) event .xfer_complete .result ,
510+ uint8_t drv_id = dev -> ep2drv [epnum ][ep_dir ];
511+ usbh_class_driver_t const * driver = usbh_get_driver (drv_id );
512+ if ( driver )
513+ {
514+ TU_LOG_USBH ("%s xfer callback\r\n" , driver -> name );
515+ driver -> xfer_cb (event .dev_addr , ep_addr , (xfer_result_t ) event .xfer_complete .result ,
489516 event .xfer_complete .len );
490- } else {
517+ }
518+ else
519+ {
491520 // no driver/callback responsible for this transfer
492521 TU_ASSERT (false,);
493522 }
@@ -1183,17 +1212,20 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
11831212 uint8_t nop_count = 0 ;
11841213#endif
11851214
1186- for (uint8_t dev_id = 0 ; dev_id < TOTAL_DEVICES ; dev_id ++ ) {
1215+ for (uint8_t dev_id = 0 ; dev_id < TOTAL_DEVICES ; dev_id ++ )
1216+ {
11871217 usbh_device_t * dev = & _usbh_devices [dev_id ];
11881218 uint8_t const daddr = dev_id + 1 ;
11891219
11901220 // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub
11911221 if (dev -> rhport == rhport && dev -> connected &&
11921222 (hub_addr == 0 || dev -> hub_addr == hub_addr ) &&
1193- (hub_port == 0 || dev -> hub_port == hub_port )) {
1223+ (hub_port == 0 || dev -> hub_port == hub_port ))
1224+ {
11941225 TU_LOG_USBH ("Device unplugged address = %u\r\n" , daddr );
11951226
1196- if (is_hub_addr (daddr )) {
1227+ if (is_hub_addr (daddr ))
1228+ {
11971229 TU_LOG (CFG_TUH_LOG_LEVEL , " is a HUB device %u\r\n" , daddr );
11981230
11991231 // Submit removed event If the device itself is a hub (un-rolled recursive)
@@ -1211,10 +1243,14 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
12111243 }
12121244
12131245 // Close class driver
1214- for (uint8_t drv_id = 0 ; drv_id < USBH_CLASS_DRIVER_COUNT ; drv_id ++ ) {
1215- usbh_class_drivers [drv_id ].close (daddr );
1246+ for (uint8_t drv_id = 0 ; drv_id < _total_driver_count ; drv_id ++ )
1247+ {
1248+ usbh_class_driver_t const * driver = usbh_get_driver (drv_id );
1249+ if ( driver )
1250+ {
1251+ driver -> close (daddr );
1252+ }
12161253 }
1217-
12181254 hcd_device_close (rhport , daddr );
12191255 clear_device (dev );
12201256 // abort on-going control xfer if any
@@ -1643,11 +1679,12 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
16431679 TU_ASSERT (drv_len >= sizeof (tusb_desc_interface_t ));
16441680
16451681 // Find driver for this interface
1646- for (uint8_t drv_id = 0 ; drv_id < USBH_CLASS_DRIVER_COUNT ; drv_id ++ )
1682+ uint8_t drv_id = 0 ;
1683+ for (; drv_id < _total_driver_count ; drv_id ++ )
16471684 {
1648- usbh_class_driver_t const * driver = & usbh_class_drivers [ drv_id ] ;
1685+ usbh_class_driver_t const * driver = usbh_get_driver ( drv_id ) ;
16491686
1650- if ( driver -> open (dev -> rhport , dev_addr , desc_itf , drv_len ) )
1687+ if (driver && driver -> open (dev -> rhport , dev_addr , desc_itf , drv_len ) )
16511688 {
16521689 // open successfully
16531690 TU_LOG_USBH (" %s opened\r\n" , driver -> name );
@@ -1668,11 +1705,12 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
16681705 break ; // exit driver find loop
16691706 }
16701707
1671- if ( drv_id >= USBH_CLASS_DRIVER_COUNT )
1672- {
1673- TU_LOG (CFG_TUH_LOG_LEVEL , "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n" ,
1674- desc_itf -> bInterfaceNumber , desc_itf -> bInterfaceClass , desc_itf -> bInterfaceSubClass , desc_itf -> bInterfaceProtocol );
1675- }
1708+ }
1709+
1710+ if ( drv_id >= _total_driver_count )
1711+ {
1712+ TU_LOG (CFG_TUH_LOG_LEVEL , "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n" ,
1713+ desc_itf -> bInterfaceNumber , desc_itf -> bInterfaceClass , desc_itf -> bInterfaceSubClass , desc_itf -> bInterfaceProtocol );
16761714 }
16771715
16781716 // next Interface or IAD descriptor
@@ -1694,7 +1732,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
16941732 uint8_t const drv_id = dev -> itf2drv [itf_num ];
16951733 if (drv_id != TUSB_INDEX_INVALID_8 )
16961734 {
1697- usbh_class_driver_t const * driver = & usbh_class_drivers [ drv_id ] ;
1735+ usbh_class_driver_t const * driver = usbh_get_driver ( drv_id ) ;
16981736 TU_LOG_USBH ("%s set config: itf = %u\r\n" , driver -> name , itf_num );
16991737 driver -> set_config (dev_addr , itf_num );
17001738 break ;
0 commit comments