HSADC missing samples (LPC 4370)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HSADC missing samples (LPC 4370)

1,460 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marquardt on Wed Apr 27 04:34:45 MST 2016
Hello all,

I got a problem with my hsadc-code, it seems that every eight samples the adc is going to stop and sleep for a short time. The code, which is based on the periph_hsadc example and the laptool code and a plotted diagram of a 4MHz sinuswave are attached. I am using DMA to save the FIFO to a ringbuffer.
Based on the user manual, I thought about three possible bottlenecks:

- the second descriptor table must be preloaded an updated through DMA?
- the trigger for the descriptortable-initiation is taking too long?
- the FIFO is full and can't be emptied fast enough, so the remaining samples can't be safed?

Did anybody of you encounter a similar problem or can find the problem in my code?

Thanks in advance!

P.S: I am trying to build a 4 channel oscilloscope with the Link2-board. Is there maybe anything else I should mind?

Original Attachment has been moved to: hsadc_2.c.zip

Labels (1)
0 Kudos
9 Replies

1,200 Views
lpcware
NXP Employee
NXP Employee
bump
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hairy.lee on Wed Jun 01 04:15:31 MST 2016
Yes I was missing a divide by 2; I'd set my match value to 1...smh.

So that's one issue down, unfortunately I'm still observing missed samples, but now at the 160 sample point.
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hairy.lee on Wed Jun 01 03:06:41 MST 2016
Hi Marquardt,

Did you manage to resolve this issue? I am using the Lab Tool HS ADC code as rodri recommended and getting a similar issue.

I've cut the HS ADC clock to 12MHz and I'm sampling a 100 kHz square and sine wave. So, I should be taking 1 sample every 83.3ns. for the square wave I have a 50% duty cycle set resulting in 5us low and 5us high.

If I can still do maths that should equate to 60 samples of minimum and 60 samples of maximum. Alas, its not. The best I achieve is 42, but mostly 30. With the square wave the missing samples are obviously less noticeable, but it really shows with the sine wave and is always around the 80 sample point. Am I missing a divide by 2?

HL
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rodri on Tue May 10 09:00:42 MST 2016
Hi,

thank you for your explanation, I didn't know that.


Quote:
Could it be, that my interrupt is taking too long or something simliar?



I don't know if interrupt blocks DMA, have you tested without count interrupt? Maybe ringbuffer is not working correctly, have you test it with, for example, an array on local RAM? I have working on an array of 30000 words, DMA saves 30000 FIFO words to this vector, and then launch an interrupt.


Quote:
Is it even possible to get the ADC going with 80 MSps, two discriptor tables and a packed 16 word FIFO? Because I can't even get close to it...


I'm working with 8MSps, it's hard to achieve 80MSps, but in this way I think that it should work. Take a look to LPC Link2 working with LabTools, they are using ADC at 80MSps
https://github.com/embeddedartists/labtool/blob/master/fw/program/source/capture_vadc.c#L198

Regards
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marquardt on Tue May 10 00:54:29 MST 2016
Hi rodri,

sorry for my late answer, i have been trying a few different thing to find the cause of my problem. The address assignment wasn't the problem, but i still switched to the declaration type you proposed. It seems that the FIFO from the ADC is already filled with values in the wrong order. For example: If I got my discriptor table set up to read the channels in the order ch(1),ch(2),ch(3),ch(4),ch(1),ch(2),ch(3),ch(4), the FIFO got them in a mixed up order. Furthermore I got an overflow at any greater clockspeed than 40 MHz.

Could it be, that my interrupt is taking too long or something simliar? Is it even possible to get the ADC going with 80 MSps, two discriptor tables and a packed 16 word FIFO? Because I can't even get close to it...

The Ringbuffer is very similiar to the circbuffer, I attach a graphic, which shows the workingroutine of the buffer. After all the DMA doesn't seem to be the problem.
[img=246x238]https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Ring_buffer.svg/2000px-Ring_buffer.svg.png...
Thank you for your help so far!
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rodri on Tue May 03 09:47:33 MST 2016
Hi Marquardt,

I'm not sure about if this is correct:
 DMA_Stuff[j].SrcAddr = (uint32_t) &LPC_ADCHS->FIFO_OUTPUT[j]; 


Src address should be always the same "FIFO_OUTPUT[0];" when Dma read one word, internally FIFO_OUTPUT[1] goes to FIFO_OUTPUT[0], try writting this:
 DMA_Stuff[j].SrcAddr = &(LPC_ADCHS->FIFO_OUTPUT[0]); 


It may be a problem if your number of LLI's are greater than 15.

If this works fine tell me, if don't, try changing 'src' and 'dst' burst size to 0x2.

Second, are you in debug mode? Sometimes debug works slower than if you write release version.

Ringbuffer:
I'm not familiarized with this, can you explain me how it works? In my case I'm saving the samples in RAM (Using a very large array), I don't know if is efficient but it works for me. I first save the samples in this array and then send to the PC using USB.

Regards!
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rodri on Tue May 03 09:45:49 MST 2016
Hi Marquardt,

I'm not sure about if this is correct:
 DMA_Stuff[j].SrcAddr = (uint32_t) &LPC_ADCHS->FIFO_OUTPUT[j]; 


Src address should be always the same "FIFO_OUTPUT[0];" when Dma read one word, internally FIFO_OUTPUT[1] goes to FIFO_OUTPUT[0], try writting this:
arrayLLI.src=&(LPC_ADCHS->FIFO_OUTPUT[0]); 


It may be a problem if your number of LLI's are greater than 15.

If this works fine tell me, if don't, try changing 'src' and 'dst' burst size to 0x2.

Second, are you in debug mode? Sometimes debug works slower than if you write your release version.

Rignbuffer:
I'm not familiarized with this, can you explain me how it works? In my case I'm saving the samples in RAM (Using a very large array), I don't know if is efficient but it works for me. I first save the samples in this array and then send to the PC using USB.

Regards!
0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marquardt on Tue May 03 05:15:13 MST 2016
Hi,

thank you for your answer, it was really helpful! I now changed to a continously operation with two swapping discriptor tables, but still keep the samples unpacked, so it is easier for me to check if the values are correct.
It now seems, that the problem with pausing adc is fixed, but I another emerged...

The values I now got in my ringbuffer are chaotic and the overflow-interrupt as well as the overrun-interrupt are triggered.

Is there something wrong with the DMA-setup, so the FIFO values can't be read fast enough maybe? Or do I need to initialize the DMA-read-request manually in the ADC-interrupt-handler and not with the FIFO-level?

I hope you can use my updated code and the new plot to find my mistake...


regards!

0 Kudos

1,200 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rodri on Mon May 02 17:43:35 MST 2016
Hi,

have you tried to perform adc operations continously? You are halting the adc at the 8th sample, but what happens if you return to the first position of the descriptor table without halting?

I am not halting the adc and I don't loose any sample,  you can configure the length of the sampling operation by DMA, saving only the intervals that you are interested

In my previous programs, I performed a 16 descriptor + halt operation, and this not work ok for me. Using only 1 descriptor + halt worked fine, but not using halt works better.

While ADC takes samples at a given clk, DMA is saving your samples to the specified address with a higher frequency, but if you want to improove the performance, you can extend to "15" the max FIFO (DMA empty all your FIFO in one interrupt) and try to compact the words in 32 bit format that is more efficient.

Try this!

regards
0 Kudos