Not able to get continuous data using two DMA threads

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.
mgiacomelli
Level 3
Level 3
25 replies posted 10 questions asked 25 sign-ins

I'm trying to read an ADC continuously using the FX3 evaluation board as in the UVC example.  I've wired up the ADC and can read samples using two threads, but I still occasionally notice discontinuities when reading a function generator output.  My understanding is that this should not happen when when using two thread.  Here is my state machine:

image (2).png

And here is my DMA configuration:

 

 

//try creating a many to one dma channel

CyU3PDmaMultiChannelConfig_t dmaMultiConfig;
CyU3PMemSet ((uint8_t *)&dmaMultiConfig, 0, sizeof (dmaMultiConfig));

dmaMultiConfig.size           = 16384; 	//GPIF counters set to 4095 32 bit words
dmaMultiConfig.count          = 4;
dmaMultiConfig.validSckCount  = 2;
dmaMultiConfig.prodSckId [0]  = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_0;
dmaMultiConfig.prodSckId [1]  = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_1;
dmaMultiConfig.consSckId [0]  = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0);
dmaMultiConfig.prodAvailCount = 0;
dmaMultiConfig.prodHeader     = 0;              
dmaMultiConfig.prodFooter     = 0;              
dmaMultiConfig.consHeader     = 0;
dmaMultiConfig.dmaMode        = CY_U3P_DMA_MODE_BYTE;
dmaMultiConfig.cb 			= NULL;
dmaMultiConfig.notification   = 0;

apiRetStatus = CyU3PDmaMultiChannelCreate (&glDmaChHandleMulti, CY_U3P_DMA_TYPE_AUTO_MANY_TO_ONE,&dmaMultiConfig);

 

 

 

I set the bus with to 32 bit, and the ADDR and DATA counters to 4095, which means that exactly 16384 bytes should be written before the buffers flip, is that right?  Still it seems that after size*count*producers I usually get a discontinuity where at least a few samples are missing.  Thereafter they happen sporadically.  

 

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

Hello,

I have modified the firmware to register callback for the Gpif errors using CyU3PPibRegisterCallback and added debug prints to track the DMA buffers.

Please use the old state machine with 4095 as counter value and new state machine with 4096 counter value, build the firmware and  share the UART debug prints for both cases.

Please let me know if control center is used. If yes, please send 16384*3 bytes data from GPIF and do BULK IN to receive 16384*3 bytes and share the snippet of control center to understand the problem better

Regards,
Rashi

View solution in original post

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

Hello,

I set the bus with to 32 bit, and the ADDR and DATA counters to 4095, which means that exactly 16384 bytes should be written before the buffers flip, is that right? 

>> Yes, your understanding is correct

 Still it seems that after size*count*producers I usually get a discontinuity where at least a few samples are missing.  Thereafter they happen sporadically.  

>> do you mean after every buffer (16384 bytes) the data is missing or is after 8 buffers the data is missed.

Can you try sending an incrementing data from GPIF block to check where the data is missed or share the results that you have which shows the error

Also, configure the system clock to 403.2 MHZ by setting the below parameter to true

clockConfig.setSysClk400 = CyTrue;

Regards,
Rashi
0 Likes

Thanks for the suggestion.  I increased the clock but it did not change the result.  With the above configuration, here is a diff of a smooth, periodic waveform (spikes are discontinuities):

image.png

The first one almost always occurs at 16384 samples.  Thereafter many of them are 4096 byte aligned.  

 

Here is an actual discontinuity:

mgiacomelli_0-1611767238812.png

 

In total 1963 (or maybe 1962 depending on noise) samples are lost (or maybe misordered?).  At 25 MHz PCLK this is 78.5 microseconds of data.  I tried a lower PCLK just in case it was a clocking issue, but the results were similar.  Since it happens after a fixed number of samples, I assume it is probably a software error on my part. 

 

One other strange thing I noticed.  If I change the function generator output, and then acquire with the streamer program, I get old data (shows previous function generator output) at first.  Is it possible I'm not initializing or resetting buffers?  I thought the dma engine would do this automatically, but if I am able to get stale data that might not be the case.  

0 Likes

Hello,

As the data is missing at the end of the buffers (16384) or during thread switching, it is possible that the data is lost when the thread switching is done. Thread switching switching generally take few micro seconds of time.

Please refer to this thread Solved: FX3 data loss in thread switching - Cypress Developer Community with similar problem and try configuring the counter limit to 4096 in your case and let me know the results

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

I changed my state machine to be as close as possible to that example:

 

 

mgiacomelli_2-1611863830343.png

Which results in:

mgiacomelli_0-1611862599294.png

Buffer number is in red, 43 Hz triangle function in blue.  As you can see, at least several thousand microseconds are randomly dropped, and thereafter buffers seem to lose sync with the GPIF state machine.  The buffer numbers are sequential though, so none are lost, just they are filled with the wrong data.  This is similar to with 4095.  

 

It seems to me that there are two issues here which may give clues:

1)  The first round of buffers appear to be filled with data acquired much earlier than the rest of the acquisition, at least many milliseconds earlier, or even just old data left in RAM.

2) Once data starts being acquired continuously, the GPIF state machine seems to get out of sync with the DMA buffers, resulting in data starting/stopping in the middle of buffers.  

I've attached the whole project if you have any ideas.  I'm completely lost, so I think I will need to reread the programmers manual again and see if anything jumps out at me. 

 

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

Hello,

I have modified the firmware to register callback for the Gpif errors using CyU3PPibRegisterCallback and added debug prints to track the DMA buffers.

Please use the old state machine with 4095 as counter value and new state machine with 4096 counter value, build the firmware and  share the UART debug prints for both cases.

Please let me know if control center is used. If yes, please send 16384*3 bytes data from GPIF and do BULK IN to receive 16384*3 bytes and share the snippet of control center to understand the problem better

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

Thanks, this looks promising.  Looks like endless CYU3P_PIB_ERR_THR0_WR_OVERRUN regardless of the counter values.  Makes sense that they happen before the streamer application is ready to accept data (i have no trigger and just run continuously), but they seem to keep happening even once the streamer is accepting data.

 

Edit:  The underflow while acquiring is due to having the number of packets too low in the c++ streamer app.  With the feedback from the logging, I can see that I need to do 128 packets per Xfer at 4095 in order to not have WR_OVERRUN errors. 4096 always generates them.  Did not think it would be so critical since I am only sampling at 10 MHz (38 MB/s).  

This sort of fixes the problem, although the first 210,000 samples I get are also dropping data before it eventually starts working.  I think I'm going to try putting some triggering into the acquisition to see if the issue goes away with better synchronization.  

 

Edit2:  Testing with triggering to synchronize acquisition works fine.  The was actually just that I had the streamer application using too few buffers per transfer, which at least on my PC needs to be really high to avoid buffer underflows.  The above code to print the buffer status on the serial debug helped me optimize transfers.  Thanks again!

0 Likes

 

I switched back to manual MANY to ONE and tagged each buffer by writing its index to the first byte:

 

mgiacomelli_2-1611770226458.png

Buffers do arrive in order with none missing, however, data is lost/corrupted within buffers which I find very confusing.  For example, the jump in the waveform at 22,140 samples seems completely random.  I feel like I am missing something fundamental about how the DMA engine works.

0 Likes