1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +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>
typedef bool (* pios_exti_vector_t)(void);
struct pios_exti_cfg {
bool (*vector)(void);
pios_exti_vector_t vector;
uint32_t line; /* use EXTI_LineN macros */
struct stm32_gpio pin;
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 */
#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_DeInit(const struct pios_exti_cfg *cfg);
#endif /* PIOS_EXTI_H */

View File

@ -35,14 +35,8 @@
/* Map EXTI line to full config */
#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 */
extern struct pios_exti_cfg __start__exti __attribute__((weak));
extern struct pios_exti_cfg __stop__exti __attribute__((weak));
static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
{
@ -147,57 +141,63 @@ 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)
{
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 */
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 */
goto out_fail;
return -1;
}
/* Bind the config to the exti line */
pios_exti_line_to_cfg_map[line_index] = cfg_index;
/* Bind the vector to the exti line */
pios_exti_vector[line_index] = cfg->vector;
/* 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 */
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);
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 */
NVIC_Init((NVIC_InitTypeDef *)&cfg->irq.init);
NVIC_Init(&cfg->irq.init);
return 0;
}
out_fail:
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;
}
return -1;
}
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
{
uint8_t cfg_index = pios_exti_line_to_cfg_map[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;
if(pios_exti_vector[line_index]) {
return pios_exti_vector[line_index]();
}
struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
return cfg->vector();
/* Unconfigured interrupt just fired! */
return false;
}
/* Bind Interrupt Handlers */
#ifdef PIOS_INCLUDE_FREERTOS

View File

@ -35,14 +35,8 @@
/* Map EXTI line to full config */
#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 */
extern struct pios_exti_cfg __start__exti __attribute__((weak));
extern struct pios_exti_cfg __stop__exti __attribute__((weak));
static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
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)
{
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 */
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 */
goto out_fail;
return -1;
}
/* Bind the config to the exti line */
pios_exti_line_to_cfg_map[line_index] = cfg_index;
/* Bind the vector to the exti line */
pios_exti_vector[line_index] = cfg->vector;
/* Initialize the GPIO pin */
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);
return 0;
}
out_fail:
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;
}
return -1;
}
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
{
uint8_t cfg_index = pios_exti_line_to_cfg_map[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;
if(pios_exti_vector[line_index]) {
return pios_exti_vector[line_index]();
}
struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
return cfg->vector();
/* Unconfigured interrupt just fired! */
return false;
}
#ifdef PIOS_INCLUDE_FREERTOS

View File

@ -33,16 +33,9 @@
#ifdef PIOS_INCLUDE_EXTI
/* Map EXTI line to full config */
#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 */
extern struct pios_exti_cfg __start__exti __attribute__((weak));
extern struct pios_exti_cfg __stop__exti __attribute__((weak));
static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
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)
{
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 */
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 */
goto out_fail;
return -1;
}
/* Bind the config to the exti line */
pios_exti_line_to_cfg_map[line_index] = cfg_index;
/* Bind the vector to the exti line */
pios_exti_vector[line_index] = cfg->vector;
/* Initialize the GPIO pin */
GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
/* Set up the EXTI interrupt source */
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);
SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
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);
return 0;
}
out_fail:
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;
}
return -1;
}
static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
{
uint8_t cfg_index = pios_exti_line_to_cfg_map[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;
if(pios_exti_vector[line_index]) {
return pios_exti_vector[line_index]();
}
struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
return cfg->vector();
/* Unconfigured interrupt just fired! */
return false;
}
/* Bind Interrupt Handlers */