2022-08-08 03:04 AM
Try to implement an atomtic operation to avoid a specific interrupt generated by GPIOB GPIO_PIN_8 . If using the code as below, it works.
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
//atomtic operation
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
But tried the code as following, it doesn't work. Using GPIOB GPIO_PIN_8 as external interrupt.
// #define EXTI_LINE_8 (EXTI_GPIO | 0x08u) /*!< External interrupt line 8 */
//The value of EXTI_LINE_8 is 0x6000008
EXTI->IMR &= ~(EXTI_LINE_8);
//atomtic operation
EXTI->IMR |= (EXTI_LINE_8);
//And tried GPIO_PIN_8, it's still not working.
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
EXTI->IMR &= ~(GPIO_PIN_8);
//atomtic operation
EXTI->IMR |= (GPIO_PIN_8);
Any suggetsions?
2022-08-08 03:17 AM
typo, should be |= ?
hth
KnarfB
2022-08-08 03:43 AM
typo.
But tried the code as following, it doesn't work. Using PB GPIO_PIN_8 as external interrupt.
EXTI->IMR &= ~(EXTI_LINE_8);
//atomtic operation
EXTI->IMR |= (EXTI_LINE_8);
2022-08-08 04:48 AM
Which STM32?
> //The value of EXTI_LINE_8 is 0x6000008
> EXTI->IMR &= ~(EXTI_LINE_8);
> EXTI->IMR |= (EXTI_LINE_8);
This of course does not disable and enable EXTI8, but you appear to know that. Don't use the Cube-defined symbols outside Cube's functions for which these symbols are defined.
> it's still not working.
What is "not working"? How exactly do you determine "working" and "non working"?
In 32-bit mcus such as STM32, atomicity - or more precisely, the exact sequencing of events - is extremely complex issue. Here, writing to EXTI_IMR does not disable the interrupt immediately after the processor executes the write, as there are write buffers in the way. In this particular case, reading back the EXTI_IMR after you've written it should ensure that the given value is written after the read instruction is executed by the processor.
JW
2022-08-08 05:16 AM
And clear the PR pendimg bit before activate interrupt. Consider also self disabling ISR in case a 100Mhz signal ia maliciously injected on the pin (rugged sw)
2022-08-08 08:04 PM
Thanks!
Tried the code as below: And confirmed IMR value has been changed. It doesn't enable/disable interrupt generated by GPIOB GPIO_PIN_8
/* enable/disable nfc irq */
void set_nfc_irq_callback(u8 enable)
{
u32 value;
if(enable)
{
//HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
/* enable GPIOB GPIO_PIN_8 interrupt */
printf("Line: %d, EXTI->IMR: %lx\r\n", __LINE__, EXTI->IMR);
EXTI->PR = (1<<8);
value = EXTI->IMR;
value |= (1<<8);
EXTI->IMR = value;
printf("Line: %d, EXTI->IMR: %lx\r\n", __LINE__, EXTI->IMR);
}
else
{
//HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
/* Don't use the Cube-defined symbols outside Cube's functions for which these symbols are defined. */
//EXTI->IMR &= ~(EXTI_LINE_8);
/* disable GPIOB GPIO_PIN_8 interrupt */
EXTI->PR = (1<<8);
value = EXTI->IMR;
printf("Line: %d, value: %lx\r\n", __LINE__, value);
value &= ~(1<<8);
EXTI->IMR = value;
printf("Line: %d, EXTI->IMR: %lx\r\n", __LINE__, EXTI->IMR);
}
}
2022-08-08 08:05 PM
Thanks!
Tried the code as below: And confirmed IMR value has been changed. It doesn't enable/disable interrupt generated by GPIOB GPIO_PIN_8
/* enable/disable nfc irq */
void set_nfc_irq_callback(u8 enable)
{
u32 value;
if(enable)
{
//HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
/* enable GPIOB GPIO_PIN_8 interrupt */
printf("Line: %d, EXTI->IMR: %lx\r\n", __LINE__, EXTI->IMR);
EXTI->PR = (1<<8);
value = EXTI->IMR;
value |= (1<<8);
EXTI->IMR = value;
printf("Line: %d, EXTI->IMR: %lx\r\n", __LINE__, EXTI->IMR);
}
else
{
//HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
/* Don't use the Cube-defined symbols outside Cube's functions for which these symbols are defined. */
//EXTI->IMR &= ~(EXTI_LINE_8);
/* disable GPIOB GPIO_PIN_8 interrupt */
EXTI->PR = (1<<8);
value = EXTI->IMR;
printf("Line: %d, value: %lx\r\n", __LINE__, value);
value &= ~(1<<8);
EXTI->IMR = value;
printf("Line: %d, EXTI->IMR: %lx\r\n", __LINE__, EXTI->IMR);
}
}
2022-08-08 08:25 PM
What said in last comment is not accuracy. From the logic analyzer, the interrupt pin is always pulled low.
If use the following code, it's OK.
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
//atomtic operation
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);