summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/extint.c85
-rw-r--r--ports/stm32/extint.h1
2 files changed, 58 insertions, 28 deletions
diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c
index fedb60d13..cdfa1a1e1 100644
--- a/ports/stm32/extint.c
+++ b/ports/stm32/extint.c
@@ -93,18 +93,24 @@
// The L4 MCU supports 40 Events/IRQs lines of the type configurable and direct.
// Here we only support configurable line types. Details, see page 330 of RM0351, Rev 1.
// The USB_FS_WAKUP event is a direct type and there is no support for it.
-#define EXTI_Mode_Interrupt offsetof(EXTI_TypeDef, IMR1)
-#define EXTI_Mode_Event offsetof(EXTI_TypeDef, EMR1)
+#define EXTI_Mode_Interrupt offsetof(EXTI_TypeDef, IMR1)
+#define EXTI_Mode_Event offsetof(EXTI_TypeDef, EMR1)
+#define EXTI_Trigger_Rising offsetof(EXTI_TypeDef, RTSR1)
+#define EXTI_Trigger_Falling offsetof(EXTI_TypeDef, FTSR1)
#define EXTI_RTSR EXTI->RTSR1
#define EXTI_FTSR EXTI->FTSR1
#elif defined(STM32H7)
-#define EXTI_Mode_Interrupt offsetof(EXTI_Core_TypeDef, IMR1)
-#define EXTI_Mode_Event offsetof(EXTI_Core_TypeDef, EMR1)
+#define EXTI_Mode_Interrupt offsetof(EXTI_Core_TypeDef, IMR1)
+#define EXTI_Mode_Event offsetof(EXTI_Core_TypeDef, EMR1)
+#define EXTI_Trigger_Rising offsetof(EXTI_Core_TypeDef, RTSR1)
+#define EXTI_Trigger_Falling offsetof(EXTI_Core_TypeDef, FTSR1)
#define EXTI_RTSR EXTI->RTSR1
#define EXTI_FTSR EXTI->FTSR1
#else
-#define EXTI_Mode_Interrupt offsetof(EXTI_TypeDef, IMR)
-#define EXTI_Mode_Event offsetof(EXTI_TypeDef, EMR)
+#define EXTI_Mode_Interrupt offsetof(EXTI_TypeDef, IMR)
+#define EXTI_Mode_Event offsetof(EXTI_TypeDef, EMR)
+#define EXTI_Trigger_Rising offsetof(EXTI_TypeDef, RTSR)
+#define EXTI_Trigger_Falling offsetof(EXTI_TypeDef, FTSR)
#define EXTI_RTSR EXTI->RTSR
#define EXTI_FTSR EXTI->FTSR
#endif
@@ -210,15 +216,21 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca
pyb_extint_hard_irq[v_line] = true;
pyb_extint_callback_arg[v_line] = MP_OBJ_NEW_SMALL_INT(v_line);
- mp_hal_gpio_clock_enable(pin->gpio);
- GPIO_InitTypeDef exti;
- exti.Pin = pin->pin_mask;
- exti.Mode = mode;
- exti.Pull = pull;
- exti.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(pin->gpio, &exti);
-
- // Calling HAL_GPIO_Init does an implicit extint_enable
+ if (pin == NULL) {
+ // pin will be NULL for non GPIO EXTI lines
+ extint_trigger_mode(v_line, mode);
+ extint_enable(v_line);
+ } else {
+ mp_hal_gpio_clock_enable(pin->gpio);
+ GPIO_InitTypeDef exti;
+ exti.Pin = pin->pin_mask;
+ exti.Mode = mode;
+ exti.Pull = pull;
+ exti.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(pin->gpio, &exti);
+
+ // Calling HAL_GPIO_Init does an implicit extint_enable
+ }
/* Enable and set NVIC Interrupt to the lowest priority */
NVIC_SetPriority(IRQn_NONNEG(nvic_irq_channel[v_line]), IRQ_PRI_EXTINT);
@@ -262,19 +274,7 @@ void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_
(SYSCFG->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
| ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
- // Enable or disable the rising detector
- if ((mode & GPIO_MODE_IT_RISING) == GPIO_MODE_IT_RISING) {
- EXTI_RTSR |= 1 << line;
- } else {
- EXTI_RTSR &= ~(1 << line);
- }
-
- // Enable or disable the falling detector
- if ((mode & GPIO_MODE_IT_FALLING) == GPIO_MODE_IT_FALLING) {
- EXTI_FTSR |= 1 << line;
- } else {
- EXTI_FTSR &= ~(1 << line);
- }
+ extint_trigger_mode(line, mode);
// Configure the NVIC
NVIC_SetPriority(IRQn_NONNEG(nvic_irq_channel[line]), IRQ_PRI_EXTINT);
@@ -353,6 +353,35 @@ void extint_swint(uint line) {
#endif
}
+void extint_trigger_mode(uint line, uint32_t mode) {
+ if (line >= EXTI_NUM_VECTORS) {
+ return;
+ }
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32H7)
+ // The Cortex-M7 doesn't have bitband support.
+ mp_uint_t irq_state = disable_irq();
+ // Enable or disable the rising detector
+ if ((mode & GPIO_MODE_IT_RISING) == GPIO_MODE_IT_RISING) {
+ EXTI_RTSR |= (1 << line);
+ } else {
+ EXTI_RTSR &= ~(1 << line);
+ }
+ // Enable or disable the falling detector
+ if ((mode & GPIO_MODE_IT_FALLING) == GPIO_MODE_IT_FALLING) {
+ EXTI_FTSR |= 1 << line;
+ } else {
+ EXTI_FTSR &= ~(1 << line);
+ }
+ enable_irq(irq_state);
+ #else
+ // Since manipulating FTSR/RTSR is a read-modify-write, and we want this to
+ // be atomic, we use the bit-band area to just affect the bit we're
+ // interested in.
+ EXTI_MODE_BB(EXTI_Trigger_Rising, line) = (mode & GPIO_MODE_IT_RISING) == GPIO_MODE_IT_RISING;
+ EXTI_MODE_BB(EXTI_Trigger_Falling, line) = (mode & GPIO_MODE_IT_FALLING) == GPIO_MODE_IT_FALLING;
+ #endif
+}
+
/// \method line()
/// Return the line number that the pin is mapped to.
STATIC mp_obj_t extint_obj_line(mp_obj_t self_in) {
diff --git a/ports/stm32/extint.h b/ports/stm32/extint.h
index 7646df731..924b48a8b 100644
--- a/ports/stm32/extint.h
+++ b/ports/stm32/extint.h
@@ -69,6 +69,7 @@ void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_
void extint_enable(uint line);
void extint_disable(uint line);
void extint_swint(uint line);
+void extint_trigger_mode(uint line, uint32_t mode);
void Handle_EXTI_Irq(uint32_t line);