I am using a TM4C129XNCZAD part on a custom board. I am seeing a situation where my USB device (board) is not connecting to a Windows 7 host. I have narrowed it down to the firmware gettng put into a "Stall" state and not ever getting out. If I clear the stall state (i.e. set it to the "Idle" state using the debugger) things work as expected.
I see where the Stall state is set in USBLib\driver\usbdenum.c in the USBDCDStallEP0 () function shown below:
void USBDCDStallEP0(uint32_t ui32Index) { ASSERT(ui32Index == 0); // // Stall the endpoint in question. // MAP_USBDevEndpointStall(USB0_BASE, USB_EP_0, USB_EP_DEV_OUT); // // Enter the stalled state. // g_psDCDInst[0].iEP0State = eUSBStateStall; }
The Stall state is then supposed to be cleared in the USBDeviceEnumHandler function in the same file. the particular case is shown below:
case eUSBStateStall: { // // If we sent a stall then acknowledge this interrupt. // if(ui32EPStatus & USB_DEV_EP0_SENT_STALL) { // // Clear the Setup End condition. // MAP_USBDevEndpointStatusClear(USB0_BASE, USB_EP_0, USB_DEV_EP0_SENT_STALL); // // Reset the global end point 0 state to IDLE. // pDevInstance->iEP0State = eUSBStateIdle; } break; }
Before clearing the Stall state, the code checks the ui32EPStatus variable to see if the USB_DEV_EP0_SENT_STALL bit is set. My question is: how does this bit get set? I see nowhere in the code where this happens. Is this done within the hardware and when the status is read the will be set? If so, is it possible that there is a possible race condition that the status is checked before it is set in hardware? Is there any reason that changing the state to Idle should not take place regardless of the status?
Thanks much,
Jeff