Skip to main content
Craig1
Associate
November 19, 2019
Solved

How to disable/MASK an exti line ON THE FLY

  • November 19, 2019
  • 19 replies
  • 6977 views

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?

This topic has been closed for replies.
Best answer by Craig1

DOH! forgot my coffee this morning, sorry this works:

EXTI->IMR &= ~(EXTI_LINE_5);//in ISR

EXTI->IMR |= (EXTI_LINE_5);//in main

19 replies

Craig1
Craig1AuthorBest answer
Associate
November 19, 2019

DOH! forgot my coffee this morning, sorry this works:

EXTI->IMR &= ~(EXTI_LINE_5);//in ISR

EXTI->IMR |= (EXTI_LINE_5);//in main

waclawek.jan
Super User
November 19, 2019

Thanks for coming back with the solution. Can you please select our post as Best so that the thread is marked as resolved.

JW

deckhard
Associate III
January 28, 2021

Masking is needed if the interrupt is a level interrupt.

To my understanding the EXTI controller is only Edge triggered so not sure why masking is needed.

Pavel A.
January 28, 2021

@deckhard​ 

> To my understanding the EXTI controller is only Edge triggered so not sure why masking is needed.

Masking can be useful for shared EXTI interrupt vectors such as EXTI15_10, EXTI9_5.

It allows to temporary delay only one EXTI pin interrupt without affecting others on the same NVIC vector.

-- pa

deckhard
Associate III
January 29, 2021

Ok that makes sense

waclawek.jan
Super User
January 29, 2021

No. Cube/HAL inevitably covers only a limited subset of possible functionality, only what is authors deem "usual".

JW

deckhard
Associate III
January 29, 2021

They do support enable/disable interrupt, but not masking.

Piranha
Principal III
February 6, 2021

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​ 

MStra.3
Associate III
May 3, 2021

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

waclawek.jan
Super User
May 4, 2021

Which STM32?

//EXTI->IMR &= -(EXTI_LINE_5)

Not *minus*, but *tilde* (for bitwise inversion).

JW

MStra.3
Associate III
May 4, 2021

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.

waclawek.jan
Super User
May 4, 2021

> 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

MStra.3
Associate III
May 4, 2021

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.