EmbeddedRelated.com
Forums

LPC23xx ADC burst mode

Started by nemecsek69 March 18, 2008
Hi. I want to use ADC in burst mode on LPC2378 (Olimex LPC-2378-STK
board) with IAR C compiler 5.10.

I need to read AD0.1, AD0.3 and AD0.5 in burst mode but I cannot solve
a problem: if all are enabled only the lower order channel is read
while the others are read as 0.

If AD channels 1,3,5 are enabled, channel 1 is ok, channels 3 and 5
are 0.
If AD channels 3 and 5 are enabled, channel 3 is ok, channel 5 is 0.
If only AD channel 5 is enabled it's ok.

My routines are interrupt driven, all vars are volatile.
START is enabled separately.



PCONP_bit.PCAD = 1; // start clock ADC

PINSEL1_bit.P0_24 = 1; // adc 1 on pin0_24
PINSEL1_bit.P0_26 = 1; // adc 3 on pin0_26
PINSEL3_bit.P1_31 = 3; // adc 5 on pin1_31

AD0CR_bit.START = 0; // adc stopped

AD0CR_bit.SEL = 0x2a; // ch 1,3,5 enabled
AD0CR_bit.CLKDIV = 179; // (PCLK 18MHz/180 = 100kHz)
AD0CR_bit.BURST = 1; // burst mode
AD0CR_bit.CLKS = 0; // 10 bit
AD0CR_bit.PDN = 1; // adc operational

ADINTEN = 0x2a; // interrupt on DONE 1,3,5

VIC_SetVectoredIRQ(Int_Adc, PRIORITY, VIC_AD0);
VICINTENABLE |= 1UL << VIC_AD0;

AD0CR_bit.START = 1; // adc start



If in burst mode it is necessary to restart the sampling every time
ADC int occurs or can it be left in freerun?

ADC int occurs every time a single conversion is performed or only
when the full set of channels (1,3 and 5 in my case) is sampled?

Thank you in advance
Alessandro

An Engineer's Guide to the LPC2100 Series

Alessandro,

Try enabling the interrupt for the highest/last channel only. In burst
mode, the ADC starts at the lowest channel and converts all enabled
channels in succession. I believe in burst mode the ADC will convert
all channels enabled in a circular fashion.

Something I've seen is that at the end of the ADC ISR, the ADC has
already converted the next channel (or two). This was with 4.5 MHz
conversion clock.

If you get all the answers to your questions, please let us know. The
burst mode seems to require a clear example.

Regards,

John Gerthoffer

________________________________

From: l... [mailto:l...] On Behalf
Of nemecsek69
Sent: Tuesday, March 18, 2008 6:03 AM
To: l...
Subject: [lpc2000] LPC23xx ADC burst mode

Hi. I want to use ADC in burst mode on LPC2378 (Olimex LPC-2378-STK
board) with IAR C compiler 5.10.

I need to read AD0.1, AD0.3 and AD0.5 in burst mode but I cannot solve
a problem: if all are enabled only the lower order channel is read
while the others are read as 0.

If AD channels 1,3,5 are enabled, channel 1 is ok, channels 3 and 5
are 0.
If AD channels 3 and 5 are enabled, channel 3 is ok, channel 5 is 0.
If only AD channel 5 is enabled it's ok.

My routines are interrupt driven, all vars are volatile.
START is enabled separately.



PCONP_bit.PCAD = 1; // start clock ADC

PINSEL1_bit.P0_24 = 1; // adc 1 on pin0_24
PINSEL1_bit.P0_26 = 1; // adc 3 on pin0_26
PINSEL3_bit.P1_31 = 3; // adc 5 on pin1_31

AD0CR_bit.START = 0; // adc stopped

AD0CR_bit.SEL = 0x2a; // ch 1,3,5 enabled
AD0CR_bit.CLKDIV = 179; // (PCLK 18MHz/180 = 100kHz)
AD0CR_bit.BURST = 1; // burst mode
AD0CR_bit.CLKS = 0; // 10 bit
AD0CR_bit.PDN = 1; // adc operational

ADINTEN = 0x2a; // interrupt on DONE 1,3,5

VIC_SetVectoredIRQ(Int_Adc, PRIORITY, VIC_AD0);
VICINTENABLE |= 1UL << VIC_AD0;

AD0CR_bit.START = 1; // adc start



If in burst mode it is necessary to restart the sampling every time
ADC int occurs or can it be left in freerun?

ADC int occurs every time a single conversion is performed or only
when the full set of channels (1,3 and 5 in my case) is sampled?

Thank you in advance
Alessandro

=======================================================================CONFIDENTIALITY NOTICE
----------------------
This message, together with any attachments, may be legally privileged
and is confidential information intended only for the use of the
individual or entity to which it is addressed. It is exempt from
disclosure under applicable law including court orders. If you are not
the intended recipient, you are hereby notified that any use,
dissemination, distribution or copy of this message, or any attachment,
is strictly prohibited. If you have received this message in error,
please notify the original sender and delete this message, along with
any attachments, from your computer.

John,

it's strange enough: after your hint I tried to set the INT on the
HIGHEST channel but the service routine is never entered. It is called
only when the INT is set for the LOWEST channel: the other ones are
simply neglected.

I have found a reference to somebody experiencing the same problem but
he never got an answer...

I'll publish my finding.

Thank you anyway

It works now but I don't know why.

I was afraid that the problem was given by ADDRx readings and somehow
the register ADDRx got corrupted after the first reading:

if (ADDRx.DONE) {
Value = ADDRx.RESULT;
}

so I changed it with

Value = ADDRx;
if ((Value & 0x80000000) != 0) { // done
Value >>= 6;
Value &= 0x3ff;
}

This second version worked immediately for all channels together.
Just to check I went back to the first version and it worked too!

Is it possible the J-link I'm using crashes the register read and now
it began working properly?
Don't know what could otherwise be...

Alessandro