Persistent stall in the Cypress FX2 FIFO

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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!


Re: Persistent stall in the Cypress FX2 FIFO
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 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

Antti Keskinen

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

Quoted text here. Click to load it

Re: Persistent stall in the Cypress FX2 FIFO
Quoted text here. Click to load it

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... :-)


Re: Persistent stall in the Cypress FX2 FIFO
Hello A.D.

Quoted text here. Click to load it

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.

Quoted text here. Click to load it

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

Re: Persistent stall in the Cypress FX2 FIFO
Quoted text here. Click to load it

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

Quoted text here. Click to load it

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...

Quoted text here. Click to load it

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...

Quoted text here. Click to load it

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

Quoted text here. Click to load it

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

Quoted text here. Click to load it

Yes, the firmware do this.

Quoted text here. Click to load it

I really appreciated your help!


Site Timeline