Hello,
I am developing a bus-powered product using the LM3S5C31 Firestorm part and am implementing the Luminary bootloader. It has been working well on Windows 7 but I found some intermittent enumeration issues in XP. I ran the USB 2.0 command verifier test against the bootloader and I got several failures:
- BOS (binary object store) descriptor test
I spent some time and found the fixes for each of these items.
- BOS test failing
The problem is caused in the USBGetDescriptor() function. I can compile with different optimization settings and sometimes it works, so that made me think of a race condition. It is due to calling USBDevEndpoint0DataAck(false) prior to calling USBBLStallEP0(). Both functions set USB_CSRL0_RXRDYC in the CSRL0 register. I fixed the issue by removing the USBDevEndpoint0DataAck() function at the beginning of USBGetDescriptor() and only calling it in cases where a stall isn't required.
Also, each call to USBBLStallEP0() in USBGetDescriptor() should be followed by:
g_sUSBDeviceState.pEP0Data = 0;g_sUSBDeviceState.ulEP0DataRemain = 0;
So that USBDEP0StateTx() doesn't get called at the bottom of the function.
- Enumeration tests failing
This is caused by HandleReset() causing a device reset if g_eDFUState is not equal to STATE_DNLOAD_IDLE or STATE_DNLOAD_DYNC. If the download hasn't started the state is STATE_IDLE, and the device should not be reset. I added a check for STATE_IDLE to avoid reset and the enumeration test passes.
Regards,
Nick Wright
Nick --
Thank you very much for posting your solution. I ran into the same problem when trying to get a Stellaris device tested for Windows device driver signing (WHQL) because the testing lab caught that same noncompliance. I made the change you describe above (I commented out the unconditional ACK at the top, created a boolean (initially false) to track whether a stall was required, set it to true in a couple of places in the switch statement instead of stalling there, and then after the switch would either send an ACK or a STALL (also clearing the Tx length) depending on the boolean). This now passes the USB Command Verifier chapter 9 tests.
I am puzzled at the fact that this is still not fixed in usblib almost five months later -- I just grabbed release 7243 and the same problem is there (an unconditional ACK at the top of USBDGetDescriptor()). Another bug that I found that affected USB performance under Linux (device would fail to work after being closed and opened in Linux because the "set interface" command would not cause the toggle bit to clear unless the interface had actually changed) has also not been fixed, even though I posted about it here.
Are there any other bugs in usblib that you know about that I should fix before we start mass-producing anything?
I am not aware of anything else. We decided not to go to production with the current Firestorm parts so I haven't worked with this code in a few months.
Good luck,
Nick
Thanks for reporting these issues - I was not aware of them prior to reading this post today. I think it's pretty likely that the official command verifier test was not run on the USB boot loader device so I'll add these issues to our tracking system and make sure we run this test soon. Look for a fix in the next-but-one release of StellarisWare.
Sorry that we missed this post, these are some very useful changes that we will include in our next release. We have implemented the suggested changes and the boot loader now passes the Chapter 9 test from the USB compliance suite.
Aaron, I will get on your other thread to work out what you are seeing with the data toggle.
Paul --
I am still using an older version of StellarisWare, but it should be easy to find this in newer versions.
In the USBDSetInterface() function in usbdenum.c, there is a for() loop over the number of interfaces. Inside of this loop there is a test for the alternate setting, and then a test that looks like this:
if(g_sUSBDeviceState.pucAltSetting[ucInterface] != psInterface->bAlternateSetting)
That is, it is comparing the current alt setting to the one being requested by the host. If they match, it does nothing.
That's the problem. I think you'll find in my other thread that the USB spec says this should change unconditionally. That is, if you remove the test and reconfigure the alt setting anyway (which clears the data toggle bit) then all should be well.
The easiest way to see this is under Linux, and to do this you need to set up a USB transfer that has an odd number of transfers (so the toggle bit on the device is not left in the power-on state). Open and close the device to repeat this transfer, and on the second attempt it will fail because Linux expects everything on the device to reset and the toggle bits don't agree. When Linux closes the device it tells it to go back to its default alt setting, but if it was already there, the StellarisWare code would ignore the request. You can get this to happen elsewhere if you can manually command the device to go back to the setting it is already on after sending an odd number of packets.
This doesn't seem to affect Windows in the slightest, and I don't think that the USB Chapter 9 tests will hit this either.
I'm going to be traveling soon so I may not be responsive -- hopefully this will get you what you need.
Thanks, I will open an issue so that we don't lose this one as well.