About sending multiple of 1kB using FX3

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

cross mob
userc_24743
Level 1
Level 1

 My system is composed with FPGA and FX3.

   

The PKTEND# single  was inserted  along with the last word of data,  and the sizeof of every FX3 buffer was set 16KB.

   

I don't know why  that PC received nothing, when i sent multiple of 1KB data ,but smaller than 16KB,  from fpga to FX3.

   

Can somebody tell me how can i send multiple of 1KB data ,but smaller than 16KB,when the sizeof of every FX3 buffer is set

   

16KB.

   

Thanks

0 Likes
1 Solution
Anonymous
Not applicable

 Hi,

   

 

   

which project ar eyou using? Are you testing using AN65974 GPIF project, or is that your custo project?

   

 

   

Regards,

   

Gayathri 

View solution in original post

0 Likes
30 Replies
Anonymous
Not applicable

 Hi,

   

 

   

which project ar eyou using? Are you testing using AN65974 GPIF project, or is that your custo project?

   

 

   

Regards,

   

Gayathri 

0 Likes
Anonymous
Not applicable

Hi,

   

if you are using the slave fifo interface then assert packet end with the last write. Then FX3 should commit the data to host.

   

regards,

   

lumpi

userc_24743
Level 1
Level 1

Under the situation mentioned above, pc host received nothing , when i send 1kB once.

   

After the sending of the second time,PC received 2 packets, one is 2KB,another is 0KB.

   

I don't know what 's the reasion.

0 Likes
Anonymous
Not applicable

 Suyang,

   

Please create a tech support case so that one of our customer support engineer helps you in solving your issue.

   

Let me know if you need any help in creating the tech support case.

   

Thanks,

   

Sai Krishna.

0 Likes
Anonymous
Not applicable

 Hi suyang208,

   

 As Lumpi pointed out, the PPORT buffer content will not transferred automatically to USB end till the buffer is full. If you are sending 1KB of data external source to Slave Fifo buffer of bigger size (16 KB in your case), you  need to assert PKEND signal with SLWR and SLCS signals for last word write. 

   

I assume you are using the Slave Fifo state machine provided as example project with GPIF 2 designer. It should work fine

   

Alternatively, you can try with the state machine and firmware I have attached in the .zip file..

   

This state machine is similar to Slave Fifo example project provided except that , for short packets (anything less than 16KB) instead of doing COMMIT action in GPIF state, interrupt is generated using INTR_CPU action and commit action is done in the firmware using CyU3PDmaChannelSetWrapUp() API which is called in CyFxApplnGPIFEventCB() function ( Registered callback function for the INTR_CPU action) . You can also add UART debugprints to check if callback is happening.

   

 

   

Regards

   

Mudabir Kabir

Anonymous
Not applicable

 I am sorry. I couldnt upload the files here. Here is the link to the attachment.

   

https://docs.google.com/file/d/0B-EPqwXSNA3lUENWRTZRbTcxR1E/edit?usp=sharing

   

Regards

   

Mudabir Kabir

userc_24743
Level 1
Level 1

 hi, Mudabir Kabir, thanks for your answer!

   

Following your advice,it will work when sent data size of whick is non-integer multiples of 1KB(less than 16KB),just like 1KB+4B.

   

But it doesn't work when the size is multiples of 1KB,the result is the same that pc can't receive any packet ,when the size of urb is set the same as the size of the dma buffer(16KB).

0 Likes
Anonymous
Not applicable

Hi,

   

Can you elaborate about your application so that we can help you further.

   

What is the External Master you are using. For a 16 KB buffer, 1KB or 1KB+4 bytes , both are considered short packets and on asserting PKEND signal with SLWR and SLCS, the data should be committed to USB end. 

   

In the previous post , on using interrupt CPU method, did you see callback occuring. ( You can check using UART debugs). This will help tell if the problem is with the Slave Fifo state machine or external master.

   

Regards

   

Mudabir Kabir

Anonymous
Not applicable

 Hi

   

 

   

Are you trying fro Control center or custom application? If custom application, can you try with Control center. What do you mean by "pc can't receive any packet ,when the size of urb is set the same as the size of the dma buffer(16KB)"?

   

 

   

Regards,

   

Gayathri

