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 "exti_regs.h"
|
||||||
|
|
||||||
#include "nvic.h"
|
#include "nvic.h"
|
||||||
#include "afio.h"
|
|
||||||
|
|
||||||
|
|
||||||
//--local definitions-----------------------------------------------------------
|
//--local definitions-----------------------------------------------------------
|
||||||
@ -24,13 +23,11 @@ static ExtiCallback callbacks[19];
|
|||||||
|
|
||||||
//--public functions------------------------------------------------------------
|
//--public functions------------------------------------------------------------
|
||||||
|
|
||||||
void exti_configure(enum ExtiLine line_mask, enum GpioPort port,
|
void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
|
||||||
enum ExtiConfig config_mask, ExtiCallback callback)
|
ExtiCallback callback)
|
||||||
{
|
{
|
||||||
exti_reset(line_mask);
|
exti_reset(line_mask);
|
||||||
|
|
||||||
afio_map_exti(line_mask, port);
|
|
||||||
|
|
||||||
//configure edge detections
|
//configure edge detections
|
||||||
if (config_mask & EXTI_CONFIG_RISING_EDGE) {
|
if (config_mask & EXTI_CONFIG_RISING_EDGE) {
|
||||||
regs->RTSR.word |= line_mask;
|
regs->RTSR.word |= line_mask;
|
||||||
@ -48,7 +45,7 @@ void exti_configure(enum ExtiLine line_mask, enum GpioPort port,
|
|||||||
regs->EMR.word |= line_mask;
|
regs->EMR.word |= line_mask;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
//register callbacks for each line selected
|
//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)) {
|
if (line_mask & (0x1 << i)) {
|
||||||
callbacks[i] = callback;
|
callbacks[i] = callback;
|
||||||
}
|
}
|
||||||
@ -66,6 +63,15 @@ void exti_configure(enum ExtiLine line_mask, enum GpioPort port,
|
|||||||
if (line_mask & 0x7c00) {
|
if (line_mask & 0x7c00) {
|
||||||
nvic_enable(NVIC_IRQ_EXTI15_10);
|
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
|
//enable irqs in last to avoid triggers during config
|
||||||
regs->IMR.word |= line_mask;
|
regs->IMR.word |= line_mask;
|
||||||
@ -94,56 +100,6 @@ void exti_reset(enum ExtiLine line_mask)
|
|||||||
nvic_disable(NVIC_IRQ_EXTI15_10);
|
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
|
//disable events/irqs
|
||||||
regs->IMR.word &= ~line_mask;
|
regs->IMR.word &= ~line_mask;
|
||||||
regs->EMR.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)
|
void exti_reset_peripheral(void)
|
||||||
{
|
{
|
||||||
//reset peripheral config
|
//reset peripheral config
|
||||||
@ -182,8 +139,6 @@ void exti_reset_peripheral(void)
|
|||||||
nvic_disable(NVIC_IRQ_PVD);
|
nvic_disable(NVIC_IRQ_PVD);
|
||||||
nvic_disable(NVIC_IRQ_RTC_ALARM);
|
nvic_disable(NVIC_IRQ_RTC_ALARM);
|
||||||
nvic_disable(NVIC_IRQ_USB_WAKEUP);
|
nvic_disable(NVIC_IRQ_USB_WAKEUP);
|
||||||
|
|
||||||
afio_map_exti(0xFFFF, 0x0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--local functions-------------------------------------------------------------
|
//--local functions-------------------------------------------------------------
|
||||||
|
|||||||
63
drv/exti.h
63
drv/exti.h
@ -10,16 +10,11 @@
|
|||||||
|
|
||||||
//--includes--------------------------------------------------------------------
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
#include "stdbool.h"
|
|
||||||
|
|
||||||
#include "gpio.h"
|
|
||||||
|
|
||||||
|
|
||||||
//--type definitions------------------------------------------------------------
|
//--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 {
|
enum ExtiLine {
|
||||||
EXTI_LINE_0 = (0x1 << 0),
|
EXTI_LINE_0 = (0x1 << 0),
|
||||||
@ -38,12 +33,6 @@ enum ExtiLine {
|
|||||||
EXTI_LINE_13 = (0x1 << 13),
|
EXTI_LINE_13 = (0x1 << 13),
|
||||||
EXTI_LINE_14 = (0x1 << 14),
|
EXTI_LINE_14 = (0x1 << 14),
|
||||||
EXTI_LINE_15 = (0x1 << 15),
|
EXTI_LINE_15 = (0x1 << 15),
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Available exti lines. These lines correspond to specific peripherals
|
|
||||||
*/
|
|
||||||
enum ExtiLineSpecific {
|
|
||||||
EXTI_LINE_PVD = (0x1 << 16),
|
EXTI_LINE_PVD = (0x1 << 16),
|
||||||
EXTI_LINE_RTC = (0x1 << 17),
|
EXTI_LINE_RTC = (0x1 << 17),
|
||||||
EXTI_LINE_USB = (0x1 << 18),
|
EXTI_LINE_USB = (0x1 << 18),
|
||||||
@ -64,43 +53,31 @@ typedef void (*ExtiCallback)(void);
|
|||||||
//--functions-------------------------------------------------------------------
|
//--functions-------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure lines on a single GPIO port. The ExtiLine enum can be used as a
|
* Configure lines to call a single callback. The ExtiLine enum can be used as a
|
||||||
* mask to configure multiple lines at the same time. Every line can only be
|
* mask to configure multiple lines at the same time.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Note: wich port is linked to a line can be changed atfer the fact using
|
* Every numbered line must be linked to a gpio port using afio_map_exti(). Each
|
||||||
* afio_map_exti()
|
* 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,
|
void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
|
||||||
enum ExtiConfig config_mask, ExtiCallback callback);
|
ExtiCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets lines. The ExtiLine enum can be used as a mask to configure multiple
|
* Resets lines. The ExtiLine enum can be used as a mask to reset multiple lines
|
||||||
* lines at the same time
|
* at the same time
|
||||||
*/
|
*/
|
||||||
void exti_reset(enum ExtiLine line_mask);
|
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
|
* Resets all lines. The exti peripheral is returned to its reset configuration
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user