Level sensitive interrupts with EXTI
I need to achieve level sensitive interrupt behavior with EXTI, similar to shared PCI interrupts on other architectures.
Have several OR'ed interrupt requests wired together to a EXTI input;
all requests are active low.
All requests can be masked or dismissed outside of STM32.
(Actually this is a device with several interrupt reason bits in a memory mapped register; the common request pin is active low; each interrupt reason bit can be masked via another memory mapped register. Like a "classic" PCI thing).
Several threads in this forum and SO (links below) suggested that this is not possible, at least not trivial.
The following trick nevertheless seems to work for me, and looks simple.
extern void exti0_handler();
void EXTI0_IRQHandler(void)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
do {
exti0_handler();
} while (HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_0) == GPIO_PIN_RESET); /* active LOW */
__DSB();
}Explanation:
* The EXTI0 interrupt is triggered by falling edge. GPIOx is some GPIO port (A,B...)
* exti0_handler() will check each of interrupts source on the shared EXTI pin and either masks it or dismisses
* If the pin still is low (request active) after exti0_handler(), repeat.
- If the interrupt pin goes down between check of the pin and return, then the falling edge detector will activate EXTI again and it won't be lost.
Can anyone spot a bug?
Of course if the EXTI pin remains low for too long time the interrupt latency would be indefinite. If this is important, number of loops can be limited (and some action taken, like masking the whole EXTI input).
Regards,
-- pa
References:
Level triggered interrupts on STM32L series
exception - Clarify interrupt mechanism on STM32H7 - Stack Overflow
