cancel
Showing results for 
Search instead for 
Did you mean: 

USBH_MSC_Read Problem is Stuck in while Loop?

NAgha.1
Associate II

Hello

USBH_MSC_Read function uses a while loop and USBH_MSC_RdWrProcess to USB mass storage.

  

while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
  {
    if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U) )
    {
      MSC_Handle->state = MSC_IDLE;
      return USBH_FAIL;
    }
  }
  MSC_Handle->state = MSC_IDLE;

This part of the blocks the application for more than 3 or 4 seconds in some usb mass storages

I investigated the USB_MSC_Bot process and it was understood that most of the time in USBH_MSC_BOT_Process in the BOT_DATA_IN_WAIT

application URB_Status is equal to USBH_URB_NOTREADY which is not handled in the BOT_DATA_IN_WAIT

I used a counter until the end of USBH_MSC_Read and USBH_URB_NOTREADY was counted for 45000 time until the loop ended

I have searched most of the post related to this issue but most of them were unanswered and no useful fix was released

 #USB​ 

#STM32F7​ 

#STM32F4​ ​ 

2 REPLIES 2
Gianluca Costa
Associate II

Hi,

if it is an F7 and you are using FW_F7 V1.17.0 try to set 1025 as USBH_MAX_DATA_BUFFER from Cubemx (USB_HOST->Parameter Setting).

Give me a feedback if it works. Thanks.

Ciao.

USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
                                 uint8_t lun,
                                 uint32_t address,
                                 uint8_t *pbuf,
                                 uint32_t length)
{
  uint32_t timeout;
  
  /*****************************************************************************
   * @brief :ExtTimeout variable controls a dynamic timeout for USB USBH_MSC_RdWrProcess
   * @note : Hanging in this while loop will occur in the event of Slow USB 
   * @note : Hanging in this while loop will occur in the event of EMI problems 
   *  Maximum Timeout  = USB_MSC_READ_TIMEOUT_MAX
   *  Timeout Step     = USB_MSC_READ_TIMEOUT_STEP
   *  Defualt Timeout  = USB_MSC_READ_TIMEOUT
   ****************************************************************************/
  static uint32_t  ExtTimeout = USB_MSC_READ_TIMEOUT ;
  USBH_StatusTypeDef USB_RdStatus = USBH_BUSY;
  MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
 
  if ((phost->device.is_connected == 0U) ||
      (phost->gState != HOST_CLASS) ||
      (MSC_Handle->unit[lun].state != MSC_IDLE))
  {
    return  USBH_FAIL;
  }
 
  MSC_Handle->state = MSC_READ;
  MSC_Handle->unit[lun].state = MSC_READ;
  MSC_Handle->rw_lun = lun;
 
  (void)USBH_MSC_SCSI_Read(phost, lun, address, pbuf, length);
 
  timeout = phost->Timer;
  
  //=================================
  // Add For prevent infinity loop
  uint32_t  tickstart = HAL_GetTick();
  
  do
  {
    USB_RdStatus = USBH_MSC_RdWrProcess(phost, lun);
    if ( USB_RdStatus == USBH_FAIL)
    {
      MSC_Handle->state = MSC_IDLE;
      ExtTimeout =USB_MSC_READ_TIMEOUT;
      return USBH_FAIL;
    }
    if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U) ||   ((HAL_GetTick() - tickstart) > ExtTimeout) )
    {
      if ( ExtTimeout < USB_MSC_READ_TIMEOUT_MAX )
      {
        ExtTimeout = ExtTimeout + USB_MSC_READ_TIMEOUT_STEP;
      }
      else
      {
        ExtTimeout =USB_MSC_READ_TIMEOUT;
      }
      MSC_Handle->state = MSC_IDLE;
      return USBH_FAIL;
    }
  }
  while(USB_RdStatus == USBH_BUSY);
  ExtTimeout =USB_MSC_READ_TIMEOUT;
  MSC_Handle->state = MSC_IDLE;
  
  return USBH_OK;
 
//  while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
//  {
//    if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U) ||   ((HAL_GetTick() - tickstart) > ExtTimeout) )
//    {
//      if ( ExtTimeout < USB_MSC_READ_TIMEOUT_MAX )
//      {
//        ExtTimeout = ExtTimeout + USB_MSC_READ_TIMEOUT_STEP;
//      }
//      else
//      {
//        ExtTimeout =USB_MSC_READ_TIMEOUT;
//      }
//      MSC_Handle->state = MSC_IDLE;
//      return USBH_FAIL;
//    }
//  }
 
}

Thanks for your response I have set

USBH_MAX_DATA_BUFFER = 1025

and it did not have any effect on this issue.

I have spent a little time and developed a dynamic timeout for this part of the code.

But it only helps

It is not a solid solution. This is my modified code: