update credits
[librepilot.git] / flight / pios / stm32f0x / pios_exti.c
blob8abf9e0f96915d16568a72d424fcff9e84712525
1 /**
2 ******************************************************************************
4 * @addtogroup PIOS PIOS Core hardware abstraction layer
5 * @{
6 * @addtogroup PIOS_EXTI External Interrupt Handlers
7 * @brief External interrupt handler functions
8 * @{
10 * @file pios_exti.c
11 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
12 * @brief External Interrupt Handlers
13 * @see The GNU Public License (GPL) Version 3
15 *****************************************************************************/
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "pios.h"
34 #ifdef PIOS_INCLUDE_EXTI
36 /* Map EXTI line to full config */
37 #define EXTI_MAX_LINES 16
39 static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
41 static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
43 switch (line) {
44 case EXTI_Line0: return 0;
46 case EXTI_Line1: return 1;
48 case EXTI_Line2: return 2;
50 case EXTI_Line3: return 3;
52 case EXTI_Line4: return 4;
54 case EXTI_Line5: return 5;
56 case EXTI_Line6: return 6;
58 case EXTI_Line7: return 7;
60 case EXTI_Line8: return 8;
62 case EXTI_Line9: return 9;
64 case EXTI_Line10: return 10;
66 case EXTI_Line11: return 11;
68 case EXTI_Line12: return 12;
70 case EXTI_Line13: return 13;
72 case EXTI_Line14: return 14;
74 case EXTI_Line15: return 15;
77 PIOS_Assert(0);
78 return 0xFF;
81 uint8_t PIOS_EXTI_gpio_port_to_exti_source_port(GPIO_TypeDef *gpio_port)
83 switch ((uint32_t)gpio_port) {
84 case (uint32_t)GPIOA: return EXTI_PortSourceGPIOA;
86 case (uint32_t)GPIOB: return EXTI_PortSourceGPIOB;
88 case (uint32_t)GPIOC: return EXTI_PortSourceGPIOC;
90 case (uint32_t)GPIOD: return EXTI_PortSourceGPIOD;
92 case (uint32_t)GPIOE: return EXTI_PortSourceGPIOE;
94 case (uint32_t)GPIOF: return EXTI_PortSourceGPIOF;
97 PIOS_Assert(0);
98 return 0xFF;
101 uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
103 switch ((uint32_t)gpio_pin) {
104 case GPIO_Pin_0: return GPIO_PinSource0;
106 case GPIO_Pin_1: return GPIO_PinSource1;
108 case GPIO_Pin_2: return GPIO_PinSource2;
110 case GPIO_Pin_3: return GPIO_PinSource3;
112 case GPIO_Pin_4: return GPIO_PinSource4;
114 case GPIO_Pin_5: return GPIO_PinSource5;
116 case GPIO_Pin_6: return GPIO_PinSource6;
118 case GPIO_Pin_7: return GPIO_PinSource7;
120 case GPIO_Pin_8: return GPIO_PinSource8;
122 case GPIO_Pin_9: return GPIO_PinSource9;
124 case GPIO_Pin_10: return GPIO_PinSource10;
126 case GPIO_Pin_11: return GPIO_PinSource11;
128 case GPIO_Pin_12: return GPIO_PinSource12;
130 case GPIO_Pin_13: return GPIO_PinSource13;
132 case GPIO_Pin_14: return GPIO_PinSource14;
134 case GPIO_Pin_15: return GPIO_PinSource15;
137 PIOS_Assert(0);
138 return 0xFF;
141 int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
143 PIOS_Assert(cfg);
145 /* Connect this config to the requested vector */
146 uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
148 if (pios_exti_vector[line_index]) {
149 /* Someone else already has this mapped */
150 return -1;
153 /* Bind the vector to the exti line */
154 pios_exti_vector[line_index] = cfg->vector;
156 /* Initialize the GPIO pin */
157 GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
159 /* Set up the EXTI interrupt source */
160 uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
161 /* 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 */
162 uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
163 SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
164 EXTI_Init((EXTI_InitTypeDef *)&cfg->exti.init);
166 /* Enable the interrupt channel */
167 NVIC_Init(&cfg->irq.init);
169 return 0;
172 int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
174 uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
176 if (pios_exti_vector[line_index] == cfg->vector) {
177 EXTI_InitTypeDef disable = cfg->exti.init;
178 disable.EXTI_LineCmd = DISABLE;
180 EXTI_Init(&disable);
181 pios_exti_vector[line_index] = 0;
183 return 0;
186 return -1;
189 static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
191 if (pios_exti_vector[line_index]) {
192 return pios_exti_vector[line_index]();
195 /* Unconfigured interrupt just fired! */
196 return false;
200 /* Bind Interrupt Handlers */
202 #ifdef PIOS_INCLUDE_FREERTOS
203 #define PIOS_EXTI_HANDLE_LINE(line, woken) \
204 if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
205 EXTI_ClearITPendingBit(EXTI_Line##line); \
206 woken = PIOS_EXTI_generic_irq_handler(line) ? pdTRUE : woken; \
208 #else
209 #define PIOS_EXTI_HANDLE_LINE(line, woken) \
210 if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
211 EXTI_ClearITPendingBit(EXTI_Line##line); \
212 PIOS_EXTI_generic_irq_handler(line); \
214 #endif
216 static void PIOS_EXTI_0_1_irq_handler(void)
218 #ifdef PIOS_INCLUDE_FREERTOS
219 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
220 #else
221 bool xHigherPriorityTaskWoken;
222 #endif
223 PIOS_EXTI_HANDLE_LINE(0, xHigherPriorityTaskWoken);
224 PIOS_EXTI_HANDLE_LINE(1, xHigherPriorityTaskWoken);
225 #ifdef PIOS_INCLUDE_FREERTOS
226 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
227 #endif
229 void EXTI0_1_IRQHandler(void) __attribute__((alias("PIOS_EXTI_0_1_irq_handler")));
232 static void PIOS_EXTI_2_3_irq_handler(void)
234 #ifdef PIOS_INCLUDE_FREERTOS
235 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
236 #else
237 bool xHigherPriorityTaskWoken;
238 #endif
239 PIOS_EXTI_HANDLE_LINE(2, xHigherPriorityTaskWoken);
240 PIOS_EXTI_HANDLE_LINE(3, xHigherPriorityTaskWoken);
241 #ifdef PIOS_INCLUDE_FREERTOS
242 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
243 #endif
245 void EXTI2_3_IRQHandler(void) __attribute__((alias("PIOS_EXTI_2_3_irq_handler")));
248 static void PIOS_EXTI4_15_irq_handler(void)
250 #ifdef PIOS_INCLUDE_FREERTOS
251 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
252 #else
253 bool xHigherPriorityTaskWoken;
254 #endif
255 PIOS_EXTI_HANDLE_LINE(4, xHigherPriorityTaskWoken);
256 PIOS_EXTI_HANDLE_LINE(5, xHigherPriorityTaskWoken);
257 PIOS_EXTI_HANDLE_LINE(6, xHigherPriorityTaskWoken);
258 PIOS_EXTI_HANDLE_LINE(7, xHigherPriorityTaskWoken);
259 PIOS_EXTI_HANDLE_LINE(8, xHigherPriorityTaskWoken);
260 PIOS_EXTI_HANDLE_LINE(9, xHigherPriorityTaskWoken);
262 PIOS_EXTI_HANDLE_LINE(10, xHigherPriorityTaskWoken);
263 PIOS_EXTI_HANDLE_LINE(11, xHigherPriorityTaskWoken);
264 PIOS_EXTI_HANDLE_LINE(12, xHigherPriorityTaskWoken);
265 PIOS_EXTI_HANDLE_LINE(13, xHigherPriorityTaskWoken);
266 PIOS_EXTI_HANDLE_LINE(14, xHigherPriorityTaskWoken);
267 PIOS_EXTI_HANDLE_LINE(15, xHigherPriorityTaskWoken);
268 #ifdef PIOS_INCLUDE_FREERTOS
269 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
270 #endif
272 void EXTI4_15_IRQHandler(void) __attribute__((alias("PIOS_EXTI4_15_irq_handler")));
274 #endif /* PIOS_INCLUDE_EXTI */
277 * @}
278 * @}