2023-01-31 01:29 PM
Hi.
I am having some issues trying to use the EXTI module, to implement interruption routines associated to ports.
The problem is related to the behavior of STM32 microcontrollers with ports interruptions. In most microcontrollers (i.e. Texas Instruments MSP430), when it comes to port interruption handling, we have interruption flags (IFG) and interruption enables (IE) for each port. Then, when an event occurs on a port, for example, a pulse transition from low to high, the IFG goes to high even if the interrupt is disabled. In case the interrupt is enabled, the IFG goes to high too and the interruption service routine (ISR) is executed. In that way, when you have an interruption disabled (IE = 0) and an event happens on the port, the IFG is set to high. If in any part of your code you enable the interruption (IE = 1), the ISR is immediately called because the IFG = 1. This is a good way to store the occurrence of an event, even in the case the interrupt is disabled in the moment when the event occurs.
But STM32 looks to work in a different way. For example, when you have a port interruption disabled (EXTI IMRx disabled) if the event occurs in any moment, the corresponding flag (EXTI PRx) is not set because the IMRx was disabled. Then, the occurrence of the event is not stored if occurred when the interruption was disabled, as you can do with other microcontrollers, as in the exampled I wrote above.
Maybe, someone could say "Why don't you enable the interrupt if you don't want to lose the event?". There could be different reasons why, one of them is the following: Let's suppose that I have two different port interruptions, one for an external signal in port A1, and other coming from a button in port A2. Let's suppose that in some portions of my code, I need to wait only for the signal in port A1 and respond as soon as possible for a timing constraint that I have in my project. Let's suppose I cannot have any other interruption enabled (neither timers nor my button in port A2) in order to respond as quick as possible when the event related to the signal in port A1 occurs. But, when I go out from that portion of the code, I will go to a main loop, in where I will enable and attend the other interruptions (timers, the button in port A2, etc.). What would happen if any of those events arrived when I was in the signal wait routine described above? With timers I won't have problems because timers rise the flag event even if the interruption were disabled. But with EXTI port interruptions I will lose the event because there is not flag which "store" the occurrence of the event when the interruption was disabled.
Then, if someone have some idea about how to solve this problem, please, give me some suggestions. Maybe there are another flag or something that I am not aware of.
Thank you in advance for your help.
Solved! Go to Solution.
2023-02-01 07:19 PM
Not sure if this code snippet will help, here it's a scheme to disable the EXTI interrupt when it is receiving a high square wave MHz input as "attack", the interrupt self disable for a while (Timer) and is reenabled by mainloop.
void IRQ_OVR_DemoEXTI_MainLoop_100msec(void) {
if(IRQ_OVR_Get(EXTI0_1_INT)==0) {
IRQ_OVR_Set(EXTI0_1_INT, 10); // allow 10 interrupt events until next comeback here
HAL_NVIC_EnableIRQ(EXTI0_1_IRQn); // reenable the interrupt
}
}
void EXTI0_1_IRQHandler(void)
{
(...)
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
if(IRQ_OVR_Fired(EXTI0_1_INT)) // did we exceed the interrupt rate over a timer period ?
HAL_NVIC_DisableIRQ(EXTI0_1_IRQn); // disable the interrupt
(...)
}
The number of interrupt vector determines the number of individual decorrelated pins.
2023-02-02 09:02 AM
Hi
Both, using the capture timers or using priorities and BASEPRI to enable/disable some interruptions are good alternatives. Personally, capture timers is not an option for my case, because in my current project I have a circuit already designed and the ports are already assigned. Then, many of them are not in the proper inputs for the timers capture feature. Additionally, we have many counters in use in those timers, and I wouldn't want to lose them in other functionalities.
Using BASEPRI looks a better option, but it is the same than enable/disable the NVIC handlers. I could let the EXTI IE enabled and EXTI NVIC handler disabled in the portion of my code I don't want to have it enabled. As EXTI IE are going to be always enabled, then the PR bits are going to be set by hardware when the event in my ports occurs. I will get the same result than using priorities and the BASEPRI register. But, if I have 2 input signals (as in fact I have) in ports PA12 and PA13?, Both share the same handler. If in a portion of my code I have to enable interruption in PA12 but I don´t want to enable it in PA13, I could not disable one and enable the other via NVIC Handlers because they share the same handler. The BASEPRI solution won't work for the same reason.
Finally, it is a really shame that EXTI module has been designed in that way. Maybe my only alternative is to have the ports EXTI interruptions always enabled and implement a kind of "logic" which store the occurrence of an event and decide to attend it immediately or later according to the part of the code in where the microcontroller is when the event happens. I will have to pay the overhead of an interruption in a place in where I don't want to interrupt, but I can decrease that overhead with that logic that let the microcontroller decide if executes the corresponding task associated to the event, o let them to be executed later.
2023-02-02 11:13 AM
How much max latency from the edge event to what you need to do in the ISR ?
What does the ISR ?
What frequency the ISR for one pin would be (worst case) ?
In case of multiple pins mapped onto the same vector, the interrupt could read a bitmask and self disable the pin source depending on such mask. There maybe more interrupt, however les repetitively. Say PA12 and PA13 are going to the same vector, the ISR could decide to kill subsequent interrupts from PA12 and enabled elsewhere. Are the EXTI interrupt pin ISR mutually enabling / disabling criss crossed themselves?
2023-02-06 01:38 PM
Agree, the EXTI looks too 20th century these days. Could be redesigned for more convenience. Together with the vectors (VTOR) alignment requirement. How hard is replacement of OR'ing with ADD'ing on modern chips?
> But, if I have 2 input signals (as in fact I have) in ports PA12 and PA13?, Both share the same handler.
This AFAIK does not have a good solution. But, more or less ugly workarounds can be done.