From 6278ecf4b0c312894821c2e4b4f5a1b6ea5688d4 Mon Sep 17 00:00:00 2001 From: Michael Beaumont Date: Tue, 9 Mar 2021 14:23:02 +0100 Subject: [PATCH] Use a critical section to listen on GPIO pins --- embassy-stm32l0/src/exti.rs | 64 +++++++++++++++++++------------------ embassy-stm32l0/src/lib.rs | 6 +--- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/embassy-stm32l0/src/exti.rs b/embassy-stm32l0/src/exti.rs index 84c38ccc..ca699a08 100644 --- a/embassy-stm32l0/src/exti.rs +++ b/embassy-stm32l0/src/exti.rs @@ -39,7 +39,37 @@ impl<'a> ExtiManager { pub struct ExtiPin { pin: T, interrupt: I, - mgr: &'static mut ExtiManager, + mgr: &'static ExtiManager, +} + +impl + 'static, I: Interrupt + 'static> ExtiPin { + fn wait_for_edge<'a>( + self: Pin<&'a mut Self>, + edge: TriggerEdge, + ) -> impl Future + 'a { + let line = self.pin.line(); + let s = unsafe { self.get_unchecked_mut() }; + + Exti::unpend(line); + + async move { + let exti: EXTI = unsafe { mem::transmute(()) }; + let mut exti = Exti::new(exti); + + let fut = InterruptFuture::new(&mut s.interrupt); + + let port = s.pin.port(); + let syscfg = &s.mgr.syscfg as *const _ as *mut SYSCFG; + cortex_m::interrupt::free(|_| { + let syscfg = unsafe { &mut *syscfg }; + exti.listen_gpio(syscfg, port, line, edge); + }); + + fut.await; + + Exti::unpend(line); + } + } } impl + 'static, I: Interrupt + 'static> WaitForRisingEdge @@ -48,21 +78,7 @@ impl + 'static, I: Interrupt + 'static> WaitF type Future<'a> = impl Future + 'a; fn wait_for_rising_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - let s = unsafe { self.get_unchecked_mut() }; - - let line = s.pin.line(); - Exti::unpend(line); - - async move { - let exti: EXTI = unsafe { mem::transmute(()) }; - let mut exti = Exti::new(exti); - let fut = InterruptFuture::new(&mut s.interrupt); - - exti.listen_gpio(&mut s.mgr.syscfg, s.pin.port(), line, TriggerEdge::Rising); - fut.await; - - Exti::unpend(line); - } + self.wait_for_edge(TriggerEdge::Rising) } } @@ -72,21 +88,7 @@ impl + 'static, I: Interrupt + 'static> WaitF type Future<'a> = impl Future + 'a; fn wait_for_falling_edge<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { - let s = unsafe { self.get_unchecked_mut() }; - - let line = s.pin.line(); - Exti::unpend(line); - - async move { - let exti: EXTI = unsafe { mem::transmute(()) }; - let mut exti = Exti::new(exti); - let fut = InterruptFuture::new(&mut s.interrupt); - - exti.listen_gpio(&mut s.mgr.syscfg, s.pin.port(), line, TriggerEdge::Falling); - fut.await; - - Exti::unpend(line); - } + self.wait_for_edge(TriggerEdge::Falling) } } diff --git a/embassy-stm32l0/src/lib.rs b/embassy-stm32l0/src/lib.rs index c4fa15c5..62f0f037 100644 --- a/embassy-stm32l0/src/lib.rs +++ b/embassy-stm32l0/src/lib.rs @@ -4,11 +4,7 @@ #![feature(type_alias_impl_trait)] #![allow(incomplete_features)] -#[cfg(not(any( - feature = "stm32l0x1", - feature = "stm32l0x2", - feature = "stm32l0x3", -)))] +#[cfg(not(any(feature = "stm32l0x1", feature = "stm32l0x2", feature = "stm32l0x3",)))] compile_error!( "No chip feature activated. You must activate exactly one of the following features: " );