EmbeddedRelated.com
Forums

IAR interrupt problem

Started by ducatman2000 September 21, 2004
Hi,

I'm trying to enable interrupt with timer1 on the LPC2106. I
configured Timer1 as IRQ source when its value correspond with the
match register 0... but interrupt routine service doesn't run and is
never reached. Here is a piece of my code:

__disable_interrupt(); // IAR intrinsic
//VIC enable registers
VICProtection=0x0;

//clears bits in the Interrupt Enable register
VICIntEnClear=0xffffffff;

VICIntEnable=0x20; //Timer1
VICIntSelect=0x00; //all interrupts are IRQs
VICVectCntl0=0x25;
VICVectAddr0=(unsigned long)&Timer1ISR;

__enable_intrinsic();

Then I also initialize Timer1:

T1_IR=0x00;
T1_MR0=TIMERMATCH;
T1_MCR=0x03; // reset timer and fire interrupt
T1_PR=0x0;
T1_TC=0x00;
T1_TCR=0x01; // start the timer

__arm __irq void Timer1ISR(void) //Timer1 ISR
{
T1_IR=0x01; //reset interrupt flag
VICVectAddr=0; //reset VIC
return;
}

My questions are:

- what is wrong with this code?
- could it be a problem with the intrinsic functions of IAR
__enable_interrupt() and __disable_interrupt(); they seem not to
work; does anybody their asm code??

Any help would be appreciated!

thanx




An Engineer's Guide to the LPC2100 Series

I'm curious about 2 things.

1. "__enable_intrinsic()"
Is this really the function you used or do you really mean
__enable_interrupt().

2. Where is your IRQ Handler? The only time I used "_irq" was to
define the IRQ handler...not the ISR.

something like...

__arm __irq void IRQ_handler(void)
{
ISRAddress = VICVectAddr; //load source address
(*ISRAddress)() //function call
VICVectAddr=0; //reset VIC
return;
}

void Timer1ISR(void) //Timer1 ISR
{
.....
} That way ISRs get called by the handler whenever any enabled
interrupt channel is activated.

Some example code should come with your IAR compiler...somewhere in
the /ARM/src directory. Make sure u look at those. They'll come in
very handy.

Leighton

--- In , "ducatman2000" <545545@b...> wrote:
> Hi,
>
> I'm trying to enable interrupt with timer1 on the LPC2106. I
> configured Timer1 as IRQ source when its value correspond with the
> match register 0... but interrupt routine service doesn't run and
is
> never reached. Here is a piece of my code:
>
> __disable_interrupt(); // IAR intrinsic
> //VIC enable registers
> VICProtection=0x0;
>
> //clears bits in the Interrupt Enable register
> VICIntEnClear=0xffffffff;
>
> VICIntEnable=0x20; //Timer1
> VICIntSelect=0x00; //all interrupts are IRQs
> VICVectCntl0=0x25;
> VICVectAddr0=(unsigned long)&Timer1ISR;
>
> __enable_intrinsic();
>
> Then I also initialize Timer1:
>
> T1_IR=0x00;
> T1_MR0=TIMERMATCH;
> T1_MCR=0x03; // reset timer and fire interrupt
> T1_PR=0x0;
> T1_TC=0x00;
> T1_TCR=0x01; // start the timer
>
> __arm __irq void Timer1ISR(void) //Timer1 ISR
> {
> T1_IR=0x01; //reset interrupt flag
> VICVectAddr=0; //reset VIC
> return;
> }
>
> My questions are:
>
> - what is wrong with this code?
> - could it be a problem with the intrinsic functions of IAR
> __enable_interrupt() and __disable_interrupt(); they seem not to
> work; does anybody their asm code??
>
> Any help would be appreciated!
>
> thanx





You are right, I made a mistake writing my previous mail, it was not
__enable_intrinsic() but of course __enable_interrupt().

