mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Merged in mindnever/librepilot/LP-342-pios_exti-improvement (pull request #266)
Lp 342 pios_exti improvement
This commit is contained in:
commit
a2d2e81220
@ -35,8 +35,10 @@
|
|||||||
|
|
||||||
#include <pios_stm32.h>
|
#include <pios_stm32.h>
|
||||||
|
|
||||||
|
typedef bool (* pios_exti_vector_t)(void);
|
||||||
|
|
||||||
struct pios_exti_cfg {
|
struct pios_exti_cfg {
|
||||||
bool (*vector)(void);
|
pios_exti_vector_t vector;
|
||||||
uint32_t line; /* use EXTI_LineN macros */
|
uint32_t line; /* use EXTI_LineN macros */
|
||||||
struct stm32_gpio pin;
|
struct stm32_gpio pin;
|
||||||
struct stm32_irq irq;
|
struct stm32_irq irq;
|
||||||
@ -44,9 +46,12 @@ struct pios_exti_cfg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* must be added to any pios_exti_cfg definition for it to be valid */
|
/* must be added to any pios_exti_cfg definition for it to be valid */
|
||||||
#define __exti_config __attribute__((section("_exti")))
|
// #define __exti_config __attribute__((section("_exti")))
|
||||||
|
|
||||||
|
#define __exti_config
|
||||||
|
|
||||||
extern int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg);
|
extern int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg);
|
||||||
|
extern int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg);
|
||||||
|
|
||||||
#endif /* PIOS_EXTI_H */
|
#endif /* PIOS_EXTI_H */
|
||||||
|
|
||||||
|
@ -35,14 +35,8 @@
|
|||||||
|
|
||||||
/* Map EXTI line to full config */
|
/* Map EXTI line to full config */
|
||||||
#define EXTI_MAX_LINES 16
|
#define EXTI_MAX_LINES 16
|
||||||
#define PIOS_EXTI_INVALID 0xFF
|
|
||||||
static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = {
|
|
||||||
[0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Table of exti configs registered at compile time */
|
static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
|
||||||
extern struct pios_exti_cfg __start__exti __attribute__((weak));
|
|
||||||
extern struct pios_exti_cfg __stop__exti __attribute__((weak));
|
|
||||||
|
|
||||||
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
|
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
|
||||||
{
|
{
|
||||||
@ -147,56 +141,62 @@ uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
|
|||||||
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
||||||
{
|
{
|
||||||
PIOS_Assert(cfg);
|
PIOS_Assert(cfg);
|
||||||
PIOS_Assert(&__start__exti);
|
|
||||||
PIOS_Assert(cfg >= &__start__exti);
|
|
||||||
PIOS_Assert(cfg < &__stop__exti);
|
|
||||||
|
|
||||||
uint8_t cfg_index = cfg - &__start__exti;
|
|
||||||
|
|
||||||
/* Connect this config to the requested vector */
|
/* Connect this config to the requested vector */
|
||||||
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
||||||
|
|
||||||
if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) {
|
if (pios_exti_vector[line_index]) {
|
||||||
/* Someone else already has this mapped */
|
/* Someone else already has this mapped */
|
||||||
goto out_fail;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind the config to the exti line */
|
/* Bind the vector to the exti line */
|
||||||
pios_exti_line_to_cfg_map[line_index] = cfg_index;
|
pios_exti_vector[line_index] = cfg->vector;
|
||||||
|
|
||||||
/* Initialize the GPIO pin */
|
/* Initialize the GPIO pin */
|
||||||
GPIO_Init(cfg->pin.gpio, (GPIO_InitTypeDef *)&cfg->pin.init);
|
GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
|
||||||
|
|
||||||
/* Set up the EXTI interrupt source */
|
/* Set up the EXTI interrupt source */
|
||||||
uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
|
uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
|
||||||
|
/* Following is not entirely correct! There is cfg->pin.pin_source to serve this purpose, and GPIO_Pin can also contain more than one bit set */
|
||||||
uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
|
uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
|
||||||
SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
|
SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
|
||||||
EXTI_Init((EXTI_InitTypeDef*)&cfg->exti.init);
|
EXTI_Init((EXTI_InitTypeDef*)&cfg->exti.init);
|
||||||
|
|
||||||
/* Enable the interrupt channel */
|
/* Enable the interrupt channel */
|
||||||
NVIC_Init((NVIC_InitTypeDef *)&cfg->irq.init);
|
NVIC_Init(&cfg->irq.init);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
|
||||||
|
{
|
||||||
|
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
||||||
|
|
||||||
|
if(pios_exti_vector[line_index] == cfg->vector) {
|
||||||
|
|
||||||
|
EXTI_InitTypeDef disable = cfg->exti.init;
|
||||||
|
disable.EXTI_LineCmd = DISABLE;
|
||||||
|
|
||||||
|
EXTI_Init(&disable);
|
||||||
|
pios_exti_vector[line_index] = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
out_fail:
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
|
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
|
||||||
{
|
{
|
||||||
uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index];
|
if(pios_exti_vector[line_index]) {
|
||||||
|
return pios_exti_vector[line_index]();
|
||||||
|
}
|
||||||
|
|
||||||
PIOS_Assert(&__start__exti);
|
|
||||||
|
|
||||||
if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) ||
|
|
||||||
cfg_index == PIOS_EXTI_INVALID) {
|
|
||||||
/* Unconfigured interrupt just fired! */
|
/* Unconfigured interrupt just fired! */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
|
|
||||||
return cfg->vector();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bind Interrupt Handlers */
|
/* Bind Interrupt Handlers */
|
||||||
|
|
||||||
|
@ -35,14 +35,8 @@
|
|||||||
|
|
||||||
/* Map EXTI line to full config */
|
/* Map EXTI line to full config */
|
||||||
#define EXTI_MAX_LINES 16
|
#define EXTI_MAX_LINES 16
|
||||||
#define PIOS_EXTI_INVALID 0xFF
|
|
||||||
static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = {
|
|
||||||
[0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Table of exti configs registered at compile time */
|
static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
|
||||||
extern struct pios_exti_cfg __start__exti __attribute__((weak));
|
|
||||||
extern struct pios_exti_cfg __stop__exti __attribute__((weak));
|
|
||||||
|
|
||||||
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
|
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
|
||||||
{
|
{
|
||||||
@ -149,22 +143,17 @@ uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
|
|||||||
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
||||||
{
|
{
|
||||||
PIOS_Assert(cfg);
|
PIOS_Assert(cfg);
|
||||||
PIOS_Assert(&__start__exti);
|
|
||||||
PIOS_Assert(cfg >= &__start__exti);
|
|
||||||
PIOS_Assert(cfg < &__stop__exti);
|
|
||||||
|
|
||||||
uint8_t cfg_index = cfg - &__start__exti;
|
|
||||||
|
|
||||||
/* Connect this config to the requested vector */
|
/* Connect this config to the requested vector */
|
||||||
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
||||||
|
|
||||||
if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) {
|
if (pios_exti_vector[line_index]) {
|
||||||
/* Someone else already has this mapped */
|
/* Someone else already has this mapped */
|
||||||
goto out_fail;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind the config to the exti line */
|
/* Bind the vector to the exti line */
|
||||||
pios_exti_line_to_cfg_map[line_index] = cfg_index;
|
pios_exti_vector[line_index] = cfg->vector;
|
||||||
|
|
||||||
/* Initialize the GPIO pin */
|
/* Initialize the GPIO pin */
|
||||||
GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
|
GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
|
||||||
@ -179,25 +168,34 @@ int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
|||||||
NVIC_Init(&cfg->irq.init);
|
NVIC_Init(&cfg->irq.init);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
|
||||||
|
{
|
||||||
|
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
||||||
|
|
||||||
|
if(pios_exti_vector[line_index] == cfg->vector) {
|
||||||
|
|
||||||
|
EXTI_InitTypeDef disable = cfg->exti.init;
|
||||||
|
disable.EXTI_LineCmd = DISABLE;
|
||||||
|
|
||||||
|
EXTI_Init(&disable);
|
||||||
|
pios_exti_vector[line_index] = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
out_fail:
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
|
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
|
||||||
{
|
{
|
||||||
uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index];
|
if(pios_exti_vector[line_index]) {
|
||||||
|
return pios_exti_vector[line_index]();
|
||||||
PIOS_Assert(&__start__exti);
|
|
||||||
|
|
||||||
if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) ||
|
|
||||||
cfg_index == PIOS_EXTI_INVALID) {
|
|
||||||
/* Unconfigured interrupt just fired! */
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
|
/* Unconfigured interrupt just fired! */
|
||||||
return cfg->vector();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PIOS_INCLUDE_FREERTOS
|
#ifdef PIOS_INCLUDE_FREERTOS
|
||||||
|
@ -33,16 +33,9 @@
|
|||||||
|
|
||||||
#ifdef PIOS_INCLUDE_EXTI
|
#ifdef PIOS_INCLUDE_EXTI
|
||||||
|
|
||||||
/* Map EXTI line to full config */
|
|
||||||
#define EXTI_MAX_LINES 16
|
#define EXTI_MAX_LINES 16
|
||||||
#define PIOS_EXTI_INVALID 0xFF
|
|
||||||
static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = {
|
|
||||||
[0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Table of exti configs registered at compile time */
|
static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
|
||||||
extern struct pios_exti_cfg __start__exti __attribute__((weak));
|
|
||||||
extern struct pios_exti_cfg __stop__exti __attribute__((weak));
|
|
||||||
|
|
||||||
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
|
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
|
||||||
{
|
{
|
||||||
@ -149,28 +142,24 @@ uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
|
|||||||
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
||||||
{
|
{
|
||||||
PIOS_Assert(cfg);
|
PIOS_Assert(cfg);
|
||||||
PIOS_Assert(&__start__exti);
|
|
||||||
PIOS_Assert(cfg >= &__start__exti);
|
|
||||||
PIOS_Assert(cfg < &__stop__exti);
|
|
||||||
|
|
||||||
uint8_t cfg_index = cfg - &__start__exti;
|
|
||||||
|
|
||||||
/* Connect this config to the requested vector */
|
/* Connect this config to the requested vector */
|
||||||
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
||||||
|
|
||||||
if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) {
|
if (pios_exti_vector[line_index]) {
|
||||||
/* Someone else already has this mapped */
|
/* Someone else already has this mapped */
|
||||||
goto out_fail;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind the config to the exti line */
|
/* Bind the vector to the exti line */
|
||||||
pios_exti_line_to_cfg_map[line_index] = cfg_index;
|
pios_exti_vector[line_index] = cfg->vector;
|
||||||
|
|
||||||
/* Initialize the GPIO pin */
|
/* Initialize the GPIO pin */
|
||||||
GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
|
GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
|
||||||
|
|
||||||
/* Set up the EXTI interrupt source */
|
/* Set up the EXTI interrupt source */
|
||||||
uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
|
uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
|
||||||
|
/* Following is not entirely correct! There is cfg->pin.pin_source to serve this purpose, and GPIO_Pin can also contain more than one bit set */
|
||||||
uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
|
uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
|
||||||
SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
|
SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
|
||||||
EXTI_Init(&cfg->exti.init);
|
EXTI_Init(&cfg->exti.init);
|
||||||
@ -179,25 +168,34 @@ int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
|
|||||||
NVIC_Init(&cfg->irq.init);
|
NVIC_Init(&cfg->irq.init);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
|
||||||
|
{
|
||||||
|
uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
|
||||||
|
|
||||||
|
if(pios_exti_vector[line_index] == cfg->vector) {
|
||||||
|
|
||||||
|
EXTI_InitTypeDef disable = cfg->exti.init;
|
||||||
|
disable.EXTI_LineCmd = DISABLE;
|
||||||
|
|
||||||
|
EXTI_Init(&disable);
|
||||||
|
pios_exti_vector[line_index] = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
out_fail:
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
|
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
|
||||||
{
|
{
|
||||||
uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index];
|
if(pios_exti_vector[line_index]) {
|
||||||
|
return pios_exti_vector[line_index]();
|
||||||
PIOS_Assert(&__start__exti);
|
|
||||||
|
|
||||||
if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) ||
|
|
||||||
cfg_index == PIOS_EXTI_INVALID) {
|
|
||||||
/* Unconfigured interrupt just fired! */
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
|
/* Unconfigured interrupt just fired! */
|
||||||
return cfg->vector();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind Interrupt Handlers */
|
/* Bind Interrupt Handlers */
|
||||||
|
Loading…
Reference in New Issue
Block a user