lock attach
Attachments are accessible only for community members.
userc_24743
Level 1
Level 1

 Hi .

   

     The whole question is described in the  attached Image.

   

     I don't know the reason of Red Part, and how can i to send the multiples of 1KB data by FPGA.

0 Likes
Anonymous
Not applicable

Hi,

In PC application, multiple to packet size buffer must be provided to USB driver to perform read from device. USB driver will complete the read operation when the whole buffer gets fulfilled, or, it receives Short Packet (data amount in packet is less than max packet, but not zero) or Zero Length Packet (ZLP, data amount in packet is 0) from device.

So, if you want to receive packet size (1KB) chunks of data in PC application, you can provide just a packet size read buffer there.

If you provide bigger buffer then device must send Short Packet or ZLP to force the read operation in PC to complete prematurely.

If you assert PKTEND simultaneously with last data then FX3 commits data to PC. In cases where data amount in FX3 buffers is not multiple to packet size, the last packet sent to PC will be naturally Short Packet. And this completes read operation in PC.
If data in buffers is multiple to packet size, then the last packet will be the full packet. And of course this does not complete the read in PC.
You have to force FX3 to send extra ZLP in this case.
 

   

Br,
Kalev

 

lock attach
Attachments are accessible only for community members.
userc_24743
Level 1
Level 1

Hi,thanks for your answer !

   

I used extra ZLP ,but some  phenomenon  which could not be understood occured ,shown the attach image.

0 Likes
Anonymous
Not applicable

 Are you deasserting the SLWR and asserting PKTEND at the same time? If so, try giving one cycle delay after deasserting the SLWR and then assert PKTEND signal.

   

 

   

regards

   

Gayathri

0 Likes
userc_24743
Level 1
Level 1

I have given four cycles delay after deasserting the SLWR and then assert PKTEND signal,but the result was the same.

0 Likes
Anonymous
Not applicable

 Hi,

   

 

   

Please create tech support case at www.cypress.com -> Support -> Technical support. One of our engineers can assist you through. I believe we may have look into the project and try replicating it here.

   

 

   

Regards,

   

Gayathri

Anonymous
Not applicable

Hi,

See "known issue" 9 in Cypress EZ-USB FX3 SDK Release Notes, Version 1.3 (FX3ReleaseNotes.pdf). Sending ZLP may cause transfer errors (unfortunately it's not described what kind of errors). You could try with huge pauses between USB packets.

I personally would avoid sending ZLP. If possible, send some dummy data instead. Or split the last full packet.

br,

kalev

0 Likes
userc_24743
Level 1
Level 1

 Hi,

   

I tried with enough pauses between USB packets,but it was still the same.

   

I tried to creat a case but  the web shown that " You do not have access to this application. Please contact webmaster@cypress.com".

0 Likes
Anonymous
Not applicable

 To create a TS case, please follow these steps :

   

 

   

1) Login into CY website.

   

2) go to Support and Community -> Technical Support -> Create a MyCase

   

3) Provide the details.

   

Regards,

   

-MADY

0 Likes
Anonymous
Not applicable

 I have come accross the same issue.  Any even multiple of 1024 bytes is sent to the USB3 from an FPGA, but nothing is received by the PC.  There are no errors.  If I send less than or more than a multiple of 1024 bytes, everything works fine.  In each case, PKTEND is set when sending the last 4 bytes (using 32 bit interface).

   

  Another issue is when sending 16384 bytes (MaxPktSize), but this causes an error on the PC.

   

  Is it possible that sending the last data with PKTEND set causes an issue if it is an exact frame size (multiple of 1024 bytes)?  This was one case I haven't yet tested.

0 Likes
Anonymous
Not applicable

 Hi everyone,

   

Through brute force experimentation and no help from any of the documentation I figured out how to write multiples of 1024 byte packet multiples to FX3 in synchronous slave FIFO mode. It basically goes like this, assuming 32-bit mode.

   

1) Write words 1 - 255 by asserting slcs_n = 0 and slwr_n = 0.

   

2) Write word 256 (or whatever multiple of 1024 bytes is your total stream length) with slcs_n = 0 and slwr_n = 0. Keep pktend_n = 1 !

   

3) Wait for 4 GPIF clock cycles.

   

4) Assert pktend_n = 0 for exactly one clock cycle to create a ZLP.

   

5) Wait 4 more clock cycles before doing anything else.

