2022-10-13 02:07 AM
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
2022-10-18 05:44 AM
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.
2022-10-23 04:46 AM
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: