zboot
04-10-07, 11:18 PM
I've been coding for the lpc2131 using WinARM.
I setup timer0 as a free running timer. I use the two match registers to generate interrupts on the compare match event. I do not reset the timer counter, I just increment the match registers by the amount needed to generate another interrupt in the future.
Now, here comes the tricky part. When I only enable one interrupt (ie only generate interrupts on either a compare match of T0MR0 or T0MR1), the code executes ok. But, when I allow both to generate interrupts, one interrupt will stop working for a while, then it will start working and the other will stop. There is sometimes a few seconds when both will work as expected.
Here is the code:
#include "timer.h"
#include "type.h"
#include "irq.h"
#include "LPC213x.h"
#include "iofun.h"
volatile long timeval;
void Timer0ISR(void) __irq;
/* Timer Counter 0 Interrupt executes each 10ms @ 60 MHz CPU Clock */
void Timer0ISR (void) __irq
{
volatile BYTE iFlag;
iFlag = T0IR;
if (iFlag & 0x01)
{
++timeval; // increment ms counter
T0MR0 = T0MR0 + TMR_1_MS - 1; // next interrupt in 1ms
T0IR |= 0x01; // clear interrupt flag
}
if (iFlag & 0x02)
{
//AD0CR |= (1 << 24); // start A2D conversion
T0MR1 = T0MR1 + TMR_1_MS*40 - 1; // next interrupt in 40ms
IOPIN1 ^= YEL_LED_PIN; // toggle LED pin
T0IR |= 0x02; // clear interrupt flag
}
VICVectAddr = 0; // Acknowledge Interrupt
}
// at 15Mhz - 15000 counts per ms
/* Setup the Timer Counter 0 Interrupt */
void init_timer (void)
{
timeval = 0;
T0TCR = 0x02; // reset timer and prescale count
T0PR = 0x0000; // divide by 1 (prescaler = 1 - 1)
T0MR0 = TMR_1_MS - 1; // interrupt in 1ms
T0MR1 = TMR_1_MS*40 - 1; // interrupt in 40ms
//T0MCR = (1 << 0) | (1 << 3); // interrupt on match of MR[0..1]
T0MCR = 8;
VICVectAddr0 = (unsigned long)Timer0ISR; // set interrupt vector in 0
VICVectCntl0 = TIMER0_INT | IRQ_SLOT_EN; // use it for Timer 0 Interrupt
VICIntEnable |= (1 << 4); // Enable Timer0 Interrupt
T0TCR = 0x01; // Timer0 Enable (reset cleared)
}
I setup timer0 as a free running timer. I use the two match registers to generate interrupts on the compare match event. I do not reset the timer counter, I just increment the match registers by the amount needed to generate another interrupt in the future.
Now, here comes the tricky part. When I only enable one interrupt (ie only generate interrupts on either a compare match of T0MR0 or T0MR1), the code executes ok. But, when I allow both to generate interrupts, one interrupt will stop working for a while, then it will start working and the other will stop. There is sometimes a few seconds when both will work as expected.
Here is the code:
#include "timer.h"
#include "type.h"
#include "irq.h"
#include "LPC213x.h"
#include "iofun.h"
volatile long timeval;
void Timer0ISR(void) __irq;
/* Timer Counter 0 Interrupt executes each 10ms @ 60 MHz CPU Clock */
void Timer0ISR (void) __irq
{
volatile BYTE iFlag;
iFlag = T0IR;
if (iFlag & 0x01)
{
++timeval; // increment ms counter
T0MR0 = T0MR0 + TMR_1_MS - 1; // next interrupt in 1ms
T0IR |= 0x01; // clear interrupt flag
}
if (iFlag & 0x02)
{
//AD0CR |= (1 << 24); // start A2D conversion
T0MR1 = T0MR1 + TMR_1_MS*40 - 1; // next interrupt in 40ms
IOPIN1 ^= YEL_LED_PIN; // toggle LED pin
T0IR |= 0x02; // clear interrupt flag
}
VICVectAddr = 0; // Acknowledge Interrupt
}
// at 15Mhz - 15000 counts per ms
/* Setup the Timer Counter 0 Interrupt */
void init_timer (void)
{
timeval = 0;
T0TCR = 0x02; // reset timer and prescale count
T0PR = 0x0000; // divide by 1 (prescaler = 1 - 1)
T0MR0 = TMR_1_MS - 1; // interrupt in 1ms
T0MR1 = TMR_1_MS*40 - 1; // interrupt in 40ms
//T0MCR = (1 << 0) | (1 << 3); // interrupt on match of MR[0..1]
T0MCR = 8;
VICVectAddr0 = (unsigned long)Timer0ISR; // set interrupt vector in 0
VICVectCntl0 = TIMER0_INT | IRQ_SLOT_EN; // use it for Timer 0 Interrupt
VICIntEnable |= (1 << 4); // Enable Timer0 Interrupt
T0TCR = 0x01; // Timer0 Enable (reset cleared)
}