- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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).
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?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Terry
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Update waveform of behavior.
One of failure is the MCU got 2 KB data but without one word then next no data in buffer.
Another is the transfer stop unexpectedly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Room the fail window:
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rashi,
Please check below read flow from my MCU:
//CE = red
//OE = blue
//WE = green
//A0 = yellow
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;
}
}
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Please modify the state machine as per this and let me if it helps.
Regards,
Rashi
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rashi,
Please see below trace from host send 1KB to FX3:
First read is PP_DMA_SIZE, then get the first data.
You also can see the first word have a strange pulse, and the timing is met with FX3 out the data.
Please check the state machine's timing.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi