I have a design using FX3 superspeed transaction. In the FX3 setup, I assign Burstlen with 16 to achieve better performance.
It's a Bulk IN endpoint. Packet size = 1024. Buffersize = 16K x 8.
At the end of the tx, HW will issue a PKTEND to end the transaction. Under normal condition, PC can receive data
without any problem. When the problem happens, FX3 hangs and can't send any data back. Setting Burstlen to 1 seems to solve the problem.
Does anyone have any clue what's the cause of this problem?
Please let me know the following details:
1. Which interface are you using between the tx and FX3? Is it the Slave FIFO interface?
2. Which OS are you using for testing? Did you try testing with a different PC/OS?
3. Do you receive any PROD events while setting the Burstlen to 16? If yes, do you see any API failing when Burstlen is set to 16?
4. Please share the debug logs so that I can understand the situation better.
Please let me add a question.
Did you modify the configuration descriptor to support 16x burst length?
Our code is based on the SlaveFifoSync in the "Designing with the EZ-USB
FX3 Slave FIFO Interface AN65974_001-65974_0I_S". I have done this project
a couple of years ago. So I don't have a fresh memory
for all the things I have done. If you like, I can post the code that I
have modified. BTW, where is the configuration descriptor that you
On Sun, Apr 12, 2020 at 6:49 PM Noriaki Tanaka <
I did have the descriptor for the 16x burst length, following is the
structure for this endpoint
// TONY: Endpoint descriptor for Image consumer EP (EP2 IN)
0x07, /* Descriptor size */
CY_U3P_USB_ENDPNT_DESCR, /* Endpoint descriptor type */
CY_FX_EP_IMG_CONSUMER, /* Endpoint address and description
CY_U3P_USB_EP_BULK, /* Bulk endpoint type */
0x00,0x04, /* Max packet size = 1024 bytes */
0x00, /* Servicing interval for data
transfers : 0 for Bulk */
/* Super speed endpoint companion descriptor for consumer EP */
0x06, /* Descriptor size */
CY_U3P_SS_EP_COMPN_DESCR, /* SS endpoint companion descriptor
STREAM_BURST_LEN-1, /* Max no. of packets in a burst : 0: burst 1
packet at a time */
0x00, /* Max streams for bulk EP = 0 (No
streams) */ // TONY: We didn't use Stream Mode
The value for STREAM_BURST_LEN is 16
On Sun, Apr 12, 2020 at 6:49 PM Noriaki Tanaka <
Can you please try testing the firmware using a windows host and let me know if it works for burst set to 16? Also, please confirm that the device is enumerated as a superspeed device.
Regarding where you can find PROD_EVENTS,
In the cyfxslfifosync.c, you will find the callback function CyFxSlFifoUtoPDmaCallback. Inside this, there is a statement:
if (type == CY_U3P_DMA_CB_PROD_EVENT)
This statement shows that a PROD_EVENT has occurred. PROD_EVENTS are triggered when a full buffer is received on the producer socket. Inside this if case, you can use the API CyU3PDeviceReset(CyFalse); to check if you are getting at least one PROD_EVENT. If PROD_EVENT is obtained, the device will go back to the USB boot mode. If this is successful, you can remove the CyU3PDeviceReset(CyFalse); statement. Now you need to uncomment the following statement in the infinite for loop found in the function SlFifoAppThread_Entry.
CyU3PDebugPrint (6, "Data tracker: buffers received: %d, buffers sent: %d.\n",
This will let us know how many buffers are sent and received.
Regarding Debug logs,
The API CyU3PDebugPrint can be used to output debug messages to be written to the UART immediately. For printing these debug messages, virtual terminals can be used. Applications like teraterm, minicom etc can be used for this.
Following is the original code in cyfxslfifosync.c
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
if (type == CY_U3P_DMA_CB_PROD_EVENT)
/* This is a produce event notification to the CPU. This
received upon reception of every buffer. The buffer will not be
out unless it is explicitly committed. The call shall fail if
is a bus reset / usb disconnect or if there is any application
status = CyU3PDmaChannelCommitBuffer (chHandle,
if (status != CY_U3P_SUCCESS)
CyU3PDebugPrint (4, "CyU3PDmaChannelCommitBuffer failed, Error
code = %d\n", status);
/* Increment the counter. */
I don't understand why I need *CyU3PDeviceReset(CyFalse); API *inside if
(type == CY_U3P_DMA_CB_PROD_EVENT) block. If the program enters this
condition block, doesn't it mean that it already gets a PROD_EVENT?
Also, is the CyU3PDmaChannelCommitBuffer() API responsible for committing
and sending data back to HOST for a IN Endpoint. Can I use the
"input->buffer_p.count" variable to check how many bytes of data (payload)
is sending ? Our system uses
3 Endpoint (EP1 IN, EP1 OUT and EP2 IN). In this callback routine, how can
I differentiate them?
As for the debug log, do I need to do anything to enable the UART port? Or,
is it enabled by default? Inside the *SlFifoAppThread_Entry(), *how can I
print the payload count for this DMA transaction?
On Mon, Apr 13, 2020 at 9:55 PM JayakrishnaT_76 <
If you are sure that the program enters the if block for PROD_EVENT then there is no need to add the API for resetting the device inside it. It was just an experiment to confirm that the program enters the if block. Yes your understanding is correct on the API CyU3PDmaChannelCommitBuffer(). You can store the "input->buffer_p.count" into a global variable and print it as a debug message in the infinite for loop.
Regarding your question on distinguishing endpoints, the DMA channels in slave fifo project is created between P Port and U Port. So, it is basically between a P Port socket and USB Socket. The Producer and Consumer sockets for the different DMA channels created in this project can be found inside the function CyFxSlFifoApplnStart. The following code snippet shows the creation of a DMA channel from U to P port.
This declares a USB Socket as Producer. The macro CY_FX_PRODUCER_USB_SOCKET is CY_U3P_UIB_SOCKET_PROD_1 which is the socket associated with OUT Endpoint 1 or 0x01. When a full buffer is received through endpoint 0x01, the PROD_EVENT is triggered and the callback function CyFxSlFiFoUtoPDmaCallback is triggered. So for each channel the corresponding callback function will be triggered based on the notification parameter set while creating the channel. Please let me know if you have any queries on this.
The UART port is by default enabled in the slave fifo firmware. This is done by the function CyFxSlFifoApplnDebugInit(). Inside the SlFifoAppThread_Entry(), you will find the if block if (glIsApplnActive). Inside this if block, you can use the statement:
CyU3PDebugPrint(4, "\r\nPayload Count %d", count);
Here, i have assumed that the payload count is stored into the global variable count.
Also, please let me know the following:
1. Please try testing the firmware using a windows host and let me know if it works for burst set to 16?
2. Please confirm that the device is enumerated as a superspeed device in the linux host.
I believe the linux recognizes the FX3 as a superspeed device. And the
transaction is OK most of the time. In order to duplicate the stuck
condition, we need to let our system run in a special mode (sending a lot
of image data back to host and stop the transaction in the middle) and do a
loop test for 3-4 hours.
As for the windows host, I wish we can do the experiment. Since our system
is based on Linux, all the SW is coding under linux. Just to let the system
runs, it require a lot of initialization procedures and it's all done in
Linux. It's almost imposible for us to rewrite everything just for the
Our device is basically a image scanner. I send image back via a Stream IN
Endpoint. User can issue command to stop the image acqirement. The problem
seems to happen when the PKTEND is sent to stop the tranaction. So I
suspect it may have something to do with the short packet. Do you have any
comment on this? I also like to mention the command Endpoints are OK when
the problem happens.
In the mean time, I will put in some log and hope it can catch the stuck
On Tue, Apr 14, 2020, 9:27 PM JayakrishnaT_76 <firstname.lastname@example.org>
I feel like your first and last paragraph of the previous response is contradictory. So, can you please elaborate the following:
1. How are you reproducing this issue?
2. What is the setup? Is it FPGA->FX3->Linux Host?
Also, please share a snapshot of the Descriptors tab of cyusb_linux after programming the device with your firmware. In addition to this, check how many prod and cons events you are getting. Also, check if you are getting any buffers on the producer socket having less than the full buffer size. This is the buffer received when PKTEND is asserted. Once we understand that the partial buffer is received properly by FX3, we can debug the problem that exist in the communication between FX3 and the host.
Thanks for your help. I will try to gather all the info and get back to
On Wed, Apr 15, 2020, 8:50 PM JayakrishnaT_76 <email@example.com>
I was able to print out the debug info in the for (;;) and hopefully will help us catch the lockup condition. With the PROD_EVENT, I can track how many times the callback is trigger and also how much data is set. But, I wonder if this is enough. When the lockup condition happens, I assume the callback will not be called and how can we start from there? (The best case is to detect a commit error)
According to my understanding, you are using only PROD_EVENT notification for the callback function of DMA channel from P Port to U Port through which the data transmission happens. Please add the notification for CONS_EVENT also for the same callback function. This can be done by changing the notification parameter as CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT.
Now, inside the callback function, if the callback type is PROD_EVENT, increment a global variable and if the callback type is CONS_EVENT, then increment another global variable. Print both these global variables in the infinite forloop. This can be used to understand how much data is received by FX3 through the P Port and how much data FX3 actually sends out to host through U port. Please make these modifications and share the UART debug logs.
You can also check if the CyU3PDmaMultiChannelCommitBuffer() API is failing. If it fails, please let me know the error code.
If the type is CONS_EVENT, do I need to do anything else on top of increasing a global variable? What does this CONS_EVENT do?
I also have a question regarding the CyU3PDebugPrint() command. Following is a example:
for (i=0;i<10;i++) CyU3PDebugPrint (6, "%d-%d ",123, 456);
I assume the output should be : 123- 456 123- 456 ..................
But it seems to insert some strange codes in between 456 & 123. Even with "\n", I got the same thing. Do you have any idea?
On Thu, May 28, 2020 at 8:20 PM JayakrishnaT_76 <
Inside the CONS_EVENT you can just increment a global variable. CONS_EVENT is triggered when a consumer socket empties a DMA buffer. So, from this we can understand how much buffers are actually emptied by the USB host.
Regarding the debugprints, please check if you have set the baudrate to 115200. Also, please try changing the priority i.e the first parameter of the DebugPrint statement to 4 from 6. I have tried this on my end and got the desired prints itself (without any strange characters). Please check the attached snapshot.
Please share a snapshot of the prints if you find the issue occurring even after making my suggestions..
In addition to my previous reply, please share the details that I asked in my response 10. This is essential to debug the problem
1. Which interface are you using between the tx and FX3? Is it the Slave
It's Slave FIFO interface.
2. Which OS are you using for testing? Did you try testing with a different
It's a Linux based system.
3. Do you receive any PROD events while setting the Burstlen to 16? If yes,
do you see any API failing when Burstlen is set to 16?
What's PROD events and how can I see it? For this Burstlen=16 IN End Point,
it's OK most of the time. As I mentioned in my mail, our design relies on a
short packet to end the tx. And it
seems to cause the hang up problem when the frequency of sending of short
4. Please share the debug logs so that I can understand the situation
How can I see the debug log? Our design is basically based on the
"Designing with the EZ-USB FX3 Slave FIFO Interface AN65974_001-65974_0I_S"
source code. So I don't expect to
see any problem.