From 7ab6622908df5cc4795f8949d465edca3f4eef8d Mon Sep 17 00:00:00 2001 From: Steins7 Date: Sun, 4 Aug 2024 19:38:24 +0200 Subject: [PATCH] Rework exti module to use a simpler API The "specific" lines configuration would not work due to index error in the callback configuration. While fixing the error, simplifying the API by moving the afio calls to the calling context seemed a cleaner way to do things --- drv/exti.c | 71 ++++++++++-------------------------------------------- drv/exti.h | 63 +++++++++++++++--------------------------------- 2 files changed, 33 insertions(+), 101 deletions(-) diff --git a/drv/exti.c b/drv/exti.c index 3db9837..c1d56af 100644 --- a/drv/exti.c +++ b/drv/exti.c @@ -11,7 +11,6 @@ #include "exti_regs.h" #include "nvic.h" -#include "afio.h" //--local definitions----------------------------------------------------------- @@ -24,13 +23,11 @@ static ExtiCallback callbacks[19]; //--public functions------------------------------------------------------------ -void exti_configure(enum ExtiLine line_mask, enum GpioPort port, - enum ExtiConfig config_mask, ExtiCallback callback) +void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask, + ExtiCallback callback) { exti_reset(line_mask); - afio_map_exti(line_mask, port); - //configure edge detections if (config_mask & EXTI_CONFIG_RISING_EDGE) { regs->RTSR.word |= line_mask; @@ -48,7 +45,7 @@ void exti_configure(enum ExtiLine line_mask, enum GpioPort port, regs->EMR.word |= line_mask; if (callback) { //register callbacks for each line selected - for (uint8_t i = 0; i < 16; ++i) { + for (uint8_t i = 0; i < 19; ++i) { if (line_mask & (0x1 << i)) { callbacks[i] = callback; } @@ -66,6 +63,15 @@ void exti_configure(enum ExtiLine line_mask, enum GpioPort port, if (line_mask & 0x7c00) { nvic_enable(NVIC_IRQ_EXTI15_10); } + if (line_mask & EXTI_LINE_PVD) { + nvic_enable(NVIC_IRQ_PVD); + } + if (line_mask & EXTI_LINE_RTC) { + nvic_enable(NVIC_IRQ_RTC_ALARM); + } + if (line_mask & EXTI_LINE_USB) { + nvic_enable(NVIC_IRQ_USB_WAKEUP); + } //enable irqs in last to avoid triggers during config regs->IMR.word |= line_mask; @@ -94,56 +100,6 @@ void exti_reset(enum ExtiLine line_mask) nvic_disable(NVIC_IRQ_EXTI15_10); } - afio_map_exti(0xFFFF, 0x0); -} - -void exti_configure_specific(enum ExtiLineSpecific line_mask, - enum ExtiConfig config_mask, ExtiCallback callback) -{ - //reset is identical to normal lines - exti_reset_specific(line_mask); - - //configure edge detections - if (config_mask & EXTI_CONFIG_RISING_EDGE) { - regs->RTSR.word |= line_mask; - } else { - regs->RTSR.word &= ~line_mask; - } - - if (config_mask & EXTI_CONFIG_FALLING_EDGE) { - regs->FTSR.word |= line_mask; - } else { - regs->FTSR.word &= ~line_mask; - } - - //reconfigure events/irqs - regs->EMR.word |= line_mask; - if (callback) { - //register callbacks for each line selected - for (uint8_t i = 0; i < 16; ++i) { - if (line_mask & (0x1 << i)) { - callbacks[i] = callback; - } - } - - //enable interrupts lines in nvic - if (line_mask & EXTI_LINE_PVD) { - nvic_enable(NVIC_IRQ_PVD); - } - if (line_mask & EXTI_LINE_RTC) { - nvic_enable(NVIC_IRQ_RTC_ALARM); - } - if (line_mask & EXTI_LINE_USB) { - nvic_enable(NVIC_IRQ_USB_WAKEUP); - } - - //enable irqs in last to avoid triggers during config - regs->IMR.word |= line_mask; - } -} - -void exti_reset_specific(enum ExtiLineSpecific line_mask) -{ //disable events/irqs regs->IMR.word &= ~line_mask; regs->EMR.word &= ~line_mask; @@ -163,6 +119,7 @@ void exti_reset_specific(enum ExtiLineSpecific line_mask) } } + void exti_reset_peripheral(void) { //reset peripheral config @@ -182,8 +139,6 @@ void exti_reset_peripheral(void) nvic_disable(NVIC_IRQ_PVD); nvic_disable(NVIC_IRQ_RTC_ALARM); nvic_disable(NVIC_IRQ_USB_WAKEUP); - - afio_map_exti(0xFFFF, 0x0); } //--local functions------------------------------------------------------------- diff --git a/drv/exti.h b/drv/exti.h index 3349aca..dc8a337 100644 --- a/drv/exti.h +++ b/drv/exti.h @@ -10,16 +10,11 @@ //--includes-------------------------------------------------------------------- -#include "stdint.h" -#include "stdbool.h" - -#include "gpio.h" - - //--type definitions------------------------------------------------------------ /** - * Available exti lines. These lines correspond to gpios + * Available exti lines. The numbered lines correspond to gpios while the + * remaining are directly mapped to peripherals */ enum ExtiLine { EXTI_LINE_0 = (0x1 << 0), @@ -38,12 +33,6 @@ enum ExtiLine { EXTI_LINE_13 = (0x1 << 13), EXTI_LINE_14 = (0x1 << 14), EXTI_LINE_15 = (0x1 << 15), -}; - -/** - * Available exti lines. These lines correspond to specific peripherals - */ -enum ExtiLineSpecific { EXTI_LINE_PVD = (0x1 << 16), EXTI_LINE_RTC = (0x1 << 17), EXTI_LINE_USB = (0x1 << 18), @@ -64,43 +53,31 @@ typedef void (*ExtiCallback)(void); //--functions------------------------------------------------------------------- /** - * Configure lines on a single GPIO port. The ExtiLine enum can be used as a - * mask to configure multiple lines at the same time. Every line can only be - * configured for a single port, reconfiguring it will override the previous - * configuration. Each line is linked to the pins of the same id (ex : pin 1 for - * exti 1). When possible, it is recommanded to use the lowest id possible for - * better performance. The ExtiConfig enum can be used as mask. If no callback - * is specified, the interrupt won't be enabled, but an event will still be sent - * to wake the cpu up. + * Configure lines to call a single callback. The ExtiLine enum can be used as a + * mask to configure multiple lines at the same time. * - * Note: wich port is linked to a line can be changed atfer the fact using - * afio_map_exti() + * Every numbered line must be linked to a gpio port using afio_map_exti(). Each + * line is linked to the pins of the same id (ex : pin 1 for exti 1). When + * possible, it is recommended to use the lowest id possible for better + * performance. Each pin must be configured independently through the gpio + * driver module + * + * The remaining lines are linked to specific peripherals which must be + * configured independently through the corresponding driver module. + * + * The ExtiConfig enum can be used as mask. If no callback is specified, the + * interrupt won't be enabled, but an event will still be sent to wake the cpu + * up. */ -void exti_configure(enum ExtiLine line_mask, enum GpioPort port, - enum ExtiConfig config_mask, ExtiCallback callback); +void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask, + ExtiCallback callback); /** - * Resets lines. The ExtiLine enum can be used as a mask to configure multiple - * lines at the same time + * Resets lines. The ExtiLine enum can be used as a mask to reset multiple lines + * at the same time */ void exti_reset(enum ExtiLine line_mask); -/** - * Configure lines for specific, non-gpio peripherals. The ExtiLineSpecific enum - * can be used as a mask to configure multiple lines at the same time. The - * ExtiConfig enum can be used as mask. If no callback is specified, the - * interrupt won't be enabled, but an event will still be sent to wake the cpu - * up - */ -void exti_configure_specific(enum ExtiLineSpecific line_mask, - enum ExtiConfig config_mask, ExtiCallback callback); - -/** - * Resets lines for specific, non-gpio peripherals. The ExtiLineSpecific enum - * can be used as a mask to configure multiple lines at the same time. - */ -void exti_reset_specific(enum ExtiLineSpecific line_mask); - /** * Resets all lines. The exti peripheral is returned to its reset configuration */