HSADC with GPDMA Transfer Dropping Samples at 80MSps

Content originally posted in LPCWare by heffalump on Mon Mar 30 18:39:58 MST 2015I have an application similar to an oscilloscope, where I am capturing signals that exceed a set threshold. The application requires a sample-rate of 60MSps or above to be feasible.

The operation of my code:[list] [*]The samples are moved into a segmented circular buffer using a GPDMA LLI. [*]The HSADC throws an interrupt if the trigger threshold is exceeded. [*]The interrupt queries the current GPDMA next LLI address and destination address to determine where in the circular buffer the trigger has occurred. [*]The interrupt modifies the LLI so that the GPDMA switches to a second circular buffer once it has filled the required number of post-trigger samples. The GPDMA is also set to throw an interrupt signaling the post-fill completion.[/list]

The problem is that the transfer is dropping chunks of samples. The samples are most regularly being lost around the time the trigger interrupt is running, i.e. the samples I am most interested in! I have attached a plot of a captured burst of 4 MHz Sine waves. The trigger point, measured during the interrupt by querying the GPDMA destination address, is 400 Samples. Samples are regularly lost occur in the following 100 HSADC cycles (~1 us).The effect is present when sampling at 80, 60 and 40 MSps. I have also attached CSVs containing captured signals. The traces are aligned with the trigger point at the 398th samples.

As the sample drops occur around the time of the trigger interrupt, am I doing something to upset the HSADC or GPDMA transfer in my handler code? The handler runs from RAM, otherwise it fails to stop the GPDMA before the circular buffer loops around. The FIFO trigger and GPDMA burst size for the transfer is set to 8 words.

// Once trailing sub-buffers are filled the DMA will switch to the start of the// second buffer and trigger an interruptHSADC_DMA_LLI[active][lastlli].ctrl |= GPDMA_DMACCxControl_I;HSADC_DMA_LLI[active][lastlli].lli = HSADC_DMA_LLI[next][0].lli;

Content originally posted in LPCWare by starblue on Tue Mar 31 00:52:50 MST 2015Did you optimize the memory layout, so that CPU and DMA don't interfere? I.e. put the two circular buffers into separate memory regions which are only used for that purpose?

Content originally posted in LPCWare by heffalump on Tue Mar 31 16:26:09 MST 2015Thanks for the idea Starblue, I'll take a look at the memory layout.

Currently the main thread loops, waiting for the interrupt handlers to signal that the acquisition is complete. There is no processing/access of the complete buffer while the other is receiving ADC samples ...yet!

Update:

I have tried running the code with the receive buffer located in RamLoc72 (RAM2) and then in RanAHB32 (RAM3). The rest of the variables and RAM functions are located in RamLoc128 (RAM). The problem remains in both cases.

Attachments

Content originally posted in LPCWare by heffalump on Tue Mar 31 23:49:11 MST 2015To further pin down the problem, I’ve disabled the HSADC threshold and set the GPDMA to capture a set number of samples. The main thread loops, waiting for the GPDMA interrupt to signal the end of the capture.

while (adc.prefilled == 0);

In this case samples are rarely dropped; sample 673 in the attached plot (80MSPS_NoTrigger.png) for example.

I then placed lines of code from the above ADCHS interrupt handler into the waiting loop, to test their effect on the HSADC capture and transfer. The lines associated with the HSADC interrupt status seem to cause the greatest disturbance. The following line causes a significant amount of samples to be lost (80MSPS_NoTrigger_QueryInterrupt.png):

I think there is a more general problem with the GPDMA and it might be impossible to get the 80 MSPS without dropping some samples.More than a year ago I also wanted to push the ADCHS to the limit, i.e. read samples continuosly into a ring buffer at maximum speed.I tried all optimizations I could think of (memory layout, GPDMA settings, FIFO threshhold of ADCHS) but I always lost some samples.As far as I remember (I gave up on the project a year ago) it might have to do with the exact timing of a LLI reload. When reaching the end of a block the GPDMA has to load the next set of descriptors and this might take just too long at times.In theory there is enough time, but I could not find a setup to make it work at all times.

Of course, if you have other transfers with real-time requirements, such as feeding the DAC, it doesn't help either.

What really killed my project at that time was that I was seeing some kind of signal crosstalk from the selected ADCHS input (say from ADCHS_0 to the reference voltage at ADCHS_NEG). The higher the sampling rate the higher the crosstalk, clearly visible on an oscilloscope at ADCHS_NEG (despite some attached C and an otherwise clean supply voltage). I used the internal source then.

I'd really love to see a solution myself to continue my project.Some time in the future I'll try to drive ADCHS_NEG from an external low-impedance source, the test board for that is already collecting dust ...

Content originally posted in LPCWare by wsinter on Sat Apr 23 19:58:28 MST 2016I also found a problem for HSADC and GPDMA. If I set the HSADC FIFO Level to 8, and DMA source and destiny burst size to 8, the ADC sample result is correct, but if I set the the FIFO Level to 4, and DMA source and destiny burst size to 4, there would be some error result, 0x8000(the fifo is empty), also ,if I set both to 1,result would be some 0x8000,

Content originally posted in LPCWare by mch0 on Sat Apr 23 22:20:14 MST 2016Yes, indeed, I now remember also some experiments with threshold+burst size.I even went so far as to trigger the DMA before the burst length data was available. I hoped to gain extra slack on the FIFO.Say trigger at 6 samples with as burst length of 8. The idea was that the missing samples would be in the FIFO before the DMA would read them.It did work (no "Fifo empty"-samples), but it did not solve the problem with occasionally missing samples.

I really should restart work on that, it was still nice enough a chip and I still feel I have not done a complete analysis of what happens when. So there might still be a solution by carefully aranging all data in non-confliczing memory (includung the location of the LLI) and making use of the 2 DMA masters accordingly.

I didn't overcome this issue with dropping samples, particularly when reading the interrupt register during a trigger event. Embedded Artists also encountered this behavior when developing the Labtool. It is thought to be due to bandwidth limitations of the buses.

As my application needs both hardware triggering and the higher sample rates, I haven't done any further work with NXP4370.

NXP could not tell me about any planned updates/ successors to the NXP4370.

I want to get the exactly position of DMA (the vaiue of DMA channel control&LLI register)in a hardware trigger interrupt(GPIO Interrupt),but if I set the burst size and FIFO Level to 8, there may be some lags because the HSADC has not arrive the DMA trigger FIFO Level , so the DMA position may not be right, and the trigger will not be stable. I tried to set the FIFO Level and burst size to 1, I think this would help me get the exactly position of DMA when the hardware trigger interrupt comes. But the result is bad, I would get 0x8000. I do not know how to solve it .