@@ -181,9 +181,6 @@ static usbh_class_driver_t const usbh_class_drivers[] =
181181};
182182
183183enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE (usbh_class_drivers ) };
184-
185- enum { RESET_DELAY = 500 }; // 200 USB specs say only 50ms but many devices require much longer
186-
187184enum { CONFIG_NUM = 1 }; // default to use configuration 1
188185
189186
@@ -251,40 +248,27 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
251248
252249#if CFG_TUSB_OS == OPT_OS_NONE
253250// TODO rework time-related function later
254- TU_ATTR_WEAK void osal_task_delay ( uint32_t msec )
255- {
251+ // weak and overridable
252+ TU_ATTR_WEAK void osal_task_delay ( uint32_t msec ) {
256253 const uint32_t start = hcd_frame_number (_usbh_controller );
257254 while ( ( hcd_frame_number (_usbh_controller ) - start ) < msec ) {}
258255}
259256#endif
260257
261258//--------------------------------------------------------------------+
262- // PUBLIC API (Parameter Verification is required)
259+ // Device API
263260//--------------------------------------------------------------------+
264261
265- bool tuh_configure (uint8_t rhport , uint32_t cfg_id , const void * cfg_param )
266- {
267- if (hcd_configure )
268- {
269- return hcd_configure (rhport , cfg_id , cfg_param );
270- }else
271- {
272- return false;
273- }
274- }
275-
276- bool tuh_mounted (uint8_t dev_addr )
277- {
278- usbh_device_t * dev = get_device (dev_addr );
262+ bool tuh_mounted (uint8_t dev_addr ) {
263+ usbh_device_t * dev = get_device (dev_addr );
279264 TU_VERIFY (dev );
280265 return dev -> configured ;
281266}
282267
283- bool tuh_vid_pid_get (uint8_t dev_addr , uint16_t * vid , uint16_t * pid )
284- {
268+ bool tuh_vid_pid_get (uint8_t dev_addr , uint16_t * vid , uint16_t * pid ) {
285269 * vid = * pid = 0 ;
286270
287- usbh_device_t const * dev = get_device (dev_addr );
271+ usbh_device_t const * dev = get_device (dev_addr );
288272 TU_VERIFY (dev && dev -> addressed && dev -> vid != 0 );
289273
290274 * vid = dev -> vid ;
@@ -293,26 +277,48 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid)
293277 return true;
294278}
295279
296- tusb_speed_t tuh_speed_get (uint8_t dev_addr )
297- {
298- usbh_device_t * dev = get_device (dev_addr );
280+ tusb_speed_t tuh_speed_get (uint8_t dev_addr ) {
281+ usbh_device_t * dev = get_device (dev_addr );
299282 return (tusb_speed_t ) (dev ? get_device (dev_addr )-> speed : _dev0 .speed );
300283}
301284
302- static void clear_device (usbh_device_t * dev )
303- {
285+ bool tuh_rhport_is_active (uint8_t rhport ) {
286+ return _usbh_controller == rhport ;
287+ }
288+
289+ bool tuh_rhport_reset_bus (uint8_t rhport , bool active ) {
290+ TU_VERIFY (tuh_rhport_is_active (rhport ));
291+ if ( active ) {
292+ hcd_port_reset (rhport );
293+ } else {
294+ hcd_port_reset_end (rhport );
295+ }
296+ return true;
297+ }
298+
299+ //--------------------------------------------------------------------+
300+ // PUBLIC API (Parameter Verification is required)
301+ //--------------------------------------------------------------------+
302+
303+ bool tuh_configure (uint8_t rhport , uint32_t cfg_id , const void * cfg_param ) {
304+ if ( hcd_configure ) {
305+ return hcd_configure (rhport , cfg_id , cfg_param );
306+ } else {
307+ return false;
308+ }
309+ }
310+
311+ static void clear_device (usbh_device_t * dev ) {
304312 tu_memclr (dev , sizeof (usbh_device_t ));
305313 memset (dev -> itf2drv , TUSB_INDEX_INVALID_8 , sizeof (dev -> itf2drv )); // invalid mapping
306314 memset (dev -> ep2drv , TUSB_INDEX_INVALID_8 , sizeof (dev -> ep2drv )); // invalid mapping
307315}
308316
309- bool tuh_inited (void )
310- {
317+ bool tuh_inited (void ) {
311318 return _usbh_controller != TUSB_INDEX_INVALID_8 ;
312319}
313320
314- bool tuh_init (uint8_t controller_id )
315- {
321+ bool tuh_init (uint8_t controller_id ) {
316322 // skip if already initialized
317323 if ( tuh_inited () ) return true;
318324
@@ -359,8 +365,7 @@ bool tuh_init(uint8_t controller_id)
359365 return true;
360366}
361367
362- bool tuh_task_event_ready (void )
363- {
368+ bool tuh_task_event_ready (void ) {
364369 // Skip if stack is not initialized
365370 if ( !tuh_inited () ) return false;
366371
@@ -385,8 +390,7 @@ bool tuh_task_event_ready(void)
385390 }
386391 @endcode
387392 */
388- void tuh_task_ext (uint32_t timeout_ms , bool in_isr )
389- {
393+ void tuh_task_ext (uint32_t timeout_ms , bool in_isr ) {
390394 (void ) in_isr ; // not implemented yet
391395
392396 // Skip if stack is not initialized
@@ -403,8 +407,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
403407 case HCD_EVENT_DEVICE_ATTACH :
404408 // due to the shared _usbh_ctrl_buf, we must complete enumerating
405409 // one device before enumerating another one.
406- if ( _dev0 .enumerating )
407- {
410+ if ( _dev0 .enumerating ) {
408411 TU_LOG_USBH ("[%u:] USBH Defer Attach until current enumeration complete\r\n" , event .rhport );
409412
410413 bool is_empty = osal_queue_empty (_usbh_q );
@@ -414,8 +417,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
414417 // Exit if this is the only event in the queue, otherwise we may loop forever
415418 return ;
416419 }
417- }else
418- {
420+ }else {
419421 TU_LOG_USBH ("[%u:] USBH DEVICE ATTACH\r\n" , event .rhport );
420422 _dev0 .enumerating = 1 ;
421423 enum_new_device (& event );
@@ -428,8 +430,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
428430
429431 #if CFG_TUH_HUB
430432 // TODO remove
431- if ( event .connection .hub_addr != 0 )
432- {
433+ if ( event .connection .hub_addr != 0 ) {
433434 // done with hub, waiting for next data on status pipe
434435 (void ) hub_edpt_status_xfer ( event .connection .hub_addr );
435436 }
@@ -1230,6 +1231,12 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
12301231// one device before enumerating another one.
12311232//--------------------------------------------------------------------+
12321233
1234+ enum {
1235+ ENUM_RESET_DELAY = 50 , // USB specs: 10 to 50ms
1236+ ENUM_CONTACT_DEBOUNCING_DELAY = 450 , // when plug/unplug a device, physical connection can be bouncing and may
1237+ // generate a series of attach/detach event. This delay wait for stable connection
1238+ };
1239+
12331240enum {
12341241 ENUM_IDLE ,
12351242 ENUM_RESET_1 , // 1st reset when attached
@@ -1311,7 +1318,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
13111318 break ;
13121319
13131320 case ENUM_HUB_GET_STATUS_2 :
1314- osal_task_delay (RESET_DELAY );
1321+ osal_task_delay (ENUM_RESET_DELAY );
13151322 TU_ASSERT ( hub_port_get_status (_dev0 .hub_addr , _dev0 .hub_port , _usbh_ctrl_buf , process_enumeration , ENUM_HUB_CLEAR_RESET_2 ), );
13161323 break ;
13171324
@@ -1468,12 +1475,14 @@ static bool enum_new_device(hcd_event_t* event)
14681475 if (_dev0 .hub_addr == 0 )
14691476 {
14701477 // connected/disconnected directly with roothub
1471- // wait until device is stable TODO non blocking
14721478 hcd_port_reset (_dev0 .rhport );
1473- osal_task_delay (RESET_DELAY ); // TODO may not work for no-OS on MCU that require reset_end() since
1474- // sof of controller may not running while resetting
1479+ osal_task_delay (ENUM_RESET_DELAY ); // TODO may not work for no-OS on MCU that require reset_end() since
1480+ // sof of controller may not running while resetting
14751481 hcd_port_reset_end ( _dev0 .rhport );
14761482
1483+ // wait until device connection is stable TODO non blocking
1484+ osal_task_delay (ENUM_CONTACT_DEBOUNCING_DELAY );
1485+
14771486 // device unplugged while delaying
14781487 if ( !hcd_port_connect_status (_dev0 .rhport ) ) {
14791488 enum_full_complete ();
@@ -1489,15 +1498,16 @@ static bool enum_new_device(hcd_event_t* event)
14891498 xfer .result = XFER_RESULT_SUCCESS ;
14901499 xfer .user_data = ENUM_ADDR0_DEVICE_DESC ;
14911500
1501+
14921502 process_enumeration (& xfer );
14931503
14941504 }
14951505#if CFG_TUH_HUB
14961506 else
14971507 {
14981508 // connected/disconnected via external hub
1499- // wait until device is stable
1500- osal_task_delay (RESET_DELAY );
1509+ // wait until device connection is stable TODO non blocking
1510+ osal_task_delay (ENUM_CONTACT_DEBOUNCING_DELAY );
15011511
15021512 // ENUM_HUB_GET_STATUS
15031513 //TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) );
@@ -1508,23 +1518,19 @@ static bool enum_new_device(hcd_event_t* event)
15081518 return true;
15091519}
15101520
1511- static uint8_t get_new_address (bool is_hub )
1512- {
1521+ static uint8_t get_new_address (bool is_hub ) {
15131522 uint8_t start ;
15141523 uint8_t end ;
15151524
1516- if ( is_hub )
1517- {
1525+ if ( is_hub ) {
15181526 start = CFG_TUH_DEVICE_MAX ;
15191527 end = start + CFG_TUH_HUB ;
1520- }else
1521- {
1528+ }else {
15221529 start = 0 ;
15231530 end = start + CFG_TUH_DEVICE_MAX ;
15241531 }
15251532
1526- for (uint8_t idx = start ; idx < end ; idx ++ )
1527- {
1533+ for (uint8_t idx = start ; idx < end ; idx ++ ) {
15281534 if (!_usbh_devices [idx ].connected ) return (idx + 1 );
15291535 }
15301536
0 commit comments