K22 USB stalling issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K22 USB stalling issue

1,643 Views
afranchuk
Contributor I

Hi all,

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.

Labels (2)
0 Kudos
5 Replies

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Alex,

As I know , K22 just has USBFSOTG mode, so how could the linux host controller recognize it as a high speed device? You know, the USB speed identification for LS/FS device is pull-ups on D+/D-, so in my understanding, the host should know well about the device speed when it is attached, would you please help to clarify? Thanks for your patience!


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

952 Views
afranchuk
Contributor I

Any Full-Speed USB 2.0 device is queried as to whether it is a High-Speed device upon connection, as per the USB 2.0 spec. I have it set up as a Full-Speed device, and it needs to stall the request for High-Speed information so the host knows it doesn't support High-Speed.

I've actually found through some debugging that what's going on is the USB handler is causing a hard fault, sometimes a bus fault and sometimes a usage fault, although when it's a bus fault (and I've disable memory pipelining to get the exact address that is faulting), the address is not a valid location in memory. However I don't think it is due to poor code on my end, because the ONLY dereference of a pointer is done to dereference the bdt address, which should definitely be valid and is maintained as valid. But I'm still debugging further....

0 Kudos

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Alex,

As I know, High Speed devices will start by connecting as a full device. After that, a high speed detection handshake will be executed to identify if the device is high speed or not, but it is not thru request from Host, The USB 2.0 spec address it as below:

High-speed Detection Handshake (not performed if low-speed device detected by hub):

Note: In the following handshake, both the hub and device are required to detect Chirp J’s and K’s of specified

minimum durations. It is strongly recommended that “gaps” in these Chirp signals as short as 16 high-speed bit

times should restart the duration timers.

4. The high-speed device leaves the D+ pull-up resistor connected, leaves the high-speed terminations

disabled, and drives the high-speed signaling current into the D- line. This creates a Chirp K on the bus.

The device chirp must last no less than 1.0 ms (TUCH) and must end no more than 7.0 ms (TUCHEND) after

high-speed Reset time T0.

5. The hub must detect the device chirp after it has seen assertion of the Chirp K for no less than 2.5 μs (TFILT).

If the hub does not detect a device chirp, it must continue the assertion of SE0 until the end of reset.

6. No more than 100 μs (TWTDCH) after the bus leaves the Chirp K state, the hub must begin to send an

alternating sequence of Chirp K’s and Chirp J’s. There must be no Idle states on the bus between the J’s

and K’s. This sequence must continue until a time (TDCHSE0) no more than 500 μs before and no less than

100 μs before the end of Reset. (This will guarantee that the bus remains active, preventing the device from

entering the high-speed Suspend state.) Each individual Chirp K and Chirp J must last no less than 40 μs

and no more than 60 μs (TDCHBIT).

7. After completing the hub chirp sequence, the hub asserts SE0 until end of Reset. At the end of reset, the

hub must transition to the high-speed Enabled state without causing any transitions on the data lines.

8. After the device completes its chirp, it looks for the high-speed hub chirp. At a minimum, the device is

required to see the sequence Chirp K-J-K-J-K-J in order to detect a valid hub chirp. Each individual Chirp

K and Chirp J must be detected for no less than 2.5 μs (TFILT).

a) If the device detects the sequence Chirp K-J-K-J-K-J, then no more than 500 μs (TWTHS) after detection,

the device is required to disconnect the D+ pull-up resistor, enable the high-speed terminations, and

enter the high-speed Default state.

b) If the device has not detected the sequence Chirp K-J-K-J-K-J by a time no less than 1.0 ms and no

more than 2.5 ms (TWTFS) after completing its own chirp, then the device is required to revert to the

full-speed Default state and wait for the end of Reset.

so would you please help to clarify?

Thanks for your patience!

Kan

0 Kudos

952 Views
afranchuk
Contributor I

Well, we brought up another board, but it is having the same issue. We've found that it occurs whether stalling is enabled or not, but when stalling is enabled it happens much more frequently. But sometimes it works! It seems like some sort of race condition between the USBFS and the MCU, since it sometimes works and sometimes doesn't. However, we're pretty sure the state of the buffer descriptors are left appropriate (left pointing to valid buffers and with valid lengths).

The hard faults occur with random causes, whether some invalid instruction or invalid memory access, and the memory access is somewhere way out in invalid regions. Has anyone ever seen this before? When the hard faults return a valid PC, it is almost always the first or second instruction of an interrupt handler, almost always the USB interrupt handler (there are only two active, that and the SysTick handler). I read somewhere that when hard faults escalate they will be thrown when an interrupt of equal or higher priority is entered in certain cases.

All we know is that when the USB isn't initialized (so the USB module is not gated, clocks are not setup, and the interrupt is not enabled), everything works fine, but with the USB module enabled, things start going odd. I read that the USB contains an internal DMA, and I thought that maybe somehow this is what is causing the random memory accesses? We've followed all the documentation available in the reference manual as well as many examples online, but somehow we're doing something wrong.

Attached is our source code for the USB. It's a bit messy at the moment (due to debugging and all that), but we're trying to set up the USB device as a MSD. Regardless, the issue occurs randomly, at random times.

We'd really appreciate it if someone could help, and look at our code to see if anything is particularly bad or possibly causing the problem.

0 Kudos

952 Views
afranchuk
Contributor I

The device IS getting a Device Qualifier query to determine whether it supports High Speed operation. See How does USB stack enumerate a device? - Microsoft Windows USB Core Team Blog - Site Home - MSDN Blo..., for example.

Regardless, I've debugged the issue to the point that whenever stalling is enabled, Hard Faults occur due to completely random writes to memory. I've deduced that this is probably because of a damaged USBFS module, which is likely... When first hooked up, my coworker didn't read the reference manual closely enough and wired 5V from the USB cable to USBVDD, while the reference manual says this should be 3.3V, and furthermore the device data sheet says at most this should be 3.6V. So I've ordered another MCU, and hope that that will fix the issue I'm seeing.

0 Kudos