@@ -86,16 +86,12 @@ typedef struct
8686 uint8_t rhport ;
8787 uint8_t hub_addr ;
8888 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 ;
9389
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+ };
9995} usbh_dev0_t ;
10096
10197typedef struct {
@@ -462,8 +458,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
462458 switch (event .event_id )
463459 {
464460 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
467463 if ( _dev0 .enumerating ) {
468464 TU_LOG_USBH ("[%u:] USBH Defer Attach until current enumeration complete\r\n" , event .rhport );
469465
@@ -587,11 +583,17 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
587583 // EP0 with setup packet
588584 TU_VERIFY (xfer -> ep_addr == 0 && xfer -> setup );
589585
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)
593587 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+ }
594594
595+ // pre-check to help reducing mutex lock
596+ TU_VERIFY (_ctrl_xfer .stage == CONTROL_STAGE_IDLE );
595597 (void ) osal_mutex_lock (_usbh_mutex , OSAL_TIMEOUT_WAIT_FOREVER );
596598
597599 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
691693
692694 if (XFER_RESULT_SUCCESS != result ) {
693695 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 );
695697 TU_LOG1 ("\r\n" );
696698
697699 // 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)
948950 }
949951}
950952
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
959958
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 ;
963967 }
968+
969+ osal_queue_send (_usbh_q , event , in_isr );
964970}
965971
966972//--------------------------------------------------------------------+
@@ -1325,28 +1331,28 @@ static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configu
13251331static void enum_full_complete (void );
13261332
13271333// process device enumeration
1328- static void process_enumeration (tuh_xfer_t * xfer )
1329- {
1334+ static void process_enumeration (tuh_xfer_t * xfer ) {
13301335 // Retry a few times with transfers in enumeration since device can be unstable when starting up
13311336 enum {
13321337 ATTEMPT_COUNT_MAX = 3 ,
13331338 ATTEMPT_DELAY_MS = 100
13341339 };
13351340 static uint8_t failed_count = 0 ;
13361341
1337- if (XFER_RESULT_SUCCESS != xfer -> result )
1338- {
1342+ if (XFER_RESULT_SUCCESS != xfer -> result ) {
13391343 // 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 ) {
13421346 failed_count ++ ;
13431347 osal_task_delay (ATTEMPT_DELAY_MS ); // delay a bit
13441348 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 ) {
13481353 enum_full_complete ();
13491354 }
1355+
13501356 return ;
13511357 }
13521358 failed_count = 0 ;
0 commit comments