task #5
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