From 3e8e109e8bd0213004a2174172832a58a8ed9270 Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Mon, 1 Feb 2021 13:20:58 +0100 Subject: [PATCH] cpu/stm32/gpio: fix EXTI flag clearing In case a non-gpio EXTI (>= 16) is pending, the isr_exti() used to clear the flag and try to call a callback, which was out-of-bouds, thus generating a hard fault. This fixes it by masking the pending_isr variables with 0xFFFF. --- cpu/stm32/periph/gpio_all.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpu/stm32/periph/gpio_all.c b/cpu/stm32/periph/gpio_all.c index 79d1882428..e505cd2e4d 100644 --- a/cpu/stm32/periph/gpio_all.c +++ b/cpu/stm32/periph/gpio_all.c @@ -36,6 +36,7 @@ * @brief The STM32F0 family has 16 external interrupt lines */ #define EXTI_NUMOF (16U) +#define EXTI_MASK (0xFFFF) /** * @brief Allocate memory for one callback and argument per EXTI channel @@ -338,8 +339,8 @@ void isr_exti(void) #if defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32L5) || \ defined(CPU_FAM_STM32MP1) /* only generate interrupts against lines which have their IMR set */ - uint32_t pending_rising_isr = (EXTI->RPR1 & EXTI_REG_IMR); - uint32_t pending_falling_isr = (EXTI->FPR1 & EXTI_REG_IMR); + uint32_t pending_rising_isr = (EXTI->RPR1 & EXTI_REG_IMR & EXTI_MASK); + uint32_t pending_falling_isr = (EXTI->FPR1 & EXTI_REG_IMR & EXTI_MASK); /* clear by writing a 1 */ EXTI->RPR1 = pending_rising_isr; @@ -348,7 +349,7 @@ void isr_exti(void) uint32_t pending_isr = pending_rising_isr | pending_falling_isr; #else /* only generate interrupts against lines which have their IMR set */ - uint32_t pending_isr = (EXTI_REG_PR & EXTI_REG_IMR); + uint32_t pending_isr = (EXTI_REG_PR & EXTI_REG_IMR & EXTI_MASK); /* clear by writing a 1 */ EXTI_REG_PR = pending_isr;