EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Setting up LPC2132 ADC in Hardware mode

Started by soren_t_hansen June 8, 2005
I followed the example from the Insiders guide from Hitex, but it
seems if it is designed only for the Keil ARM compiler. Also I suspect
it to have an error where ADCR should be ADDR.

Anyway the interrupt function doesn't get called, and I have no clue
why not. In the Keil example they make a change in the startup.s, but
doing that didn't solve the problem.

How do I set up the ADC to hardware mode, using the GNU ARM toolchain?

My program looks like this:

void AD_ISR (void)
{
unsigned val, chan;
static unsigned result[4];

val = AD0DR;
val = ((val >> 6) & 0x03FF);
chan = ((AD0CR >> 0x18) & 0x07);
result[chan] = val;
}

int main (void) {

//The ADC setup
VPBDIV = 0x00000002;
AD0CR = 0x00270607;

VICVectCntl0 = 0x00000032;
VICVectAddr0 = (unsigned)AD_ISR;

VICIntEnable = 0x00040000;

IODIR1 = 0x00FF0000; /* P1.16..23 defined as Outputs */

while(1)
{

} The vector table in the startup.s look like this:

Vectors: LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP /* Reserved Vector */
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr

Reset_Addr: .word Reset_Handler
Undef_Addr: .word Undef_Handler
SWI_Addr: .word SWI_Handler
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
.word 0 /* Reserved Address */
IRQ_Addr: .word IRQ_Handler
FIQ_Addr: .word FIQ_Handler

Undef_Handler: B Undef_Handler
SWI_Handler: B SWI_Handler
PAbt_Handler: B PAbt_Handler
DAbt_Handler: B DAbt_Handler
IRQ_Handler: B IRQ_Handler
FIQ_Handler: B FIQ_Handler

Best Regards
Sen



An Engineer's Guide to the LPC2100 Series

--- In lpc2000@lpc2..., "soren_t_hansen" <soren_t_hansen@y...>
wrote:
> I followed the example from the Insiders guide from Hitex, but it
> seems if it is designed only for the Keil ARM compiler. Also I suspect
> it to have an error where ADCR should be ADDR.
>
> Anyway the interrupt function doesn't get called, and I have no clue
> why not. In the Keil example they make a change in the startup.s, but
> doing that didn't solve the problem.
>
> How do I set up the ADC to hardware mode, using the GNU ARM toolchain?
>
> My program looks like this:
>
> void AD_ISR (void)
> {
> unsigned val, chan;
> static unsigned result[4];
>
> val = AD0DR;
> val = ((val >> 6) & 0x03FF);
> chan = ((AD0CR >> 0x18) & 0x07);
> result[chan] = val;
> }
>
> int main (void) {
>
> //The ADC setup
> VPBDIV = 0x00000002;
> AD0CR = 0x00270607;
>
> VICVectCntl0 = 0x00000032;
> VICVectAddr0 = (unsigned)AD_ISR;
>
> VICIntEnable = 0x00040000;
>
> IODIR1 = 0x00FF0000; /* P1.16..23 defined as Outputs */
>
> while(1)
> {
>
> } > The vector table in the startup.s look like this:
>
> Vectors: LDR PC, Reset_Addr
> LDR PC, Undef_Addr
> LDR PC, SWI_Addr
> LDR PC, PAbt_Addr
> LDR PC, DAbt_Addr
> NOP /* Reserved Vector */
> LDR PC, IRQ_Addr
> LDR PC, FIQ_Addr
>
> Reset_Addr: .word Reset_Handler
> Undef_Addr: .word Undef_Handler
> SWI_Addr: .word SWI_Handler
> PAbt_Addr: .word PAbt_Handler
> DAbt_Addr: .word DAbt_Handler
> .word 0 /* Reserved Address */
> IRQ_Addr: .word IRQ_Handler
> FIQ_Addr: .word FIQ_Handler
>
> Undef_Handler: B Undef_Handler
> SWI_Handler: B SWI_Handler
> PAbt_Handler: B PAbt_Handler
> DAbt_Handler: B DAbt_Handler
> IRQ_Handler: B IRQ_Handler
> FIQ_Handler: B FIQ_Handler
>
> Best Regards
> Sen

I've managed to enter the interrupt handler once, but after that,
nothing happens. Does this setup disable interrupts, which I then have
to enable again when returning from the interrupt handler?
Or is it the setup of the ADCR that is incorrect and only gives me one
sample?

Best Regards
Sen


--- In lpc2000@lpc2..., "soren_t_hansen"
<soren_t_hansen@y...> wrote:
> --- In lpc2000@lpc2..., "soren_t_hansen"
<soren_t_hansen@y...>
> wrote:
> > I followed the example from the Insiders guide from Hitex, but it
> > seems if it is designed only for the Keil ARM compiler. Also I
> > suspect it to have an error where ADCR should be ADDR.
> >
> > Anyway the interrupt function doesn't get called, and I have no
> > clue why not. In the Keil example they make a change in the
> > startup.s, but doing that didn't solve the problem.
> >
> > How do I set up the ADC to hardware mode, using the GNU ARM
> > toolchain?
> >
> > My program looks like this:
> >
> > void AD_ISR (void)
> > {
> > unsigned val, chan;
> > static unsigned result[4];
> >
> > val = AD0DR;
> > val = ((val >> 6) & 0x03FF);
> > chan = ((AD0CR >> 0x18) & 0x07);
> > result[chan] = val;
> > }
> >
> > int main (void) {
> >
> > //The ADC setup
> > VPBDIV = 0x00000002;
> > AD0CR = 0x00270607;
> >
> > VICVectCntl0 = 0x00000032;
> > VICVectAddr0 = (unsigned)AD_ISR;
> >
> > VICIntEnable = 0x00040000;
> >
> > IODIR1 = 0x00FF0000; /* P1.16..23 defined as Outputs */
> >
> > while(1)
> > {
> >
> > }
> >
> >
> > The vector table in the startup.s look like this:
> >
> > Vectors: LDR PC, Reset_Addr
> > LDR PC, Undef_Addr
> > LDR PC, SWI_Addr
> > LDR PC, PAbt_Addr
> > LDR PC, DAbt_Addr
> > NOP /* Reserved Vector */
> > LDR PC, IRQ_Addr
> > LDR PC, FIQ_Addr
> >
> > Reset_Addr: .word Reset_Handler
> > Undef_Addr: .word Undef_Handler
> > SWI_Addr: .word SWI_Handler
> > PAbt_Addr: .word PAbt_Handler
> > DAbt_Addr: .word DAbt_Handler
> > .word 0 /* Reserved Address */
> > IRQ_Addr: .word IRQ_Handler
> > FIQ_Addr: .word FIQ_Handler
> >
> > Undef_Handler: B Undef_Handler
> > SWI_Handler: B SWI_Handler
> > PAbt_Handler: B PAbt_Handler
> > DAbt_Handler: B DAbt_Handler
> > IRQ_Handler: B IRQ_Handler
> > FIQ_Handler: B FIQ_Handler
> >
> > Best Regards
> > Sen
>
> I've managed to enter the interrupt handler once, but after that,
> nothing happens. Does this setup disable interrupts, which I then
> have to enable again when returning from the interrupt handler?
> Or is it the setup of the ADCR that is incorrect and only gives me
> one sample?

With this code, your AD_ISR() should never be called. If/when an IRQ
triggers, the CPU jumps to address 0x18, which in your startup code
contains an "LDR PC, IRQ_Addr", which jumps to an infinite loop
(IRQ_Handler: B IRQ_Handler).

To use the VIC, you should replace the "LDR PC, IRQ_Addr" with "LDR
PC, [PC, #-0x0FF0]". This instruction reads the handler address from
VICVectAddr and jumps to it.
In your AD_ISR(), you also need a dummy write to VICVectAddr to tell
the VIC that this interrupt source has been handled.

Karl Olsen




Memfault Beyond the Launch