From 6b32219738fff547891dbd481d75fce83ee16e22 Mon Sep 17 00:00:00 2001 From: Carlo Parata Date: Fri, 4 Dec 2020 14:51:39 +0100 Subject: [PATCH 1/2] Add clear pending interrupt feature with clearPendingInterrupt API --- cores/arduino/WInterrupts.cpp | 10 ++++++++++ cores/arduino/WInterrupts.h | 2 ++ cores/arduino/stm32/interrupt.h | 1 + libraries/SrcWrapper/src/stm32/interrupt.cpp | 12 ++++++++++++ 4 files changed, 25 insertions(+) diff --git a/cores/arduino/WInterrupts.cpp b/cores/arduino/WInterrupts.cpp index a61a10014d..ea7ecc2858 100644 --- a/cores/arduino/WInterrupts.cpp +++ b/cores/arduino/WInterrupts.cpp @@ -87,3 +87,13 @@ void detachInterrupt(uint32_t pin) UNUSED(pin); #endif } + +void clearPendingInterrupt(uint32_t pin) +{ +#if !defined(HAL_EXTI_MODULE_DISABLED) + PinName p = digitalPinToPinName(pin); + stm32_interrupt_clear_pending(STM_GPIO_PIN(p)); +#else + UNUSED(pin); +#endif +} diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h index 04cecc602a..81c378a542 100644 --- a/cores/arduino/WInterrupts.h +++ b/cores/arduino/WInterrupts.h @@ -33,4 +33,6 @@ void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode); void detachInterrupt(uint32_t pin); +void clearPendingInterrupt(uint32_t pin); + #endif /* _WIRING_INTERRUPTS_ */ diff --git a/cores/arduino/stm32/interrupt.h b/cores/arduino/stm32/interrupt.h index b15b57335d..b514c9ff78 100644 --- a/cores/arduino/stm32/interrupt.h +++ b/cores/arduino/stm32/interrupt.h @@ -69,6 +69,7 @@ /* Exported functions ------------------------------------------------------- */ void stm32_interrupt_enable(GPIO_TypeDef *port, uint16_t pin, void (*callback)(void), uint32_t mode); void stm32_interrupt_disable(GPIO_TypeDef *port, uint16_t pin); + void stm32_interrupt_clear_pending(uint16_t pin); #endif /* !HAL_EXTI_MODULE_DISABLED */ #endif /* __INTERRUPT_H */ diff --git a/libraries/SrcWrapper/src/stm32/interrupt.cpp b/libraries/SrcWrapper/src/stm32/interrupt.cpp index 5a3d01f6da..02ca80a0ab 100644 --- a/libraries/SrcWrapper/src/stm32/interrupt.cpp +++ b/libraries/SrcWrapper/src/stm32/interrupt.cpp @@ -232,6 +232,18 @@ void stm32_interrupt_disable(GPIO_TypeDef *port, uint16_t pin) HAL_NVIC_DisableIRQ(gpio_irq_conf[id].irqnb); } +/** + * @brief This function clear the pending interrupts on the selected pin + * @param pin : one of the gpio pin + * @retval None + */ +void stm32_interrupt_clear_pending(uint16_t pin) +{ + uint8_t id = get_pin_id(pin); + __HAL_GPIO_EXTI_CLEAR_IT(pin); + HAL_NVIC_ClearPendingIRQ(gpio_irq_conf[id].irqnb); +} + /** * @brief This function his called by the HAL if the IRQ is valid * @param GPIO_Pin : one of the gpio pin From 7accc6c1111c5f2bbdb684d55d3bac260eacca5d Mon Sep 17 00:00:00 2001 From: Carlo Parata Date: Mon, 14 Dec 2020 12:51:22 +0100 Subject: [PATCH 2/2] Remove clearPendingInterrupt and improve implementation of stm32_interrupt_disable --- cores/arduino/WInterrupts.cpp | 10 --- cores/arduino/WInterrupts.h | 2 - cores/arduino/stm32/interrupt.h | 1 - libraries/SrcWrapper/src/stm32/interrupt.cpp | 74 ++++++++++++++++---- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/cores/arduino/WInterrupts.cpp b/cores/arduino/WInterrupts.cpp index ea7ecc2858..a61a10014d 100644 --- a/cores/arduino/WInterrupts.cpp +++ b/cores/arduino/WInterrupts.cpp @@ -87,13 +87,3 @@ void detachInterrupt(uint32_t pin) UNUSED(pin); #endif } - -void clearPendingInterrupt(uint32_t pin) -{ -#if !defined(HAL_EXTI_MODULE_DISABLED) - PinName p = digitalPinToPinName(pin); - stm32_interrupt_clear_pending(STM_GPIO_PIN(p)); -#else - UNUSED(pin); -#endif -} diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h index 81c378a542..04cecc602a 100644 --- a/cores/arduino/WInterrupts.h +++ b/cores/arduino/WInterrupts.h @@ -33,6 +33,4 @@ void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode); void detachInterrupt(uint32_t pin); -void clearPendingInterrupt(uint32_t pin); - #endif /* _WIRING_INTERRUPTS_ */ diff --git a/cores/arduino/stm32/interrupt.h b/cores/arduino/stm32/interrupt.h index b514c9ff78..b15b57335d 100644 --- a/cores/arduino/stm32/interrupt.h +++ b/cores/arduino/stm32/interrupt.h @@ -69,7 +69,6 @@ /* Exported functions ------------------------------------------------------- */ void stm32_interrupt_enable(GPIO_TypeDef *port, uint16_t pin, void (*callback)(void), uint32_t mode); void stm32_interrupt_disable(GPIO_TypeDef *port, uint16_t pin); - void stm32_interrupt_clear_pending(uint16_t pin); #endif /* !HAL_EXTI_MODULE_DISABLED */ #endif /* __INTERRUPT_H */ diff --git a/libraries/SrcWrapper/src/stm32/interrupt.cpp b/libraries/SrcWrapper/src/stm32/interrupt.cpp index 02ca80a0ab..a5447fb7f6 100644 --- a/libraries/SrcWrapper/src/stm32/interrupt.cpp +++ b/libraries/SrcWrapper/src/stm32/interrupt.cpp @@ -219,8 +219,18 @@ void stm32_interrupt_enable(GPIO_TypeDef *port, uint16_t pin, void (*callback)(v */ void stm32_interrupt_disable(GPIO_TypeDef *port, uint16_t pin) { - UNUSED(port); + GPIO_InitTypeDef GPIO_InitStruct; uint8_t id = get_pin_id(pin); +#ifdef STM32F1xx + uint8_t position; + uint32_t CRxRegOffset = 0; + uint32_t ODRRegOffset = 0; + volatile uint32_t *CRxRegister; + const uint32_t ConfigMask = 0x00000008; //MODE0 == 0x0 && CNF0 == 0x2 +#else + uint32_t pull; +#endif /* STM32F1xx */ + gpio_irq_conf[id].callback = NULL; for (int i = 0; i < NB_EXTI; i++) { @@ -230,18 +240,58 @@ void stm32_interrupt_disable(GPIO_TypeDef *port, uint16_t pin) } } HAL_NVIC_DisableIRQ(gpio_irq_conf[id].irqnb); -} -/** - * @brief This function clear the pending interrupts on the selected pin - * @param pin : one of the gpio pin - * @retval None - */ -void stm32_interrupt_clear_pending(uint16_t pin) -{ - uint8_t id = get_pin_id(pin); - __HAL_GPIO_EXTI_CLEAR_IT(pin); - HAL_NVIC_ClearPendingIRQ(gpio_irq_conf[id].irqnb); + //reconfigure the pin as input + GPIO_InitStruct.Pin = pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + + //read the pull mode directly in the register as no function exists to get it. + //Do it in case the user already defines the IO through the digital io + //interface +#ifndef STM32F1xx + pull = port->PUPDR; +#ifdef GPIO_PUPDR_PUPD0 + pull &= (GPIO_PUPDR_PUPD0 << (id * 2)); + GPIO_InitStruct.Pull = (GPIO_PUPDR_PUPD0 & (pull >> (id * 2))); +#else + pull &= (GPIO_PUPDR_PUPDR0 << (id * 2)); + GPIO_InitStruct.Pull = (GPIO_PUPDR_PUPDR0 & (pull >> (id * 2))); +#endif /* GPIO_PUPDR_PUPD0 */ +#else + CRxRegister = (pin < GPIO_PIN_8) ? &port->CRL : &port->CRH; + + for (position = 0; position < 16; position++) { + if (pin == (0x0001 << position)) { + CRxRegOffset = (pin < GPIO_PIN_8) ? (position << 2) : ((position - 8) << 2); + ODRRegOffset = position; + } + } + + if ((*CRxRegister & ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << CRxRegOffset)) == (ConfigMask << CRxRegOffset)) { + if ((port->ODR & (GPIO_ODR_ODR0 << ODRRegOffset)) == (GPIO_ODR_ODR0 << ODRRegOffset)) { + GPIO_InitStruct.Pull = GPIO_PULLUP; + } else { + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + } + } else { + GPIO_InitStruct.Pull = GPIO_NOPULL; + } +#endif /* STM32F1xx */ + + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + +#if defined(STM32MP1xx) + PERIPH_LOCK(port); +#endif + + //call the DeInit before in order to disable the EXTI settings + HAL_GPIO_DeInit(port, pin); + //reconfigure the pin as input keeping the same pull mode settings + HAL_GPIO_Init(port, &GPIO_InitStruct); + +#if defined(STM32MP1xx) + PERIPH_UNLOCK(port); +#endif } /**