aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/exti.rs (renamed from embassy-stm32f4/src/exti.rs)342
-rw-r--r--embassy-stm32/src/lib.rs1
-rw-r--r--embassy-stm32f4/src/lib.rs3
-rw-r--r--embassy-stm32l0/src/exti.rs268
-rw-r--r--embassy-stm32l0/src/lib.rs4
5 files changed, 295 insertions, 323 deletions
diff --git a/embassy-stm32f4/src/exti.rs b/embassy-stm32/src/exti.rs
index 154ca45c1..a00079450 100644
--- a/embassy-stm32f4/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -3,35 +3,33 @@ use core::mem;
3use core::pin::Pin; 3use core::pin::Pin;
4use cortex_m; 4use cortex_m;
5 5
6use embassy::traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; 6use crate::hal::gpio;
7
8use embassy::traits::gpio::{
9 WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
10};
7use embassy::util::InterruptFuture; 11use embassy::util::InterruptFuture;
8 12
9use crate::hal::gpio;
10use crate::hal::gpio::Edge;
11use crate::hal::syscfg::SysCfg;
12use crate::pac::EXTI;
13use embedded_hal::digital::v2 as digital; 13use embedded_hal::digital::v2 as digital;
14 14
15use crate::interrupt; 15use crate::interrupt;
16 16
17pub struct ExtiPin<T: gpio::ExtiPin + WithInterrupt> { 17pub struct ExtiPin<T: Instance> {
18 pin: T, 18 pin: T,
19 interrupt: T::Interrupt, 19 interrupt: T::Interrupt,
20} 20}
21 21
22impl<T: gpio::ExtiPin + WithInterrupt> ExtiPin<T> { 22impl<T: Instance> ExtiPin<T> {
23 pub fn new(mut pin: T, interrupt: T::Interrupt) -> Self { 23 pub fn new(mut pin: T, interrupt: T::Interrupt) -> Self {
24 let mut syscfg: SysCfg = unsafe { mem::transmute(()) };
25
26 cortex_m::interrupt::free(|_| { 24 cortex_m::interrupt::free(|_| {
27 pin.make_interrupt_source(&mut syscfg); 25 pin.make_source();
28 }); 26 });
29 27
30 Self { pin, interrupt } 28 Self { pin, interrupt }
31 } 29 }
32} 30}
33 31
34impl<T: gpio::ExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin for ExtiPin<T> { 32impl<T: Instance + digital::OutputPin> digital::OutputPin for ExtiPin<T> {
35 type Error = T::Error; 33 type Error = T::Error;
36 34
37 fn set_low(&mut self) -> Result<(), Self::Error> { 35 fn set_low(&mut self) -> Result<(), Self::Error> {
@@ -43,9 +41,7 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin f
43 } 41 }
44} 42}
45 43
46impl<T: gpio::ExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::StatefulOutputPin 44impl<T: Instance + digital::StatefulOutputPin> digital::StatefulOutputPin for ExtiPin<T> {
47 for ExtiPin<T>
48{
49 fn is_set_low(&self) -> Result<bool, Self::Error> { 45 fn is_set_low(&self) -> Result<bool, Self::Error> {
50 self.pin.is_set_low() 46 self.pin.is_set_low()
51 } 47 }
@@ -55,9 +51,7 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::Sta
55 } 51 }
56} 52}
57 53
58impl<T: gpio::ExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::ToggleableOutputPin 54impl<T: Instance + digital::ToggleableOutputPin> digital::ToggleableOutputPin for ExtiPin<T> {
59 for ExtiPin<T>
60{
61 type Error = T::Error; 55 type Error = T::Error;
62 56
63 fn toggle(&mut self) -> Result<(), Self::Error> { 57 fn toggle(&mut self) -> Result<(), Self::Error> {
@@ -65,7 +59,7 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::T
65 } 59 }
66} 60}
67 61
68impl<T: gpio::ExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for ExtiPin<T> { 62impl<T: Instance + digital::InputPin> digital::InputPin for ExtiPin<T> {
69 type Error = T::Error; 63 type Error = T::Error;
70 64
71 fn is_high(&self) -> Result<bool, Self::Error> { 65 fn is_high(&self) -> Result<bool, Self::Error> {
@@ -77,71 +71,129 @@ impl<T: gpio::ExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for
77 } 71 }
78} 72}
79 73
80/* 74impl<T: Instance + digital::InputPin + 'static> ExtiPin<T> {
81 Irq Handler Description 75 fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future<Output = ()> + 'a {
82 EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
83 EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
84 EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
85 EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
86 EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
87 EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
88 EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15
89*/
90
91impl<T: gpio::ExtiPin + WithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> {
92 type Future<'a> = impl Future<Output = ()> + 'a;
93
94 fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
95 let s = unsafe { self.get_unchecked_mut() }; 76 let s = unsafe { self.get_unchecked_mut() };
96 77
97 s.pin.clear_interrupt_pending_bit(); 78 s.pin.clear_pending_bit();
98 async move { 79 async move {
99 let fut = InterruptFuture::new(&mut s.interrupt); 80 let fut = InterruptFuture::new(&mut s.interrupt);
100 let pin = &mut s.pin; 81 let pin = &mut s.pin;
101 cortex_m::interrupt::free(|_| { 82 cortex_m::interrupt::free(|_| {
102 let mut exti: EXTI = unsafe { mem::transmute(()) }; 83 pin.trigger_edge(if state {
103 84 EdgeOption::Rising
104 pin.trigger_on_edge(&mut exti, Edge::RISING); 85 } else {
105 pin.enable_interrupt(&mut exti); 86 EdgeOption::Falling
87 });
106 }); 88 });
89
90 if (state && s.pin.is_high().unwrap_or(false))
91 || (!state && s.pin.is_low().unwrap_or(false))
92 {
93 return;
94 }
95
107 fut.await; 96 fut.await;
108 97
109 s.pin.clear_interrupt_pending_bit(); 98 s.pin.clear_pending_bit();
110 } 99 }
111 } 100 }
112} 101}
113 102
114impl<T: gpio::ExtiPin + WithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T> { 103impl<T: Instance + 'static> ExtiPin<T> {
115 type Future<'a> = impl Future<Output = ()> + 'a; 104 fn wait_for_edge<'a>(
116 105 self: Pin<&'a mut Self>,
117 fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { 106 state: EdgeOption,
107 ) -> impl Future<Output = ()> + 'a {
118 let s = unsafe { self.get_unchecked_mut() }; 108 let s = unsafe { self.get_unchecked_mut() };
119 109
120 s.pin.clear_interrupt_pending_bit(); 110 s.pin.clear_pending_bit();
121 async move { 111 async move {
122 let fut = InterruptFuture::new(&mut s.interrupt); 112 let fut = InterruptFuture::new(&mut s.interrupt);
123 let pin = &mut s.pin; 113 let pin = &mut s.pin;
124 cortex_m::interrupt::free(|_| { 114 cortex_m::interrupt::free(|_| {
125 let mut exti: EXTI = unsafe { mem::transmute(()) }; 115 pin.trigger_edge(state);
126
127 pin.trigger_on_edge(&mut exti, Edge::FALLING);
128 pin.enable_interrupt(&mut exti);
129 }); 116 });
117
130 fut.await; 118 fut.await;
131 119
132 s.pin.clear_interrupt_pending_bit(); 120 s.pin.clear_pending_bit();
133 } 121 }
134 } 122 }
135} 123}
136 124
125impl<T: Instance + digital::InputPin + 'static> WaitForHigh for ExtiPin<T> {
126 type Future<'a> = impl Future<Output = ()> + 'a;
127
128 fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
129 self.wait_for_state(true)
130 }
131}
132
133impl<T: Instance + digital::InputPin + 'static> WaitForLow for ExtiPin<T> {
134 type Future<'a> = impl Future<Output = ()> + 'a;
135
136 fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
137 self.wait_for_state(false)
138 }
139}
140
141/*
142 Irq Handler Description
143 EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
144 EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
145 EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
146 EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
147 EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
148 EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
149 EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15
150*/
151
152impl<T: Instance + 'static> WaitForRisingEdge for ExtiPin<T> {
153 type Future<'a> = impl Future<Output = ()> + 'a;
154
155 fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
156 self.wait_for_edge(EdgeOption::Rising)
157 }
158}
159
160impl<T: Instance + 'static> WaitForFallingEdge for ExtiPin<T> {
161 type Future<'a> = impl Future<Output = ()> + 'a;
162
163 fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
164 self.wait_for_edge(EdgeOption::Falling)
165 }
166}
167
168impl<T: Instance + 'static> WaitForAnyEdge for ExtiPin<T> {
169 type Future<'a> = impl Future<Output = ()> + 'a;
170
171 fn wait_for_any_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
172 self.wait_for_edge(EdgeOption::RisingFalling)
173 }
174}
175
137mod private { 176mod private {
138 pub trait Sealed {} 177 pub trait Sealed {}
139} 178}
140 179
180#[derive(Copy, Clone)]
181pub enum EdgeOption {
182 Rising,
183 Falling,
184 RisingFalling,
185}
186
141pub trait WithInterrupt: private::Sealed { 187pub trait WithInterrupt: private::Sealed {
142 type Interrupt: interrupt::Interrupt; 188 type Interrupt: interrupt::Interrupt;
143} 189}
144 190
191pub trait Instance: WithInterrupt {
192 fn make_source(&mut self);
193 fn clear_pending_bit(&mut self);
194 fn trigger_edge(&mut self, edge: EdgeOption);
195}
196
145macro_rules! exti { 197macro_rules! exti {
146 ($set:ident, [ 198 ($set:ident, [
147 $($INT:ident => $pin:ident,)+ 199 $($INT:ident => $pin:ident,)+
@@ -151,8 +203,90 @@ macro_rules! exti {
151 impl<T> WithInterrupt for gpio::$set::$pin<T> { 203 impl<T> WithInterrupt for gpio::$set::$pin<T> {
152 type Interrupt = interrupt::$INT; 204 type Interrupt = interrupt::$INT;
153 } 205 }
154 )+
155 206
207 #[cfg(any(
208 feature = "stm32f401",
209 feature = "stm32f405",
210 feature = "stm32f407",
211 feature = "stm32f410",
212 feature = "stm32f411",
213 feature = "stm32f412",
214 feature = "stm32f413",
215 feature = "stm32f415",
216 feature = "stm32f417",
217 feature = "stm32f423",
218 feature = "stm32f427",
219 feature = "stm32f429",
220 feature = "stm32f437",
221 feature = "stm32f439",
222 feature = "stm32f446",
223 feature = "stm32f469",
224 feature = "stm32f479",
225 ))]
226 impl<T> Instance for gpio::$set::$pin<gpio::Input<T>> {
227 fn make_source(&mut self) {
228 use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg};
229 use crate::pac::EXTI;
230 let mut syscfg: SysCfg = unsafe { mem::transmute(()) };
231 self.make_interrupt_source(&mut syscfg);
232 }
233
234 fn clear_pending_bit(&mut self) {
235 use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg};
236
237 self.clear_interrupt_pending_bit();
238 }
239
240 fn trigger_edge(&mut self, edge: EdgeOption) {
241 use crate::hal::{gpio::Edge, gpio::ExtiPin, syscfg::SysCfg};
242 use crate::pac::EXTI;
243 let mut exti: EXTI = unsafe { mem::transmute(()) };
244 let edge = match edge {
245 EdgeOption::Falling => Edge::FALLING,
246 EdgeOption::Rising => Edge::RISING,
247 EdgeOption::RisingFalling => Edge::RISING_FALLING,
248 };
249 self.trigger_on_edge(&mut exti, edge);
250 self.enable_interrupt(&mut exti);
251 }
252 }
253
254 #[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
255 impl<T> Instance for gpio::$set::$pin<T> {
256 fn make_source(&mut self) {}
257
258 fn clear_pending_bit(&mut self) {
259 use crate::hal::{
260 exti::{Exti, ExtiLine, GpioLine, TriggerEdge},
261 syscfg::SYSCFG,
262 };
263
264 Exti::unpend(GpioLine::from_raw_line(self.pin_number()).unwrap());
265 }
266
267 fn trigger_edge(&mut self, edge: EdgeOption) {
268 use crate::hal::{
269 exti::{Exti, ExtiLine, GpioLine, TriggerEdge},
270 syscfg::SYSCFG,
271 };
272
273 use crate::pac::EXTI;
274
275 let edge = match edge {
276 EdgeOption::Falling => TriggerEdge::Falling,
277 EdgeOption::Rising => TriggerEdge::Rising,
278 EdgeOption::RisingFalling => TriggerEdge::Both,
279 };
280
281 let exti: EXTI = unsafe { mem::transmute(()) };
282 let mut exti = Exti::new(exti);
283 let port = self.port();
284 let mut syscfg: SYSCFG = unsafe { mem::transmute(()) };
285 let line = GpioLine::from_raw_line(self.pin_number()).unwrap();
286 exti.listen_gpio(&mut syscfg, port, line, edge);
287 }
288 }
289 )+
156 }; 290 };
157} 291}
158 292
@@ -533,3 +667,111 @@ exti!(gpiok, [
533 EXTI9_5 => PK6, 667 EXTI9_5 => PK6,
534 EXTI9_5 => PK7, 668 EXTI9_5 => PK7,
535]); 669]);
670
671#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
672exti!(gpioa, [
673 EXTI0_1 => PA0,
674 EXTI0_1 => PA1,
675 EXTI2_3 => PA2,
676 EXTI2_3 => PA3,
677 EXTI4_15 => PA4,
678 EXTI4_15 => PA5,
679 EXTI4_15 => PA6,
680 EXTI4_15 => PA7,
681 EXTI4_15 => PA8,
682 EXTI4_15 => PA9,
683 EXTI4_15 => PA10,
684 EXTI4_15 => PA11,
685 EXTI4_15 => PA12,
686 EXTI4_15 => PA13,
687 EXTI4_15 => PA14,
688 EXTI4_15 => PA15,
689]);
690
691#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
692exti!(gpiob, [
693 EXTI0_1 => PB0,
694 EXTI0_1 => PB1,
695 EXTI2_3 => PB2,
696 EXTI2_3 => PB3,
697 EXTI4_15 => PB4,
698 EXTI4_15 => PB5,
699 EXTI4_15 => PB6,
700 EXTI4_15 => PB7,
701 EXTI4_15 => PB8,
702 EXTI4_15 => PB9,
703 EXTI4_15 => PB10,
704 EXTI4_15 => PB11,
705 EXTI4_15 => PB12,
706 EXTI4_15 => PB13,
707 EXTI4_15 => PB14,
708 EXTI4_15 => PB15,
709]);
710
711#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
712exti!(gpioc, [
713 EXTI0_1 => PC0,
714 EXTI0_1 => PC1,
715 EXTI2_3 => PC2,
716 EXTI2_3 => PC3,
717 EXTI4_15 => PC4,
718 EXTI4_15 => PC5,
719 EXTI4_15 => PC6,
720 EXTI4_15 => PC7,
721 EXTI4_15 => PC8,
722 EXTI4_15 => PC9,
723 EXTI4_15 => PC10,
724 EXTI4_15 => PC11,
725 EXTI4_15 => PC12,
726 EXTI4_15 => PC13,
727 EXTI4_15 => PC14,
728 EXTI4_15 => PC15,
729]);
730
731#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
732exti!(gpiod, [
733 EXTI0_1 => PD0,
734 EXTI0_1 => PD1,
735 EXTI2_3 => PD2,
736 EXTI2_3 => PD3,
737 EXTI4_15 => PD4,
738 EXTI4_15 => PD5,
739 EXTI4_15 => PD6,
740 EXTI4_15 => PD7,
741 EXTI4_15 => PD8,
742 EXTI4_15 => PD9,
743 EXTI4_15 => PD10,
744 EXTI4_15 => PD11,
745 EXTI4_15 => PD12,
746 EXTI4_15 => PD13,
747 EXTI4_15 => PD14,
748 EXTI4_15 => PD15,
749]);
750
751#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
752exti!(gpioe, [
753 EXTI0_1 => PE0,
754 EXTI0_1 => PE1,
755 EXTI2_3 => PE2,
756 EXTI2_3 => PE3,
757 EXTI4_15 => PE4,
758 EXTI4_15 => PE5,
759 EXTI4_15 => PE6,
760 EXTI4_15 => PE7,
761 EXTI4_15 => PE8,
762 EXTI4_15 => PE9,
763 EXTI4_15 => PE10,
764 EXTI4_15 => PE11,
765 EXTI4_15 => PE12,
766 EXTI4_15 => PE13,
767 EXTI4_15 => PE14,
768 EXTI4_15 => PE15,
769]);
770
771#[cfg(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",))]
772exti!(gpioh, [
773 EXTI0_1 => PH0,
774 EXTI0_1 => PH1,
775 EXTI4_15 => PH9,
776 EXTI4_15 => PH10,
777]);
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index a1f40b2c7..954067f32 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -32,4 +32,5 @@ pub use {stm32l0xx_hal as hal, stm32l0xx_hal::pac};
32 32
33pub mod fmt; 33pub mod fmt;
34 34
35pub mod exti;
35pub mod interrupt; 36pub mod interrupt;
diff --git a/embassy-stm32f4/src/lib.rs b/embassy-stm32f4/src/lib.rs
index 0d490525c..bdd4d0fda 100644
--- a/embassy-stm32f4/src/lib.rs
+++ b/embassy-stm32f4/src/lib.rs
@@ -307,11 +307,10 @@ compile_error!(
307 "Multile chip features activated. You must activate exactly one of the following features: " 307 "Multile chip features activated. You must activate exactly one of the following features: "
308); 308);
309 309
310pub use embassy_stm32::{fmt, hal, interrupt, pac}; 310pub use embassy_stm32::{exti, fmt, hal, interrupt, pac};
311 311
312#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",)))] 312#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",)))]
313pub mod can; 313pub mod can;
314pub mod exti;
315#[cfg(not(feature = "stm32f410"))] 314#[cfg(not(feature = "stm32f410"))]
316pub mod qei; 315pub mod qei;
317pub mod rtc; 316pub mod rtc;
diff --git a/embassy-stm32l0/src/exti.rs b/embassy-stm32l0/src/exti.rs
deleted file mode 100644
index f50c3ae8e..000000000
--- a/embassy-stm32l0/src/exti.rs
+++ /dev/null
@@ -1,268 +0,0 @@
1use core::future::Future;
2use core::mem;
3use core::pin::Pin;
4
5use embassy::traits::gpio::{
6 WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
7};
8use embassy::util::InterruptFuture;
9
10use crate::hal::{
11 exti::{Exti, ExtiLine, GpioLine, TriggerEdge},
12 gpio,
13 syscfg::SYSCFG,
14};
15use crate::interrupt;
16use crate::pac::EXTI;
17use embedded_hal::digital::v2::InputPin;
18
19pub struct ExtiPin<T: PinWithInterrupt> {
20 pin: T,
21 interrupt: T::Interrupt,
22}
23
24impl<T: PinWithInterrupt + 'static> ExtiPin<T> {
25 pub fn new(pin: T, interrupt: T::Interrupt) -> ExtiPin<T> {
26 ExtiPin { pin, interrupt }
27 }
28
29 fn wait_for_edge<'a>(
30 self: Pin<&'a mut Self>,
31 edge: TriggerEdge,
32 ) -> impl Future<Output = ()> + 'a {
33 let line = self.pin.line();
34 let s = unsafe { self.get_unchecked_mut() };
35
36 Exti::unpend(line);
37
38 async move {
39 let exti: EXTI = unsafe { mem::transmute(()) };
40 let mut exti = Exti::new(exti);
41
42 let fut = InterruptFuture::new(&mut s.interrupt);
43
44 let port = s.pin.port();
45 cortex_m::interrupt::free(|_| {
46 let mut syscfg: SYSCFG = unsafe { mem::transmute(()) };
47 exti.listen_gpio(&mut syscfg, port, line, edge);
48 });
49
50 fut.await;
51
52 Exti::unpend(line);
53 }
54 }
55}
56
57impl<T: InputPin + PinWithInterrupt + 'static> ExtiPin<T> {
58 fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future<Output = ()> + 'a {
59 let line = self.pin.line();
60 let s = unsafe { self.get_unchecked_mut() };
61
62 Exti::unpend(line);
63
64 async move {
65 let exti: EXTI = unsafe { mem::transmute(()) };
66 let mut exti = Exti::new(exti);
67
68 let fut = InterruptFuture::new(&mut s.interrupt);
69
70 let port = s.pin.port();
71 cortex_m::interrupt::free(|_| {
72 let mut syscfg: SYSCFG = unsafe { mem::transmute(()) };
73 let edge = if state {
74 TriggerEdge::Rising
75 } else {
76 TriggerEdge::Falling
77 };
78 exti.listen_gpio(&mut syscfg, port, line, edge);
79 });
80
81 let pin_has_state = if state {
82 s.pin.is_high()
83 } else {
84 s.pin.is_low()
85 }
86 .unwrap_or(false);
87 if pin_has_state {
88 return ();
89 }
90
91 fut.await;
92
93 Exti::unpend(line);
94 }
95 }
96}
97
98impl<T: PinWithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> {
99 type Future<'a> = impl Future<Output = ()> + 'a;
100
101 fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
102 self.wait_for_edge(TriggerEdge::Rising)
103 }
104}
105
106impl<T: PinWithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T> {
107 type Future<'a> = impl Future<Output = ()> + 'a;
108
109 fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
110 self.wait_for_edge(TriggerEdge::Falling)
111 }
112}
113
114impl<T: PinWithInterrupt + 'static> WaitForAnyEdge for ExtiPin<T> {
115 type Future<'a> = impl Future<Output = ()> + 'a;
116
117 fn wait_for_any_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
118 self.wait_for_edge(TriggerEdge::Both)
119 }
120}
121
122impl<T: InputPin + PinWithInterrupt + 'static> WaitForHigh for ExtiPin<T> {
123 type Future<'a> = impl Future<Output = ()> + 'a;
124
125 fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
126 self.wait_for_state(true)
127 }
128}
129
130impl<T: InputPin + PinWithInterrupt + 'static> WaitForLow for ExtiPin<T> {
131 type Future<'a> = impl Future<Output = ()> + 'a;
132
133 fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
134 self.wait_for_state(false)
135 }
136}
137
138mod private {
139 pub trait Sealed {}
140}
141
142pub trait PinWithInterrupt: private::Sealed {
143 type Interrupt: interrupt::Interrupt;
144 fn port(&self) -> gpio::Port;
145 fn line(&self) -> GpioLine;
146}
147
148macro_rules! exti {
149 ($set:ident, [
150 $($INT:ident => $pin:ident,)+
151 ]) => {
152 $(
153 impl<T> private::Sealed for gpio::$set::$pin<T> {}
154 impl<T> PinWithInterrupt for gpio::$set::$pin<T> {
155 type Interrupt = interrupt::$INT;
156 fn port(&self) -> gpio::Port {
157 self.port()
158 }
159 fn line(&self) -> GpioLine {
160 GpioLine::from_raw_line(self.pin_number()).unwrap()
161 }
162 }
163 )+
164
165 };
166}
167
168exti!(gpioa, [
169 EXTI0_1 => PA0,
170 EXTI0_1 => PA1,
171 EXTI2_3 => PA2,
172 EXTI2_3 => PA3,
173 EXTI4_15 => PA4,
174 EXTI4_15 => PA5,
175 EXTI4_15 => PA6,
176 EXTI4_15 => PA7,
177 EXTI4_15 => PA8,
178 EXTI4_15 => PA9,
179 EXTI4_15 => PA10,
180 EXTI4_15 => PA11,
181 EXTI4_15 => PA12,
182 EXTI4_15 => PA13,
183 EXTI4_15 => PA14,
184 EXTI4_15 => PA15,
185]);
186
187exti!(gpiob, [
188 EXTI0_1 => PB0,
189 EXTI0_1 => PB1,
190 EXTI2_3 => PB2,
191 EXTI2_3 => PB3,
192 EXTI4_15 => PB4,
193 EXTI4_15 => PB5,
194 EXTI4_15 => PB6,
195 EXTI4_15 => PB7,
196 EXTI4_15 => PB8,
197 EXTI4_15 => PB9,
198 EXTI4_15 => PB10,
199 EXTI4_15 => PB11,
200 EXTI4_15 => PB12,
201 EXTI4_15 => PB13,
202 EXTI4_15 => PB14,
203 EXTI4_15 => PB15,
204]);
205
206exti!(gpioc, [
207 EXTI0_1 => PC0,
208 EXTI0_1 => PC1,
209 EXTI2_3 => PC2,
210 EXTI2_3 => PC3,
211 EXTI4_15 => PC4,
212 EXTI4_15 => PC5,
213 EXTI4_15 => PC6,
214 EXTI4_15 => PC7,
215 EXTI4_15 => PC8,
216 EXTI4_15 => PC9,
217 EXTI4_15 => PC10,
218 EXTI4_15 => PC11,
219 EXTI4_15 => PC12,
220 EXTI4_15 => PC13,
221 EXTI4_15 => PC14,
222 EXTI4_15 => PC15,
223]);
224
225exti!(gpiod, [
226 EXTI0_1 => PD0,
227 EXTI0_1 => PD1,
228 EXTI2_3 => PD2,
229 EXTI2_3 => PD3,
230 EXTI4_15 => PD4,
231 EXTI4_15 => PD5,
232 EXTI4_15 => PD6,
233 EXTI4_15 => PD7,
234 EXTI4_15 => PD8,
235 EXTI4_15 => PD9,
236 EXTI4_15 => PD10,
237 EXTI4_15 => PD11,
238 EXTI4_15 => PD12,
239 EXTI4_15 => PD13,
240 EXTI4_15 => PD14,
241 EXTI4_15 => PD15,
242]);
243
244exti!(gpioe, [
245 EXTI0_1 => PE0,
246 EXTI0_1 => PE1,
247 EXTI2_3 => PE2,
248 EXTI2_3 => PE3,
249 EXTI4_15 => PE4,
250 EXTI4_15 => PE5,
251 EXTI4_15 => PE6,
252 EXTI4_15 => PE7,
253 EXTI4_15 => PE8,
254 EXTI4_15 => PE9,
255 EXTI4_15 => PE10,
256 EXTI4_15 => PE11,
257 EXTI4_15 => PE12,
258 EXTI4_15 => PE13,
259 EXTI4_15 => PE14,
260 EXTI4_15 => PE15,
261]);
262
263exti!(gpioh, [
264 EXTI0_1 => PH0,
265 EXTI0_1 => PH1,
266 EXTI4_15 => PH9,
267 EXTI4_15 => PH10,
268]);
diff --git a/embassy-stm32l0/src/lib.rs b/embassy-stm32l0/src/lib.rs
index e80fe6cb4..a684c4e3e 100644
--- a/embassy-stm32l0/src/lib.rs
+++ b/embassy-stm32l0/src/lib.rs
@@ -19,6 +19,4 @@ compile_error!(
19 "Multile chip features activated. You must activate exactly one of the following features: " 19 "Multile chip features activated. You must activate exactly one of the following features: "
20); 20);
21 21
22pub use embassy_stm32::{fmt, hal, interrupt, pac}; 22pub use embassy_stm32::{exti, fmt, hal, interrupt, pac};
23
24pub mod exti;