@@ -55,16 +55,12 @@ typedef struct
5555 uint8_t rhport ;
5656 uint8_t hub_addr ;
5757 uint8_t hub_port ;
58- uint8_t speed ;
59-
60- // enumeration is in progress, done when all interfaces are configured
61- volatile uint8_t enumerating ;
6258
63- // struct TU_ATTR_PACKED {
64- // uint8_t speed : 4; // packed speed to save footprint
65- // volatile uint8_t enumerating : 1;
66- // uint8_t TU_RESERVED : 3;
67- // };
59+ struct TU_ATTR_PACKED {
60+ uint8_t speed : 4 ; // packed speed to save footprint
61+ volatile uint8_t enumerating : 1 ; // enumeration is in progress, false if not connected or all interfaces are configured
62+ uint8_t TU_RESERVED : 3 ;
63+ };
6864} usbh_dev0_t ;
6965
7066typedef struct {
@@ -431,8 +427,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
431427 switch (event .event_id )
432428 {
433429 case HCD_EVENT_DEVICE_ATTACH :
434- // due to the shared _usbh_ctrl_buf, we must complete enumerating
435- // one device before enumerating another one.
430+ // due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one.
431+ // TODO better to have an separated queue for newly attached devices
436432 if ( _dev0 .enumerating ) {
437433 TU_LOG_USBH ("[%u:] USBH Defer Attach until current enumeration complete\r\n" , event .rhport );
438434
@@ -556,11 +552,17 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
556552 // EP0 with setup packet
557553 TU_VERIFY (xfer -> ep_addr == 0 && xfer -> setup );
558554
559- // pre-check to help reducing mutex lock
560- TU_VERIFY (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
561-
555+ // Check if device is still connected (enumerating for dev0)
562556 uint8_t const daddr = xfer -> daddr ;
557+ if ( daddr == 0 ) {
558+ if (!_dev0 .enumerating ) return false;
559+ } else {
560+ usbh_device_t const * dev = get_device (daddr );
561+ if (dev && dev -> connected == 0 ) return false;
562+ }
563563
564+ // pre-check to help reducing mutex lock
565+ TU_VERIFY (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
564566 (void ) osal_mutex_lock (_usbh_mutex , OSAL_TIMEOUT_WAIT_FOREVER );
565567
566568 bool const is_idle = (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
@@ -917,19 +919,23 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info)
917919 }
918920}
919921
920- TU_ATTR_FAST_FUNC void hcd_event_handler (hcd_event_t const * event , bool in_isr )
921- {
922- switch (event -> event_id )
923- {
924- // case HCD_EVENT_DEVICE_REMOVE:
925- // // FIXME device remove from a hub need an HCD API for hcd to free up endpoint
926- // // mark device as removing to prevent further xfer before the event is processed in usbh task
927- // break;
922+ TU_ATTR_FAST_FUNC void hcd_event_handler (hcd_event_t const * event , bool in_isr ) {
923+ switch (event -> event_id ) {
924+ case HCD_EVENT_DEVICE_REMOVE :
925+ // FIXME device remove from a hub need an HCD API for hcd to free up endpoint
926+ // mark device as removing to prevent further xfer before the event is processed in usbh task
928927
929- default :
930- osal_queue_send (_usbh_q , event , in_isr );
931- break ;
928+ // Check if dev0 is removed
929+ if ((event -> rhport == _dev0 .rhport ) && (event -> connection .hub_addr == _dev0 .hub_addr ) &&
930+ (event -> connection .hub_port == _dev0 .hub_port )) {
931+ _dev0 .enumerating = 0 ;
932+ }
933+ break ;
934+
935+ default : break ;
932936 }
937+
938+ osal_queue_send (_usbh_q , event , in_isr );
933939}
934940
935941//--------------------------------------------------------------------+
@@ -1294,28 +1300,28 @@ static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configu
12941300static void enum_full_complete (void );
12951301
12961302// process device enumeration
1297- static void process_enumeration (tuh_xfer_t * xfer )
1298- {
1303+ static void process_enumeration (tuh_xfer_t * xfer ) {
12991304 // Retry a few times with transfers in enumeration since device can be unstable when starting up
13001305 enum {
13011306 ATTEMPT_COUNT_MAX = 3 ,
13021307 ATTEMPT_DELAY_MS = 100
13031308 };
13041309 static uint8_t failed_count = 0 ;
13051310
1306- if (XFER_RESULT_SUCCESS != xfer -> result )
1307- {
1311+ if (XFER_RESULT_SUCCESS != xfer -> result ) {
13081312 // retry if not reaching max attempt
1309- if ( failed_count < ATTEMPT_COUNT_MAX )
1310- {
1313+ bool retry = _dev0 . enumerating && ( failed_count < ATTEMPT_COUNT_MAX );
1314+ if ( retry ) {
13111315 failed_count ++ ;
13121316 osal_task_delay (ATTEMPT_DELAY_MS ); // delay a bit
13131317 TU_LOG1 ("Enumeration attempt %u\r\n" , failed_count );
1314- TU_ASSERT (tuh_control_xfer (xfer ), );
1315- }else
1316- {
1318+ retry = tuh_control_xfer (xfer );
1319+ }
1320+
1321+ if (!retry ) {
13171322 enum_full_complete ();
13181323 }
1324+
13191325 return ;
13201326 }
13211327 failed_count = 0 ;
0 commit comments