fix WhatsNew for release
[librepilot.git] / flight / pios / stm32f10x / pios_exti.c
blobefdda068e11a56eb77f9cd460acfdaf79560f97f
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
38 #define PIOS_EXTI_INVALID 0xFF
39 static uint8_t pios_exti_line_to_cfg_map[EXTI_MAX_LINES] = {
40 [0 ... EXTI_MAX_LINES - 1] = PIOS_EXTI_INVALID,
43 /* Table of exti configs registered at compile time */
44 extern struct pios_exti_cfg __start__exti __attribute__((weak));
45 extern struct pios_exti_cfg __stop__exti __attribute__((weak));
47 static uint8_t PIOS_EXTI_line_to_index(uint32_t line)
49 switch (line) {
50 case EXTI_Line0: return 0;
52 case EXTI_Line1: return 1;
54 case EXTI_Line2: return 2;
56 case EXTI_Line3: return 3;
58 case EXTI_Line4: return 4;
60 case EXTI_Line5: return 5;
62 case EXTI_Line6: return 6;
64 case EXTI_Line7: return 7;
66 case EXTI_Line8: return 8;
68 case EXTI_Line9: return 9;
70 case EXTI_Line10: return 10;
72 case EXTI_Line11: return 11;
74 case EXTI_Line12: return 12;
76 case EXTI_Line13: return 13;
78 case EXTI_Line14: return 14;
80 case EXTI_Line15: return 15;
83 PIOS_Assert(0);
84 return 0xFF;
87 uint8_t PIOS_EXTI_gpio_port_to_exti_source_port(GPIO_TypeDef *gpio_port)
89 switch ((uint32_t)gpio_port) {
90 case (uint32_t)GPIOA: return GPIO_PortSourceGPIOA;
92 case (uint32_t)GPIOB: return GPIO_PortSourceGPIOB;
94 case (uint32_t)GPIOC: return GPIO_PortSourceGPIOC;
96 case (uint32_t)GPIOD: return GPIO_PortSourceGPIOD;
98 case (uint32_t)GPIOE: return GPIO_PortSourceGPIOE;
100 case (uint32_t)GPIOF: return GPIO_PortSourceGPIOF;
102 case (uint32_t)GPIOG: return GPIO_PortSourceGPIOG;
105 PIOS_Assert(0);
106 return 0xFF;
109 uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin)
111 switch ((uint32_t)gpio_pin) {
112 case GPIO_Pin_0: return GPIO_PinSource0;
114 case GPIO_Pin_1: return GPIO_PinSource1;
116 case GPIO_Pin_2: return GPIO_PinSource2;
118 case GPIO_Pin_3: return GPIO_PinSource3;
120 case GPIO_Pin_4: return GPIO_PinSource4;
122 case GPIO_Pin_5: return GPIO_PinSource5;
124 case GPIO_Pin_6: return GPIO_PinSource6;
126 case GPIO_Pin_7: return GPIO_PinSource7;
128 case GPIO_Pin_8: return GPIO_PinSource8;
130 case GPIO_Pin_9: return GPIO_PinSource9;
132 case GPIO_Pin_10: return GPIO_PinSource10;
134 case GPIO_Pin_11: return GPIO_PinSource11;
136 case GPIO_Pin_12: return GPIO_PinSource12;
138 case GPIO_Pin_13: return GPIO_PinSource13;
140 case GPIO_Pin_14: return GPIO_PinSource14;
142 case GPIO_Pin_15: return GPIO_PinSource15;
145 PIOS_Assert(0);
146 return 0xFF;
149 int32_t PIOS_EXTI_Init(const struct pios_exti_cfg *cfg)
151 PIOS_Assert(cfg);
152 PIOS_Assert(&__start__exti);
153 PIOS_Assert(cfg >= &__start__exti);
154 PIOS_Assert(cfg < &__stop__exti);
156 uint8_t cfg_index = cfg - &__start__exti;
158 /* Connect this config to the requested vector */
159 uint8_t line_index = PIOS_EXTI_line_to_index(cfg->line);
161 if (pios_exti_line_to_cfg_map[line_index] != PIOS_EXTI_INVALID) {
162 /* Someone else already has this mapped */
163 goto out_fail;
166 /* Bind the config to the exti line */
167 pios_exti_line_to_cfg_map[line_index] = cfg_index;
169 /* Initialize the GPIO pin */
170 GPIO_Init(cfg->pin.gpio, &cfg->pin.init);
172 /* Set up the EXTI interrupt source */
173 uint8_t exti_source_port = PIOS_EXTI_gpio_port_to_exti_source_port(cfg->pin.gpio);
174 uint8_t exti_source_pin = PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg->pin.init.GPIO_Pin);
175 GPIO_EXTILineConfig(exti_source_port, exti_source_pin);
176 EXTI_Init(&cfg->exti.init);
178 /* Enable the interrupt channel */
179 NVIC_Init(&cfg->irq.init);
181 return 0;
183 out_fail:
184 return -1;
187 static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index)
189 uint8_t cfg_index = pios_exti_line_to_cfg_map[line_index];
191 PIOS_Assert(&__start__exti);
193 if (cfg_index > NELEMENTS(pios_exti_line_to_cfg_map) ||
194 cfg_index == PIOS_EXTI_INVALID) {
195 /* Unconfigured interrupt just fired! */
196 return false;
199 struct pios_exti_cfg *cfg = &__start__exti + cfg_index;
200 return cfg->vector();
203 #ifdef PIOS_INCLUDE_FREERTOS
204 #define PIOS_EXTI_HANDLE_LINE(line, woken) \
205 if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
206 EXTI_ClearITPendingBit(EXTI_Line##line); \
207 woken = PIOS_EXTI_generic_irq_handler(line) ? pdTRUE : woken; \
209 #else
210 #define PIOS_EXTI_HANDLE_LINE(line, woken) \
211 if (EXTI_GetITStatus(EXTI_Line##line) != RESET) { \
212 EXTI_ClearITPendingBit(EXTI_Line##line); \
213 PIOS_EXTI_generic_irq_handler(line); \
215 #endif
217 /* Bind Interrupt Handlers */
219 static void PIOS_EXTI_0_irq_handler(void)
221 #ifdef PIOS_INCLUDE_FREERTOS
222 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
223 #else
224 bool xHigherPriorityTaskWoken; // dummy variable
225 #endif
226 PIOS_EXTI_HANDLE_LINE(0, xHigherPriorityTaskWoken);
227 #ifdef PIOS_INCLUDE_FREERTOS
228 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
229 #endif
231 void EXTI0_IRQHandler(void) __attribute__((alias("PIOS_EXTI_0_irq_handler")));
233 static void PIOS_EXTI_1_irq_handler(void)
235 #ifdef PIOS_INCLUDE_FREERTOS
236 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
237 #else
238 bool xHigherPriorityTaskWoken; // dummy variable
239 #endif
240 PIOS_EXTI_HANDLE_LINE(1, xHigherPriorityTaskWoken);
241 #ifdef PIOS_INCLUDE_FREERTOS
242 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
243 #endif
245 void EXTI1_IRQHandler(void) __attribute__((alias("PIOS_EXTI_1_irq_handler")));
247 static void PIOS_EXTI_2_irq_handler(void)
249 #ifdef PIOS_INCLUDE_FREERTOS
250 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
251 #else
252 bool xHigherPriorityTaskWoken; // dummy variable
253 #endif
254 PIOS_EXTI_HANDLE_LINE(2, xHigherPriorityTaskWoken);
255 #ifdef PIOS_INCLUDE_FREERTOS
256 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
257 #endif
259 void EXTI2_IRQHandler(void) __attribute__((alias("PIOS_EXTI_2_irq_handler")));
261 static void PIOS_EXTI_3_irq_handler(void)
263 #ifdef PIOS_INCLUDE_FREERTOS
264 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
265 #else
266 bool xHigherPriorityTaskWoken; // dummy variable
267 #endif
268 PIOS_EXTI_HANDLE_LINE(3, xHigherPriorityTaskWoken);
269 #ifdef PIOS_INCLUDE_FREERTOS
270 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
271 #endif
273 void EXTI3_IRQHandler(void) __attribute__((alias("PIOS_EXTI_3_irq_handler")));
275 static void PIOS_EXTI_4_irq_handler(void)
277 #ifdef PIOS_INCLUDE_FREERTOS
278 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
279 #else
280 bool xHigherPriorityTaskWoken; // dummy variable
281 #endif
282 PIOS_EXTI_HANDLE_LINE(4, xHigherPriorityTaskWoken);
283 #ifdef PIOS_INCLUDE_FREERTOS
284 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
285 #endif
287 void EXTI4_IRQHandler(void) __attribute__((alias("PIOS_EXTI_4_irq_handler")));
289 static void PIOS_EXTI_9_5_irq_handler(void)
291 #ifdef PIOS_INCLUDE_FREERTOS
292 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
293 #else
294 bool xHigherPriorityTaskWoken; // dummy variable
295 #endif
296 PIOS_EXTI_HANDLE_LINE(5, xHigherPriorityTaskWoken);
297 PIOS_EXTI_HANDLE_LINE(6, xHigherPriorityTaskWoken);
298 PIOS_EXTI_HANDLE_LINE(7, xHigherPriorityTaskWoken);
299 PIOS_EXTI_HANDLE_LINE(8, xHigherPriorityTaskWoken);
300 PIOS_EXTI_HANDLE_LINE(9, xHigherPriorityTaskWoken);
301 #ifdef PIOS_INCLUDE_FREERTOS
302 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
303 #endif
305 void EXTI9_5_IRQHandler(void) __attribute__((alias("PIOS_EXTI_9_5_irq_handler")));
307 static void PIOS_EXTI_15_10_irq_handler(void)
309 #ifdef PIOS_INCLUDE_FREERTOS
310 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
311 #else
312 bool xHigherPriorityTaskWoken; // dummy variable
313 #endif
314 PIOS_EXTI_HANDLE_LINE(10, xHigherPriorityTaskWoken);
315 PIOS_EXTI_HANDLE_LINE(11, xHigherPriorityTaskWoken);
316 PIOS_EXTI_HANDLE_LINE(12, xHigherPriorityTaskWoken);
317 PIOS_EXTI_HANDLE_LINE(13, xHigherPriorityTaskWoken);
318 PIOS_EXTI_HANDLE_LINE(14, xHigherPriorityTaskWoken);
319 PIOS_EXTI_HANDLE_LINE(15, xHigherPriorityTaskWoken);
320 #ifdef PIOS_INCLUDE_FREERTOS
321 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
322 #endif
324 void EXTI15_10_IRQHandler(void) __attribute__((alias("PIOS_EXTI_15_10_irq_handler")));
326 #endif /* PIOS_INCLUDE_EXTI */
329 * @}
330 * @}