I've been having some trouble properly making the USB module return a STALL handshake packet. I am using a full gnu toolchain, and a USBDM board to program the chip. The main USB functionality works fine (it is all bare metal stuff, without the Kinetis SDK or any of those frameworks), but it seems that stalling on unrecognized functions on the command endpoint (endpoint 0) isn't functioning properly. I've done a lot of things to try to debug the issue, but haven't quite gotten to fix it.
I'm trying to use the USB functionality in Device mode, and trying to use USB 2.0, rather than 1.1. When a 2.0 device is connected, the linux usb host controller sends a Setup packet for Device Qualifier, which is for High-Speed mode, but I only want to use Full-Speed mode. From what I've read, in this case it is appropriate, and expected, to stall the endpoint when you don't want to support High-Speed mode. The linux usb host controller tries 3 times, and after that if all three were stalled, it just goes on to the usual Get Configuration Setup packet.
Here's what I've found, using wireshark to watch USB transactions (I'm running on x86 GNU/Linux):
- It will reliably always stall the first Device Qualifier packet. Occasionally the second one will also be correctly stalled, and VERY RARELY the third will be stalled correctly as well, allowing the device to actually properly set itself up.
- When it doesn't stall all three, one will timeout after 5 seconds, and then all subsequent requests from the host controller go completely unanswered, usually with a EPROTO (a protocol error).
- It seems there is a timing issue/race condition here, because upon disabling the systick interrupt (so it won't occur during the usb interrupt, it being the only other interrupt I have enabled), all three will always properly stall, although then after that all other requests have a protocol error, which is odd.
All of my code that touches any USB-related registers is contained in the USB interrupt, so there really shouldn't be a race condition occurring.
If I register the device as USB 1.1, it always correctly initializes because no stall is encountered (since the host controller doesn't send a Device Qualifier packet). However, I would really like it to register as USB 2.0, and regardless I need to make sure the stall works correctly.
Currently, I unstall when a new Setup packet comes in, because that is what the USB spec says you should do. However, I've tried unstalling in a variety of locations, in the hopes of making it work.
Does anyone have any bare metal examples of using the K2x USB module, or has anyone ever encountered this sort of thing before? It's difficult to determine whether there's some small hardware defect that may be causing the issue, as unlikely as that may be. My code closely resembles the code found here, which is what I used as a starting point.
Thanks in advance for your help, I'm all out of ideas.