2019-11-19 10:28 AM
I'm currently trying to implement a button interrupt and need to disable the button interrupt after the initial call to the isr to avoid excessive interrupt triggering due to debounce. I'm using STM32CUBEIDE/MX currently. The button works as desired if I use
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn); (in interrupt)
//do some stuff
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); (in main)
but this is non-ideal as it disables exti lines 5 through 9.
I've been trying to mask the EXTI line using EXTI_IMR. This seems to work for the first button press, but I'm never able to re-trigger the ISR
EXTI->IMR &= ~(EXTI_LINE_5);//in ISR
EXTI->IMR &= (EXTI_LINE_5);//in main
Thoughts?
Solved! Go to Solution.
2021-01-29 01:13 AM
They do support enable/disable interrupt, but not masking.
2021-02-06 11:42 AM
As Jan noted, there are gotchas related to interrupt disabling at peripheral level. This is explained in ARM Application Note 321, section 4.9 "Disabling interrupts at peripherals".
@deckhard
2021-05-03 02:34 PM
That solution doesn't work for me. In my case the line that signals an IRQ comes from an ADC and it uses the same line for SPI data output, so after I get the IRQ and then read the result from the ADC I get multiple IRQs unless I disable EXTI 9-5. It solves this problem but I have another peripheral using pin 7 for an IRQ so I don't really want 5-9 disabled together. Here is my code:
Mike.
//EXTI->IMR &= -(EXTI_LINE_5); // Disable interrupts on line 5 while we read ADC. THIS DOESN'T WORK - NEED TO FIND A FIX... TODO
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn); //Disable interrupt pins as pin5 will toggle when we read from ADC. Would rather fix the line above.
spi3TxRxResult = HAL_SPI_TransmitReceive(&hspi3, spi3TxBuffer, ADC_Reading, 4, 2); // 2ms timeout.
if (spi3TxRxResult != HAL_OK) Error_Handler();
ADC_Ch = ADC_Reading[3] & 0x03;
Chan_Status[ADC_Ch] = ADC_Reading[3] >> 4;
Chan_Reading[ADC_Ch] = ((ADC_Reading[0] & 0x7F) << 16) + (ADC_Reading[1] << 8) + ADC_Reading[2];
EXTI->PR = 1 << 5; // Clear pending register for this EXTI Pin.
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); // Re-enable interrupts. Would rather fix and use the line below.
//EXTI->IMR |= (EXTI_LINE_5); // Re-enable interrupts on line 5. THIS DOESN'T WORK - NEED TO FIND A FIX... TODO
2021-05-03 09:38 PM
Which STM32?
//EXTI->IMR &= -(EXTI_LINE_5)
Not *minus*, but *tilde* (for bitwise inversion).
JW
2021-05-04 08:00 AM
I am using the STM32F407VETx - I assume any in the STM32F4 family would work the same.
I thought the *minus* was weird but clearly that is what is in this post. I had tried with *tilde* and had the same results.
Mike.
2021-05-04 02:10 PM
> I assume any in the STM32F4 family would work the same.
Maybe yes, maybe not. Probably yes, but "probably" means little when facing a problem.
> I thought the *minus* was weird but clearly that is what is in this post.
No, it's not. A bad font is used in this mockup of a forum. Zoom up that post if your browser allows it, or, better, copy/paste that text into your programmer's editor.
Read out the EXTI register content before and after the operation and check/post.
How and where is EXTI_LINE_5 defined?
JW
2021-05-04 04:10 PM
Well, bad font for sure!
OK so I changed to the tilde and looked at EXTI->IMR before (0x48B5) and after (0x48B0).
EXTI_LINE_5 is defined in stm32f4xx_hal_exti.h as:
#define EXTI_LINE_5 (EXTI_GPIO | 0x05u) /*!< External interrupt line 5 */
Seems weird to me that it isn't a single bit...
Mike.
2021-05-04 04:59 PM
OK, I found the solution. EXTI_LINE_5 is defined as some large number like: 0x600005. It appears that line 5 corresponds to bit 5 so the following works for me:
EXTI->IMR &= 0xFFFFFFDF; To disable IRQ on line 5
EXTI->IMR |= 0x00000020; To enable IRQ on line 5
Mike.
2021-05-04 11:56 PM
This is a well deserved punishment for using Cube/HAL and its haphazardly defined symbols, instead of direct register access and symbols from CMSIS-mandated device headers.
Cube is good only as long as you stay within clicking distance of CubeMX. Anything other than the "usual usage" as envisaged by Cube's authors leave you vulnerable to Cube's innards. Here, definition of given symbol changed with changing Cube version, who could tell that when this thread started. I tried to find that symbol in some older CubeF4 I happen to have on my disk, but it was not there are all.
JW
2021-05-22 05:42 AM
It should be noted that operations on EXTI_IMR bits are not atomic. Therefore to use them from interrupts or multiple threads, they must be enclosed in critical sections. One can use OS/platform provided functions or a code like this:
https://community.st.com/s/question/0D50X0000BVmd12SQB/stm32l4-critical-section