--- In l..., "Brendan Murphy"
wrote: >
> --- In l..., "gert_vervoort" wrote:
> >
> > --- In l..., "abufadel" wrote:
> >
> > > /* Timer 1 interrupt is an IRQ interrupt */
> > > VICIntSelect &= ~0x20;
> > > /* Enable timer 1 interrupt */
> > > VICIntEnable = 0x20;
> > > /* Use slot 1 for timer 1 interrupt */
> > > VICVectCntl1 = 0x25;
> > > /* Set the address of ISR for slot 1 */
> > > VICVectAddr1 = (unsigned long)timer1ISR;
> > >
> >
> > The above code assumes that timer1 is connected to VIC channel 1,
> > however timer1 is connected to VIC channel 5.
> >
> > See table table 44 in the LPC2106 user manual from NXP
> (http://www.standardics.nxp.com/support/documents/microcontrollers/pdf
> /user.manual.lpc2104.lpc2105.lpc2106.pdf)
> >
> > Gert
> > Gert,
>
> There's nothing wrong with the code above.
>
> Timer 1 is indeed channel 5: this is used in the following registers: >
> - VICIntEnable (to enable channel) set to 0x20 (i.e. bit position 5)
> - VICIntSelect (to select IRQ/FIQ) bit 5 cleared: &= ~0x20
> - value written to VICVectCntl1: 0x20 to enable the slot, and 0x05 to > select the channel for the slot (i.e. the priority of
the interrupt: > in this case 1, the 2nd highest available)
>
> To the OP: are you enabling interrupts in the CPSR as well?
>
> Brendan
>
Shouldn't the write to VICIntEnable be the last statement (set
everything up then enable it)?
Also, shouldn't the write to VICIntEnable be preceeded by a write to
the timer 1 register that clears it's interrupt (to make sure it is
cleared before enabling it)?
TC
Reply by Brendan Murphy●September 8, 20072007-09-08
--- In l..., "abufadel" wrote: > >
> > And what happens when "main()" returns?
> > I must have skipped a line while copying.
>
> while (timer1Count < 5);
>
> comes right before return 0; Essentially, timer1 isr increments the
> counter and toggles the led.
>
> Thank you.
Make sure you declare any variable shared between an interrupt and
background function as "volatile", i.e.
volatile int timer1Count;
Reply by rtstofer●September 8, 20072007-09-08
> I must have skipped a line while copying.
>
> while (timer1Count < 5);
>
> comes right before return 0; Essentially, timer1 isr increments the
> counter and toggles the led.
>
> Thank you.
>
> -- A
>
For embedded systems, it is unusual for a main() function to return.
Sometimes the startup code can handle this because it calls the main
function and has a loop that traps the CPU if main returns. This
isn't always the case, sometimes the startup code branches to main and
doesn't provide the loop.
So, always put 'while(1) ;' at the end of your main function to
prevent a return.
As Brendan pointed out, your startup code might not have enabled the
interrupts in CPSR. Just before the branch to main, look for this:
MSR CPSR_c,#MODE_SVC /* enable interrupts */
MSR CPSR_c,#MODE_USR
/* Enter the C code */
b main
Notice the branch to main. It better not return or we'll be joining
Tinkerbell in Neverland.
Richard
Reply by abufadel●September 8, 20072007-09-08
--- In l..., "Brendan Murphy"
wrote: >
> --- In l..., "abufadel" wrote:
> >
> > Greetings,
> > I am trying to get the Timers 0 and 1 to work with interrupts
> using
> > the Olimex 2106 board, but cannot get the interrupts to work. I am
> > following the example code given in the CrossStudio help, which I
> > provide below. I seem to be unable to get an interrupt? Is there a
> > special way or trick for debugging with interrupts? How can I see
> > what the Timer Counter is?
> >
> > Thank you in advance for your time and help.
> >
> >
> >
> > static void timer1ISR(void) __attribute__ ((interrupt ("IRQ")));
> >
> > static
> > void
> > timer1ISR(void)
> > {
> > ++timer1Count;
> > /* Clear the timer 1 interrupt */
> > T1IR = 0xFF;
> > /* Update VIC priorities */
> > VICVectAddr = 0;
> > }
> >
> > int
> > main(void)
> > {
> >
> > /* Timer 1 interrupt is an IRQ interrupt */
> > VICIntSelect &= ~0x20;
> > /* Enable timer 1 interrupt */
> > VICIntEnable = 0x20;
> > /* Use slot 1 for timer 1 interrupt */
> > VICVectCntl1 = 0x25;
> > /* Set the address of ISR for slot 1 */
> > VICVectAddr1 = (unsigned long)timer1ISR;
> >
> > /* Reset timer 1 */
> > T1TCR = 0;
> > /* Set the timer 1 prescale counter */
> > T1PR = 2500;
> > /* Set timer 1 match register */
> > T1MR0 = 1000;
> > /* Generate interrupt and reset counter on match */
> > T1MCR = 3;
> > /* Start timer 1 */
> > T1TCR = 1;
> >
> > /* Enable Interrupts */
> > __ARMLIB_enableIRQ(); /*CrossStudio specific*/
> > /*I also tried using VICINTEN = 0x20*/
> >
> > return 0;
> > }
> > And what happens when "main()" returns?
>
I must have skipped a line while copying.
while (timer1Count < 5);
comes right before return 0; Essentially, timer1 isr increments the
counter and toggles the led.
Thank you.
-- A
Reply by Brendan Murphy●September 8, 20072007-09-08
--- In l..., "gert_vervoort" wrote: >
> --- In l..., "abufadel" wrote:
>
> > /* Timer 1 interrupt is an IRQ interrupt */
> > VICIntSelect &= ~0x20;
> > /* Enable timer 1 interrupt */
> > VICIntEnable = 0x20;
> > /* Use slot 1 for timer 1 interrupt */
> > VICVectCntl1 = 0x25;
> > /* Set the address of ISR for slot 1 */
> > VICVectAddr1 = (unsigned long)timer1ISR;
> > The above code assumes that timer1 is connected to VIC channel 1,
> however timer1 is connected to VIC channel 5.
>
> See table table 44 in the LPC2106 user manual from NXP
> (http://www.standardics.nxp.com/support/documents/microcontrollers/pdf
/user.manual.lpc2104.lpc2105.lpc2106.pdf) >
> Gert
>
Gert,
There's nothing wrong with the code above.
Timer 1 is indeed channel 5: this is used in the following registers:
- VICIntEnable (to enable channel) set to 0x20 (i.e. bit position 5)
- VICIntSelect (to select IRQ/FIQ) bit 5 cleared: &= ~0x20
- value written to VICVectCntl1: 0x20 to enable the slot, and 0x05 to
select the channel for the slot (i.e. the priority of the interrupt:
in this case 1, the 2nd highest available)
To the OP: are you enabling interrupts in the CPSR as well?
Brendan
Reply by gert_vervoort●September 8, 20072007-09-08
--- In l..., "abufadel" wrote:
> /* Timer 1 interrupt is an IRQ interrupt */
> VICIntSelect &= ~0x20;
> /* Enable timer 1 interrupt */
> VICIntEnable = 0x20;
> /* Use slot 1 for timer 1 interrupt */
> VICVectCntl1 = 0x25;
> /* Set the address of ISR for slot 1 */
> VICVectAddr1 = (unsigned long)timer1ISR;
>
The above code assumes that timer1 is connected to VIC channel 1,
however timer1 is connected to VIC channel 5.
Reply by Brendan Murphy●September 8, 20072007-09-08
--- In l..., "abufadel" wrote: >
> Greetings,
> I am trying to get the Timers 0 and 1 to work with interrupts using > the Olimex 2106 board, but cannot get the interrupts
to work. I am
> following the example code given in the CrossStudio help, which I
> provide below. I seem to be unable to get an interrupt? Is there a
> special way or trick for debugging with interrupts? How can I see
> what the Timer Counter is?
>
> Thank you in advance for your time and help.
>
> static void timer1ISR(void) __attribute__ ((interrupt ("IRQ")));
>
> static
> void
> timer1ISR(void)
> {
> ++timer1Count;
> /* Clear the timer 1 interrupt */
> T1IR = 0xFF;
> /* Update VIC priorities */
> VICVectAddr = 0;
> }
>
> int
> main(void)
> {
>
> /* Timer 1 interrupt is an IRQ interrupt */
> VICIntSelect &= ~0x20;
> /* Enable timer 1 interrupt */
> VICIntEnable = 0x20;
> /* Use slot 1 for timer 1 interrupt */
> VICVectCntl1 = 0x25;
> /* Set the address of ISR for slot 1 */
> VICVectAddr1 = (unsigned long)timer1ISR;
>
> /* Reset timer 1 */
> T1TCR = 0;
> /* Set the timer 1 prescale counter */
> T1PR = 2500;
> /* Set timer 1 match register */
> T1MR0 = 1000;
> /* Generate interrupt and reset counter on match */
> T1MCR = 3;
> /* Start timer 1 */
> T1TCR = 1;
>
> /* Enable Interrupts */
> __ARMLIB_enableIRQ(); /*CrossStudio specific*/
> /*I also tried using VICINTEN = 0x20*/
>
> return 0;
> }
>
And what happens when "main()" returns?
Reply by abufadel●September 8, 20072007-09-08
Greetings,
I am trying to get the Timers 0 and 1 to work with interrupts using
the Olimex 2106 board, but cannot get the interrupts to work. I am
following the example code given in the CrossStudio help, which I
provide below. I seem to be unable to get an interrupt? Is there a
special way or trick for debugging with interrupts? How can I see
what the Timer Counter is?