Circular Buffer implementation in Fx3

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

cross mob
poas_4520791
Level 4
Level 4
First like received

Hi

The data from PC should transfer to p-port through circular buffer in a continuous manner and data should not repeat.can anyone help me to do this.

0 Likes
1 Solution

Hello,

I find that data from PC is routed to the USB port (U Port). From there you need to transfer the data to GPIF or P port. I understand this is your basic application. This do not require the use of buffer with 2 different index values.

This can be done by making use of a DMA channel between U port and P Port. The communication between different blocks present in FX3 is done by making use of DMA channels. DMA channel has a logical producer socket which in your case is a USB Socket and a consumer socket which is a P Port Socket. The DMA channel also has buffers associated with it. Each buffer can have a size which is a multiple of 16 bytes. You can make use of multiple buffers to avoid lose of data. This is because if a buffer is full, the producer socket automatically writes data to the next available buffer. In the meanwhile, the filled buffer is committed and emptied.

If the data length is less than 16 bytes or not a multiple of 16 bytes, then you can make use of CyU3PDmaChannelSetWrapUp API to commit the last few bytes. The details regarding this API can be found in page 235 of FX3 API Guide.

Also please try AN87216. It is used for developing a master interface using FX3 for communicating with an external slave FIFO. The full file and documentation regarding this can be found from the following link:

https://www.cypress.com/documentation/application-notes/an87216-designing-gpif-ii-master-interface

Please modify this firmware based on your application and let us know the results.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna

View solution in original post

37 Replies
JayakrishnaT_76
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hello,

Firstly, can you please let us know what did you meant by circular buffer? Is it like a circular queue of  buffer or individual buffers that are circular.

All the buffers used in the example projects provided with FX3 SDK are circular queues of buffer. That is while we create a DMA channel, we set the size of buffer allocated with the channel and the number of buffers allocated to that channel. When a buffer is filled, the incoming data will be automatically written to the next buffer. In the meanwhile, the first buffer is committed to the consumer socket. After committing the buffer, we discard the buffer data. When the last buffer is filled, the first buffer can be used to store the incoming data. For better understanding can you please go through Page 38 of AN75779 which can be found in the following link.

https://www.cypress.com/file/123506/download

Is this what you exactly want?

If you want the other case, can you please let us know what exactly is the application? Also can you let us know how you can understand when the buffer becomes full and what is the advantage of using such a buffer?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

Thanks for your reply, i'm using array of buffers with two variables to hold index values like this,

#define MAX_LENGTH 32

unsigned char buffer [MAX_LENGTH];

unsigned char head;

unsigned char tail;

The advantage of implementing circular buffer is we can send/receive/store  data of large size by Increasing  MAX_LENGTH value.

Best Regards,

Aswini

0 Likes

Hello Aswini,

Please find my comments below:

1. For sending data from U port to P port, we make use of DMA channels.

2. These DMA channels have buffers allocated with it. So you need not create a separate buffer with 2 variables.

3. You can configure the DMA channel as shown below

     CyU3PDmaChannelConfig_t dmaCfg;

     CyU3PMemSet ((uint8_t *)&dmaCfg, 0, sizeof (dmaCfg));

     dmaCfg.size  = CY_FX_DMA_BUF_SIZE;              /* This is the buffer size. You can change the size of this buffer according to your need*/

     dmaCfg.count = CY_FX_DMA_BUF_COUNT;                                           // This is the number of such buffers required

     dmaCfg.prodSckId = CY_FX_GPIF_PRODUCER_SOCKET;                    // producer socket is any socket associated with U port

     dmaCfg.consSckId = CY_FX_EP_CONSUMER_SOCKET;                        // consumer socket is any socket associated with P port

     dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;                              

     dmaCfg.prodHeader = 0;

     dmaCfg.prodFooter = 0;

     dmaCfg.consHeader = 0;

     dmaCfg.prodAvailCount = 0;

     dmaCfg.notification = CY_U3P_DMA_CB_CONS_SUSP;

     dmaCfg.cb = GpifToUsbDmaCallback;

     apiRetStatus = CyU3PDmaChannelCreate (&glDmaChHandle, CY_U3P_DMA_TYPE_AUTO, &dmaCfg)

     This creates an AUTO DMA Channel(without any CPU intervention).

4.The size of the DMA buffers should be multiples of 16 bytes, the maximum size of an individual DMA buffer can be as much as 0xFFF0 bytes. You can configure multiple buffers of such size by changing the CY_FX_DMA_BUF_COUNT value. So that when one buffer is filled, next buffer will be written. This prevents the buffers from getting overwritten.

Best Regards,

Jayakrish

Best Regards,
Jayakrishna
0 Likes

Hii Jayakrishna,