Now I have introduced the IRQ Handler exactly as you told me. In that
way, the Timer1 ISR should be called by the irq_handler whenever an
interrupt occurs. BUT, it sill not work! In debug mode I can see the
timer incrementing and when it reaches the match value register, it
resets and put the IR1 bit to '1' but the ISR is never reached... I
think there is a problem with the IAR intrinsic __enable_interrupt()
and __disable_interrupt(). In step by step mode, when the
__enable_interrupt() is executed, that blocks the programm... Any
idea of the problem, or do you know the asm code of __enable_interrupt
() ans __disable_interrupt ?

(the code follow at the end of this mail)

Thank you very much !

--- In , "Leighton Rowe" <leightonsrowe@y...>
wrote:
> I'm curious about 2 things.
>
> 1. "__enable_intrinsic()"
> Is this really the function you used or do you really mean
> __enable_interrupt().
>
> 2. Where is your IRQ Handler? The only time I used "_irq" was to
> define the IRQ handler...not the ISR.
>
> something like...
>
> __arm __irq void IRQ_handler(void)
> {
> ISRAddress = VICVectAddr; //load source address
> (*ISRAddress)() //function call
> VICVectAddr=0; //reset VIC
> return;
> }
>
> void Timer1ISR(void) //Timer1 ISR
> {
> .....
> } > That way ISRs get called by the handler whenever any enabled
> interrupt channel is activated.
>
> Some example code should come with your IAR compiler...somewhere in
> the /ARM/src directory. Make sure u look at those. They'll come in
> very handy.
>
> Leighton

Here is a piece of my code:
> >
> > __disable_interrupt(); // IAR intrinsic
> > VICProtection=0x0;
> >
> > VICIntEnClear=0xffffffff;
> >
> > VICIntEnable=0x20; //Timer1
> > VICIntSelect=0x00; //all interrupts are IRQs
> > VICVectCntl0=0x25;
> > VICVectAddr0=(unsigned long)&Timer1ISR;
> > __enable_interrupt();
> >
> > Then I also initialize Timer1:
> >
> > T1_IR=0x00;
> > T1_MR0=TIMERMATCH;
> > T1_MCR=0x03; // reset timer and fire interrupt
> > T1_PR=0x0;
> > T1_TC=0x00;
> > T1_TCR=0x01; // start the timer
> >
> > __arm __irq void irq_handler(void) //Timer1 ISR
> > {
> > ISRAddress = VICVectAddr; //load source address
> > (*ISRAddress)() //function call
> > VICVectAddr=0; //reset VIC
> > return;
> > }
> >
> > void Timer1ISR()
> > {
> > IR1 = 0x01;
> > }
> >



--- In , "ducatman2000" <545545@b...> wrote:
> You are right, I made a mistake writing my previous mail, it was
not
> __enable_intrinsic() but of course __enable_interrupt().
>
> Now I have introduced the IRQ Handler exactly as you told me. In
that
> way, the Timer1 ISR should be called by the irq_handler whenever
an
> interrupt occurs. BUT, it sill not work! In debug mode I can see
the
> timer incrementing and when it reaches the match value register,
it
> resets and put the IR1 bit to '1' but the ISR is never reached...
I
> think there is a problem with the IAR intrinsic __enable_interrupt
() and __disable_interrupt().
> In step by step mode, when the
> __enable_interrupt() is executed, that blocks the programm...

I remember this happening to me before, but at the time I wasn't
sure why. I'm still learning the IAR library functions. Do you have
the vectors in cstartup configured?

org 0x00
pc,=?cstartup
....
org 0x18
ldr pc,=irq_handler
...

If u did, then check the status of cpsr after both intrinsic
enable/disable functions. If the I & F bits (global IRQ & FIQ flags)
don't change correctly, then those 2 library functions may very well
be the fault.

> do you know the asm code of __enable_interrupt () ans
__disable_interrupt ?
>
> (the code follow at the end of this mail)

...that you can do for enable/disable with 3 asm instructions.

read cpsr --> register
modify I F bits
store register --> cpsr

As long as you configure your processor to the required priviledge
level (see ?cstartup examples & the ARM7TDMIS Documentation), you
can easily modify the I & F bits of the cpsr register to
enable/disable IRQ and FIQ global interrupts.

Good luck!
Leighton