Timer priority

14 Jun 2011

Hi,

As far as I've seen, when you create a timer (or ticker or timeout) it is put in the timer3 group. You can lower the priority of this group by doing

NVIC_SetPriority(TIMER3_IRQn, 1);

However, I want the one timer to have a different priority than the other. How do I do this? Can I set the priority individualy somehow? Or should I declare the other timer in the TIMER2_IRQn group somehow?

Thanks in advance!

Melchior

Edit: I would very much like to keep the timer.attach() functionality :p

Edit2: I currently have something like:

void TIMER0_init(void)
{ 
    LPC_SC->PCONP |= 1<<1; // Timer0 Power On
    LPC_TIM0->MR0 = 2398;  // Match count for 100uS
    LPC_TIM0->MCR = 3;     // Interrupt and Reset on Match
    LPC_TIM0->TCR = 1;     // Enable Timer0
    testing.printf("TIMER0 initialized.\r\n");

}

extern "C" void TIMER0_IRQHandler(void)
{ // send a message every 2398 ms
    testing.printf("TIMER0_IRQHandler is live!\r\n");
}

int main() 
{
    NVIC_SetVector(TIMER0_IRQn,uint32_t(TIMER0_IRQHandler));
    TIMER0_init();
    NVIC_SetPriority(TIMER0_IRQn, 2);
    while(1) 
    {
        setdata(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
        if(can.write(CANMessage((1792+node_id),candata,1))) 
        {
            canact=!canact;
        }
        wait(1); // send a bootup message every second
    }
}

Which does nothing. (interrupt wise)

14 Jun 2011

A full test code. The ticker works, since it has higher priority, the TIMER0_IRQ does not.

#include "mbed.h"

DigitalOut myled(LED1);
DigitalOut ledje(LED2);
DigitalOut nogeenledje(LED3);
Ticker testtimer;

void TIMER0_init(void)
{ 
    LPC_SC->PCONP |= 1<<1; // Timer0 Power On
    LPC_TIM0->MR0 = 3600000;  // Match count for 150ms
    LPC_TIM0->MCR = 3;     // Interrupt and Reset on Match
    LPC_TIM0->TCR = 1;     // Enable Timer0
    NVIC_EnableIRQ(TIMER0_IRQn); 
}

extern "C" void myIRQ(void)
{
    ledje = !ledje;
}

void toggle()
{
    nogeenledje = !nogeenledje;
}

int main() 
{
    ledje = 0;
    NVIC_SetVector(TIMER0_IRQn,(uint32_t)&myIRQ);
    NVIC_SetPriority(TIMER0_IRQn,1);
    testtimer.attach(&toggle,0.3);
    TIMER0_init();
    
    
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}

What am I forgetting?

Melchior

14 Jun 2011

Melchior Pau wrote:

What am I forgetting?

Maybe to clear the LPC_TIM0->IR interrupt flag for MR0 in your ISR?

14 Jun 2011

Ah yes, I did try that, but "Writing a logic one to the corresponding IR bit will reset the interrupt. Writing a zero has no effect", with MR0 = bit 0,

extern "C" void myIRQ(void)
{
    ledje = !ledje;
    LPC_TIM0->IR |= 0<<1;
}

does not seem to work.

Edit: Okay...

int i = 0;

extern "C" void myIRQ(void)
{
    if(i==0)
    {
        i++;
    }
    else
    {
        ledje = !ledje;
        i=0;
    }
    LPC_TIM0->IR |= 0<<1;
}

This does work... I don't really get why that would work and the one above wouldn't. Anyone?

14 Jun 2011

Looks like a typo crept in -

Melchior Pau wrote:

extern "C" void myIRQ(void)
{
    ledje = !ledje;
    LPC_TIM0->IR |= 0<<1;
}

Should be

extern "C" void myIRQ(void)
{
    ledje = !ledje;
    LPC_TIM0->IR |= 1<<0;     // Writes a 1 to bit 0 of the IR register
}
14 Jun 2011

Try

LPC_TIM0->IR = 1<<0;
14 Jun 2011

D'oh, cheers :D