Electronic – Interrupt never fires

atxmegacinterruptsisrtimer

I'm new to embedded and I've been struggling with this for days. I just don't understand why this doesn't work.

I'm using an ATxMega128A1. I want to use a timer overflow interrupt to left shift a bit on a port to the next pin. The timer works. I can see it click through CNT in the simulator, and the overflow flag gets set, but the ISR never executes (and thus, the overflow flag never gets reset either). Does anyone have any idea where I'm going wrong? I more or less copy/pasted the timer/interrupt code from Atmel's training code.

ISR(TCC0_OVF_vect)
{
    LEDPORT = (LEDPORT << 1);
}

int main(void)
{
    initLights();

    // Set up Timer/Counter 0.
    TCC0.PER = 0x10; // 
    TCC0.CTRLA = ( TCC0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV1_gc; //start timer with system clock
    TCC0.INTCTRLA = ( TCC0.INTCTRLA & ~TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_LO_gc; // Enable overflow interrupt.

    // enable global interrupts:
    sei();

    while(true)
    {   
        //do nothing, the timer interrupt will handle it
    }
}

Best Answer

As you probably know, the XMEGA has a multilevel interrupt controller. You not only have to enable the global interrupt but also the desired Level-Interrupt (Low-Level since you configured your timer priority to "low") in the control register.

CTRL – Control register

Bit 0 – LOLVLEN: Low-level Interrupt Enable(1)

When this bit is set, all low-level interrupts are enabled. If this bit is cleared, low-level interrupt requests will be ignored.

The code to enable the specific interrupt level is below.

//enable low level interrupts
PMIC.CTRL |= PMIC_LOLVLEN_bm; //0b00000001