1
0
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:
Alessio Morale 2016-07-03 16:05:03 +02:00
commit a2d2e81220
4 changed files with 91 additions and 90 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */