2020-12-19 11:18 AM
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.
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
2020-12-19 12:17 PM
Looks good, IMO. Just minor things:
JW
2020-12-20 12:54 AM
I mean not next clear but break yu miss
void EXTI0_IRQHandler(void)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
do {
exti0_handler();
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) break;
} while (HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_0) == GPIO_PIN_RESET); /* active LOW */
__DSB();
}
2020-12-20 07:41 AM
Thank you Jan. Yes, handler() is ok when no source bit is set. DSB is left there perhaps just for luck ;)
2020-12-20 08:36 AM
This your code is totaly miss , when no next interrupt edge you stay in while neverending.
My first code is ok, when new IRQ flag raised while is break, and NVIC controll start new EXTI0_IRQHandler ...
2020-12-20 10:35 AM
You're right. I'll remove my wrong 'guess'. -- pa
2020-12-24 08:41 AM
Pavel's code is perfectly fine if the rest of the code and hardware functions as described. EXTI clear can even be put inside the while loop before exti0_handler(), potentially decreasing the chance of interrupt reentering.
@MM..1, you should stop writing misinformation with such high confidence. Your code is exactly like ST's HAL - hacked something together without real understanding. And the language skill also should be at least at a level understandable by others.
2020-12-24 02:41 PM
@Piranha Pavel removes wrong code from message, and yes my eng isnt native
2021-01-03 09:09 AM
OK, then it's clear about Pavel's code. But this particular line is still a nonsense:
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) break;
Most of the users here aren't native English speakers. It's not so much about grammar, but more about expressing the ideas in a clear and structured way - so that others can understand and use that information.
2021-01-03 09:18 AM
Why nonsense explain...