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.

TM4C129ENCPDT: USBLIB Hanging in USBDescGetInterface

Part Number: TM4C129ENCPDT

Hello I have a TM4C129ENCPDT processor running TIRTOS 2.1.1.71b

The processor is connected to two USB modems through a HUB.

Most of the time it works fine, but sometimes I find it just freezes in processing USBDescGetInterface.

When it does this it is because the descriptor length is 0 and as such the loop never exits

while(ui32TotLength < ui32Size)
{
//
// Does this descriptor match the type passed (if a specific type
// has been specified)?
//
if((ui32Type == USB_DESC_ANY) ||
(psDescCheck->bDescriptorType == (uint8_t)(ui32Type & 0xFF)))
{
//
// We found a matching descriptor. If our count matches the
// supplied index, we are done so return the pointer.
//
if(ui32Count == ui32Index)
{
return(psDescCheck);
}

//
// We have not found enough descriptors yet to satisfy the supplied
// index so increment our count and continue.
//
ui32Count++;
}

//
// Move on to the next descriptor.
//
ui32TotLength += (uint32_t)psDescCheck->bLength;
psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
}

Any suggestion as to why sometimes the descriptor would have a null length?

The returned size is as expected.

  • Hi Barry,

    I haven't seen this particular issue before and need to delve into it further, I'll give a reply with some more information tomorrow.

    Best Regards,

    Ralph Jacobi

  • Thanks for the reply.

    I have investigated further and found that the reason for the function locking up is that I request a config descriptor of length 209 bytes but only 64 bytes of the data is written to the RAM buffer

    ProcessUSBDeviceStateMachine calls USBHCDGetConfigDescriptor

                ui32Bytes =
                        USBHCDControlTransfer(0, &sSetupPacket, psDevice,
                                                                    (uint8_t *)psDevice->psConfigDescriptor,
                                                                    sSetupPacket.wLength,
                                                                    psDevice->sDeviceDescriptor.bMaxPacketSize0);

    accepts any number of bytes as being okay without checking for the correct length being returned

  • I found when failure occurs, USBHCDControlTransfer returns a size of -1, but the respons only checks for non zero and hence accepts the response as being okay.

  • Hello Barry,

    I have investigated further and found that the reason for the function locking up is that I request a config descriptor of length 209 bytes but only 64 bytes of the data is written to the RAM buffer

    Are you trying to receive the 209 in one packet or broken up across multiple packets?

    Best Regards,

    Ralph Jacobi

  • Hello Ralph

    The USB transfer is set to 64 bytes per packet, so it is across multiple packets.

    I have seen responses with 64 bytes and 128 bytes then fail.

    It always seems to be the first modem to connect in that fails.

    I changed the code to check for the -1 and report unknown connected so the code no longer locks up. What I have found is that when it does fail I either see the USB simply stop working (most common), or the second modem working.  If I reset the failed modem, I don't get another connect attempt as the stack has reported UNKNOWN connected in the first slot and I have a maximum of 3 devices allowed for including HUB.

  • I should add we have thousands of devices using the same TI USB stack but modem direct to the processor USB and have not noticed this issue with those devices. It only seems to occur where the USB modem is connected via the HUB and we have 2 modems connected to the same HUB.

    Also, with my changed detection of -1, when the one modem is working, the other modem recovers after a while. So it seems if stack doesn't hang it will recover, but sometimes it can hang.

    If I restart the application through the debugger, it will hang every 3 to 6 attempts, so is repeatable but not occurring 100% of the time.

    The loop below returns with the eEPOState == eEPOStateError

        while(g_sUSBHEP0State.iState != eEP0StateIdle)
        {
            OS_INT_DISABLE(g_sUSBHCD.ui32IntNum);

            if((g_sUSBHCD.ui32IntEvents & (INT_EVENT_ENUM | INT_EVENT_SOF)) ==
               (INT_EVENT_ENUM | INT_EVENT_SOF))
            {
                g_sUSBHCD.ui32IntEvents &= ~(INT_EVENT_ENUM | INT_EVENT_SOF);

                USBHCDEnumHandler();
            }

            OS_INT_ENABLE(g_sUSBHCD.ui32IntNum);

            if(g_sUSBHEP0State.iState == eEP0StateError)
            {
                return(0xffffffff);
            }

            //
            // If we aborted the transfer due to an error, tell the caller
            // that no bytes were transferred.
            //
            if(g_sUSBHCD.ui32IntEvents & (INT_EVENT_VBUS_ERR |
                                          INT_EVENT_DISCONNECT))
            {
                return(0xffffffff);
            }
        }

  • Hi Barry,

    Thanks for the added details. I've been trying to look for any indicators as to why this is going on via historic support requests, library changes, bug reports etc. but I haven't really come up with anything yet. I find that strange though because surely you can't be the only person using a HUB application like this one, so I am not sure what is unique about your situation versus others. That the return being missing isn't tripping up any other applications is a head scratcher honestly. Either it shouldn't be tripping you up, or others should have run into the issue too.

    For some background here - while I do own support and have a good bit of knowledge of the USB library, I had no role in the development of it, so this is the first time I am really delving into what is going on with these functions.

    I think adding the check for the -1 is a good adjustment and a step in the right direction as well, and the results at least are getting us further along here. That was going to be an ask once I understood you were sending 64 bytes at a time - the stack is only designed to handle 64 byte transfers so if it had been set for more that would have been the issue.

    Given the progress made and the details you've shared, what would help me the most moving forward is if you could get a USB analyzer and capture the USB data being exchanges for both the successful and the failing cases. Then I can review what is different and see what I can come up with for further improvements that can be made to handle this better.

    It might also be interesting to see the traffic for when the modem recovers after a while. That could also be insightful to understand what does and doesn't let the stack properly enumerate the second modem.

    Best Regards,

    Ralph Jacobi