update credits
[librepilot.git] / flight / pios / stm32f30x / pios_exti.c
blob8f2d785402eb18530aa534f80fe3eca4da8ea57b
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 #define EXTI_MAX_LINES 16
38 static pios_exti_vector_t pios_exti_vector[EXTI_MAX_LINES];
40 static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
42 switch (line) {
43 case EXTI_Line0: return 0;
45 case EXTI_Line1: return 1;
47 case EXTI_Line2: return 2;
49 case EXTI_Line3: return 3;
51 case EXTI_Line4: return 4;
53 case EXTI_Line5: return 5;
55 case EXTI_Line6: return 6;
57 case EXTI_Line7: return 7;
59 case EXTI_Line8: return 8;
61 case EXTI_Line9: return 9;
63 case EXTI_Line10: return 10;
65 case EXTI_Line11: return 11;
67 case EXTI_Line12: return 12;
69 case EXTI_Line13: return 13;
71 case EXTI_Line14: return 14;
73 case EXTI_Line15: return 15;
76 PIOS_Assert(0);
77 return 0xFF;
80 uint8_t PIOS_EXTI_gpio_port_to_exti_source_port(GPIO_TypeDef *gpio_port)
82 switch ((uint32_t)gpio_port) {
83 case (uint32_t)GPIOA: return EXTI_PortSourceGPIOA;
85 case (uint32_t)GPIOB: return EXTI_PortSourceGPIOB;
87 case (uint32_t)GPIOC: return EXTI_PortSourceGPIOC;
89 case (uint32_t)GPIOD: return EXTI_PortSourceGPIOD;
91 case (uint32_t)GPIOE: return EXTI_PortSourceGPIOE;
93 case (uint32_t)GPIOF: return EXTI_PortSourceGPIOF;
96 PIOS_Assert(0);
97 return 0xFF;
100 uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
102 switch ((uint32_t)gpio_pin) {
103 case GPIO_Pin_0: return GPIO_PinSource0;
105 case GPIO_Pin_1: return GPIO_PinSource1;
107 case GPIO_Pin_2: return GPIO_PinSource2;
109 case GPIO_Pin_3: return GPIO_PinSource3;
111 case GPIO_Pin_4: return GPIO_PinSource4;
113 case GPIO_Pin_5: return GPIO_PinSource5;
115 case GPIO_Pin_6: return GPIO_PinSource6;
117 case GPIO_Pin_7: return GPIO_PinSource7;
119 case GPIO_Pin_8: return GPIO_PinSource8;
121 case GPIO_Pin_9: return GPIO_PinSource9;
123 case GPIO_Pin_10: return GPIO_PinSource10;
125 case GPIO_Pin_11: return GPIO_PinSource11;
127 case GPIO_Pin_12: return GPIO_PinSource12;
129 case GPIO_Pin_13: return GPIO_PinSource13;
131 case GPIO_Pin_14: return GPIO_PinSource14;
133 case GPIO_Pin_15: return GPIO_PinSource15;
136 PIOS_Assert(0);
137 return 0xFF;
140 int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
142 PIOS_Assert(cfg);
144 /* Connect this config to the requested vector */
145 uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
147 if (pios_exti_vector[line_index]) {
148 /* Someone else already has this mapped */
149 return -1;
152 /* Bind the vector to the exti line */
153 pios_exti_vector[line_index] = cfg->vector;
155 /* Initialize the GPIO pin */
156 GPIO_Init(cfg->pin.gpio, (GPIO_InitTypeDef *)&cfg->pin.init);
158 /* Set up the EXTI interrupt source */
159 uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
160 /* 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 */
161 uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
162 SYSCFG_EXTILineConfig(exti_source_port, exti_source_pin);
163 EXTI_Init((EXTI_InitTypeDef *)&cfg->exti.init);
165 /* Enable the interrupt channel */
166 NVIC_Init((NVIC_InitTypeDef *)&cfg->irq.init);
168 return 0;
171 int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg *cfg)
173 uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
175 if (pios_exti_vector[line_index] == cfg->vector) {
176 EXTI_InitTypeDef disable = cfg->exti.init;
177 disable.EXTI_LineCmd = DISABLE;
179 EXTI_Init(&disable);
180 pios_exti_vector[line_index] = 0;
182 return 0;
185 return -1;
188 static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
190 if (pios_exti_vector[line_index]) {
191 return pios_exti_vector[line_index]();
194 /* Unconfigured interrupt just fired! */
195 return false;
198 /* Bind Interrupt Handlers */
200 #ifdef PIOS_INCLUDE_FREERTOS
201 #define PIOS_EXTI_HANDLE_LINE(line, woken) \
202 if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
203 EXTI_ClearITPendingBit(EXTI_Line##line); \
204 woken = PIOS_EXTI_generic_irq_handler(line) ? pdTRUE : woken; \
206 #else
207 #define PIOS_EXTI_HANDLE_LINE(line, woken) \
208 if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
209 EXTI_ClearITPendingBit(EXTI_Line##line); \
210 PIOS_EXTI_generic_irq_handler(line); \
212 #endif
214 static void PIOS_EXTI_0_irq_handler(void)
216 #ifdef PIOS_INCLUDE_FREERTOS
217 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
218 #else
219 bool xHigherPriorityTaskWoken;
220 #endif
221 PIOS_EXTI_HANDLE_LINE(0, xHigherPriorityTaskWoken);
222 #ifdef PIOS_INCLUDE_FREERTOS
223 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
224 #endif
226 void EXTI0_IRQHandler(void) __attribute__((alias("PIOS_EXTI_0_irq_handler")));
228 static void PIOS_EXTI_1_irq_handler(void)
230 #ifdef PIOS_INCLUDE_FREERTOS
231 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
232 #else
233 bool xHigherPriorityTaskWoken;
234 #endif
235 PIOS_EXTI_HANDLE_LINE(1, xHigherPriorityTaskWoken);
236 #ifdef PIOS_INCLUDE_FREERTOS
237 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
238 #endif
240 void EXTI1_IRQHandler(void) __attribute__((alias("PIOS_EXTI_1_irq_handler")));
242 static void PIOS_EXTI_2_irq_handler(void)
244 #ifdef PIOS_INCLUDE_FREERTOS
245 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
246 #else
247 bool xHigherPriorityTaskWoken;
248 #endif
249 PIOS_EXTI_HANDLE_LINE(2, xHigherPriorityTaskWoken);
250 #ifdef PIOS_INCLUDE_FREERTOS
251 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
252 #endif
254 void EXTI2_IRQHandler(void) __attribute__((alias("PIOS_EXTI_2_irq_handler")));
256 static void PIOS_EXTI_3_irq_handler(void)
258 #ifdef PIOS_INCLUDE_FREERTOS
259 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
260 #else
261 bool xHigherPriorityTaskWoken;
262 #endif
263 PIOS_EXTI_HANDLE_LINE(3, xHigherPriorityTaskWoken);
264 #ifdef PIOS_INCLUDE_FREERTOS
265 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
266 #endif
268 void EXTI3_IRQHandler(void) __attribute__((alias("PIOS_EXTI_3_irq_handler")));
270 static void PIOS_EXTI_4_irq_handler(void)
272 #ifdef PIOS_INCLUDE_FREERTOS
273 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
274 #else
275 bool xHigherPriorityTaskWoken;
276 #endif
277 PIOS_EXTI_HANDLE_LINE(4, xHigherPriorityTaskWoken);
278 #ifdef PIOS_INCLUDE_FREERTOS
279 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
280 #endif
282 void EXTI4_IRQHandler(void) __attribute__((alias("PIOS_EXTI_4_irq_handler")));
284 static void PIOS_EXTI_9_5_irq_handler(void)
286 #ifdef PIOS_INCLUDE_FREERTOS
287 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
288 #else
289 bool xHigherPriorityTaskWoken;
290 #endif
291 PIOS_EXTI_HANDLE_LINE(5, xHigherPriorityTaskWoken);
292 PIOS_EXTI_HANDLE_LINE(6, xHigherPriorityTaskWoken);
293 PIOS_EXTI_HANDLE_LINE(7, xHigherPriorityTaskWoken);
294 PIOS_EXTI_HANDLE_LINE(8, xHigherPriorityTaskWoken);
295 PIOS_EXTI_HANDLE_LINE(9, xHigherPriorityTaskWoken);
296 #ifdef PIOS_INCLUDE_FREERTOS
297 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
298 #endif
300 void EXTI9_5_IRQHandler(void) __attribute__((alias("PIOS_EXTI_9_5_irq_handler")));
302 static void PIOS_EXTI_15_10_irq_handler(void)
304 #ifdef PIOS_INCLUDE_FREERTOS
305 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
306 #else
307 bool xHigherPriorityTaskWoken;
308 #endif
309 PIOS_EXTI_HANDLE_LINE(10, xHigherPriorityTaskWoken);
310 PIOS_EXTI_HANDLE_LINE(11, xHigherPriorityTaskWoken);
311 PIOS_EXTI_HANDLE_LINE(12, xHigherPriorityTaskWoken);
312 PIOS_EXTI_HANDLE_LINE(13, xHigherPriorityTaskWoken);
313 PIOS_EXTI_HANDLE_LINE(14, xHigherPriorityTaskWoken);
314 PIOS_EXTI_HANDLE_LINE(15, xHigherPriorityTaskWoken);
315 #ifdef PIOS_INCLUDE_FREERTOS
316 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
317 #endif
319 void EXTI15_10_IRQHandler(void) __attribute__((alias("PIOS_EXTI_15_10_irq_handler")));
321 #endif /* PIOS_INCLUDE_EXTI */
324 * @}
325 * @}