2 ******************************************************************************
4 * @addtogroup PIOS PIOS Core hardware abstraction layer
6 * @addtogroup PIOS_EXTI External Interrupt Handlers
7 * @brief External interrupt handler functions
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
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
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
)
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;
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
;
95 case (uint32_t)GPIOG
: return EXTI_PortSourceGPIOG
;
102 uint8_t PIOS_EXTI_gpio_pin_to_exti_source_pin(uint32_t gpio_pin
)
104 switch ((uint32_t)gpio_pin
) {
105 case GPIO_Pin_0
: return GPIO_PinSource0
;
107 case GPIO_Pin_1
: return GPIO_PinSource1
;
109 case GPIO_Pin_2
: return GPIO_PinSource2
;
111 case GPIO_Pin_3
: return GPIO_PinSource3
;
113 case GPIO_Pin_4
: return GPIO_PinSource4
;
115 case GPIO_Pin_5
: return GPIO_PinSource5
;
117 case GPIO_Pin_6
: return GPIO_PinSource6
;
119 case GPIO_Pin_7
: return GPIO_PinSource7
;
121 case GPIO_Pin_8
: return GPIO_PinSource8
;
123 case GPIO_Pin_9
: return GPIO_PinSource9
;
125 case GPIO_Pin_10
: return GPIO_PinSource10
;
127 case GPIO_Pin_11
: return GPIO_PinSource11
;
129 case GPIO_Pin_12
: return GPIO_PinSource12
;
131 case GPIO_Pin_13
: return GPIO_PinSource13
;
133 case GPIO_Pin_14
: return GPIO_PinSource14
;
135 case GPIO_Pin_15
: return GPIO_PinSource15
;
142 int32_t PIOS_EXTI_Init(const struct pios_exti_cfg
*cfg
)
146 /* Connect this config to the requested vector */
147 uint8_t line_index
= PIOS_EXTI_line_to_index(cfg
->line
);
149 if (pios_exti_vector
[line_index
]) {
150 /* Someone else already has this mapped */
154 /* Bind the vector to the exti line */
155 pios_exti_vector
[line_index
] = cfg
->vector
;
157 /* Initialize the GPIO pin */
158 GPIO_Init(cfg
->pin
.gpio
, &cfg
->pin
.init
);
160 /* Set up the EXTI interrupt source */
161 uint8_t exti_source_port
= PIOS_EXTI_gpio_port_to_exti_source_port(cfg
->pin
.gpio
);
162 /* 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 */
163 uint8_t exti_source_pin
= PIOS_EXTI_gpio_pin_to_exti_source_pin(cfg
->pin
.init
.GPIO_Pin
);
164 SYSCFG_EXTILineConfig(exti_source_port
, exti_source_pin
);
165 EXTI_Init(&cfg
->exti
.init
);
167 /* Enable the interrupt channel */
168 NVIC_Init(&cfg
->irq
.init
);
173 int32_t PIOS_EXTI_DeInit(const struct pios_exti_cfg
*cfg
)
175 uint8_t line_index
= PIOS_EXTI_line_to_index(cfg
->line
);
177 if (pios_exti_vector
[line_index
] == cfg
->vector
) {
178 EXTI_InitTypeDef disable
= cfg
->exti
.init
;
179 disable
.EXTI_LineCmd
= DISABLE
;
182 pios_exti_vector
[line_index
] = 0;
190 static bool PIOS_EXTI_generic_irq_handler(uint8_t line_index
)
192 if (pios_exti_vector
[line_index
]) {
193 return pios_exti_vector
[line_index
]();
196 /* Unconfigured interrupt just fired! */
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; \
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); \
216 static void PIOS_EXTI_0_irq_handler(void)
218 #ifdef PIOS_INCLUDE_FREERTOS
219 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
221 bool xHigherPriorityTaskWoken
;
223 PIOS_EXTI_HANDLE_LINE(0, xHigherPriorityTaskWoken
);
224 #ifdef PIOS_INCLUDE_FREERTOS
225 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
228 void EXTI0_IRQHandler(void) __attribute__((alias("PIOS_EXTI_0_irq_handler")));
230 static void PIOS_EXTI_1_irq_handler(void)
232 #ifdef PIOS_INCLUDE_FREERTOS
233 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
235 bool xHigherPriorityTaskWoken
;
237 PIOS_EXTI_HANDLE_LINE(1, xHigherPriorityTaskWoken
);
238 #ifdef PIOS_INCLUDE_FREERTOS
239 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
242 void EXTI1_IRQHandler(void) __attribute__((alias("PIOS_EXTI_1_irq_handler")));
244 static void PIOS_EXTI_2_irq_handler(void)
246 #ifdef PIOS_INCLUDE_FREERTOS
247 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
249 bool xHigherPriorityTaskWoken
;
251 PIOS_EXTI_HANDLE_LINE(2, xHigherPriorityTaskWoken
);
252 #ifdef PIOS_INCLUDE_FREERTOS
253 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
256 void EXTI2_IRQHandler(void) __attribute__((alias("PIOS_EXTI_2_irq_handler")));
258 static void PIOS_EXTI_3_irq_handler(void)
260 #ifdef PIOS_INCLUDE_FREERTOS
261 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
263 bool xHigherPriorityTaskWoken
;
265 PIOS_EXTI_HANDLE_LINE(3, xHigherPriorityTaskWoken
);
266 #ifdef PIOS_INCLUDE_FREERTOS
267 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
270 void EXTI3_IRQHandler(void) __attribute__((alias("PIOS_EXTI_3_irq_handler")));
272 static void PIOS_EXTI_4_irq_handler(void)
274 #ifdef PIOS_INCLUDE_FREERTOS
275 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
277 bool xHigherPriorityTaskWoken
;
279 PIOS_EXTI_HANDLE_LINE(4, xHigherPriorityTaskWoken
);
280 #ifdef PIOS_INCLUDE_FREERTOS
281 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
284 void EXTI4_IRQHandler(void) __attribute__((alias("PIOS_EXTI_4_irq_handler")));
286 static void PIOS_EXTI_9_5_irq_handler(void)
288 #ifdef PIOS_INCLUDE_FREERTOS
289 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
291 bool xHigherPriorityTaskWoken
;
293 PIOS_EXTI_HANDLE_LINE(5, xHigherPriorityTaskWoken
);
294 PIOS_EXTI_HANDLE_LINE(6, xHigherPriorityTaskWoken
);
295 PIOS_EXTI_HANDLE_LINE(7, xHigherPriorityTaskWoken
);
296 PIOS_EXTI_HANDLE_LINE(8, xHigherPriorityTaskWoken
);
297 PIOS_EXTI_HANDLE_LINE(9, xHigherPriorityTaskWoken
);
298 #ifdef PIOS_INCLUDE_FREERTOS
299 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
302 void EXTI9_5_IRQHandler(void) __attribute__((alias("PIOS_EXTI_9_5_irq_handler")));
304 static void PIOS_EXTI_15_10_irq_handler(void)
306 #ifdef PIOS_INCLUDE_FREERTOS
307 portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
309 bool xHigherPriorityTaskWoken
;
311 PIOS_EXTI_HANDLE_LINE(10, xHigherPriorityTaskWoken
);
312 PIOS_EXTI_HANDLE_LINE(11, xHigherPriorityTaskWoken
);
313 PIOS_EXTI_HANDLE_LINE(12, xHigherPriorityTaskWoken
);
314 PIOS_EXTI_HANDLE_LINE(13, xHigherPriorityTaskWoken
);
315 PIOS_EXTI_HANDLE_LINE(14, xHigherPriorityTaskWoken
);
316 PIOS_EXTI_HANDLE_LINE(15, xHigherPriorityTaskWoken
);
317 #ifdef PIOS_INCLUDE_FREERTOS
318 portEND_SWITCHING_ISR(xHigherPriorityTaskWoken
);
321 void EXTI15_10_IRQHandler(void) __attribute__((alias("PIOS_EXTI_15_10_irq_handler")));
323 #endif /* PIOS_INCLUDE_EXTI */