Fx3 design with Burstlen = 16

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ToWu_1150381
Level 1
Level 1
5 replies posted First reply posted First question asked

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?

Thanks

Tony

0 Likes
16 Replies
JayakrishnaT_76
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hello,

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.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Tony,

Please let me add a question.

Did you modify the configuration descriptor to support 16x burst length?

Regards,

Noriaki

0 Likes

Hi Noriaki,

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

mentioned?

Best Regards,

Tony

On Sun, Apr 12, 2020 at 6:49 PM Noriaki Tanaka <

0 Likes

Hi Noriaki,

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

type */

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

Best Regards,

Tony

On Sun, Apr 12, 2020 at 6:49 PM Noriaki Tanaka <

0 Likes

Hello,

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",

                    glDMARxCount, glDMATxCount);

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.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi Jayakrishna,

Following is the original code in cyfxslfifosync.c

void

CyFxSlFifoUtoPDmaCallback (

CyU3PDmaChannel *chHandle,

CyU3PDmaCbType_t type,

CyU3PDmaCBInput_t *input

)

{

CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

if (type == CY_U3P_DMA_CB_PROD_EVENT)

{

/* This is a produce event notification to the CPU. This

notification is

  • received upon reception of every buffer. The buffer will not be

sent

  • out unless it is explicitly committed. The call shall fail if

there

  • is a bus reset / usb disconnect or if there is any application

error. */

status = CyU3PDmaChannelCommitBuffer (chHandle,

input->buffer_p.count, 0);

if (status != CY_U3P_SUCCESS)

{

CyU3PDebugPrint (4, "CyU3PDmaChannelCommitBuffer failed, Error

code = %d\n", status);

}

/* Increment the counter. */

glDMARxCount++;

}

}

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?

Best Regards,

Tony

On Mon, Apr 13, 2020 at 9:55 PM JayakrishnaT_76 <

0 Likes

Hello Tony,

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.

pastedImage_0.png

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.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi Jayakrishna,

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

experiment.

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

condition.

Best Regards,

Tony

On Tue, Apr 14, 2020, 9:27 PM JayakrishnaT_76 <community-manager@cypress.com>

0 Likes

Hello,

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.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi Jayakrishna,

Thanks for your help. I will try to gather all the info and get back to

you.

Thanks

Tony

On Wed, Apr 15, 2020, 8:50 PM JayakrishnaT_76 <community-manager@cypress.com>

0 Likes

Hi Jayarishna,

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)

Best Regards,

Tony

0 Likes

Hello Tony,

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.

Best Regards,

Jayakrishna 

Best Regards,
Jayakrishna
0 Likes

Hi Jayakrishna,

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?

Best Regards,

Tony

On Thu, May 28, 2020 at 8:20 PM JayakrishnaT_76 <

0 Likes

Hello Tony,

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.

pastedImage_0.png

Please share a snapshot of the prints if you find the issue occurring even after making my suggestions..

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello Tony,

In addition to my previous reply, please share the details that I asked in my response 10. This is essential to debug the problem

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi Jayakrishna,

1. Which interface are you using between the tx and FX3? Is it the Slave

FIFO interface?

It's Slave FIFO interface.

2. Which OS are you using for testing? Did you try testing with a different

PC/OS?

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

packets increased.

4. Please share the debug logs so that I can understand the situation

better.

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.

Best Regards,,

Tony

0 Likes