@@ -86,16 +86,12 @@ typedef struct
86
86
uint8_t rhport ;
87
87
uint8_t hub_addr ;
88
88
uint8_t hub_port ;
89
- uint8_t speed ;
90
-
91
- // enumeration is in progress, done when all interfaces are configured
92
- volatile uint8_t enumerating ;
93
89
94
- // struct TU_ATTR_PACKED {
95
- // uint8_t speed : 4; // packed speed to save footprint
96
- // volatile uint8_t enumerating : 1;
97
- // uint8_t TU_RESERVED : 3;
98
- // };
90
+ struct TU_ATTR_PACKED {
91
+ uint8_t speed : 4 ; // packed speed to save footprint
92
+ volatile uint8_t enumerating : 1 ; // enumeration is in progress, false if not connected or all interfaces are configured
93
+ uint8_t TU_RESERVED : 3 ;
94
+ };
99
95
} usbh_dev0_t ;
100
96
101
97
typedef struct {
@@ -462,8 +458,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
462
458
switch (event .event_id )
463
459
{
464
460
case HCD_EVENT_DEVICE_ATTACH :
465
- // due to the shared _usbh_ctrl_buf, we must complete enumerating
466
- // one device before enumerating another one.
461
+ // due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one.
462
+ // TODO better to have an separated queue for newly attached devices
467
463
if ( _dev0 .enumerating ) {
468
464
TU_LOG_USBH ("[%u:] USBH Defer Attach until current enumeration complete\r\n" , event .rhport );
469
465
@@ -587,11 +583,17 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
587
583
// EP0 with setup packet
588
584
TU_VERIFY (xfer -> ep_addr == 0 && xfer -> setup );
589
585
590
- // pre-check to help reducing mutex lock
591
- TU_VERIFY (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
592
-
586
+ // Check if device is still connected (enumerating for dev0)
593
587
uint8_t const daddr = xfer -> daddr ;
588
+ if ( daddr == 0 ) {
589
+ if (!_dev0 .enumerating ) return false;
590
+ } else {
591
+ usbh_device_t const * dev = get_device (daddr );
592
+ if (dev && dev -> connected == 0 ) return false;
593
+ }
594
594
595
+ // pre-check to help reducing mutex lock
596
+ TU_VERIFY (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
595
597
(void ) osal_mutex_lock (_usbh_mutex , OSAL_TIMEOUT_WAIT_FOREVER );
596
598
597
599
bool const is_idle = (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
@@ -691,7 +693,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
691
693
692
694
if (XFER_RESULT_SUCCESS != result ) {
693
695
TU_LOG1 ("[%u:%u] Control %s, xferred_bytes = %lu\r\n" , rhport , dev_addr , result == XFER_RESULT_STALLED ? "STALLED" : "FAILED" , xferred_bytes );
694
- TU_LOG_BUF ( 1 , request , 8 );
696
+ TU_LOG1_BUF ( request , 8 );
695
697
TU_LOG1 ("\r\n" );
696
698
697
699
// terminate transfer if any stage failed
@@ -948,19 +950,23 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info)
948
950
}
949
951
}
950
952
951
- TU_ATTR_FAST_FUNC void hcd_event_handler (hcd_event_t const * event , bool in_isr )
952
- {
953
- switch (event -> event_id )
954
- {
955
- // case HCD_EVENT_DEVICE_REMOVE:
956
- // // FIXME device remove from a hub need an HCD API for hcd to free up endpoint
957
- // // mark device as removing to prevent further xfer before the event is processed in usbh task
958
- // break;
953
+ TU_ATTR_FAST_FUNC void hcd_event_handler (hcd_event_t const * event , bool in_isr ) {
954
+ switch (event -> event_id ) {
955
+ case HCD_EVENT_DEVICE_REMOVE :
956
+ // FIXME device remove from a hub need an HCD API for hcd to free up endpoint
957
+ // mark device as removing to prevent further xfer before the event is processed in usbh task
959
958
960
- default :
961
- osal_queue_send (_usbh_q , event , in_isr );
962
- break ;
959
+ // Check if dev0 is removed
960
+ if ((event -> rhport == _dev0 .rhport ) && (event -> connection .hub_addr == _dev0 .hub_addr ) &&
961
+ (event -> connection .hub_port == _dev0 .hub_port )) {
962
+ _dev0 .enumerating = 0 ;
963
+ }
964
+ break ;
965
+
966
+ default : break ;
963
967
}
968
+
969
+ osal_queue_send (_usbh_q , event , in_isr );
964
970
}
965
971
966
972
//--------------------------------------------------------------------+
@@ -1325,28 +1331,28 @@ static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configu
1325
1331
static void enum_full_complete (void );
1326
1332
1327
1333
// process device enumeration
1328
- static void process_enumeration (tuh_xfer_t * xfer )
1329
- {
1334
+ static void process_enumeration (tuh_xfer_t * xfer ) {
1330
1335
// Retry a few times with transfers in enumeration since device can be unstable when starting up
1331
1336
enum {
1332
1337
ATTEMPT_COUNT_MAX = 3 ,
1333
1338
ATTEMPT_DELAY_MS = 100
1334
1339
};
1335
1340
static uint8_t failed_count = 0 ;
1336
1341
1337
- if (XFER_RESULT_SUCCESS != xfer -> result )
1338
- {
1342
+ if (XFER_RESULT_SUCCESS != xfer -> result ) {
1339
1343
// retry if not reaching max attempt
1340
- if ( failed_count < ATTEMPT_COUNT_MAX )
1341
- {
1344
+ bool retry = _dev0 . enumerating && ( failed_count < ATTEMPT_COUNT_MAX );
1345
+ if ( retry ) {
1342
1346
failed_count ++ ;
1343
1347
osal_task_delay (ATTEMPT_DELAY_MS ); // delay a bit
1344
1348
TU_LOG1 ("Enumeration attempt %u\r\n" , failed_count );
1345
- TU_ASSERT (tuh_control_xfer (xfer ), );
1346
- }else
1347
- {
1349
+ retry = tuh_control_xfer (xfer );
1350
+ }
1351
+
1352
+ if (!retry ) {
1348
1353
enum_full_complete ();
1349
1354
}
1355
+
1350
1356
return ;
1351
1357
}
1352
1358
failed_count = 0 ;
0 commit comments