aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-01-21 18:17:28 +0100
committerGitHub <[email protected]>2021-01-21 18:17:28 +0100
commita44ab63341518dea8db538fc8194b29100db2543 (patch)
treee00457427d4b9fa4044668833d73fc06706d1370
parent57eabb372e750e0604c8d56a4d4e4ecd5ca3e853 (diff)
parent27cd3a03dc1cb88878b80088b637eec21dc3178f (diff)
Merge pull request #13 from xoviat/stm32-interrupt
Add EXTI interrupt handler for GPIO pins
-rw-r--r--embassy-stm32f4/src/exti.rs492
-rw-r--r--embassy-stm32f4/src/lib.rs1
2 files changed, 493 insertions, 0 deletions
diff --git a/embassy-stm32f4/src/exti.rs b/embassy-stm32f4/src/exti.rs
new file mode 100644
index 000000000..9b722374c
--- /dev/null
+++ b/embassy-stm32f4/src/exti.rs
@@ -0,0 +1,492 @@
1use core::future::Future;
2use core::mem;
3use core::pin::Pin;
4
5use embassy::gpio::{WaitForFallingEdge, WaitForRisingEdge};
6use embassy::interrupt::OwnedInterrupt;
7use embassy::util::InterruptFuture;
8
9use crate::hal::gpio;
10use crate::hal::gpio::{Edge, ExtiPin as HalExtiPin};
11use crate::hal::syscfg::SysCfg;
12use crate::pac::EXTI;
13
14use crate::interrupt;
15
16pub struct ExtiManager {
17 syscfg: SysCfg,
18}
19
20impl<'a> ExtiManager {
21 pub fn new(_exti: EXTI, syscfg: SysCfg) -> Self {
22 Self { syscfg: syscfg }
23 }
24
25 pub fn new_pin<T, I>(&'static mut self, mut pin: T, interrupt: I) -> ExtiPin<T, I>
26 where
27 T: HalExtiPin + WithInterrupt<Instance = I>,
28 I: OwnedInterrupt,
29 {
30 pin.make_interrupt_source(&mut self.syscfg);
31
32 ExtiPin {
33 pin: pin,
34 interrupt: interrupt,
35 _mgr: self,
36 }
37 }
38}
39
40pub struct ExtiPin<T: HalExtiPin, I: OwnedInterrupt> {
41 pin: T,
42 interrupt: I,
43 _mgr: &'static ExtiManager,
44}
45
46/*
47 Irq Handler Description
48 EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
49 EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
50 EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
51 EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
52 EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
53 EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
54 EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15
55*/
56
57impl<T: HalExtiPin + 'static, I: OwnedInterrupt + 'static> WaitForRisingEdge for ExtiPin<T, I> {
58 type Future<'a> = impl Future<Output = ()> + 'a;
59
60 fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
61 let s = unsafe { self.get_unchecked_mut() };
62
63 async move {
64 let fut = InterruptFuture::new(&mut s.interrupt);
65 s.pin.clear_interrupt_pending_bit();
66 let mut exti: EXTI = unsafe { mem::transmute(()) };
67
68 s.pin.trigger_on_edge(&mut exti, Edge::RISING);
69 s.pin.enable_interrupt(&mut exti);
70 fut.await;
71
72 s.pin.clear_interrupt_pending_bit();
73 }
74 }
75}
76
77impl<T: HalExtiPin + 'static, I: OwnedInterrupt + 'static> WaitForFallingEdge for ExtiPin<T, I> {
78 type Future<'a> = impl Future<Output = ()> + 'a;
79
80 fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
81 let s = unsafe { self.get_unchecked_mut() };
82
83 async move {
84 let fut = InterruptFuture::new(&mut s.interrupt);
85 s.pin.clear_interrupt_pending_bit();
86 let mut exti: EXTI = unsafe { mem::transmute(()) };
87
88 s.pin.trigger_on_edge(&mut exti, Edge::FALLING);
89 s.pin.enable_interrupt(&mut exti);
90 fut.await;
91
92 s.pin.clear_interrupt_pending_bit();
93 }
94 }
95}
96
97mod private {
98 pub trait Sealed {}
99}
100
101pub trait WithInterrupt: private::Sealed {
102 type Instance;
103}
104
105macro_rules! exti {
106 ($($PER:ident => ($set:ident, $pin:ident),)+) => {
107 $(
108 impl<T> private::Sealed for gpio::$set::$pin<T> {}
109 impl<T> WithInterrupt for gpio::$set::$pin<T> {
110 type Instance = interrupt::$PER;
111 }
112 )+
113 }
114}
115
116#[cfg(any(
117 feature = "stm32f401",
118 feature = "stm32f405",
119 feature = "stm32f407",
120 feature = "stm32f410",
121 feature = "stm32f411",
122 feature = "stm32f412",
123 feature = "stm32f413",
124 feature = "stm32f415",
125 feature = "stm32f417",
126 feature = "stm32f423",
127 feature = "stm32f427",
128 feature = "stm32f429",
129 feature = "stm32f437",
130 feature = "stm32f439",
131 feature = "stm32f446",
132 feature = "stm32f469",
133 feature = "stm32f479"
134))]
135exti! {
136 EXTI0Interrupt => (gpioa, PA0),
137 EXTI1Interrupt => (gpioa, PA1),
138 EXTI2Interrupt => (gpioa, PA2),
139 EXTI3Interrupt => (gpioa, PA3),
140 EXTI4Interrupt => (gpioa, PA4),
141 EXTI9_5Interrupt => (gpioa, PA5),
142 EXTI9_5Interrupt => (gpioa, PA6),
143 EXTI9_5Interrupt => (gpioa, PA7),
144 EXTI9_5Interrupt => (gpioa, PA8),
145 EXTI9_5Interrupt => (gpioa, PA9),
146 EXTI15_10Interrupt => (gpioa, PA10),
147 EXTI15_10Interrupt => (gpioa, PA11),
148 EXTI15_10Interrupt => (gpioa, PA12),
149 EXTI15_10Interrupt => (gpioa, PA13),
150 EXTI15_10Interrupt => (gpioa, PA14),
151 EXTI15_10Interrupt => (gpioa, PA15),
152}
153
154#[cfg(any(
155 feature = "stm32f401",
156 feature = "stm32f405",
157 feature = "stm32f407",
158 feature = "stm32f410",
159 feature = "stm32f411",
160 feature = "stm32f412",
161 feature = "stm32f413",
162 feature = "stm32f415",
163 feature = "stm32f417",
164 feature = "stm32f423",
165 feature = "stm32f427",
166 feature = "stm32f429",
167 feature = "stm32f437",
168 feature = "stm32f439",
169 feature = "stm32f446",
170 feature = "stm32f469",
171 feature = "stm32f479"
172))]
173exti! {
174 EXTI0Interrupt => (gpiob, PB0),
175 EXTI1Interrupt => (gpiob, PB1),
176 EXTI2Interrupt => (gpiob, PB2),
177 EXTI3Interrupt => (gpiob, PB3),
178 EXTI4Interrupt => (gpiob, PB4),
179 EXTI9_5Interrupt => (gpiob, PB5),
180 EXTI9_5Interrupt => (gpiob, PB6),
181 EXTI9_5Interrupt => (gpiob, PB7),
182 EXTI9_5Interrupt => (gpiob, PB8),
183 EXTI9_5Interrupt => (gpiob, PB9),
184 EXTI15_10Interrupt => (gpiob, PB10),
185 EXTI15_10Interrupt => (gpiob, PB11),
186 EXTI15_10Interrupt => (gpiob, PB12),
187 EXTI15_10Interrupt => (gpiob, PB13),
188 EXTI15_10Interrupt => (gpiob, PB14),
189 EXTI15_10Interrupt => (gpiob, PB15),
190}
191
192#[cfg(any(
193 feature = "stm32f401",
194 feature = "stm32f405",
195 feature = "stm32f407",
196 feature = "stm32f410",
197 feature = "stm32f411",
198 feature = "stm32f412",
199 feature = "stm32f413",
200 feature = "stm32f415",
201 feature = "stm32f417",
202 feature = "stm32f423",
203 feature = "stm32f427",
204 feature = "stm32f429",
205 feature = "stm32f437",
206 feature = "stm32f439",
207 feature = "stm32f446",
208 feature = "stm32f469",
209 feature = "stm32f479"
210))]
211exti! {
212 EXTI0Interrupt => (gpioc, PC0),
213 EXTI1Interrupt => (gpioc, PC1),
214 EXTI2Interrupt => (gpioc, PC2),
215 EXTI3Interrupt => (gpioc, PC3),
216 EXTI4Interrupt => (gpioc, PC4),
217 EXTI9_5Interrupt => (gpioc, PC5),
218 EXTI9_5Interrupt => (gpioc, PC6),
219 EXTI9_5Interrupt => (gpioc, PC7),
220 EXTI9_5Interrupt => (gpioc, PC8),
221 EXTI9_5Interrupt => (gpioc, PC9),
222 EXTI15_10Interrupt => (gpioc, PC10),
223 EXTI15_10Interrupt => (gpioc, PC11),
224 EXTI15_10Interrupt => (gpioc, PC12),
225 EXTI15_10Interrupt => (gpioc, PC13),
226 EXTI15_10Interrupt => (gpioc, PC14),
227 EXTI15_10Interrupt => (gpioc, PC15),
228}
229
230#[cfg(any(
231 feature = "stm32f401",
232 feature = "stm32f405",
233 feature = "stm32f407",
234 feature = "stm32f411",
235 feature = "stm32f412",
236 feature = "stm32f413",
237 feature = "stm32f415",
238 feature = "stm32f417",
239 feature = "stm32f423",
240 feature = "stm32f427",
241 feature = "stm32f429",
242 feature = "stm32f437",
243 feature = "stm32f439",
244 feature = "stm32f446",
245 feature = "stm32f469",
246 feature = "stm32f479"
247))]
248exti! {
249 EXTI0Interrupt => (gpiod, PD0),
250 EXTI1Interrupt => (gpiod, PD1),
251 EXTI2Interrupt => (gpiod, PD2),
252 EXTI3Interrupt => (gpiod, PD3),
253 EXTI4Interrupt => (gpiod, PD4),
254 EXTI9_5Interrupt => (gpiod, PD5),
255 EXTI9_5Interrupt => (gpiod, PD6),
256 EXTI9_5Interrupt => (gpiod, PD7),
257 EXTI9_5Interrupt => (gpiod, PD8),
258 EXTI9_5Interrupt => (gpiod, PD9),
259 EXTI15_10Interrupt => (gpiod, PD10),
260 EXTI15_10Interrupt => (gpiod, PD11),
261 EXTI15_10Interrupt => (gpiod, PD12),
262 EXTI15_10Interrupt => (gpiod, PD13),
263 EXTI15_10Interrupt => (gpiod, PD14),
264 EXTI15_10Interrupt => (gpiod, PD15),
265}
266
267#[cfg(any(
268 feature = "stm32f401",
269 feature = "stm32f405",
270 feature = "stm32f407",
271 feature = "stm32f411",
272 feature = "stm32f412",
273 feature = "stm32f413",
274 feature = "stm32f415",
275 feature = "stm32f417",
276 feature = "stm32f423",
277 feature = "stm32f427",
278 feature = "stm32f429",
279 feature = "stm32f437",
280 feature = "stm32f439",
281 feature = "stm32f446",
282 feature = "stm32f469",
283 feature = "stm32f479"
284))]
285exti! {
286 EXTI0Interrupt => (gpioe, PE0),
287 EXTI1Interrupt => (gpioe, PE1),
288 EXTI2Interrupt => (gpioe, PE2),
289 EXTI3Interrupt => (gpioe, PE3),
290 EXTI4Interrupt => (gpioe, PE4),
291 EXTI9_5Interrupt => (gpioe, PE5),
292 EXTI9_5Interrupt => (gpioe, PE6),
293 EXTI9_5Interrupt => (gpioe, PE7),
294 EXTI9_5Interrupt => (gpioe, PE8),
295 EXTI9_5Interrupt => (gpioe, PE9),
296 EXTI15_10Interrupt => (gpioe, PE10),
297 EXTI15_10Interrupt => (gpioe, PE11),
298 EXTI15_10Interrupt => (gpioe, PE12),
299 EXTI15_10Interrupt => (gpioe, PE13),
300 EXTI15_10Interrupt => (gpioe, PE14),
301 EXTI15_10Interrupt => (gpioe, PE15),
302}
303
304#[cfg(any(
305 feature = "stm32f405",
306 feature = "stm32f407",
307 feature = "stm32f412",
308 feature = "stm32f413",
309 feature = "stm32f415",
310 feature = "stm32f417",
311 feature = "stm32f423",
312 feature = "stm32f427",
313 feature = "stm32f429",
314 feature = "stm32f437",
315 feature = "stm32f439",
316 feature = "stm32f446",
317 feature = "stm32f469",
318 feature = "stm32f479"
319))]
320exti! {
321 EXTI0Interrupt => (gpiof, PF0),
322 EXTI1Interrupt => (gpiof, PF1),
323 EXTI2Interrupt => (gpiof, PF2),
324 EXTI3Interrupt => (gpiof, PF3),
325 EXTI4Interrupt => (gpiof, PF4),
326 EXTI9_5Interrupt => (gpiof, PF5),
327 EXTI9_5Interrupt => (gpiof, PF6),
328 EXTI9_5Interrupt => (gpiof, PF7),
329 EXTI9_5Interrupt => (gpiof, PF8),
330 EXTI9_5Interrupt => (gpiof, PF9),
331 EXTI15_10Interrupt => (gpiof, PF10),
332 EXTI15_10Interrupt => (gpiof, PF11),
333 EXTI15_10Interrupt => (gpiof, PF12),
334 EXTI15_10Interrupt => (gpiof, PF13),
335 EXTI15_10Interrupt => (gpiof, PF14),
336 EXTI15_10Interrupt => (gpiof, PF15),
337}
338
339#[cfg(any(
340 feature = "stm32f405",
341 feature = "stm32f407",
342 feature = "stm32f412",
343 feature = "stm32f413",
344 feature = "stm32f415",
345 feature = "stm32f417",
346 feature = "stm32f423",
347 feature = "stm32f427",
348 feature = "stm32f429",
349 feature = "stm32f437",
350 feature = "stm32f439",
351 feature = "stm32f446",
352 feature = "stm32f469",
353 feature = "stm32f479"
354))]
355exti! {
356 EXTI0Interrupt => (gpiog, PG0),
357 EXTI1Interrupt => (gpiog, PG1),
358 EXTI2Interrupt => (gpiog, PG2),
359 EXTI3Interrupt => (gpiog, PG3),
360 EXTI4Interrupt => (gpiog, PG4),
361 EXTI9_5Interrupt => (gpiog, PG5),
362 EXTI9_5Interrupt => (gpiog, PG6),
363 EXTI9_5Interrupt => (gpiog, PG7),
364 EXTI9_5Interrupt => (gpiog, PG8),
365 EXTI9_5Interrupt => (gpiog, PG9),
366 EXTI15_10Interrupt => (gpiog, PG10),
367 EXTI15_10Interrupt => (gpiog, PG11),
368 EXTI15_10Interrupt => (gpiog, PG12),
369 EXTI15_10Interrupt => (gpiog, PG13),
370 EXTI15_10Interrupt => (gpiog, PG14),
371 EXTI15_10Interrupt => (gpiog, PG15),
372}
373
374#[cfg(any(
375 feature = "stm32f405",
376 feature = "stm32f407",
377 feature = "stm32f410",
378 feature = "stm32f411",
379 feature = "stm32f412",
380 feature = "stm32f413",
381 feature = "stm32f415",
382 feature = "stm32f417",
383 feature = "stm32f423",
384 feature = "stm32f427",
385 feature = "stm32f429",
386 feature = "stm32f437",
387 feature = "stm32f439",
388 feature = "stm32f446",
389 feature = "stm32f469",
390 feature = "stm32f479"
391))]
392exti! {
393 EXTI0Interrupt => (gpioh, PH0),
394 EXTI1Interrupt => (gpioh, PH1),
395 EXTI2Interrupt => (gpioh, PH2),
396 EXTI3Interrupt => (gpioh, PH3),
397 EXTI4Interrupt => (gpioh, PH4),
398 EXTI9_5Interrupt => (gpioh, PH5),
399 EXTI9_5Interrupt => (gpioh, PH6),
400 EXTI9_5Interrupt => (gpioh, PH7),
401 EXTI9_5Interrupt => (gpioh, PH8),
402 EXTI9_5Interrupt => (gpioh, PH9),
403 EXTI15_10Interrupt => (gpioh, PH10),
404 EXTI15_10Interrupt => (gpioh, PH11),
405 EXTI15_10Interrupt => (gpioh, PH12),
406 EXTI15_10Interrupt => (gpioh, PH13),
407 EXTI15_10Interrupt => (gpioh, PH14),
408 EXTI15_10Interrupt => (gpioh, PH15),
409}
410
411#[cfg(any(feature = "stm32f401"))]
412exti! {
413 EXTI0Interrupt => (gpioh, PH0),
414 EXTI1Interrupt => (gpioh, PH1),
415}
416
417#[cfg(any(
418 feature = "stm32f405",
419 feature = "stm32f407",
420 feature = "stm32f415",
421 feature = "stm32f417",
422 feature = "stm32f427",
423 feature = "stm32f429",
424 feature = "stm32f437",
425 feature = "stm32f439",
426 feature = "stm32f469",
427 feature = "stm32f479"
428))]
429exti! {
430 EXTI0Interrupt => (gpioi, PI0),
431 EXTI1Interrupt => (gpioi, PI1),
432 EXTI2Interrupt => (gpioi, PI2),
433 EXTI3Interrupt => (gpioi, PI3),
434 EXTI4Interrupt => (gpioi, PI4),
435 EXTI9_5Interrupt => (gpioi, PI5),
436 EXTI9_5Interrupt => (gpioi, PI6),
437 EXTI9_5Interrupt => (gpioi, PI7),
438 EXTI9_5Interrupt => (gpioi, PI8),
439 EXTI9_5Interrupt => (gpioi, PI9),
440 EXTI15_10Interrupt => (gpioi, PI10),
441 EXTI15_10Interrupt => (gpioi, PI11),
442 EXTI15_10Interrupt => (gpioi, PI12),
443 EXTI15_10Interrupt => (gpioi, PI13),
444 EXTI15_10Interrupt => (gpioi, PI14),
445 EXTI15_10Interrupt => (gpioi, PI15),
446}
447
448#[cfg(any(
449 feature = "stm32f427",
450 feature = "stm32f429",
451 feature = "stm32f437",
452 feature = "stm32f439",
453 feature = "stm32f469",
454 feature = "stm32f479"
455))]
456exti! {
457 EXTI0Interrupt => (gpioj, PJ0),
458 EXTI1Interrupt => (gpioj, PJ1),
459 EXTI2Interrupt => (gpioj, PJ2),
460 EXTI3Interrupt => (gpioj, PJ3),
461 EXTI4Interrupt => (gpioj, PJ4),
462 EXTI9_5Interrupt => (gpioj, PJ5),
463 EXTI9_5Interrupt => (gpioj, PJ6),
464 EXTI9_5Interrupt => (gpioj, PJ7),
465 EXTI9_5Interrupt => (gpioj, PJ8),
466 EXTI9_5Interrupt => (gpioj, PJ9),
467 EXTI15_10Interrupt => (gpioj, PJ10),
468 EXTI15_10Interrupt => (gpioj, PJ11),
469 EXTI15_10Interrupt => (gpioj, PJ12),
470 EXTI15_10Interrupt => (gpioj, PJ13),
471 EXTI15_10Interrupt => (gpioj, PJ14),
472 EXTI15_10Interrupt => (gpioj, PJ15),
473}
474
475#[cfg(any(
476 feature = "stm32f427",
477 feature = "stm32f429",
478 feature = "stm32f437",
479 feature = "stm32f439",
480 feature = "stm32f469",
481 feature = "stm32f479"
482))]
483exti! {
484 EXTI0Interrupt => (gpiok, PK0),
485 EXTI1Interrupt => (gpiok, PK1),
486 EXTI2Interrupt => (gpiok, PK2),
487 EXTI3Interrupt => (gpiok, PK3),
488 EXTI4Interrupt => (gpiok, PK4),
489 EXTI9_5Interrupt => (gpiok, PK5),
490 EXTI9_5Interrupt => (gpiok, PK6),
491 EXTI9_5Interrupt => (gpiok, PK7),
492}
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs
index 0f4a70bba..57b9db965 100644
--- a/embassy-stm32f4/src/lib.rs
+++ b/embassy-stm32f4/src/lib.rs
@@ -311,6 +311,7 @@ pub use stm32f4xx_hal::stm32 as pac;
311// This mod MUST go first, so that the others see its macros. 311// This mod MUST go first, so that the others see its macros.
312pub(crate) mod fmt; 312pub(crate) mod fmt;
313 313
314pub mod exti;
314pub mod interrupt; 315pub mod interrupt;
315pub mod serial; 316pub mod serial;
316 317