ADC library internals

08 Feb 2010

Hello, I'm developing an IMU board and have some questions about the library internals.

My question is if each time that I call to "read_u16()" the value that the functions returns is readed in that moment (normalized from 12 to 16 bits) from the input voltage, or if the library sets up a continuous DMA sampling with decimation and downsamplig to reduce noise and increment resolution.

Thanks.

08 Feb 2010

Hi Samuel,

It just reads a value from the ADC in software controlled mode, and returns it (normalised to 16-bits).

Simon

10 Feb 2010

Thanks for the quick reply, Simon. Is there any way to get the raw output of the ADC (in the range 0-4096)? I'm planning to oversample to get 16 bit of precission, and turning the normalised value back to 12 bits is a waste of cpu time.

Anyway, is it possible to "program" the registers of the ADC to enable burst and DMA using the online compiler?

10 Feb 2010 . Edited: 10 Feb 2010

Hi Samuel,

Samuel Cabrero wrote:
Is there any way to get the raw output of the ADC (in the range 0-4096)? I'm planning to oversample to get 16 bit of precission, and turning the normalised value back to 12 bits is a waste of cpu time.

The API doesn't expose that explicitly, as that would expose the underlying number of bits of the ADC e.g. the LPC2368 is 10-bit, and the LPC1768 is 12-bit, but both will give the same results via the API (even if one is more accurate). The idea with the API was to make it a little more abstract so code was portable/compatible across targets. The normalisation is basically a couple of shifts and an add, so the overhead is a few CPU cycles which for compatibility seemed a good trade-off for basic ADC reading, but for something more specific may not be.

I guess what you are looking for is more of a streaming ADC, so there could be a good opportunity for a different approach (and maybe even to wrap that up in an alternative abstraction if the use case is common).

Samuel Cabrero wrote:
Anyway, is it possible to "program" the registers of the ADC to enable burst and DMA using the online compiler?

Sure, the structure for the ADC is at:

So you'd want to be poking those registers; for example, the main control register would be:

  • LPC_ADC->ADCR = xxx;

Simon

11 Feb 2010

In terms of resources, you may find the LPC17xx user manual useful if you don't have it already. Also I just wrote an ADC driver which may also be useful as an example.

ADC_test

21 Feb 2010

Simon,

I cannot seem to access the resources that should be tied to the links you have posted. I am also trying to accomplish a very similar task: A/D access, scanning across 4 channels, at a selected sampling rate, and DMA'd to memory. Your postings suggest you have programmed part of this and I would like to have a look for reference. Once I get the scanning and DMA working I will post, but right now, I can't even get past reading the A/D registers; the processor seems to HANG whenever I attempt to read the A/D registers. Could you be of any help here? Suggestions? code examples?

thanks,

Russ

21 Feb 2010

Hi,

See your post about register reads and hanging for a full explanation of the problems you are seeing.

Simon

23 Feb 2010 . Edited: 23 Feb 2010

 

Russ Heibel wrote:

Simon,

I cannot seem to access the resources that should be tied to the links you have posted. I am also trying to accomplish a very similar task: A/D access, scanning across 4 channels, at a selected sampling rate, and DMA'd to memory. Your postings suggest you have programmed part of this and I would like to have a look for reference. Once I get the scanning and DMA working I will post, but right now, I can't even get past reading the A/D registers; the processor seems to HANG whenever I attempt to read the A/D registers. Could you be of any help here? Suggestions? code examples?

thanks,

Russ

Hi Russ,

Not sure why you are not able to access the code. I just checked it and I can at least download the ZIP file. A direct link to the ZIP file is here.

I did encounter plenty of hangs during development of the driver but these were related to not reading registers rather than reading them. Specifically, I initially intended to use the ADGDR register to read the data of the most recent conversion but found I had use the method of reading from ADDR0 to ADDR7 to make sure flags were cleared.

 

Regards,

SimonB

 

24 Feb 2010

Simon,

Yes, the files are accessible. I was trying to click on the wrong links. I finally found the links that take you to the code. Thanks,

As for the processor hanging. After code inspection and reading the manual, I discovered that I had forgotten to turn on the power to the A/D secton via the PCON register. Once I did this, the processor quit "hanging" during read of registers.

I have read your response above about the ADGDR and ADDRn registers. I have been playing around with different means of using the A/D and have come to the point where I cannot seem to ever get the DONE and OVERRUN bits to clear. I have slowed the clock down significantly and put in consecutive reads and I always end up with a "0xC" in the most significant nibble. Have any advise here?

Ultimately what I am trying to accomplish the ability to sample 1-6 A/D channels at a designated rate. So far, the only way I can determine one might be able to accomplish this on the LPC1768 is as follows:

- Set up A/D to scan specific channels, running at a 12MHz clock rate (to maximize the clocking rate of the 65 conversion clocks)

- Set up a counter to interrupt at the desired sample rate

- Utilize an Interrupt to read the n channels.

Ideally I would prefer the unit to be able to trigger a scan at a designate rate, and have DMA move the converted samples into memory. The the application could just take care of managing the DMA and processing of the acquired data. But it doesn't look like the LPC1768 supports this type of acquisition.

Russ

 

24 Feb 2010

Hi Russ,

I looked at the DMA documentation and got confused. I decided to try and work without it for now unless I find later that the interrupts routines really max out.

You can run the ADC in burst mode to grab all six channels. The driver I posted has an example of that. If you need a precise sample rate that you can't get by dividing the clock then you might need to use a timer to generate the sample triggers i.e.

  • Set up timer at sample rate
  • Set up ADC in burst mode with interrupt on final ADC channel
  • Timer interrupt enables ADC burst
  • ADC interrupt reads and processes values and disables ADC burst until next timer interrupt

Using burst mode you can reduce the number of interrupt calls you need since you only need to service the ADC once per scan rather than once per channel.

24 Feb 2010

 

Russ Heibel wrote:

Simon,

Yes, the files are accessible. I was trying to click on the wrong links. I finally found the links that take you to the code. Thanks,

As for the processor hanging. After code inspection and reading the manual, I discovered that I had forgotten to turn on the power to the A/D secton via the PCON register. Once I did this, the processor quit "hanging" during read of registers.

I have read your response above about the ADGDR and ADDRn registers. I have been playing around with different means of using the A/D and have come to the point where I cannot seem to ever get the DONE and OVERRUN bits to clear. I have slowed the clock down significantly and put in consecutive reads and I always end up with a "0xC" in the most significant nibble. Have any advise here?

Ultimately what I am trying to accomplish the ability to sample 1-6 A/D channels at a designated rate. So far, the only way I can determine one might be able to accomplish this on the LPC1768 is as follows:

- Set up A/D to scan specific channels, running at a 12MHz clock rate (to maximize the clocking rate of the 65 conversion clocks)

- Set up a counter to interrupt at the desired sample rate

- Utilize an Interrupt to read the n channels.

Ideally I would prefer the unit to be able to trigger a scan at a designate rate, and have DMA move the converted samples into memory. The the application could just take care of managing the DMA and processing of the acquired data. But it doesn't look like the LPC1768 supports this type of acquisition.

Russ

 

 

 

Hi Russ, at the moment I'm sampling 6 channels in burst mode using the driver wrote by Simon Blandford. My target sample rate was 500Hz for the 6 channels, so I set up a timer in the main loop to get the most recent converted value from the driver at that frecuency.
To use the "lost" samples, I added oversampling and decimating to the driver code, increasing the resolution and reducing noise. With this setup I'm getting one sample of 15 bits resolution at a rate of 488Hz for each channel.