gpiote: change port api to directly return futures.
This commit is contained in:
parent
61b1d4e188
commit
2e062f5627
@ -1,6 +1,8 @@
|
|||||||
use anyfmt::{panic, *};
|
use anyfmt::{panic, *};
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
|
use core::future::Future;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
use core::task::{Context, Poll};
|
||||||
use embassy::util::Signal;
|
use embassy::util::Signal;
|
||||||
|
|
||||||
use crate::hal::gpio::{Input, Level, Output, Pin, Port};
|
use crate::hal::gpio::{Input, Level, Output, Pin, Port};
|
||||||
@ -201,10 +203,18 @@ impl Gpiote {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_port_input<'a, T>(&'a self, pin: Pin<Input<T>>) -> PortInput<'a, T> {
|
pub fn wait_port_input<'a, T>(
|
||||||
|
&'a self,
|
||||||
|
pin: &'a Pin<Input<T>>,
|
||||||
|
polarity: PortInputPolarity,
|
||||||
|
) -> PortInputFuture<'a, T> {
|
||||||
interrupt::free(|_| {
|
interrupt::free(|_| {
|
||||||
unsafe { INSTANCE = self };
|
unsafe { INSTANCE = self };
|
||||||
PortInput { gpiote: self, pin }
|
PortInputFuture {
|
||||||
|
gpiote: self,
|
||||||
|
pin,
|
||||||
|
polarity,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,29 +295,28 @@ impl Gpiote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PortInput<'a, T> {
|
pub struct PortInputFuture<'a, T> {
|
||||||
gpiote: &'a Gpiote,
|
gpiote: &'a Gpiote,
|
||||||
pin: Pin<Input<T>>,
|
pin: &'a Pin<Input<T>>,
|
||||||
|
polarity: PortInputPolarity,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for PortInput<'a, T> {
|
impl<'a, T> Drop for PortInputFuture<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
pin_conf(&self.pin).modify(|_, w| w.sense().disabled());
|
pin_conf(&self.pin).modify(|_, w| w.sense().disabled());
|
||||||
self.gpiote.port_signals[pin_num(&self.pin)].reset();
|
self.gpiote.port_signals[pin_num(&self.pin)].reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> PortInput<'a, T> {
|
impl<'a, T> Future for PortInputFuture<'a, T> {
|
||||||
pub async fn wait(&self, polarity: PortInputPolarity) {
|
type Output = ();
|
||||||
pin_conf(&self.pin).modify(|_, w| match polarity {
|
|
||||||
|
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
pin_conf(&self.pin).modify(|_, w| match self.polarity {
|
||||||
PortInputPolarity::Low => w.sense().low(),
|
PortInputPolarity::Low => w.sense().low(),
|
||||||
PortInputPolarity::High => w.sense().high(),
|
PortInputPolarity::High => w.sense().high(),
|
||||||
});
|
});
|
||||||
self.gpiote.port_signals[pin_num(&self.pin)].wait().await;
|
self.gpiote.port_signals[pin_num(&self.pin)].poll_wait(cx)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pin(&self) -> &Pin<Input<T>> {
|
|
||||||
&self.pin
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ use anyfmt::panic;
|
|||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::pin::Pin;
|
|
||||||
use core::task::{Context, Poll, Waker};
|
use core::task::{Context, Poll, Waker};
|
||||||
|
|
||||||
pub struct Signal<T> {
|
pub struct Signal<T> {
|
||||||
@ -42,21 +41,9 @@ impl<T: Send> Signal<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait<'a>(&'a self) -> impl Future<Output = T> + 'a {
|
pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> {
|
||||||
WaitFuture { signal: self }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct WaitFuture<'a, T> {
|
|
||||||
signal: &'a Signal<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Send> Future for WaitFuture<'a, T> {
|
|
||||||
type Output = T;
|
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
|
|
||||||
cortex_m::interrupt::free(|_| unsafe {
|
cortex_m::interrupt::free(|_| unsafe {
|
||||||
let state = &mut *self.signal.state.get();
|
let state = &mut *self.state.get();
|
||||||
match state {
|
match state {
|
||||||
State::None => {
|
State::None => {
|
||||||
*state = State::Waiting(cx.waker().clone());
|
*state = State::Waiting(cx.waker().clone());
|
||||||
@ -71,4 +58,8 @@ impl<'a, T: Send> Future for WaitFuture<'a, T> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wait(&self) -> impl Future<Output = T> + '_ {
|
||||||
|
futures::future::poll_fn(move |cx| self.poll_wait(cx))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,13 @@ use nrf52840_hal::gpio;
|
|||||||
|
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_nrf::gpiote;
|
use embassy_nrf::gpiote::{Gpiote, PortInputPolarity};
|
||||||
|
|
||||||
async fn button(g: &gpiote::Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
|
|
||||||
let ch = g.new_port_input(pin);
|
|
||||||
|
|
||||||
|
async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
|
||||||
loop {
|
loop {
|
||||||
ch.wait(gpiote::PortInputPolarity::Low).await;
|
g.wait_port_input(&pin, PortInputPolarity::Low).await;
|
||||||
info!("Button {:?} pressed!", n);
|
info!("Button {:?} pressed!", n);
|
||||||
ch.wait(gpiote::PortInputPolarity::High).await;
|
g.wait_port_input(&pin, PortInputPolarity::High).await;
|
||||||
info!("Button {:?} released!", n);
|
info!("Button {:?} released!", n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,12 +28,12 @@ async fn run() {
|
|||||||
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
|
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
|
||||||
let port0 = gpio::p0::Parts::new(p.P0);
|
let port0 = gpio::p0::Parts::new(p.P0);
|
||||||
|
|
||||||
let g = gpiote::Gpiote::new(p.GPIOTE);
|
let g = Gpiote::new(p.GPIOTE);
|
||||||
info!(
|
info!(
|
||||||
"sizeof Signal<()> = {:usize}",
|
"sizeof Signal<()> = {:usize}",
|
||||||
mem::size_of::<embassy::util::Signal<()>>()
|
mem::size_of::<embassy::util::Signal<()>>()
|
||||||
);
|
);
|
||||||
info!("sizeof gpiote = {:usize}", mem::size_of::<gpiote::Gpiote>());
|
info!("sizeof gpiote = {:usize}", mem::size_of::<Gpiote>());
|
||||||
|
|
||||||
info!("Starting!");
|
info!("Starting!");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user