I'm using FX3 to transfer data from FPGA to USB host via GPIF and encounter some problems with data transfer.
Hope someone could tell me what to do to identify the cause or give me any advice to prevent the situation.
I use a two-socket DMA channel with AUTO_MANY_TO_ONE type and every address has 6 16-KB buffer.
Input are address 0 and 1 of GPIF and output is usb port.
GPIF is configured for 32-bit data buses and input clock is 99MHz.
After data transferring for a while, data packets received by PC and hardware USB analyzer would be wrong .
The length of the time before it happens is random.
Once the data is wrong, the situation would last.
The following are 2 situations of wrong data.
1.Input data at address 0 of GPIF :55 33 56 4C 00 00 34 00 22 E8 00 00……
but data that hardware USB analyzer and USB host receive become
75 75 76 76 77 77 78 78 00 00 70 68 55 33 56 4C 00 00 34 00 22 E8 00 00 …
There are some unknown data appearing in the front of the data I input.
I have checked every byte of dma buffer memory continuously to see if unique header "55 33 56 4C" is written at wrong memory address.
But the header data are always written at the head of every dma buffer without offset and unexpected data.
2.The order of data I sent to GPIF was
address 0 data A
address 1 data B
address 0 data C
but the order of data received by USB analyzer is NOT data A ->B ->C
Configuration of Dma channel and GPIF
muldmaCfg.size = (16 * 1024);
muldmaCfg.count = 6;
muldmaCfg.validSckCount = 2;
muldmaCfg.prodSckId = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_0;
muldmaCfg.prodSckId = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_1;
muldmaCfg.consSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_3);
muldmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
muldmaCfg.notification = 0;
muldmaCfg.cb = 0;
muldmaCfg.prodHeader = 0;
muldmaCfg.prodFooter = 0;
muldmaCfg.consHeader = 0;
muldmaCfg.prodAvailCount = 0;
CyU3PDmaMultiChannelCreate(&G_DmaChHandle, CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE, &muldmaCfg);
CyU3PDmaMultiChannelSetXfer(&G_DmaChHandle, 0, 0);
pibClock.clkDiv = 2;
pibClock.clkSrc = CY_U3P_SYS_CLK;
pibClock.isHalfDiv = CyFalse;
CyU3PGpifSocketConfigure(0, CY_U3P_PIB_SOCKET_0, 6, CyFalse, 1);
CyU3PGpifSocketConfigure(1, CY_U3P_PIB_SOCKET_1, 6, CyFalse, 1);
GPIF state machine:
- Since you are using AUTO channel I think the headers are being added in the FPGA. Right?
- And can you please let me know what is the clockConfig structure which is passed when calling CyU3PDeviceInit() API.
- And are you taking care in the FPGA to send exact 16KB of data to each socket and before sending next 16KB do you switch the GPIF thread address lines from the FPGA? (And sampling of these address lines is being done in IDLE state right?)
Thanks for your help!
1.Yes, all the data processing are in the FPGA including headers adding.
clockConfig.setSysClk400 = CyTrue;
clockConfig.cpuClkDiv = 2;
clockConfig.dmaClkDiv = 2;
clockConfig.mmioClkDiv = 2;
clockConfig.useStandbyClk = CyFalse;
clockConfig.clkSrc = CY_U3P_SYS_CLK;
3.Yes,I send exactly 16KB data to each socket.If not, there would be a packet end signal to indicate the end of data.
4.I switch GPIF thread address at the end of last 32-bit of data simultaneously.
I will check the timing of switching address again!
Also please refer to the state machine and firmware of AN65974(http://www.cypress.com/documentation/application-notes/an65974-designing-ez-usb-fx3-slave-fifo-inter... )
- In your first post you had mentioned your data order as following:
"The order of data I sent to GPIF was
address 0 data A
address 1 data B
address 0 data C"
Here what does data A/B/C indicate? Is it one word Or one buffer amount of data?