FX3 fifo cannot transfer large data

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

cross mob
lock attach
Attachments are accessible only for community members.
TeLu_4270821
Level 1
Level 1
10 replies posted 5 replies posted Welcome!

I am using FX3 implement a test, The transfer like below:

PC(HOST) ←→ FX3 ← Async SRAM interface(80Mhz) → MCU(STM32)

Here are what I did. Refer AN76405 9.1.8 to write and read to FX3.

1. Use the example from SDK 1.3.  slavefifo_examples/slfifoasync

2. Set async SRAM interface from GPIFII Designer. Every set is default then build it. rename to gpif2sram.h

3. Modify some content in cyfxslfifoasync.c to replace cyfxgpif_asyncsf.h. Also can check my the attach.

    include_header.JPG

     modify.JPG

4. And build the example finally. I only got one warning message warning: sh_link not set for section `.ARM.exidx' without any error.

5. I use CyControl.exe to send bulk to my MCU. It work fine with short data. under 1KB. When I start send 16KB, it will fail at large data transfer (over 16KB).

    997.JPG

       I also found something. My MCU check PP_DMA_XFER in the time(DMA_READY not polling right) which value is always 0x0253. According to reference manual,         DMA_BUSY is always set?

       I also check UART_TX, the message's change like below:

       Data tracker: buffers received: 0, buffers sent: 0.

        ↓transfer 2KB data

        Data tracker: buffers received: 2, buffers sent: 0.

       ↓transfer 2KB data

        Data tracker: buffers received: 4, buffers sent: 0.

        ↓transfer 16KB data

        Data tracker: buffers received: 10, buffers sent: 0.//CyControl.exe shoe error code 997

        If function is work. it would have to show 20 not 10.

       Could anyone can help to give some clue for me?

0 Likes
1 Solution

Hello Terry,

Please refer to section 7.4.7.3  Addressing methods which mentions that when PP_MODE =1, the GPIF II hardware decodes the address based on address bit A7. If A7=1, GPIF II interprets the access as a register access and performs a read or write to the register address specified by A[7:0]. If A7=0, then GPIF II interprets the access to be a socket access and performs a read or write operation to the socket number specified in the PP_DMA_XFER register.

So, to access the PP register like PP_DMA_SIZE can be accessed when A7 bit of the address line is 1. Please confirm this is taken care while accessing from the registers an sockets

"While performing register access, the most significant bit of the 8-bit address should be 1, notifying FX3 that it is register access operation. Similarly, for performing socket access, the most significant bit should be set to 0."

Is possible to put some delay between the register access (PP_DMA_SIZE) and the socket access. If yes, please try with some delay between the register access and socket access.

If possible, please share the MCU code snippet where the register is accessed and then data is being read.

Regards,

Rashi

Regards,
Rashi

View solution in original post

0 Likes
16 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

The error code 997 on Control Center indicates the timeout error. This means that the DMA buffers in FX3 are not free to accept the data sent from the host.

In the the firmware you shared, the DMA buffer size for channel glChHandleSlFifoUtoP is 1024 bytes (is device is USB3.0) and DMA buffer count for this channel is CY_FX_SLFIFO_DMA_BUF_COUNT      (2)

If the MCU is not consuming the DMA buffers as fast as the data being sent by the host then the DMA buffer won't be free and hence the error 997.

To send 16 KB of data, you can increas the DMA buffer size to 16 KB and CY_FX_SLFIFO_DMA_BUF_COUNT (4).

To check if the MCU is consuming the DMA buffers, register for CONS event

dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

    /* Enabling the callback for produce event. */

    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;

    dmaCfg.cb = CyFxSlFifoUtoPDmaCallback;

and then track the CY_U3P_DMA_CB_CONS_EVENT in the CyFxSlFifoUtoPDmaCallback using a varaible and getthe UART prints in the

void

CyFxSlFifoUtoPDmaCallback (

        CyU3PDmaChannel   *chHandle,

        CyU3PDmaCbType_t  type,

        CyU3PDmaCBInput_t *input

        )

{

........

if (type == CY_U3P_DMA_CB_CONS_EVENT)

    {

       glDMATxCount_UtoP++;

}

SlFifoAppThread_Entry(){

.......

CyU3PThreadSleep (1000);

        if (glIsApplnActive)

        {

            /* Print the number of buffers received so far from the USB host. */

            CyU3PDebugPrint (6, "Data tracker: buffers received: %d, buffers sent: %d, buffers_consumed : %d.\n\r",

                    glDMARxCount, glDMATxCount,glDMATxCount_UtoP );

        }

Please let me know if this works

Regards,

Rashi

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

Hi Rashi,

I change from DMA buffer and buffer count like below:

#define CY_FX_SLFIFO_DMA_BUF_COUNT      (4)                       /* Slave FIFO channel buffer count */

#define CY_FX_SLFIFO_DMA_TX_SIZE        (0x8000)             

#define CY_FX_SLFIFO_DMA_RX_SIZE        (0x8000)              

check event CY_U3P_DMA_CB_CONS_EVENT in CyFxSlFifoUtoPDmaCallback.

The result showed my mcu didn't consume the DMA buffers with 16KB.

From FX3's debug UART show:

Data tracker: buffers received: 0, buffers sent: 0, buffers_consumed : 0.

Data tracker: buffers received: 1, buffers sent: 0, buffers_consumed : 1. <--- short data, 5 bytes.

Data tracker: buffers received: 3, buffers sent: 0, buffers_consumed : 3. <--- short data, 2KB.

Data tracker: buffers received: 19, buffers sent: 0, buffers_consumed : 19. <--- Long data, 16KB.

Data tracker: buffers received: 35, buffers sent: 0, buffers_consumed : 32. <--- Long data, 16KB.

Do you have any idea with that?

Terry

0 Likes

Hello Terry,

From the UART prints, it seems that the MCU(master) doesn't consume the data in the DMA buffer.

Please check the interface signals between the MCU and GPIF II of FX3.

To debug the problem, please share the GPIF state machine (gpif2sram.cyfx) that you are working with and try calling CyU3PGpifGetSMState API in the for(;;) loop to check in which state the GPIF II state machine is when the problem occurs

CyU3PGpifGetSMState(&SMState);

CyU3PDebugPrint (4, "\n\rAplnStrt:SMState = 0x%x",SMState);

Also, probe the interfacing signals and share the traces

Regards,

Rashi

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

Hi Rashi,

GPIF project at attach "async_sram.cydsn.zip".

And I also implement the function CyU3PGpifGetSMState in my for(;;). When my MCU didn't consume the buffer.,SMState was 0x6 and 0x4.

I knew what CyU3PGpifGetSMState is. But my interface is too fast. I don't know which function should I callin.

Also please check my waveform with continue read.

READ.JPG

Terry

0 Likes

Update waveform of behavior.

One of failure is the MCU got 2 KB data but without one word then next no data in buffer.

Alltime.jpg

Another is the transfer stop unexpectedly.

Noresp.JPG

0 Likes

Hi Rashi,

If I set below parameter, I cannot transfer over 32KB.

#define CY_FX_SLFIFO_DMA_TX_SIZE        (0x8000)         

#define CY_FX_SLFIFO_DMA_RX_SIZE        (0x8000)       

So I change to 0 to set to infinite.

#define CY_FX_SLFIFO_DMA_TX_SIZE        (0)         

#define CY_FX_SLFIFO_DMA_RX_SIZE        (0) 

I also change the timing, one is polling PP event, from 2us to 10us.

Below is from AN76405 9.1.8

Delay1.JPG

Another is hard to explain. I change below procedure which only receive 1024 bytes then disable DMA. Then reenable DMA and get next 1024 bytes again. The setting which let me get over 1MB data once in while. But after 3 or 4 times transfer 1MB, I got the received buffer and consumed buffer not equal again. I print the state of CyU3PGpifGetSMState() out to check. I found the value was 0,  2 or 3 or 4 . Look like state machine has some trouble...

AplnStrt:SMState = 0x0 Data tracker: buffers received: 3432, buffers sent: 0, buffers_consumed : 3426.

buffers received must 4096 not 3432.

buffers consumed must 4096 too, not 3426.

Delay2.JPG

Below is the window of waveform which CyU3PGpifGetSMState() return 3

Send 1MB: Pattern 5555AAAA5555AAAA...... From logic analysis, D0 can check by 0 1 0 1 0 1

Debuf UART message: AplnStrt:SMState = 0x3 Data tracker: buffers received: 101, buffers sent: 0, buffers_consumed : 95.

allof.JPG

0 Likes

Hello Terry,

After going through the response 4 and 5 of the thread, here are the comments

One of failure is the MCU got 2 KB data but without one word then the next no data in the buffer.

>>Please let me know how much data is being sent from the host when the first issue is seen. Please try sending 2 chunks of 2 KB of data from the host and let me know if the last 16 bite word is missed in both the chunks.

Also, can you try modifying the state machine's transition equation from the ADDR_COMP state to the READ state? Instead of ADDR_CMP_MATCH, you can try ADDR_CMP_MATCH&!OE. This will let know if the issue was caused when both OE and ADDR_CMP_MATCH assert at the same time when in ADDR_COMP state.

Can you please take a reference and measure the timings at which the signals (OE, CE, and A0) are asserted and shared the zoomed traces before two cycles from the instance when the issue is seen so that we can understand which signal is causing the issue.

Regards,

Rashi

Regards,
Rashi
0 Likes

Hello Terry,

To debug the problem we would need to do some test:

1) Please set the transfer size to 0 (i.e. infinite transfer size) and DMA buffer size to 1024 bytes and DMA buffer count to 4 and do not disable and enable the DMA channel.

#define CY_FX_SLFIFO_DMA_TX_SIZE        (0)        

#define CY_FX_SLFIFO_DMA_RX_SIZE        (0)

dmaCfg.size  = size; // size will be 1024 if FX3 is connected to USB 3.0 port

2) After these modifications, build the project and program the FX3.

Please follow the steps for the test:

Step 1: Now, send 1024 bytes to the FX3 from the Control center.

Step2: Check the interface traces and the data bus to know whether the 1024 bytes sent from the control center are received.

Step3: If Step 2 passes, continue (STEP 1 and STEP2) sending data from the control center in 1024 bytes chunk and stop when the data received by MCU is not proper and let me know after how many transfers does the issue occur. Please share the interface signal timing and share the UART debug prints showing the DMA events tracker and return value of CyU3PGpifGetSMState()

Data tracker: buffers received: buffers sent: 0, buffers_consumed :

Regards,

Rashi

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

Hi Rashi,

Below experiment all of change state machine from ADDR_COMP to READ: ADDR_CMP_MATCH&!OE. The attach "sram_interface.cydsn.zip" is what I use.

I always use address 00[A6-A0] to get the bus's data.

If I don't disable, I can only get short data, almost under 8KB.

AplnStrt:SMState = 0x1  Data tracker: buffers received: 6, buffers sent: 0, buffers_consumed : 6. <<<<test 1, count 0 data =0 ,not 5555 or AAAA, return

AplnStrt:SMState = 0x1  Data tracker: buffers received: 5, buffers sent: 0, buffers_consumed : 5. <<<<test 2, count 510 data=0, not 5555 or AAAA, return

AplnStrt:SMState = 0x1  Data tracker: buffers received: 5, buffers sent: 0, buffers_consumed : 6. <<<<test 3, count 0 data=0, not 5555 or AAAA, return

Below is scope from test 3.

//CE = red

//OE = blue

//WE = green

//A0 = yellow

If data not 5555 or AAAA, A0 will 1 0 1 0 1 0 1 0 to trigger scope. It look have critical reflection.

W_AP0298.PNG

Room the fail window:

W_AP0299.PNG

Enable DMA then disable to get 1 KB:

I almost broke my finger to test the 1KB transfer..... It is always feedback 0x1 by CyU3PGpifGetSMState() by small batch transfer(under 1KB).

AplnStrt:SMState = 0x1 Data tracker: buffers received: 2477, buffers sent: 0, buffers_consumed : 2473. // different from 6 because #define CY_FX_SLFIFO_DMA_BUF_COUNT      (4) 

If I use 1MB to transfer data, it have some chance can reproduce CyU3PGpifGetSMState()  return 0 or 3 or 4.

Terry.

0 Likes

Hello Terry,

I always use address 00[A6-A0] to get the bus's data.

If you are using the same address zero to get the bus data, the state "ADDR_COMP" is not needed. Please let me know if this is the case.

From the traces I understand that for (!CE & !OE) the one data word should be driven and when (OE & CE) the address should be sampled. IS my understanding correct?

If not, please explain me the functionality that you are expecting from the GPIF state machine so that I can help you with the designing of the GPIF state machine.

Regards,

Rashi

Regards,
Rashi
0 Likes

Hi Rashi,

Please check below read flow from my MCU:

//CE = red

//OE = blue

//WE = green

//A0 = yellow

W_AP0300.PNG

Read by MCU's controller:

1. !CE and ADDR are set first

2. After 2.8ns, !OE will be set.

3. After 50ns, controller will get the data from GPIF.

4. Once controller get the data, OE set, after 2.8ns, CE set.

Do I modify state machine for GPIF?

You are correct for my bus address plan of get data. It always uses 00 to get data.

Below is the MCU code which is.

while(1)

  {

    //USB3.0 get 1024 byte a time

    wait_us(10);

    if(0x9 == IORD_REG16(PP_SOCK_STAT_L) )

    {

      int Size_from_FX3 = 1024;

      int buffer_cnt=0;

      volatile uint32_t Get_addr = 0x60000000;

      // 0x60000000 == bus address 0x00 (A6 ~ A0)

      // 0x60000002 == bus address 0x01 (A6 ~ A0)

       

      buffer_cnt = 0;

     

      int return_flag = 0;// if not 0, stop main functon and trigger scope

      uint16_t TMP_PRINT;//print data which not 5555 or AAAA

        for ( int i = 0; i < Size_from_FX3/2; ++i)

          {

            test_arry[buffer_cnt++] = *(uint16_t *) Get_addr;//Get data from 0x00

            //check 5555 or AAAA

            if (0X5555 != test_arry[buffer_cnt-1] && 0XAAAA != test_arry[buffer_cnt-1] )

            {

              return_flag++;

              if (return_flag!=0)

              {

                //print fail and stop get data

                TMP_PRINT = test_arry[buffer_cnt-1];

                val = *(uint16_t *) (Get_addr+2);//trigger scope,A0 = 1.

                val = *(uint16_t *) (Get_addr+0);//trigger scope,A0 = 0.

                val = *(uint16_t *) (Get_addr+2);//trigger scope,A0 = 1.

                val = *(uint16_t *) (Get_addr+0);//trigger scope,A0 = 0.

                printf("state machine fail, final data=%X counter=%d\r\n",TMP_PRINT,i);

                return 1;

              }

            }

          }

    }

  } 

0 Likes

Hello Terry,

As mentioned in the description that ADDR is always set to 0 so it seems that transition to IDLE state and IN_ADDR is not required every time.

So, I have modified the the state machine as per the timing you provided.(attached)

Please let me know if the GPIF state machine meets your requirement

check_admux.PNG

Please modify the state machine as per this and let me if it helps.

Regards,

Rashi

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

Hi Rashi,

If I change the state machine from your suggestion. It seem over control, I cannot read P-Port register normally.

I can change my MCU controller to make enable address first. I seem easy to design state machine.

//CE = red

//OE = blue

//WE = green

//A0 = yellow

W_AP0301.PNG

Step 1. !CE ->35ns

Step 2. !OE and DR_DATA  -> 100ns

Step 3. CE & OE->return to idle

The state machine I use like the attach and picture. SMa.JPG

I can access P-PORT register without any issue. But I always get shift word and cannot get last word. I send the pattern like below:

5555 AAAA 5555 AAAA 5555 AAAA......AAAA.total 1KB.

And I got AAAA 5555 AAAA 5555 .....AAAA. You can see I miss the first word 5555. It seem I am noob to design state machine...

Debug UART message from FX3:

AplnStrt:SMState = 0x1  Data tracker: buffers received: 1, buffers sent: 0, buffers_consumed : 1.

It seems I'd consumed already but just lost first 16bit word.

Terry

0 Likes

Hello Terry,

Please probe the data lines to check if the data (first word) was driven from FX3 and not read by MCU.

Please send only 1KB data in the same pattern as mentioned above and share the traces to check if the first word (5555) seen on the traces.

Regards,

Rashi

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

Hi Rashi,

Please see below trace from host send 1KB to FX3:

First read is PP_DMA_SIZE, then get the first data.

full.PNG

You also can see the first word have a strange pulse, and the timing is met with FX3 out the data.

fullintro.jpg

Please check the state machine's timing.

SM25.JPG

SMtiming.JPG

W_AP0307.PNG

You can see the first word D0(data pin 0) was 0. So and I print the data from my MCU also was AAAA(0b10101010) not 5555(0b01010101) with 1KB. So I doubt the pulse which I lost first  word(5555) maybe.

Terry

0 Likes

Hello Terry,

Please refer to section 7.4.7.3  Addressing methods which mentions that when PP_MODE =1, the GPIF II hardware decodes the address based on address bit A7. If A7=1, GPIF II interprets the access as a register access and performs a read or write to the register address specified by A[7:0]. If A7=0, then GPIF II interprets the access to be a socket access and performs a read or write operation to the socket number specified in the PP_DMA_XFER register.

So, to access the PP register like PP_DMA_SIZE can be accessed when A7 bit of the address line is 1. Please confirm this is taken care while accessing from the registers an sockets

"While performing register access, the most significant bit of the 8-bit address should be 1, notifying FX3 that it is register access operation. Similarly, for performing socket access, the most significant bit should be set to 0."

Is possible to put some delay between the register access (PP_DMA_SIZE) and the socket access. If yes, please try with some delay between the register access and socket access.

If possible, please share the MCU code snippet where the register is accessed and then data is being read.

Regards,

Rashi

Regards,
Rashi
0 Likes