mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
exti: rewrite exti layer to improve portability
The exti layer now allows drivers to register interrupt callbacks during board initialization. All details of the driver using a particular EXTI pin have been removed from the EXTI layer so it can now be used on any board without board-specific modification. This includes some nice refinements provided by Mike Smith during initial review. His original commits have been squashed into this one.
This commit is contained in:
parent
64202ce092
commit
bfe6676eed
@ -72,7 +72,7 @@ void PIOS_DEBUG_PinValue4BitL(uint8_t value)
|
||||
/**
|
||||
* Report a serious error and halt
|
||||
*/
|
||||
void PIOS_DEBUG_Panic(const char *msg)
|
||||
void PIOS_DEBUG_Panic(const char *msg) __attribute__ ((noreturn))
|
||||
{
|
||||
#ifdef PIOS_COM_DEBUG
|
||||
register int *lr asm("lr"); // Link-register holds the PC of the caller
|
||||
|
@ -284,6 +284,4 @@ extern uint32_t pios_com_telem_usb_id;
|
||||
#define PIOS_USB_DETECT_GPIO_PORT GPIOC
|
||||
#define PIOS_USB_MAX_DEVS 1
|
||||
#define PIOS_USB_DETECT_GPIO_PIN GPIO_Pin_15
|
||||
#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line15
|
||||
#define PIOS_IRQ_USB_PRIORITY PIOS_IRQ_PRIO_MID
|
||||
#endif /* STM32103CB_AHRS_H_ */
|
||||
|
@ -316,8 +316,6 @@ extern uint32_t pios_com_aux_id;
|
||||
#define PIOS_USB_MAX_DEVS 1
|
||||
#define PIOS_USB_HID_MAX_DEVS 1
|
||||
#define PIOS_USB_DETECT_GPIO_PIN GPIO_Pin_4
|
||||
#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line4
|
||||
#define PIOS_IRQ_USB_PRIORITY PIOS_IRQ_PRIO_MID
|
||||
|
||||
/**
|
||||
* glue macros for file IO
|
||||
|
@ -36,19 +36,11 @@
|
||||
#error PIOS_EXTI Must be included in the project!
|
||||
#endif /* PIOS_INCLUDE_EXTI */
|
||||
|
||||
#include <pios_exti.h>
|
||||
|
||||
/* Glocal Variables */
|
||||
ConversionTypeTypeDef CurrentRead;
|
||||
|
||||
#ifdef PIOS_BMP085_HAS_GPIOS
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreHandle PIOS_BMP085_EOC;
|
||||
#else
|
||||
int32_t PIOS_BMP085_EOC;
|
||||
#endif
|
||||
|
||||
#endif /* PIOS_BMP085_HAS_GPIOS */
|
||||
|
||||
/* Local Variables */
|
||||
static BMP085CalibDataTypeDef CalibData;
|
||||
|
||||
@ -60,18 +52,69 @@ static volatile uint32_t RawPressure;
|
||||
static volatile uint32_t Pressure;
|
||||
static volatile uint16_t Temperature;
|
||||
|
||||
#ifdef PIOS_BMP085_HAS_GPIOS
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreHandle PIOS_BMP085_EOC;
|
||||
#else
|
||||
int32_t PIOS_BMP085_EOC;
|
||||
#endif
|
||||
|
||||
void PIOS_BMP085_EndOfConversion (void)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
#endif
|
||||
|
||||
/* Read the ADC Value */
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveFromISR(PIOS_BMP085_EOC, &xHigherPriorityTaskWoken);
|
||||
#else
|
||||
PIOS_BMP085_EOC=1;
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
/* Yield From ISR if needed */
|
||||
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct pios_exti_cfg pios_exti_bmp085_cfg __exti_config = {
|
||||
.vector = PIOS_BMP085_EndOfConversion,
|
||||
.line = PIOS_BMP085_EOC_EXTI_LINE,
|
||||
.pin = {
|
||||
.gpio = PIOS_BMP085_EOC_GPIO_PORT,
|
||||
.init = {
|
||||
.GPIO_Pin = PIOS_BMP085_EOC_GPIO_PIN,
|
||||
.GPIO_Mode = GPIO_Mode_IN_FLOATING,
|
||||
},
|
||||
},
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = PIOS_BMP085_EOC_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_BMP085_EOC_PRIO,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
.exti = {
|
||||
.init = {
|
||||
.EXTI_Line = PIOS_BMP085_EOC_EXTI_LINE,
|
||||
.EXTI_Mode = EXTI_Mode_Interrupt,
|
||||
.EXTI_Trigger = EXTI_Trigger_Rising,
|
||||
.EXTI_LineCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* PIOS_BMP085_HAS_GPIOS */
|
||||
/**
|
||||
* Initialise the BMP085 sensor
|
||||
*/
|
||||
void PIOS_BMP085_Init(void)
|
||||
{
|
||||
|
||||
#ifdef PIOS_BMP085_HAS_GPIOS
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
/* Semaphore used by ISR to signal End-Of-Conversion */
|
||||
vSemaphoreCreateBinary(PIOS_BMP085_EOC);
|
||||
@ -84,27 +127,12 @@ void PIOS_BMP085_Init(void)
|
||||
/* Enable EOC GPIO clock */
|
||||
RCC_APB2PeriphClockCmd(PIOS_BMP085_EOC_CLK | RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
/* Configure EOC pin as input floating */
|
||||
GPIO_InitStructure.GPIO_Pin = PIOS_BMP085_EOC_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(PIOS_BMP085_EOC_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
/* Configure the End Of Conversion (EOC) interrupt */
|
||||
GPIO_EXTILineConfig(PIOS_BMP085_EOC_PORT_SOURCE, PIOS_BMP085_EOC_PIN_SOURCE);
|
||||
EXTI_InitStructure.EXTI_Line = PIOS_BMP085_EOC_EXTI_LINE;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
/* Enable and set EOC EXTI Interrupt to the lowest priority */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = PIOS_BMP085_EOC_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_BMP085_EOC_PRIO;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
if (PIOS_EXTI_Init(&pios_exti_bmp085_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
/* Configure XCLR pin as push/pull alternate funtion output */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = PIOS_BMP085_XCLR_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(PIOS_BMP085_XCLR_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
#if defined(PIOS_INCLUDE_HMC5843)
|
||||
|
||||
#include <pios_exti.h>
|
||||
|
||||
/* HMC5843 Addresses */
|
||||
#define PIOS_HMC5843_I2C_ADDR 0x1E
|
||||
#define PIOS_HMC5843_CONFIG_REG_A (uint8_t)0x00
|
||||
@ -107,37 +109,48 @@ static void PIOS_HMC5843_Config(PIOS_HMC5843_ConfigTypeDef * HMC5843_Config_Stru
|
||||
static bool PIOS_HMC5843_Read(uint8_t address, uint8_t * buffer, uint8_t len);
|
||||
static bool PIOS_HMC5843_Write(uint8_t address, uint8_t buffer);
|
||||
|
||||
void PIOS_HMC5843_EndOfConversion (void)
|
||||
{
|
||||
pios_hmc5843_data_ready = true;
|
||||
}
|
||||
|
||||
static const struct pios_exti_cfg pios_exti_hmc5843_cfg __exti_config = {
|
||||
.vector = PIOS_HMC5843_EndOfConversion,
|
||||
.line = PIOS_HMC5843_DRDY_EXTI_LINE,
|
||||
.pin = {
|
||||
.gpio = PIOS_HMC5843_DRDY_GPIO_PORT,
|
||||
.init = {
|
||||
.GPIO_Pin = PIOS_HMC5843_DRDY_GPIO_PIN,
|
||||
.GPIO_Mode = GPIO_Mode_IN_FLOATING,
|
||||
},
|
||||
},
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = PIOS_HMC5843_DRDY_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_HMC5843_DRDY_PRIO,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
.exti = {
|
||||
.init = {
|
||||
.EXTI_Line = PIOS_HMC5843_DRDY_EXTI_LINE,
|
||||
.EXTI_Mode = EXTI_Mode_Interrupt,
|
||||
.EXTI_Trigger = EXTI_Trigger_Rising,
|
||||
.EXTI_LineCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @brieft Initialise the HMC5843 sensor
|
||||
* @brief Initialise the HMC5843 sensor
|
||||
*/
|
||||
void PIOS_HMC5843_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
/* Enable DRDY GPIO clock */
|
||||
RCC_APB2PeriphClockCmd(PIOS_HMC5843_DRDY_CLK | RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
/* Configure EOC pin as input floating */
|
||||
GPIO_InitStructure.GPIO_Pin = PIOS_HMC5843_DRDY_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(PIOS_HMC5843_DRDY_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
/* Configure the End Of Conversion (EOC) interrupt */
|
||||
GPIO_EXTILineConfig(PIOS_HMC5843_DRDY_PORT_SOURCE, PIOS_HMC5843_DRDY_PIN_SOURCE);
|
||||
EXTI_InitStructure.EXTI_Line = PIOS_HMC5843_DRDY_EXTI_LINE;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
/* Enable and set EOC EXTI Interrupt to the lowest priority */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = PIOS_HMC5843_DRDY_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_HMC5843_DRDY_PRIO;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
PIOS_EXTI_Init(&pios_exti_hmc5843_cfg);
|
||||
|
||||
/* Configure the HMC5843 Sensor */
|
||||
PIOS_HMC5843_ConfigTypeDef HMC5843_InitStructure;
|
||||
@ -362,11 +375,6 @@ static bool PIOS_HMC5843_Write(uint8_t address, uint8_t buffer)
|
||||
return PIOS_I2C_Transfer(PIOS_I2C_MAIN_ADAPTER, txn_list, NELEMENTS(txn_list));
|
||||
}
|
||||
|
||||
void PIOS_HMC5843_IRQHandler(void)
|
||||
{
|
||||
pios_hmc5843_data_ready = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -155,7 +155,7 @@ typedef struct
|
||||
*/
|
||||
|
||||
void EXTI_DeInit(void);
|
||||
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
|
||||
void EXTI_Init(const EXTI_InitTypeDef* EXTI_InitStruct);
|
||||
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
|
||||
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
|
||||
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
|
||||
|
@ -97,7 +97,7 @@ void EXTI_DeInit(void)
|
||||
* that contains the configuration information for the EXTI peripheral.
|
||||
* @retval None
|
||||
*/
|
||||
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
|
||||
void EXTI_Init(const EXTI_InitTypeDef* EXTI_InitStruct)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
* @{
|
||||
* @addtogroup PIOS_EXTI External Interrupt Handlers
|
||||
* @brief External interrupt handler functions
|
||||
* @note Currently deals with BMP085 readings
|
||||
* @{
|
||||
*
|
||||
* @file pios_exti.c
|
||||
@ -35,61 +34,196 @@
|
||||
|
||||
#if defined(PIOS_INCLUDE_EXTI)
|
||||
|
||||
/**
|
||||
* Handle external lines 15 to 10 interrupt requests
|
||||
*/
|
||||
void EXTI15_10_IRQHandler(void)
|
||||
/* 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 uint8_t PIOS_EXTI_line_to_index (uint32_t line)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_BMP085) && defined(PIOS_BMP085_HAS_GPIOS)
|
||||
if (EXTI_GetITStatus(PIOS_BMP085_EOC_EXTI_LINE) != RESET) {
|
||||
/* Read the ADC Value */
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveFromISR(PIOS_BMP085_EOC, &xHigherPriorityTaskWoken);
|
||||
#else
|
||||
PIOS_BMP085_EOC=1;
|
||||
#endif
|
||||
|
||||
/* Clear the EXTI line pending bit */
|
||||
EXTI_ClearITPendingBit(PIOS_BMP085_EOC_EXTI_LINE);
|
||||
switch (line) {
|
||||
case EXTI_Line0: return 0;
|
||||
case EXTI_Line1: return 1;
|
||||
case EXTI_Line2: return 2;
|
||||
case EXTI_Line3: return 3;
|
||||
case EXTI_Line4: return 4;
|
||||
case EXTI_Line5: return 5;
|
||||
case EXTI_Line6: return 6;
|
||||
case EXTI_Line7: return 7;
|
||||
case EXTI_Line8: return 8;
|
||||
case EXTI_Line9: return 9;
|
||||
case EXTI_Line10: return 10;
|
||||
case EXTI_Line11: return 11;
|
||||
case EXTI_Line12: return 12;
|
||||
case EXTI_Line13: return 13;
|
||||
case EXTI_Line14: return 14;
|
||||
case EXTI_Line15: return 15;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
/* Yield From ISR if needed */
|
||||
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
|
||||
#endif
|
||||
PIOS_Assert(0);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle external lines 9 to 5 interrupt requests
|
||||
*/
|
||||
extern void PIOS_HMC5843_IRQHandler(void);
|
||||
void EXTI9_5_IRQHandler(void)
|
||||
uint8_t PIOS_EXTI_gpio_port_to_exti_source_port(GPIO_TypeDef * gpio_port)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_HMC5843)
|
||||
if (EXTI_GetITStatus(PIOS_HMC5843_DRDY_EXTI_LINE) != RESET) {
|
||||
PIOS_HMC5843_IRQHandler();
|
||||
EXTI_ClearITPendingBit(PIOS_HMC5843_DRDY_EXTI_LINE);
|
||||
switch((uint32_t)gpio_port) {
|
||||
case (uint32_t)GPIOA: return (GPIO_PortSourceGPIOA);
|
||||
case (uint32_t)GPIOB: return (GPIO_PortSourceGPIOB);
|
||||
case (uint32_t)GPIOC: return (GPIO_PortSourceGPIOC);
|
||||
case (uint32_t)GPIOD: return (GPIO_PortSourceGPIOD);
|
||||
case (uint32_t)GPIOE: return (GPIO_PortSourceGPIOE);
|
||||
case (uint32_t)GPIOF: return (GPIO_PortSourceGPIOF);
|
||||
case (uint32_t)GPIOG: return (GPIO_PortSourceGPIOG);
|
||||
}
|
||||
#endif
|
||||
|
||||
PIOS_Assert(0);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle external line 4 interrupt requests
|
||||
*/
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
void EXTI4_IRQHandler(void)
|
||||
uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
|
||||
{
|
||||
if (EXTI_GetITStatus(PIOS_USB_DETECT_EXTI_LINE) != RESET) {
|
||||
/* Clear the EXTI line pending bit */
|
||||
EXTI_ClearITPendingBit(PIOS_USB_DETECT_EXTI_LINE);
|
||||
switch((uint32_t)gpio_pin) {
|
||||
case GPIO_Pin_0: return (GPIO_PinSource0);
|
||||
case GPIO_Pin_1: return (GPIO_PinSource1);
|
||||
case GPIO_Pin_2: return (GPIO_PinSource2);
|
||||
case GPIO_Pin_3: return (GPIO_PinSource3);
|
||||
case GPIO_Pin_4: return (GPIO_PinSource4);
|
||||
case GPIO_Pin_5: return (GPIO_PinSource5);
|
||||
case GPIO_Pin_6: return (GPIO_PinSource6);
|
||||
case GPIO_Pin_7: return (GPIO_PinSource7);
|
||||
case GPIO_Pin_8: return (GPIO_PinSource8);
|
||||
case GPIO_Pin_9: return (GPIO_PinSource9);
|
||||
case GPIO_Pin_10: return (GPIO_PinSource10);
|
||||
case GPIO_Pin_11: return (GPIO_PinSource11);
|
||||
case GPIO_Pin_12: return (GPIO_PinSource12);
|
||||
case GPIO_Pin_13: return (GPIO_PinSource13);
|
||||
case GPIO_Pin_14: return (GPIO_PinSource14);
|
||||
case GPIO_Pin_15: return (GPIO_PinSource15);
|
||||
}
|
||||
|
||||
PIOS_Assert(0);
|
||||
return 0xFF;
|
||||
}
|
||||
#endif
|
||||
|
||||
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) {
|
||||
/* Someone else already has this mapped */
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
/* Bind the config to the exti line */
|
||||
pios_exti_line_to_cfg_map[line_index] = cfg_index;
|
||||
|
||||
/* 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);
|
||||
uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
|
||||
GPIO_EXTILineConfig(exti_source_port, exti_source_pin);
|
||||
EXTI_Init(&cfg->exti.init);
|
||||
|
||||
/* Enable the interrupt channel */
|
||||
NVIC_Init(&cfg->irq.init);
|
||||
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void 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;
|
||||
}
|
||||
|
||||
struct pios_exti_cfg * cfg = &__start__exti + cfg_index;
|
||||
cfg->vector();
|
||||
}
|
||||
|
||||
/* Bind Interrupt Handlers */
|
||||
|
||||
#define PIOS_EXTI_HANDLE_LINE(line) \
|
||||
if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
|
||||
EXTI_ClearITPendingBit(EXTI_Line##line); \
|
||||
PIOS_EXTI_generic_irq_handler(line); \
|
||||
}
|
||||
|
||||
static void PIOS_EXTI_0_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(0);
|
||||
}
|
||||
void EXTI0_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_0_irq_handler")));
|
||||
|
||||
static void PIOS_EXTI_1_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(1);
|
||||
}
|
||||
void EXTI1_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_1_irq_handler")));
|
||||
|
||||
static void PIOS_EXTI_2_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(2);
|
||||
}
|
||||
void EXTI2_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_2_irq_handler")));
|
||||
|
||||
static void PIOS_EXTI_3_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(3);
|
||||
}
|
||||
void EXTI3_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_3_irq_handler")));
|
||||
|
||||
static void PIOS_EXTI_4_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(4);
|
||||
}
|
||||
void EXTI4_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_4_irq_handler")));
|
||||
|
||||
static void PIOS_EXTI_9_5_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(5);
|
||||
PIOS_EXTI_HANDLE_LINE(6);
|
||||
PIOS_EXTI_HANDLE_LINE(7);
|
||||
PIOS_EXTI_HANDLE_LINE(8);
|
||||
PIOS_EXTI_HANDLE_LINE(9);
|
||||
}
|
||||
void EXTI9_5_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_9_5_irq_handler")));
|
||||
|
||||
static void PIOS_EXTI_15_10_irq_handler (void)
|
||||
{
|
||||
PIOS_EXTI_HANDLE_LINE(10);
|
||||
PIOS_EXTI_HANDLE_LINE(11);
|
||||
PIOS_EXTI_HANDLE_LINE(12);
|
||||
PIOS_EXTI_HANDLE_LINE(13);
|
||||
PIOS_EXTI_HANDLE_LINE(14);
|
||||
PIOS_EXTI_HANDLE_LINE(15);
|
||||
}
|
||||
void EXTI15_10_IRQHandler(void) __attribute__ ((alias ("PIOS_EXTI_15_10_irq_handler")));
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,21 @@
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
#include <pios_stm32.h>
|
||||
|
||||
struct pios_exti_cfg {
|
||||
void (* vector)(void);
|
||||
uint32_t line; /* use EXTI_LineN macros */
|
||||
struct stm32_gpio pin;
|
||||
struct stm32_irq irq;
|
||||
struct stm32_exti exti;
|
||||
};
|
||||
|
||||
/* must be added to any pios_exti_cfg definition for it to be valid */
|
||||
#define __exti_config __attribute__((section("_exti")))
|
||||
|
||||
extern int32_t PIOS_EXTI_Init(const struct pios_exti_cfg * cfg);
|
||||
|
||||
#endif /* PIOS_EXTI_H */
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,10 @@ struct stm32_irq {
|
||||
NVIC_InitTypeDef init;
|
||||
};
|
||||
|
||||
struct stm32_exti {
|
||||
EXTI_InitTypeDef init;
|
||||
};
|
||||
|
||||
struct stm32_dma_chan {
|
||||
DMA_Channel_TypeDef *channel;
|
||||
DMA_InitTypeDef init;
|
||||
|
Loading…
x
Reference in New Issue
Block a user