diff --git a/embassy-stm32l0/Cargo.toml b/embassy-stm32l0/Cargo.toml index 70aa431c..c74d1407 100644 --- a/embassy-stm32l0/Cargo.toml +++ b/embassy-stm32l0/Cargo.toml @@ -18,6 +18,7 @@ stm32l0x3 = ["stm32l0xx-hal/stm32l0x3"] [dependencies] embassy = { version = "0.1.0", path = "../embassy" } defmt = { version = "0.2.0", optional = true } +futures = { version = "0.3.5", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } log = { version = "0.4.11", optional = true } cortex-m-rt = "0.6.13" cortex-m = "0.7.1" diff --git a/embassy-stm32l0/src/exti.rs b/embassy-stm32l0/src/exti.rs index 32c56c49..f50c3ae8 100644 --- a/embassy-stm32l0/src/exti.rs +++ b/embassy-stm32l0/src/exti.rs @@ -2,7 +2,9 @@ use core::future::Future; use core::mem; use core::pin::Pin; -use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; +use embassy::traits::gpio::{ + WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge, +}; use embassy::util::InterruptFuture; use crate::hal::{ @@ -12,6 +14,7 @@ use crate::hal::{ }; use crate::interrupt; use crate::pac::EXTI; +use embedded_hal::digital::v2::InputPin; pub struct ExtiPin { pin: T, @@ -51,6 +54,47 @@ impl ExtiPin { } } +impl ExtiPin { + fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> 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(); + cortex_m::interrupt::free(|_| { + let mut syscfg: SYSCFG = unsafe { mem::transmute(()) }; + let edge = if state { + TriggerEdge::Rising + } else { + TriggerEdge::Falling + }; + exti.listen_gpio(&mut syscfg, port, line, edge); + }); + + let pin_has_state = if state { + s.pin.is_high() + } else { + s.pin.is_low() + } + .unwrap_or(false); + if pin_has_state { + return (); + } + + fut.await; + + Exti::unpend(line); + } + } +} + impl WaitForRisingEdge for ExtiPin { type Future<'a> = impl Future + 'a; @@ -75,6 +119,22 @@ impl WaitForAnyEdge for ExtiPin { } } +impl WaitForHigh for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_state(true) + } +} + +impl WaitForLow for ExtiPin { + type Future<'a> = impl Future + 'a; + + fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> { + self.wait_for_state(false) + } +} + mod private { pub trait Sealed {} }