0 Likes
Anonymous
Not applicable

 This works great for 1kB multiples except when it reaches 16kB (FX3 Buffer Size).  Does anyone have a solution for transmitting a single 16kB (16384 bytes) packet from the Slave FIFO interface all the way to the PC?

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

 I have changed the State Machine (using GPIF II) and have eliminated all "Mirrored States" which changed the protocol slightly.  The packets now work as I would expect them to function (ie less than a full packet, send PKTEND active while writting to the last 32-bit word with no ZLP following.  For exact packet size, send last 32-bit word with PKTEND inactive while writing, then wait a short time and write a ZLP).  This works for reliably sending up to 64K Bytes from the Slave Port to the PC.  There is still an issue in sending multiple 16K Byte packets back to back without waiting or you loose multiple 32-bit words at the beginning of the next block of transfers.

   

  Another issue is with sending a lot of transfers with less than 16K Byte back to back, and it is dependant on the size of the transfers. 

   

  I have attached the State Machine Diagram.

0 Likes
Anonymous
Not applicable

Hi halftrack,

> ...then wait a short time and write a ZLP

You should not rely on timings. Instead, you should check GPIF flags. You cannot write any data (including initiating ZLP) into FX3 if there is no free buffer ready.

   

See also known issue #9 in FX3ReleaseNotes.pdf - sending ZLP may cause data transfer errors.

   

Note that it's not easy to guarantee enough pause between ZLP and subsequent data packet as this is suggested by Cypress. According USB protocol, host polls for IN pipe packets. Although you initiate sending of ZLP in FX3, host may start polling/receiving of this packet significantly later. Depending on host application and load on CPU, pause may exceed tens of seconds. And even if host starts polling of this ZLP, still errors in USB cable may cause this ZLP to be re-polled/re-sent over cable several times.

   

To build bulletproof workaround in FX3, you should be able to determine when exactly FX3 finishes sending of this ZLP over USB cable. Probably it's easier to solve this issue in host application - pause a bit there before starting next read if ZLP is received (I have not verified this solution).

   

If you know data length beforehand (as it seems to be your case) then you can avoid sending ZLPs just by splitting last full packets into two Short Packets.

   

br,
kalev

0 Likes
Anonymous
Not applicable

Kalev 

   

  Thanks for the response. I have correctly increased the delay after writing a Zero Length Packet to meet the 125uS and I have always been using the DMA Flags to ensure writing only when the flags are valid.  There is an issue when you write a full buffer (16384 bytes) that appearantly does not set the DMA flag properly and this is why I need a wait after fully writing to the buffer.  If I don't wait after writing a full buffer before I send the Zero Length Packet, the full buffer of data is lost.  If I write 1 word less than the full buffer size, everything works fine with sending a short packet (PKTEND is active during last write).  I understand this is not a proper use, but the issue is with the Cypress FX3 and this was the only solution that appears to provide some level of operation!

   

  I would appreciate any information that may solve this issue in a better way.  Please tell me if you find a working solution.

   

Note: Using dedicated DMA Flags to "DMA Thread 3 Ready".   This is what I believe is my Bulk In Flag to use for writing to the DMA engine when the two bit address is "11".

   

Scott

0 Likes
Anonymous
Not applicable

Hi Scott,

I write across buffer boundaries in my design all the time but I have never hit data loss.

Differently from you, I do not use GPIF address lines. Could it be that there is something wrong in controlling addresses?

I use Thread_0_DMA_Ready and Thread_0_DMA_Watermark flags to determine whether the write to FX3 buffer is allowed or not. While Thread_0_DMA_Watermark and Thread_0_DMA_Ready both are asserted (i.e. there is a lot of free space in buffer) then I write data items in burst mode at each clock front. When Thread_0_DMA_Watermark gets deasserted (buffer is almost full) then I wait several clock cycles after every single write to let the Thread_0_DMA_Ready to settle down/reflect buffer state. If Thread_0_DMA_Ready still keeps asserted, I write next data item. Etc.

I also never generate ZLPs.

With such an implementation I have never seen data loss.

> If I don't wait after writing a full buffer before
> I send the Zero Length Packet, the full buffer of data is lost.

Is sending ZLP the key for data loss? If you continue sending data without inserting ZLP, does it work?

About this 125us delay after ZLP. Are you inserting this delay between writes in GPIF side? ZLP known issue refers to the timing problem in USB communication between FX3 and Host. You can't control USB timings reliably from GPIF side.

