#[cfg(feature = "embassy")]
mod future;
mod hal;
mod pins;
mod types;
use core::convert::Infallible;
pub use types::*;
use crate::gpio::Pin;
use crate::gpio::{Input, PinLevel, PinPullUpDown, PinSpeed};
#[cfg(feature = "embassy")]
use crate::mode::Async;
use crate::mode::{Blocking, Mode};
use core::marker::PhantomData;
use embassy_hal_internal::{into_ref, Peripheral};
pub struct ExtiInput<'d, M: Mode> {
pin: Input<'d>,
_mode: PhantomData<M>,
}
impl<'d, M: Mode> Unpin for ExtiInput<'d, M> {}
impl<'d, M: Mode> ExtiInput<'d, M> {
pub fn new(
pin: impl Peripheral<P = impl Pin> + 'd,
pull: PinPullUpDown,
speed: PinSpeed,
) -> Self {
into_ref!(pin);
Self {
pin: Input::new(pin, pull, speed),
_mode: PhantomData,
}
}
#[inline]
fn get_level(&self) -> PinLevel {
self.pin.read()
}
}
impl<'d> ExtiInput<'d, Blocking> {
#[inline]
pub fn wait_for_low(&self) {
while self.get_level() == PinLevel::Hight {}
}
#[inline]
pub fn wait_for_high(&self) {
while self.get_level() == PinLevel::Low {}
}
#[inline]
pub fn wait_for_rising_edge(&self) {
self.wait_for_low();
self.wait_for_high();
}
#[inline]
pub fn wait_for_falling_edge(&self) {
self.wait_for_high();
self.wait_for_low();
}
#[inline]
pub fn wait_for_any_edge(&self) {
let last = self.get_level();
while last == self.get_level() {}
}
}
#[cfg(feature = "embassy")]
impl<'d> ExtiInput<'d, Async> {
pub async fn wait_for_low(&self) {
if self.get_level() == PinLevel::Low {
return;
}
future::ExtiInputFuture::new(self.pin.pin.port(), self.pin.pin.pin(), Edge::Falling).await
}
pub async fn wait_for_high(&self) {
if self.get_level() == PinLevel::Hight {
return;
}
future::ExtiInputFuture::new(self.pin.pin.port(), self.pin.pin.pin(), Edge::Rising).await
}
pub async fn wait_for_rising_edge(&self) {
future::ExtiInputFuture::new(self.pin.pin.port(), self.pin.pin.pin(), Edge::Rising).await
}
pub async fn wait_for_falling_edge(&self) {
future::ExtiInputFuture::new(self.pin.pin.port(), self.pin.pin.pin(), Edge::Falling).await
}
pub async fn wait_for_any_edge(&self) {
future::ExtiInputFuture::new(self.pin.pin.port(), self.pin.pin.pin(), Edge::RisingFalling)
.await
}
}
impl<'a, M: Mode> embedded_hal::digital::v2::InputPin for ExtiInput<'a, M> {
type Error = Infallible;
fn is_low(&self) -> Result<bool, Self::Error> {
self.pin.is_low()
}
fn is_high(&self) -> Result<bool, Self::Error> {
self.pin.is_high()
}
}