aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32f4/src/exti.rs64
1 files changed, 29 insertions, 35 deletions
diff --git a/embassy-stm32f4/src/exti.rs b/embassy-stm32f4/src/exti.rs
index bf1dd3a71..11704e6d1 100644
--- a/embassy-stm32f4/src/exti.rs
+++ b/embassy-stm32f4/src/exti.rs
@@ -1,49 +1,39 @@
1use core::cell::UnsafeCell;
1use core::future::Future; 2use core::future::Future;
2use core::mem; 3use core::mem;
3use core::pin::Pin; 4use core::pin::Pin;
5use cortex_m;
4 6
5use embassy::interrupt::Interrupt; 7use embassy::interrupt::Interrupt;
6use embassy::traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; 8use embassy::traits::gpio::{WaitForFallingEdge, WaitForRisingEdge};
7use embassy::util::InterruptFuture; 9use embassy::util::InterruptFuture;
8 10
9use crate::hal::gpio; 11use crate::hal::gpio;
10use crate::hal::gpio::{Edge, ExtiPin as HalExtiPin}; 12use crate::hal::gpio::Edge;
11use crate::hal::syscfg::SysCfg; 13use crate::hal::syscfg::SysCfg;
12use crate::pac::EXTI; 14use crate::pac::EXTI;
13use embedded_hal::digital::v2 as digital; 15use embedded_hal::digital::v2 as digital;
14 16
15use crate::interrupt; 17use crate::interrupt;
16 18
17pub struct ExtiManager { 19pub struct ExtiPin<T: gpio::ExtiPin + WithInterrupt> {
18 syscfg: SysCfg, 20 pin: T,
21 interrupt: T::Interrupt,
19} 22}
20 23
21impl<'a> ExtiManager { 24impl<T: gpio::ExtiPin + WithInterrupt> ExtiPin<T> {
22 pub fn new(_exti: EXTI, syscfg: SysCfg) -> Self { 25 fn new(mut pin: T, interrupt: T::Interrupt) -> Self {
23 Self { syscfg } 26 let mut syscfg: SysCfg = unsafe { mem::transmute(()) };
24 }
25 27
26 pub fn new_pin<T>(&'static self, mut pin: T, interrupt: T::Interrupt) -> ExtiPin<T> 28 cortex_m::interrupt::free(|_| {
27 where 29 pin.make_interrupt_source(&mut syscfg);
28 T: HalExtiPin + WithInterrupt, 30 });
29 {
30 pin.make_interrupt_source(&mut self.syscfg);
31 31
32 ExtiPin { 32 Self { pin, interrupt }
33 pin,
34 interrupt,
35 _mgr: self,
36 }
37 } 33 }
38} 34}
39 35
40pub struct ExtiPin<T: HalExtiPin + WithInterrupt> { 36impl<T: gpio::ExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin for ExtiPin<T> {
41 pin: T,
42 interrupt: T::Interrupt,
43 _mgr: &'static ExtiManager,
44}
45
46impl<T: HalExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin for ExtiPin<T> {
47 type Error = T::Error; 37 type Error = T::Error;
48 38
49 fn set_low(&mut self) -> Result<(), Self::Error> { 39 fn set_low(&mut self) -> Result<(), Self::Error> {
@@ -55,7 +45,7 @@ impl<T: HalExtiPin + WithInterrupt + digital::OutputPin> digital::OutputPin for
55 } 45 }
56} 46}
57 47
58impl<T: HalExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::StatefulOutputPin 48impl<T: gpio::ExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::StatefulOutputPin
59 for ExtiPin<T> 49 for ExtiPin<T>
60{ 50{
61 fn is_set_low(&self) -> Result<bool, Self::Error> { 51 fn is_set_low(&self) -> Result<bool, Self::Error> {
@@ -67,7 +57,7 @@ impl<T: HalExtiPin + WithInterrupt + digital::StatefulOutputPin> digital::Statef
67 } 57 }
68} 58}
69 59
70impl<T: HalExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::ToggleableOutputPin 60impl<T: gpio::ExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::ToggleableOutputPin
71 for ExtiPin<T> 61 for ExtiPin<T>
72{ 62{
73 type Error = T::Error; 63 type Error = T::Error;
@@ -77,7 +67,7 @@ impl<T: HalExtiPin + WithInterrupt + digital::ToggleableOutputPin> digital::Togg
77 } 67 }
78} 68}
79 69
80impl<T: HalExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for ExtiPin<T> { 70impl<T: gpio::ExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for ExtiPin<T> {
81 type Error = T::Error; 71 type Error = T::Error;
82 72
83 fn is_high(&self) -> Result<bool, Self::Error> { 73 fn is_high(&self) -> Result<bool, Self::Error> {
@@ -100,7 +90,7 @@ impl<T: HalExtiPin + WithInterrupt + digital::InputPin> digital::InputPin for Ex
100 EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15 90 EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15
101*/ 91*/
102 92
103impl<T: HalExtiPin + WithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> { 93impl<T: gpio::ExtiPin + WithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> {
104 type Future<'a> = impl Future<Output = ()> + 'a; 94 type Future<'a> = impl Future<Output = ()> + 'a;
105 95
106 fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { 96 fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
@@ -109,10 +99,12 @@ impl<T: HalExtiPin + WithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> {
109 s.pin.clear_interrupt_pending_bit(); 99 s.pin.clear_interrupt_pending_bit();
110 async move { 100 async move {
111 let fut = InterruptFuture::new(&mut s.interrupt); 101 let fut = InterruptFuture::new(&mut s.interrupt);
112 let mut exti: EXTI = unsafe { mem::transmute(()) }; 102 cortex_m::interrupt::free(|_| {
103 let mut exti: EXTI = unsafe { mem::transmute(()) };
113 104
114 s.pin.trigger_on_edge(&mut exti, Edge::RISING); 105 s.pin.trigger_on_edge(&mut exti, Edge::RISING);
115 s.pin.enable_interrupt(&mut exti); 106 s.pin.enable_interrupt(&mut exti);
107 });
116 fut.await; 108 fut.await;
117 109
118 s.pin.clear_interrupt_pending_bit(); 110 s.pin.clear_interrupt_pending_bit();
@@ -120,7 +112,7 @@ impl<T: HalExtiPin + WithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> {
120 } 112 }
121} 113}
122 114
123impl<T: HalExtiPin + WithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T> { 115impl<T: gpio::ExtiPin + WithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T> {
124 type Future<'a> = impl Future<Output = ()> + 'a; 116 type Future<'a> = impl Future<Output = ()> + 'a;
125 117
126 fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { 118 fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
@@ -129,10 +121,12 @@ impl<T: HalExtiPin + WithInterrupt + 'static> WaitForFallingEdge for ExtiPin<T>
129 s.pin.clear_interrupt_pending_bit(); 121 s.pin.clear_interrupt_pending_bit();
130 async move { 122 async move {
131 let fut = InterruptFuture::new(&mut s.interrupt); 123 let fut = InterruptFuture::new(&mut s.interrupt);
132 let mut exti: EXTI = unsafe { mem::transmute(()) }; 124 cortex_m::interrupt::free(|_| {
125 let mut exti: EXTI = unsafe { mem::transmute(()) };
133 126
134 s.pin.trigger_on_edge(&mut exti, Edge::FALLING); 127 s.pin.trigger_on_edge(&mut exti, Edge::FALLING);
135 s.pin.enable_interrupt(&mut exti); 128 s.pin.enable_interrupt(&mut exti);
129 });
136 fut.await; 130 fut.await;
137 131
138 s.pin.clear_interrupt_pending_bit(); 132 s.pin.clear_interrupt_pending_bit();