With FX3 DMA callbacks you can verify what the buffers with what data are delivered from GPIF to USB, so that you can determine whether the data gets lost in GPIF or USB side.

br,
kalev
 

0 Likes
Anonymous
Not applicable

 kalev

   

  You might want to verify everything works fine when you write exactly 1 buffer size (this is 16384 bytes or 2048 32-bit words in my case).  The only time I have an issue is writing exact multiples of 1 buffer size.  

   

 

   

I can write any amounts, except exact multiples of the buffer size, and everything works fine.  

   

If I write exactly 1x, 2x, or 3x the buffer size, there is data loss of the data sent. (unless I delay before writing the zero length packet)

   

If I write exactly 4x the buffer size (ends up being 65536 bytes), this works fine.  I am not sure why this works.

   

 

   

br

   

Scott

0 Likes
Anonymous
Not applicable

Hi Scott,

I guess you perform 64K byte reads in host. Then, when FX3 has sent 64K bytes of data, the entire host buffer gets fulfilled and is returned to your application. See my post on 24 Oct 2013 above.

If you perform 64K reads in host and transferring of 4x buffer size 16K data succeeds, then I believe that you check GPIF flags correctly. Otherwise some data should get lost during switching from one buffer to another.

If you send 1x, 2x, or 3x buffer sizes of data, you generate ZLP respectively in 2nd, 3rd, or 4th buffer.
Do you state that if you generate this ZLP immediately after the buffer becomes available (i.e. flags indicate the buffer is empty) then the data gets lost?
And if you wait a bit more and then generate ZLP, then the transfer succeeds? BTW, how much do you wait?

So, according your tests, there is significant difference whether you write data into buffer or generate ZLP there? Data can be written immediatly, ZLP not?

How the read operation finishes in Host? Does it return with SUCCESS code, just with less data than expected?

kalev 

0 Likes
Anonymous
Not applicable

 Kalev

   

  Specifics for full buffer test related to multiples of 1024 byte writes (slave FIFO to PC).

   

  If I detect a last write that falls on any 1024 byte boundary, I don't set the PKTEND bit when writing the last 4-byte word (I have a 32 bit interface).  I then wait 4 clock cycles to ensure that the flag has been updated.  Then I check and wait for the flag to indicates that the device is ready.  I then proceed to send the ZLP. 

   

  For sizes less than or more than  the exact multiples of a full buffer size (16384 bytes), this works and the PC receives the data properly.

   

  For exact multiples of the full buffer size (16384 bytes), except at 65536 bytes, the slave FIFO interface acts as it does for all other cases, except there isn't any response from the PC (no data received, no indication of any lose of data, no errors or problems)   I then send a short packet to the PC and only the short packet is received by the PC, with everything working just fine.  

   

Note: I have found out that the delay doesn't always work either.

   

Scott

0 Likes
Anonymous
Not applicable

Hi,

Based on your description:

   

a) everything works if there is some data in a buffer when you assert PKTEND. Note that depending on amount of data in buffer, FX3 either sends a Short Packet (data is not 1024 multiple) or ZLP (data is 1024 multiple) as a last USB packet to host in this case.

b)  asserting PKTEND seems to be ignored if you have switched to new empty buffer. However, if you write data to this buffer, performing the check of flags exactly with same timings, data is not ignored!

I could conclude that FX3 ignores the requests to send empty GPIF buffers to host. But you say that waiting a bit before asserting PKTEND mostly helps. Very strange. Why should this depend on timing?

Could it be that you do something with buffers in software callbacks? For example discard empty buffers?

For exploring purposes you could try also to send  ZLPs only without data at all.

But in general, if possible, I suggest to avoid ZLPs due to their "known issue".

br,
kalev

0 Likes
Anonymous
Not applicable

Hi Scott,

Few ideas for exploring GPIF/USB behaviour.

1) GPIF DMA state machine should submit fulfilled buffers automatically to USB DMA. Asserting PKTEND should force GPIF to submit the underling buffer prematurely.

You can set DMA to MANUAL mode and simulate data sending with software only. Committing full 16384 bytes buffer and empty 0 bytes buffer from software should be equivalent to how you send 16384 bytes from GPIF.

2) You can register DMA callbacks and verify there, what the buffers the GPIF actually submits to USB.

br,
kalev

0 Likes