This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
In developing a USB Mass Storage Device Host, we uncovered what we believe is a bug in the Tivaware USB library. Inside the USBHCDPipeRead function (usbhostenum.c), there are two while loops (see attached). The exterior while loop is waiting for ui32RemainingBytes to be zero and the interior while loop is a while(1) that can be broken out of by various conditions. The problem is presented when a USB device is disconnected while the code within the while loops are being executed. Because of the disconnection, the USB interrupt is triggered and the interrupt handler sets the DISCONNECT bit of g_sUSBHCD.ui32IntEvents. This bit is checked inside of the interior while loop and, since it is set, the Pipe State is set to ePipeError and the interior while loop is broken out of. However, ui32RemainingBytes is still non-zero, so the outer while loop continues executing. The next time through the interior while loop, the DISCONNECT bit is still set and the Pipe State is again set to ePipeError and the interior loop is again broken out of. This becomes an infinite loop. One way to fix the issue would be to clear the DISCONNECT bit which would allow the ePipeError status of the Pipe State to clear ui32RemainingBytes before breaking out of the interior while loop. Another way would be to set ui32RemainingBytes to zero directly.
A condensed version of the code is below.
I have also attached usbhostenum.c to show the entire block..
while(ui32RemainingBytes != 0)
{
//
// Wait for a status change.
//
while(1)
{
//
// If any error event occurs then exit out of the loop.
//
if(g_sUSBHCD.ui32IntEvents & (INT_EVENT_DISCONNECT |
INT_EVENT_VBUS_ERR |
INT_EVENT_POWER_FAULT))
{
//
// Set the pipe state to error.
//
g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState = ePipeError;
break;
}
//
// If data is ready then return it.
//
if(g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState == ePipeDataReady)
{
break;
}
else if(g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState == ePipeError)
{
//
// An error occurred so stop this transaction and set the
// number of bytes to zero.
//
ui32Size = 0;
ui32RemainingBytes = 0;
break;
}
}
}
Thank you.
Sincerely,
Jim Manz
Hi Jim,
sorry but I can't understand where is the problem and where the solution.
In fact the source you posted is exactly the same I found in Tivaware 2.1.0.12573.
Does It mean that the problem is already solved in this version ?
I am experiencing this issue when I connect a memory stick and immediately extract it, before it is enumerated.
Doing so, the function USBHCDPipeRead ALWAYS hangs in the same infinite loop that you described in your post...
I have tried to force the exit from that loop but, from that moment on, the USB stick is no more recognized and enumerated.
Thank you in advance
Mario
I am using:
- EK-TM4C129XL Launchpad
- Tivaware 2.1.0.12573
- usb_host_msc project from Tivaware
Jim,
thank you for the quick reply.
I have applied your correction and now I can see the program flow exiting the internal and external loop.
That is good but the problem is that the USB Host is no more working. When I insert the memory stick again, it is not recognized and enumerated.
In this situation the function USBHCDPipeRead() is continuously involved and it triggers the event INT_EVENT_DISCONNECT (set together with INT_EVENT_SOF).
The field g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState is set every other time at ePipeReadDMA or ePipeReading.
My feeling is that this problem concerns the DMA, but I'm not sure.
Any suggestions?
Thanks
Mario
Hi Vidushi.
The only way I found to bypass the problem is the following:
In the UsbMain() function in UsbHost.c module I have modified the case STATE_NO_DEVICE adding a check on timeout error and performing a USB re-init whenever this occurs. Below the new source code
switch(g_eState)
{
//
// A previously connected device has been disconnected.
//
case STATE_NO_DEVICE:
{
if (g_eUIState == STATE_UNKNOWN_DEVICE)
{
UARTprintf("\nUnknown device disconnected.\n");
}
#if defined(USB_) // MG Patch : USB halted after fast pen-drive insert/extract operation
else if (g_eUIState == STATE_TIMEOUT_DEVICE)
{
USBHMSCDriveClose(g_psMSCInstance);
UsbInit();
SysCtlDelay((g_ui32SysClock / 3) / 5); // 200 ms delay
}
#endif
else
{
UARTprintf("\nMass storage device disconnected.\n");
}
ulPrompt = 1;
break;
}
Regards
Mario
Hi Mario,
Are you talking about usbHostEnum.c?
i didnt get USBHOst.c file in ti:\usblib folder however USBHost.h exists. please clarify.
Regards
Vidushi
Hi Mario,
Please Suggest me temporary solution for this problem till your new library is under development as it is lingering from long time tried lot of solutions but unable to resolve this matter.
Regards
Vidushi
Hello Amit,
can you tell me where can I find the patch you are speaking about?
Regards
Mario
Hello Amit,
I have been working on the same problem for some time, so can you send me a link to the new release, if it's ready. Preferably with the changes that have been made to any source files and which particular bugs does it fix.
Thank you.
Regards,
Stamen.