@@ -181,9 +181,6 @@ static usbh_class_driver_t const usbh_class_drivers[] =
181
181
};
182
182
183
183
enum { 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
-
187
184
enum { CONFIG_NUM = 1 }; // default to use configuration 1
188
185
189
186
@@ -251,40 +248,27 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
251
248
252
249
#if CFG_TUSB_OS == OPT_OS_NONE
253
250
// 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 ) {
256
253
const uint32_t start = hcd_frame_number (_usbh_controller );
257
254
while ( ( hcd_frame_number (_usbh_controller ) - start ) < msec ) {}
258
255
}
259
256
#endif
260
257
261
258
//--------------------------------------------------------------------+
262
- // PUBLIC API (Parameter Verification is required)
259
+ // Device API
263
260
//--------------------------------------------------------------------+
264
261
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 );
279
264
TU_VERIFY (dev );
280
265
return dev -> configured ;
281
266
}
282
267
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 ) {
285
269
* vid = * pid = 0 ;
286
270
287
- usbh_device_t const * dev = get_device (dev_addr );
271
+ usbh_device_t const * dev = get_device (dev_addr );
288
272
TU_VERIFY (dev && dev -> addressed && dev -> vid != 0 );
289
273
290
274
* vid = dev -> vid ;
@@ -293,26 +277,48 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid)
293
277
return true;
294
278
}
295
279
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 );
299
282
return (tusb_speed_t ) (dev ? get_device (dev_addr )-> speed : _dev0 .speed );
300
283
}
301
284
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 ) {
304
312
tu_memclr (dev , sizeof (usbh_device_t ));
305
313
memset (dev -> itf2drv , TUSB_INDEX_INVALID_8 , sizeof (dev -> itf2drv )); // invalid mapping
306
314
memset (dev -> ep2drv , TUSB_INDEX_INVALID_8 , sizeof (dev -> ep2drv )); // invalid mapping
307
315
}
308
316
309
- bool tuh_inited (void )
310
- {
317
+ bool tuh_inited (void ) {
311
318
return _usbh_controller != TUSB_INDEX_INVALID_8 ;
312
319
}
313
320
314
- bool tuh_init (uint8_t controller_id )
315
- {
321
+ bool tuh_init (uint8_t controller_id ) {
316
322
// skip if already initialized
317
323
if ( tuh_inited () ) return true;
318
324
@@ -359,8 +365,7 @@ bool tuh_init(uint8_t controller_id)
359
365
return true;
360
366
}
361
367
362
- bool tuh_task_event_ready (void )
363
- {
368
+ bool tuh_task_event_ready (void ) {
364
369
// Skip if stack is not initialized
365
370
if ( !tuh_inited () ) return false;
366
371
@@ -385,8 +390,7 @@ bool tuh_task_event_ready(void)
385
390
}
386
391
@endcode
387
392
*/
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 ) {
390
394
(void ) in_isr ; // not implemented yet
391
395
392
396
// Skip if stack is not initialized
@@ -403,8 +407,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
403
407
case HCD_EVENT_DEVICE_ATTACH :
404
408
// due to the shared _usbh_ctrl_buf, we must complete enumerating
405
409
// one device before enumerating another one.
406
- if ( _dev0 .enumerating )
407
- {
410
+ if ( _dev0 .enumerating ) {
408
411
TU_LOG_USBH ("[%u:] USBH Defer Attach until current enumeration complete\r\n" , event .rhport );
409
412
410
413
bool is_empty = osal_queue_empty (_usbh_q );
@@ -414,8 +417,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
414
417
// Exit if this is the only event in the queue, otherwise we may loop forever
415
418
return ;
416
419
}
417
- }else
418
- {
420
+ }else {
419
421
TU_LOG_USBH ("[%u:] USBH DEVICE ATTACH\r\n" , event .rhport );
420
422
_dev0 .enumerating = 1 ;
421
423
enum_new_device (& event );
@@ -428,8 +430,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
428
430
429
431
#if CFG_TUH_HUB
430
432
// TODO remove
431
- if ( event .connection .hub_addr != 0 )
432
- {
433
+ if ( event .connection .hub_addr != 0 ) {
433
434
// done with hub, waiting for next data on status pipe
434
435
(void ) hub_edpt_status_xfer ( event .connection .hub_addr );
435
436
}
@@ -1230,6 +1231,12 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
1230
1231
// one device before enumerating another one.
1231
1232
//--------------------------------------------------------------------+
1232
1233
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
+
1233
1240
enum {
1234
1241
ENUM_IDLE ,
1235
1242
ENUM_RESET_1 , // 1st reset when attached
@@ -1311,7 +1318,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
1311
1318
break ;
1312
1319
1313
1320
case ENUM_HUB_GET_STATUS_2 :
1314
- osal_task_delay (RESET_DELAY );
1321
+ osal_task_delay (ENUM_RESET_DELAY );
1315
1322
TU_ASSERT ( hub_port_get_status (_dev0 .hub_addr , _dev0 .hub_port , _usbh_ctrl_buf , process_enumeration , ENUM_HUB_CLEAR_RESET_2 ), );
1316
1323
break ;
1317
1324
@@ -1468,12 +1475,14 @@ static bool enum_new_device(hcd_event_t* event)
1468
1475
if (_dev0 .hub_addr == 0 )
1469
1476
{
1470
1477
// connected/disconnected directly with roothub
1471
- // wait until device is stable TODO non blocking
1472
1478
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
1475
1481
hcd_port_reset_end ( _dev0 .rhport );
1476
1482
1483
+ // wait until device connection is stable TODO non blocking
1484
+ osal_task_delay (ENUM_CONTACT_DEBOUNCING_DELAY );
1485
+
1477
1486
// device unplugged while delaying
1478
1487
if ( !hcd_port_connect_status (_dev0 .rhport ) ) {
1479
1488
enum_full_complete ();
@@ -1489,15 +1498,16 @@ static bool enum_new_device(hcd_event_t* event)
1489
1498
xfer .result = XFER_RESULT_SUCCESS ;
1490
1499
xfer .user_data = ENUM_ADDR0_DEVICE_DESC ;
1491
1500
1501
+
1492
1502
process_enumeration (& xfer );
1493
1503
1494
1504
}
1495
1505
#if CFG_TUH_HUB
1496
1506
else
1497
1507
{
1498
1508
// 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 );
1501
1511
1502
1512
// ENUM_HUB_GET_STATUS
1503
1513
//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)
1508
1518
return true;
1509
1519
}
1510
1520
1511
- static uint8_t get_new_address (bool is_hub )
1512
- {
1521
+ static uint8_t get_new_address (bool is_hub ) {
1513
1522
uint8_t start ;
1514
1523
uint8_t end ;
1515
1524
1516
- if ( is_hub )
1517
- {
1525
+ if ( is_hub ) {
1518
1526
start = CFG_TUH_DEVICE_MAX ;
1519
1527
end = start + CFG_TUH_HUB ;
1520
- }else
1521
- {
1528
+ }else {
1522
1529
start = 0 ;
1523
1530
end = start + CFG_TUH_DEVICE_MAX ;
1524
1531
}
1525
1532
1526
- for (uint8_t idx = start ; idx < end ; idx ++ )
1527
- {
1533
+ for (uint8_t idx = start ; idx < end ; idx ++ ) {
1528
1534
if (!_usbh_devices [idx ].connected ) return (idx + 1 );
1529
1535
}
1530
1536
0 commit comments