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
This commit is contained in:
parent
ba9bc57a49
commit
7ab6622908
71
drv/exti.c
71
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-------------------------------------------------------------
|
||||
|
||||
63
drv/exti.h
63
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
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user