Add WaitFor{Low,High} for stm32l0 exti pins

This commit is contained in:
Michael Beaumont 2021-03-18 18:48:24 +01:00
parent 1908141c86
commit 7b0bed2c5e
No known key found for this signature in database
GPG key ID: 94C1243E6859F368
2 changed files with 62 additions and 1 deletions

View file

@ -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"

View file

@ -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<T: PinWithInterrupt> {
pin: T,
@ -51,6 +54,47 @@ impl<T: PinWithInterrupt + 'static> ExtiPin<T> {
}
}
impl<T: InputPin + PinWithInterrupt + 'static> ExtiPin<T> {
fn wait_for_state<'a>(self: Pin<&'a mut Self>, state: bool) -> impl Future<Output = ()> + '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<T: PinWithInterrupt + 'static> WaitForRisingEdge for ExtiPin<T> {
type Future<'a> = impl Future<Output = ()> + 'a;
@ -75,6 +119,22 @@ impl<T: PinWithInterrupt + 'static> WaitForAnyEdge for ExtiPin<T> {
}
}
impl<T: InputPin + PinWithInterrupt + 'static> WaitForHigh for ExtiPin<T> {
type Future<'a> = impl Future<Output = ()> + 'a;
fn wait_for_high<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
self.wait_for_state(true)
}
}
impl<T: InputPin + PinWithInterrupt + 'static> WaitForLow for ExtiPin<T> {
type Future<'a> = impl Future<Output = ()> + 'a;
fn wait_for_low<'a>(self: Pin<&'a mut Self>) -> Self::Future<'a> {
self.wait_for_state(false)
}
}
mod private {
pub trait Sealed {}
}