Persistent stall in the Cypress FX2 FIFO

Hi all, I am using the Cypress FX2 to interface an FPGA to a PC via an USB2.0 link. The FX2 was configured to provide 4 bulk endpoints (+ synchronous FIFOs). Each bulk EP (2,4,6,8) is 512 byte long and is double buffered. All seems to work quite fine, but when a FIFO get full (i.e. the PC send more than 512 bytes) the EP does not take data any more, even if the FPGA empty the FIFO! The endpoint seems to be stalled, but the stall flag in the EPxCS register is cleared. I tryed also to reset the pipe or to send a Clear Feature message, but nothing succeed in unlocking this "stall" condition. What else should i try?!? Any help is highly appreciated! TIA

A.D.

Reply to
A.D.
Loading thread data ...

Hello !

Are you absolutely certain that the endpoint is STALLed ? STALL condition usually means that the endpoint has received an invalid USB request. In this case, and looking at the FX2 TRM, it might mean you're not serving the IBN and PING requests sent by the host.

For example, the host sends you a BULK OUT packet with more data than you can handle in one transfer. First, the DATA IN interrupt of the appropriate endpoint is set, and you service it properly to receive the data and clear the master interrupt (INT2IRQ) and the individual interrupt register. This is all well and good, and is done precisely the same way for transfers which are below the limit. However, when more data is sent in while the buffer is still full (sending more than 512 bytes), the firmware responds with a NAK signal to the host to any further sends. This indicates that the endpoint cannot receive any more data, and in USB 2.0 environment, it instructs the host to start sending PING requests instead. A PING request is much like asking "are you ready yet ?", and is used instead of multiple NAK returns to conserve bandwidth.

In your scenario, it might be possible that after the NAK signal is sent back to the host, you're not serving the PING/IBN interrupts generated by the firmware. If you do not serve these interrupts (clear them), the firmware most likely STALLs the endpoint to indicate that it has received a request that was not served (i.e. an unsupported USB request). Since the host is constantly sending the PING packet to you, and you're not serving it, the endpoint stays STALLed for ever more, regardless of you clearing or resetting the endpoint.

See the FX2 TRM for instructions on how to serve the PING interrupt (Chapter

8.6.3.1.). If this helps you solve the issue, post back to these boards to indicate that it was the culprit. This indication helps others who're wrestling with the same problem

Greetings, Antti Keskinen

----- Original Message ----- From: "A.D." Newsgroups: comp.arch.embedded Sent: Sunday, November 20, 2005 6:28 PM Subject: Persistent stall in the Cypress FX2 FIFO

Reply to
Antti Keskinen

"Antti Keskinen" ha scritto nel messaggio news:dls3d5$2vrr$ snipped-for-privacy@news.cc.tut.fi...

[CUT]

Hi Antti, thank you for your answer! You're right, it doesn't looks like a real stall condition... Moreover in my application I use the AUTOIN/AUOTOUT feature, so the CPU does not access the data (data are directly committed to the FIFOs), and so the CPU doesn't need to handle the IBN and PING interrupt (Am I right?). Today I noticed that the condition that triggers this apparent "stall" is sending 2 bulk packets without empting the FIFO first, it doesn't matter how long they are (it appends even for 4 byte long packets). If I download a packet from the FIFO before sending the next one all works fine... But if the EP receive two packets it doesn't take other packets, even if I empty the FIFO: I have to reset the FX2! I'm really puzzled... :-)

Regards, A.D.

Reply to
A.D.

Hello A.D.

"A.D." scribed:

You're correct, partly. According to the manual, when the endpoint is configured for AUTOIN/-OUT, the FX2 CPU is bypassed and data is directly fed into the FIFOs. However, it might still be possible that the CPU is triggered with the IBN and PING interrupts. Your best bet, if you can access the FX2's firmware code, would be to install some sort of stub routines there that give at least some debug output. This will let you know if the interrupts are fired even when the AUTOIN/-OUT mode is enabled.

Since you're using double-buffering, this is exactly what I'd presumed would happen when you're using the AUTOIN/-OUT feature: the internal firmware of the FX2 is able to receive two packets (each packet occupies it's OWN buffer position), and after receiving two packets without being cleared out, the firmware enters a deadlock-stall state, unable to recover from the situation, because both reception buffers are full.

This hints that the in-built firmware (whatever version it might even be ?) is quite incompetent in it's design: it assumes each packet it receives completely fills the first-, second-, third- or fourth-order buffer, respectively. It cannot handle situations when packets it receives are smaller or larger than what a single buffer could hold.

Your only solution, without rewriting the firmware for FX2, would be to use the triple-buffering feature, and order your FPGA to instantly react for FIFO interrupts. In english, the FPGA must react fast when data arrives into the FIFO, so that it is immediately extracted to whatever temporary storage you can muster up. This allows the FIFO buffer to receive more data from the USB host. Using a triple-buffer allows you some leeway as to how fast the data is extracted from the buffer.

The other option, obviously, is to hand-write the FX2 firmware to be able to cope with smaller-than-buffer or larger-than-buffer packets, so that they get crammed into the same buffer slot or distributed over multiple buffers.

As for the reason as to why the firmware deadlocks when the buffers are "used up", I have no clue. Your best bet would be to e-mail the tech department of Cypress, with exact instructions on replicating what you've observed so far, and a query of how the stock firmware's AUTOIN/-OUT feature really works. Also, in the firmware example, the OUT endpoints are armed with dummy bytes at start-up, with equal dummy writes as there are buffering levels (See page

9-32 in the TRM). I presume you've done this ? The endpoints must be "armed" for the AUTOIN/-OUT feature to work (don't ask me why, though).

Dunno if this helps. But it's worth a shot :)

- Antti

Reply to
Antti Keskinen

"Antti Keskinen" ha scritto nel messaggio news:dlvrhi$249l$ snipped-for-privacy@news.cc.tut.fi...

I use the "old" FX2, not the newer low power one. Yes, I konw, the part that I'm using is discouraged by Cypress... :-)

Yes, it is exactly what happens. I noticed that the manual call this feature "Quantum FIFO"! ...Actually it is a waste of bandwidth! But I suspect that there is also some kind of "silicon bug": apart from the persistent deadlock that is triggered by the reception of N-1 packet (when an N-buffered FIFO is used), I get corrupted data from the FIFO if I send more than one packet. Maybe the newer versions behaves differently...

I found a quick&dirty workaround: I wrote a little routine in the FX2 firmware that stalls the endpoint when the FIFO is not empty, and clears the stall when it get empty. In this way the host have just to try to send a packet until it succeeds...

Inserting the CPU in the datapath will dramnatically reduce the througput. For this reason I have not considered this approach.

Maybe it is a "feature", or maybe it is a bug... I don't know...

Yes, the firmware do this.

I really appreciated your help!

Regards, A.D.

Reply to
A.D.

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.