Actually  with circular buffer we can send any number of bytes not only multiples of 16 and also doesn't need to shuffle elements when one is consumed,so i'm trying to implement it.I'm getting the data into circular buffer and then data should transfer to consumer socket.can anyone let me know how to do this.

I used the code which you gave,but i'm not getting the actual output.

Best Regards,

Aswini

0 Likes

Hello Aswini,

Can you please let me know what exactly is the application. Can you also let me know how you are planning to read the data transmitted from U port to P port?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hii,

Data from PC  --> circular buffer --> consumer socket --> p-port.

This is the flow i'm trying to implement in FX3.

Best Regards,

Aswini

0 Likes

Hello,

I find that data from PC is routed to the USB port (U Port). From there you need to transfer the data to GPIF or P port. I understand this is your basic application. This do not require the use of buffer with 2 different index values.

This can be done by making use of a DMA channel between U port and P Port. The communication between different blocks present in FX3 is done by making use of DMA channels. DMA channel has a logical producer socket which in your case is a USB Socket and a consumer socket which is a P Port Socket. The DMA channel also has buffers associated with it. Each buffer can have a size which is a multiple of 16 bytes. You can make use of multiple buffers to avoid lose of data. This is because if a buffer is full, the producer socket automatically writes data to the next available buffer. In the meanwhile, the filled buffer is committed and emptied.

If the data length is less than 16 bytes or not a multiple of 16 bytes, then you can make use of CyU3PDmaChannelSetWrapUp API to commit the last few bytes. The details regarding this API can be found in page 235 of FX3 API Guide.

Also please try AN87216. It is used for developing a master interface using FX3 for communicating with an external slave FIFO. The full file and documentation regarding this can be found from the following link:

https://www.cypress.com/documentation/application-notes/an87216-designing-gpif-ii-master-interface

Please modify this firmware based on your application and let us know the results.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna

Hi,

Sorry for late reply.Based on your explanation i'm trying to transfer data without using circular buffer. I changed the dma configuration code based on the code which you have sent,but while booting fx3 is not detecting.Kindly,let me know what might be the problem.

can you help me to do this?

Regards,

Aswini

0 Likes

Hello,

Can you please let me know which boot mode you used. Also is it like after loading the code, the device does not enumerate in the Control Center Application?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi,

The main problem is,the device is not detecting in control center.

Regards,

Aswini

0 Likes

Hello Aswini,

I found this thread where you addressed the same problem:

FX3 is not detecting

I tried loading the firmware using FX3 Explorer kit and found that it was enumerating properly. Please check your board settings.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi,

yeah,it's detecting in control center but i'm getting 997 error.

Regards,

Aswini

0 Likes

Hello,

Can you let me know whether you are using a vendor command? Also can you share a screenshot of the Control center application when you get the error?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

1.PNG

0 Likes

Hello,

The error 997 occurs when you do not have any data to be transmitted to the host. Please verify whether the data is transferred to the to the P port from the external master. This data transferred by the external master to the P port will be routed to U port via DMA channel. This data can be read by the Host through the U port.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi,

Here i want to transfer data from U port to P port  via DMA channel not from P port to U port .Can you let me know what i need to add to send the data that is getting from PC side to p port.

Regards,

Aswini

0 Likes

Hello Aswini,

If you want to send data from U port to P port, then you need OUT endpoint and not IN endpoint. Please change BULK IN EP 81 to BULK OUT EP 02. You need to change the DMA producer and consumer sockets also. Please check your code snippet below:

pastedImage_0.png

Here, I find that you have created an AUTO DMA channel which is from P to U port and makes use of BULK IN EP 81. You need to change that BULK EP 81 to BULK OUT EP 02. Then you need to use the corresponding Socket ID of BULK OUT EP 02 in the producer socket ID. Consumer Socket ID will be the socket ID of the P Port. Then whenever USB fills a buffer, the Prod event will be triggered and the buffer will be committed to the P Port socket.

Best regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi,

2.PNG

This is the  dma configuration for U to P port.

0 Likes

Hello,

In this configuration, i find that the data is transferred from U port to the CPU and not to the P Port. In order to transfer the data from U port to P port, you need to use the following configuration.

    dmaCfg.size  = DMA_BUF_SIZE* size;

    dmaCfg.count = CY_FX_SLFIFO_DMA_BUF_COUNT_U_2_P;

    dmaCfg.prodSckId = CY_FX_PRODUCER_USB_SOCKET;

    dmaCfg.consSckId = CY_FX_CONSUMER_PPORT_SOCKET;

    dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;

    dmaCfg.cb = CyFxSlFifoUtoPDmaCallback;

    dmaCfg.prodHeader = 0;

    dmaCfg.prodFooter = 0;

    dmaCfg.consHeader = 0;

    dmaCfg.prodAvailCount = 0;

