I have several interrupts in the system, including TC capture, external interrupts and ADC conversion interrupts. There's one vector in particular that, when executed, will prevent ANY vector from executing even after the reti()
instruction.
The TCB2 Capture interrupt vector (Vector 25) is the only vector in the system that stops everything leading to a WDT reset.
Global Interrupt Flag is 1, and the INTFLAGS for the activated interrupts get set correctly when an interrupt occurs. But no vector is executed. This applies for all interrupts.
I've tried changing the vector a little, making sure the reti()
instruction is present and making sure the vector table didn't change.
I also already made sure the code kept executing normally after the reti()
. The only thing that seems not to work are vectors.
volatile uint8_t new_input_regs = 0x00;
/*[Other code, including other vectors without this issue]*/
void __vector_25() {
new_input_regs = PORTD_IN; //Get PORTD input values
TCB2_CTRLA &= ~(0x01); //Clear TC enable and flags
TCB2_INTFLAGS = 0xFF;
asm("WDR"); //Reset the WD timer
event_type = EVENT_INPUT_INTERRUPT; //Set the event
reti();
}
After this executes, all interrupts stop working until reset (This also causes a Watchdog Reset eventually due to no interrupts executing).
More info about the register and vector table here: https://i.sstatic.net/f27lR.jpg
Thanks to the comment, i've noticed the ISRs were too optimized, even skipping retis and merging vectors in one single block of assemble with no returns. The default vector functions (Like __vector_25()
used above) do not work as expected, leading to un-terminated ISRs and missing reti()
even when manually written. This lead to completely unexpected behaviour.
I've changed the vector definition to ISR(_VECTOR(25))
and removed reti()
at the end of functions. Interrupts have resumed working as they should.
Thanks for the help.