2024-12-20 01:51 PM
Hello Everyone,
I have run into some unexpected behavior on STM32H723 microcontroller on the Nucleo-H723ZG board. It appears that the ARM Interrupt chaining may not be working.
Here's my setup:
I have shorted 3 pins on CN12, which shorts PB1, PB2 and PB15 together. PB1 and PB2 are set up as inputs with rising edge interrupt enabled on both. Both interrupts are at the same priority. PB15 is an output.
Every time I drive PB15 high and then low, I get the interrupts on PB1 and PB2, which I can verify by incremented variables. If I disable one or both of the interrupts, then only the enabled interrupt/interrupts happen. All that is as expected.
But when I measure how long it takes to execute the interrupts, executing both interrupts takes exactly twice as long as executing one interrupt. This should not be the case. The hardware interrupt chaining should mean the second interrupt does not have to save/restore registers and it should take less time to execute.
My questions:
Does one need to set some register or change some configuration to enable interrupt chaining?
Do we know if interrupt chaining works on this processor?
Is there some other subtlety that I am missing?
This is how I measure these times. I set the pin, waste some time by executing some code, then clear the pin. If the interrupt happens between the time I set and clear the pins, it will take longer to execute the code and the pin's high time will be longer by the time the processor is busy servicing the interrupt.
My main code is as follows:
while (1) {
LL_mDelay(250);
GPIOB->BSRR = 0x00008000; // Set PB15
for(i=0; i<8; i++) { // Waste some time
Hack += i;
}
GPIOB->BSRR = 0x80000000; // Clear PB15
}
In order to prevent the compiler for optimizing away the for loop, both i and Hack are declared as volatile.
When I do this, with the interrupts disabled, PB15 stays high for ~200ns due to executing the for() loop.
When I do this with one of the interrupts enabled, the PB15 high time extends by 84ns.
When I do this with both interrupts enabled, the PB15 high time extends by 170ns, almost exactly double the time for two interrupts.
For this test, the interrupt handlers do nothing other than clear the interrupt by writing to EXTI->PR1.
void EXTI1_IRQHandler(void)
{
EXTI->PR1 = 0x0002; // Acknowledge GPIO B[1] interrupt
}
void EXTI2_IRQHandler(void)
{
EXTI->PR1 = 0x0004; // Acknowledge GPIO B[2] interrupt
}
Any insights would be greatly appreciated.
Regards,
Hamid