You can choose a MANUAL or AUTO channel depending on the application. If the data is to be transferred from U port to P port without any CPU intervention, you can make use of an AUTO channel. Otherwise you can make use of a MANUAL channel.

apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoUtoP, CY_U3P_DMA_TYPE_MANUAL, &dmaCfg); //for manual channel

apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoUtoP, CY_U3P_DMA_TYPE_AUTO, &dmaCfg); //for AUTO channel

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

I have modified the code,but fx3 isn't detecting there might be some issue in the code.can you please check the below code snippet and let me know the issue.

5-11.PNG

Regards,

Aswini

0 Likes

Hello,

Is it like the device is not showing up in the control center after you load the firmware?

Can you please share the project?

Best regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes
lock attach
Attachments are accessible only for community members.

On Tue, Nov 5, 2019 at 11:19 AM JayakrishnaT_76 <

0 Likes

Hello Aswini,

I find that the device is enumerating properly when i loaded your firmware. I also found that the data transfer was also fine. Please check my screenshot below:

pastedImage_0.png

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

I changed buffer size as 1024 and i have transfered 513 bytes then i'm getting error 997.

I'm not getting more than 511 bytes if i change buffer size also.what may be the problem? can  you let me know.

Regards,

Aswini

0 Likes

Hello Aswini,

Please clarify my doubts below:

1. Are you using USB 3.0 or USB 2.0?

2. How did you change the buffer size? Did you change the variable CY_FX_DMA_BUF_SIZE or size?

3. How did you transfer 513 bytes? Was it a data transfer or file transfer?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

I'm using USB 3.0

How did you change the buffer size? Did you change the variable CY_FX_DMA_BUF_SIZE or size?

yeah,by changing CY_FX_DMA_BUF_SIZE.

How did you transfer 513 bytes? Was it a data transfer or file transfer?

Through control centre i'm transfering data .crop.png

0 Likes

Hello Aswini,

Control Center application is used for communication between Host(PC) and FX3 using the CyUSB3.sys driver. When you want to send some data from PC to U port, you need to use OUT endpoints. IN endpoints are used for reading data from U port to PC. I see that here you have selected Bulk IN endpoint in the control center. But for your application, you need to select BULK out endpoint.

Also can you let me know whether you have modified this project? Because I find that the project attached earlier had all the 3 as OUT endpoints but in the last screenshot, 2 are IN endpoints and the remaining is OUT endpoint.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

I have modified the code and the image i have sent was a previous one just for showing you where i'm transfering data.

Regards,

Aswini

0 Likes

Hello,

Please make use of OUT 1 endpoint as this is the endpoint that is configured in the firmware to be used for the DMA channel between U port and P port. Please try sending data using OUT 1 endpoint. I used the same code and transferred about 947 bytes without any trouble as shown below.

pastedImage_1.png

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

Can you please share a screenshot of the control center application when the data transfer is failing. Please send the screenshot when you are using the latest Firmware.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

5-30.PNG

Regards,

Aswini

0 Likes

Hello Aswini,

Can you let me know how much data you transmitted and how much times did you transmit the data? You have used 192 as Bytes to transfer but i can see only 93 bytes transmitted.  Actually the Control Center application automatically fills the Bytes to Transfer field with the value equal to the number of bytes you enter in the Data to send field. If you change the Bytes to Transfer field to a higher value, then the application will send 0's in the remaining space.

I did the same transfer and found no errors as shown in the fig below.

pastedImage_1.png

I have one more question. You told me before that the data transfer was failing when you try to transfer above 511 bytes. Is this the same now also or is it failing always?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello,

Now i'm receiving large no.of bytes and also i don't have the problem of getting more than 511 bytes.

I have a doubt like if i change bytes to transfer size more than two times  it isn't working.kindly explain the reason for this issue .

i have one more question.Can i transfer .img file?

Regards,

Aswini

0 Likes

Hello,

Can you please let me know whether you are reading data from the P port using any master device?

This error occurs because you are using a buffer count of 2. When you transfer DATA for one time, it will be stored in the first buffer. When you transfer data for the second time, it will be stored in the second buffer. When you do not read data from the other side, the producer will not have buffers to write data. This produces this error. So please read data from the P port using a master.

Yes, you can transfer .img file by making use of transfer-file out button in the control center.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hello Jayakrishna,

Thanks a lot for clarifying my doubts.

Currently i'm working on visual studio  i will let you know if i got any doubts.

Regards,

Aswini

0 Likes

Hello,

In Microsoft visual studio 2017,while debugging i'm getting this issues as shown in below  image and also another thing is"object reference not set to an instance of an object" .can you let me know what might the solution for this.

vs1.PNG

Regards,

Aswini

0 Likes

Hello Aswini,

Please go through the following link to know what is a NullReferenceException and how to fix it.

https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it 

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes