stm32/extint: Fix ExtInt to work with non-GPIO pins.

This commit is contained in:
Dave Hylands 2019-02-13 11:41:54 -08:00 committed by Damien George
parent 303f27f656
commit 363900be5d
2 changed files with 57 additions and 27 deletions

View File

@ -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);
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
// 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) {

View File

@ -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);