Skyward boardcore
Loading...
Searching...
No Matches
external_interrupts.cpp
Go to the documentation of this file.
1/* Copyright (c) 2019 Skyward Experimental Rocketry
2 * Authors: Alvise de'Faveri Tron, Luca Erbetta, Davide Mor
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "external_interrupts.h"
24
25#include <miosix.h>
26
27#include "kernel/logging.h"
28
29using namespace miosix;
30
66// All unused interrupts call this function.
67extern void unexpectedInterrupt();
68extern "C" void Default_EXTI_Handler()
69{
70 IRQerrorLog("\r\n***Unexpected Peripheral interrupt [Boardcore]\r\n");
71}
72
78void __attribute__((weak)) EXTI0_IRQHandlerImpl()
79{
80 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI0\r\n");
81}
82
83void __attribute__((weak)) EXTI1_IRQHandlerImpl()
84{
85 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI1\r\n");
86}
87
88void __attribute__((weak)) EXTI2_IRQHandlerImpl()
89{
90 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI2\r\n");
91}
92
93void __attribute__((weak)) EXTI3_IRQHandlerImpl()
94{
95 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI3\r\n");
96}
97
98void __attribute__((weak)) EXTI4_IRQHandlerImpl()
99{
100 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI4\r\n");
101}
102
103void __attribute__((weak)) EXTI5_IRQHandlerImpl()
104{
105 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI5\r\n");
106}
107
108void __attribute__((weak)) EXTI6_IRQHandlerImpl()
109{
110 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI6\r\n");
111}
112
113void __attribute__((weak)) EXTI7_IRQHandlerImpl()
114{
115 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI7\r\n");
116}
117
118void __attribute__((weak)) EXTI8_IRQHandlerImpl()
119{
120 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI8\r\n");
121}
122
123void __attribute__((weak)) EXTI9_IRQHandlerImpl()
124{
125 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI9\r\n");
126}
127
128void __attribute__((weak)) EXTI10_IRQHandlerImpl()
129{
130 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI10\r\n");
131}
132
133void __attribute__((weak)) EXTI11_IRQHandlerImpl()
134{
135 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI11\r\n");
136}
137
138void __attribute__((weak)) EXTI12_IRQHandlerImpl()
139{
140 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI12\r\n");
141}
142
143void __attribute__((weak)) EXTI13_IRQHandlerImpl()
144{
145 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI13\r\n");
146}
147
148void __attribute__((weak)) EXTI14_IRQHandlerImpl()
149{
150 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI14\r\n");
151}
152
153void __attribute__((weak)) EXTI15_IRQHandlerImpl()
154{
155 IRQerrorLog("\r\nUnexpected Peripheral interrupt EXTI15\r\n");
156}
157
162void __attribute__((naked)) EXTI0_IRQHandler()
163{
164 saveContext();
165 EXTI->PR = EXTI_PR_PR0;
166 asm volatile("bl _Z20EXTI0_IRQHandlerImplv");
167 restoreContext();
168}
169
174void __attribute__((naked)) EXTI1_IRQHandler()
175{
176 saveContext();
177 EXTI->PR = EXTI_PR_PR1;
178 asm volatile("bl _Z20EXTI1_IRQHandlerImplv");
179 restoreContext();
180}
181
186void __attribute__((naked)) EXTI2_IRQHandler()
187{
188 saveContext();
189 EXTI->PR = EXTI_PR_PR2;
190 asm volatile("bl _Z20EXTI2_IRQHandlerImplv");
191 restoreContext();
192}
193
198void __attribute__((naked)) EXTI3_IRQHandler()
199{
200 saveContext();
201 EXTI->PR = EXTI_PR_PR3;
202 asm volatile("bl _Z20EXTI3_IRQHandlerImplv");
203 restoreContext();
204}
205
210void __attribute__((naked)) EXTI4_IRQHandler()
211{
212 saveContext();
213 EXTI->PR = EXTI_PR_PR4;
214 asm volatile("bl _Z20EXTI4_IRQHandlerImplv");
215 restoreContext();
216}
217
222void __attribute__((naked)) EXTI9_5_IRQHandler()
223{
224 saveContext();
225 asm volatile("bl _Z22EXTI9_5_IRQHandlerImplv");
226 restoreContext();
227}
228
233void __attribute__((naked)) EXTI15_10_IRQHandler()
234{
235 saveContext();
236 asm volatile("bl _Z24EXTI15_10_IRQHandlerImplv");
237 restoreContext();
238}
239
246void __attribute__((used)) EXTI9_5_IRQHandlerImpl()
247{
248 if (EXTI->PR & EXTI_PR_PR5)
249 {
250 EXTI->PR = EXTI_PR_PR5; // Clear pending flag
251 EXTI5_IRQHandlerImpl();
252 }
253 else if (EXTI->PR & EXTI_PR_PR6)
254 {
255 EXTI->PR = EXTI_PR_PR6;
256 EXTI6_IRQHandlerImpl();
257 }
258 else if (EXTI->PR & EXTI_PR_PR7)
259 {
260 EXTI->PR = EXTI_PR_PR7;
261 EXTI7_IRQHandlerImpl();
262 }
263 else if (EXTI->PR & EXTI_PR_PR8)
264 {
265 EXTI->PR = EXTI_PR_PR8;
266 EXTI8_IRQHandlerImpl();
267 }
268 else if (EXTI->PR & EXTI_PR_PR9)
269 {
270 EXTI->PR = EXTI_PR_PR9;
271 EXTI9_IRQHandlerImpl();
272 }
273 else
274 {
275#ifndef FLIGHT
277#endif
278 }
279}
280
281void __attribute__((used)) EXTI15_10_IRQHandlerImpl()
282{
283 if (EXTI->PR & EXTI_PR_PR10)
284 {
285 EXTI->PR = EXTI_PR_PR10; // Clear pending flag
286 EXTI10_IRQHandlerImpl();
287 }
288 else if (EXTI->PR & EXTI_PR_PR11)
289 {
290 EXTI->PR = EXTI_PR_PR11;
291 EXTI11_IRQHandlerImpl();
292 }
293 else if (EXTI->PR & EXTI_PR_PR12)
294 {
295 EXTI->PR = EXTI_PR_PR12;
296 EXTI12_IRQHandlerImpl();
297 }
298 else if (EXTI->PR & EXTI_PR_PR13)
299 {
300 EXTI->PR = EXTI_PR_PR13;
301 EXTI13_IRQHandlerImpl();
302 }
303 else if (EXTI->PR & EXTI_PR_PR14)
304 {
305 EXTI->PR = EXTI_PR_PR14;
306 EXTI14_IRQHandlerImpl();
307 }
308 else if (EXTI->PR & EXTI_PR_PR15)
309 {
310 EXTI->PR = EXTI_PR_PR15;
311 EXTI15_IRQHandlerImpl();
312 }
313 else
314 {
315#ifndef FLIGHT
317#endif
318 }
319}
320
321constexpr unsigned ConvertGPIO_BASEtoUnsigned(unsigned P)
322{
323 // clang-format off
324 return P == GPIOA_BASE? 0 :
325 P == GPIOB_BASE? 1 :
326 P == GPIOC_BASE? 2 :
327 P == GPIOD_BASE? 3 :
328 P == GPIOE_BASE? 4 :
329 P == GPIOF_BASE? 5 :
330 P == GPIOG_BASE? 6 :
331 P == GPIOH_BASE? 7 :
332 P == GPIOI_BASE? 8 :
333#if (defined (STM32F427xx) || defined (STM32F437xx) || defined (STM32F429xx) || defined (STM32F439xx))
334 P == GPIOJ_BASE? 9 :
335 P == GPIOK_BASE? 10 :
336#endif
337 0;
338 // clang-format on
339}
340
341constexpr unsigned GetEXTI_IRQn(unsigned N)
342{
343 // clang-format off
344
345 return N==0? EXTI0_IRQn :
346 N==1? EXTI1_IRQn :
347 N==2? EXTI2_IRQn :
348 N==3? EXTI3_IRQn :
349 N==4? EXTI4_IRQn :
350 (N>=5&&N<=9)? EXTI9_5_IRQn :
351 EXTI15_10_IRQn;
352
353 // clang-format on
354}
355
356constexpr unsigned GetEXTICR_register_value(unsigned P, unsigned N)
357{
358 return (ConvertGPIO_BASEtoUnsigned(P) << ((N % 4) * 4));
359}
360
361constexpr unsigned GetEXTICR_register_mask(unsigned P, unsigned N)
362{
363 return (0b1111 << ((N % 4) * 4));
364}
365
366void enableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum,
367 InterruptTrigger trigger, unsigned int priority)
368{
369 auto exticrRegValue = GetEXTICR_register_value(gpioPort, gpioNum);
370
371 {
372 FastInterruptDisableLock dLock;
373
374 RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
375 SYSCFG->EXTICR[int(gpioNum / 4)] |= exticrRegValue;
376 }
377
378 EXTI->IMR |= 1 << gpioNum;
379
380 if (trigger == InterruptTrigger::RISING_EDGE ||
382 {
383 EXTI->RTSR |= 1 << gpioNum;
384 }
385
386 if (trigger == InterruptTrigger::FALLING_EDGE ||
388 {
389 EXTI->FTSR |= 1 << gpioNum;
390 }
391
392 NVIC_EnableIRQ(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNum)));
393 NVIC_SetPriority(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNum)), priority);
394}
395
396void disableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum)
397{
398 EXTI->RTSR &= ~(1 << gpioNum);
399 EXTI->FTSR &= ~(1 << gpioNum);
400 EXTI->IMR &= ~(1 << gpioNum);
401
402 auto exticrRegMask = GetEXTICR_register_mask(gpioPort, gpioNum);
403
404 {
405 FastInterruptDisableLock dLock;
406
407 SYSCFG->EXTICR[int(gpioNum / 4)] &= ~exticrRegMask;
408 }
409}
410
411void changeInterruptTrigger(unsigned int gpioPort, unsigned int gpioNum,
412 InterruptTrigger trigger)
413{
414 switch (trigger)
415 {
417 EXTI->RTSR |= 1 << gpioNum;
418 EXTI->FTSR &= ~(1 << gpioNum);
419 break;
420
422 EXTI->RTSR &= ~(1 << gpioNum);
423 EXTI->FTSR |= 1 << gpioNum;
424 break;
425
427 EXTI->RTSR |= 1 << gpioNum;
428 EXTI->FTSR |= 1 << gpioNum;
429 break;
430 }
431}
constexpr unsigned GetEXTICR_register_mask(unsigned P, unsigned N)
void unexpectedInterrupt()
constexpr unsigned GetEXTICR_register_value(unsigned P, unsigned N)
void changeInterruptTrigger(unsigned int gpioPort, unsigned int gpioNum, InterruptTrigger trigger)
Changes interrupt trigger on an enabled interrupt.
void disableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum)
Disables external interrupts on the provided pin.
void __attribute__((weak)) EXTI0_IRQHandlerImpl()
constexpr unsigned ConvertGPIO_BASEtoUnsigned(unsigned P)
void Default_EXTI_Handler()
constexpr unsigned GetEXTI_IRQn(unsigned N)
void enableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum, InterruptTrigger trigger, unsigned int priority)
Enables external interrupts on the provided pin. Remember to set the GPIO to input mode!
InterruptTrigger