From fabc3e8d69598f9705fe672502436b340b7d8407 Mon Sep 17 00:00:00 2001 From: Vladimir Zidar Date: Thu, 26 May 2016 23:48:33 +0200 Subject: [PATCH 1/2] LP-342 Simplify pios_exti configuration, allow dynamic configuration and reconfiguration. adds PIOS_EXTI_DeInit() --- flight/pios/inc/pios_exti.h | 9 +++-- flight/pios/stm32f0x/pios_exti.c | 56 ++++++++++++++----------------- flight/pios/stm32f10x/pios_exti.c | 48 +++++++++++--------------- flight/pios/stm32f4xx/pios_exti.c | 50 ++++++++++++--------------- 4 files changed, 73 insertions(+), 90 deletions(-) diff --git a/flight/pios/inc/pios_exti.h b/flight/pios/inc/pios_exti.h index 529e8ee2c..f59f4270a 100644 --- a/flight/pios/inc/pios_exti.h +++ b/flight/pios/inc/pios_exti.h @@ -35,8 +35,10 @@ #include +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 */ diff --git a/flight/pios/stm32f0x/pios_exti.c b/flight/pios/stm32f0x/pios_exti.c index 863f88a92..138c54e42 100644 --- a/flight/pios/stm32f0x/pios_exti.c +++ b/flight/pios/stm32f0x/pios_exti.c @@ -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,57 @@ 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) { + 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 diff --git a/flight/pios/stm32f10x/pios_exti.c b/flight/pios/stm32f10x/pios_exti.c index efdda068e..b0325f902 100644 --- a/flight/pios/stm32f10x/pios_exti.c +++ b/flight/pios/stm32f10x/pios_exti.c @@ -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,28 @@ 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) { + 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 diff --git a/flight/pios/stm32f4xx/pios_exti.c b/flight/pios/stm32f4xx/pios_exti.c index e32cc98b9..89122c362 100644 --- a/flight/pios/stm32f4xx/pios_exti.c +++ b/flight/pios/stm32f4xx/pios_exti.c @@ -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,28 @@ 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) { + 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 */ From 4aebc7cc5e7576ca41be62db2809ba2d5553bfb0 Mon Sep 17 00:00:00 2001 From: Vladimir Zidar Date: Fri, 27 May 2016 03:13:49 +0200 Subject: [PATCH 2/2] LP-342 Added EXTI_Init(DISABLE) to PIOS_EXTI_DeInit. --- flight/pios/stm32f0x/pios_exti.c | 6 ++++++ flight/pios/stm32f10x/pios_exti.c | 6 ++++++ flight/pios/stm32f4xx/pios_exti.c | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/flight/pios/stm32f0x/pios_exti.c b/flight/pios/stm32f0x/pios_exti.c index 138c54e42..29203eb62 100644 --- a/flight/pios/stm32f0x/pios_exti.c +++ b/flight/pios/stm32f0x/pios_exti.c @@ -174,7 +174,13 @@ 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; } diff --git a/flight/pios/stm32f10x/pios_exti.c b/flight/pios/stm32f10x/pios_exti.c index b0325f902..958f8d056 100644 --- a/flight/pios/stm32f10x/pios_exti.c +++ b/flight/pios/stm32f10x/pios_exti.c @@ -175,7 +175,13 @@ 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; } diff --git a/flight/pios/stm32f4xx/pios_exti.c b/flight/pios/stm32f4xx/pios_exti.c index 89122c362..8b3a45bff 100644 --- a/flight/pios/stm32f4xx/pios_exti.c +++ b/flight/pios/stm32f4xx/pios_exti.c @@ -175,7 +175,13 @@ 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; }