Timers Again

15 Jul 2010

I have a new project involving timer generated pulses, with a pulse interval between 20 uS and 1mS. The timers are turned on with an initial compare value, and the timer ISR, in addition to generating the pulse, loads a new compare value if required.

This sample code with two timers shows my problem. The pulses are generated, but instead of the pulse interval being determined by the compare value of at least 100uS, the interval is approximate 1uS.

It looks like the interrupt is never cleared, putting the ISR into an endless loop.

So what am I missing?

Little aside: in March I was told that all the mbed timer stuff uses timer 3, but I saw something recently saying that it uses timer 0. Has a change been made?

#include "mbed.h"

void SetupTimer0(void);
void Timer0_IRQHandler(void);
void SetupTimer1(void);
void Timer1_IRQHandler(void);

DigitalOut myled(LED1);
DigitalOut myled2(LED2);
DigitalOut  X_STEP_PIN(p15);
DigitalOut  Y_STEP_PIN(p17);

int main() {
    SetupTimer0();
    SetupTimer1();
    while(1) {
//        myled2 = 1;
//        wait(0.2);
//        myled2 = 0;
//        wait(0.2);
    }
}

void SetupTimer1(void)
{
   LPC_SC->PCONP |= 1 << 2;     // Power on Timer`
   LPC_TIM1->TCR = 0x2;         // Reset and set to timer mode
   LPC_TIM1->CTCR = 0x0;
   LPC_TIM1->PR = 0;            // No prescale
   LPC_TIM1->MR0 = 2398;        // Match count for 100mS
   LPC_TIM1->MCR = 3;           // Interrupt and Reset on Match
   LPC_TIM1->TCR = 1;           // Enable Timer
   
   // Enable the ISR vector
   NVIC_SetVector (TIMER1_IRQn, (uint32_t)&Timer1_IRQHandler);
   NVIC_EnableIRQ(TIMER1_IRQn);
}

void Timer1_IRQHandler(void)
{
   X_STEP_PIN = 1;
   LPC_TIM1->MR0 = 23980;  // Match count for Step Interval
   myled2 = !myled2;
   X_STEP_PIN = 0;
}
void SetupTimer0(void)
{
   LPC_SC-> PCONP |= 1 << 1;    // Power on Timer0
   LPC_TIM0->TCR = 0x2;         // Reset and set to timer mode
   LPC_TIM0->CTCR = 0x0;
   LPC_TIM0->PR = 0;            // No prescale
   LPC_TIM0->MR0 =  2398;       // Match count for 100mS
   LPC_TIM0->MCR = 3;           // Interrupt, Stop, and Reset on match
   LPC_TIM0->TCR = 1;           // Enable Timer0
   // Enable the ISR vector
   NVIC_SetVector (TIMER0_IRQn, (uint32_t)&Timer0_IRQHandler);
   NVIC_EnableIRQ(TIMER0_IRQn);
}

void Timer0_IRQHandler(void)
{
   Y_STEP_PIN = 1;
   LPC_TIM0->MR0 = 239800;  // Match count for Step Interval
   myled = !myled;
   Y_STEP_PIN = 0;
}

26 Nov 2010

Hi john!!

listen, I'm no expert with the mbed, I've been working with it for about 2 months. I kinda of had the same problem as you and I believe I solved it, but guessing with the post date, probably you already solved it too.

In page 493 of the user's manual says:

21.6.1 Interrupt Register (T[0/1/2/3]IR - 0x40004000, 0x40008000,
0x40090000, 0x40094000)
The Interrupt Register consists of 4 bits for the match interrupts and 4 bits for the capture
interrupts. If an interrupt is generated then the corresponding bit in the IR will be high.
Otherwise, the bit will be low. Writing a logic one to the corresponding IR bit will reset the
interrupt. Writing a zero has no effect. The act of clearing an interrupt for a timer match
also clears any corresponding DMA request.

For this timer interrupt you have to "clear" the interrupt by ways of doing:

LPC_TIM0->IR = 1;

And does it, this allows the ISR to actually end and exit. Hope this can help.

******

But I have a question for you too. I'm trying to use CAP registers but not as a counter, but to use it to detect a rising or falling edge in one of the CAPn.0 or CAPn.1 so basically what it does is that whenever an event like this happens, a capture register is loaded with the value of the Timer Counter so you have the precision time of the event. However, in page 497 of the user manual, says the following:

21.6.10 Capture Control Register (T[0/1/2/3]CCR - 0x40004028, 0x40008028,
0x40090028, 0x40094028)
The Capture Control Register is used to control whether one of the four Capture Registers
is loaded with the value in the Timer Counter when the capture event occurs, and whether
an interrupt is generated by the capture event. Setting both the rising and falling bits at the
same time is a valid configuration, resulting in a capture event for both edges. In the
description below, "n" represents the Timer number, 0 or 1.

It calls my attention that n in CAPn.0 and CAPn.1 only applies for 0 or 1, (CAP0.[0/1] or CAP1.[0/1]) for the purpose of detecting the exact time of an event. However, if you take a look at the mbed schematic CAP0.x and CAP1.x its not connected to any DIP pin that we can use. So we can't use it, right?

Basically what I want is to capture the exact time when in a certain pin a rising edge or falling edge happens. Exactly what the description says, but according to the description it only works for CAP1.x or CAP0.x. CAP2.x and CAP3.x are indeed available, but not as event detectors.

Do you have any advice for me?