diff options
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 35 | ||||
| -rw-r--r-- | embassy/src/util/signal.rs | 21 | ||||
| -rw-r--r-- | examples/src/bin/gpiote_port.rs | 14 |
3 files changed, 34 insertions, 36 deletions
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 2b1ca40b1..9626d3299 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | use anyfmt::{panic, *}; | 1 | use anyfmt::{panic, *}; |
| 2 | use core::cell::Cell; | 2 | use core::cell::Cell; |
| 3 | use core::future::Future; | ||
| 3 | use core::ptr; | 4 | use core::ptr; |
| 5 | use core::task::{Context, Poll}; | ||
| 4 | use embassy::util::Signal; | 6 | use embassy::util::Signal; |
| 5 | 7 | ||
| 6 | use crate::hal::gpio::{Input, Level, Output, Pin, Port}; | 8 | use crate::hal::gpio::{Input, Level, Output, Pin, Port}; |
| @@ -201,10 +203,18 @@ impl Gpiote { | |||
| 201 | }) | 203 | }) |
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | pub fn new_port_input<'a, T>(&'a self, pin: Pin<Input<T>>) -> PortInput<'a, T> { | 206 | pub fn wait_port_input<'a, T>( |
| 207 | &'a self, | ||
| 208 | pin: &'a Pin<Input<T>>, | ||
| 209 | polarity: PortInputPolarity, | ||
| 210 | ) -> PortInputFuture<'a, T> { | ||
| 205 | interrupt::free(|_| { | 211 | interrupt::free(|_| { |
| 206 | unsafe { INSTANCE = self }; | 212 | unsafe { INSTANCE = self }; |
| 207 | PortInput { gpiote: self, pin } | 213 | PortInputFuture { |
| 214 | gpiote: self, | ||
| 215 | pin, | ||
| 216 | polarity, | ||
| 217 | } | ||
| 208 | }) | 218 | }) |
| 209 | } | 219 | } |
| 210 | 220 | ||
| @@ -285,29 +295,28 @@ impl Gpiote { | |||
| 285 | } | 295 | } |
| 286 | } | 296 | } |
| 287 | 297 | ||
| 288 | pub struct PortInput<'a, T> { | 298 | pub struct PortInputFuture<'a, T> { |
| 289 | gpiote: &'a Gpiote, | 299 | gpiote: &'a Gpiote, |
| 290 | pin: Pin<Input<T>>, | 300 | pin: &'a Pin<Input<T>>, |
| 301 | polarity: PortInputPolarity, | ||
| 291 | } | 302 | } |
| 292 | 303 | ||
| 293 | impl<'a, T> Drop for PortInput<'a, T> { | 304 | impl<'a, T> Drop for PortInputFuture<'a, T> { |
| 294 | fn drop(&mut self) { | 305 | fn drop(&mut self) { |
| 295 | pin_conf(&self.pin).modify(|_, w| w.sense().disabled()); | 306 | pin_conf(&self.pin).modify(|_, w| w.sense().disabled()); |
| 296 | self.gpiote.port_signals[pin_num(&self.pin)].reset(); | 307 | self.gpiote.port_signals[pin_num(&self.pin)].reset(); |
| 297 | } | 308 | } |
| 298 | } | 309 | } |
| 299 | 310 | ||
| 300 | impl<'a, T> PortInput<'a, T> { | 311 | impl<'a, T> Future for PortInputFuture<'a, T> { |
| 301 | pub async fn wait(&self, polarity: PortInputPolarity) { | 312 | type Output = (); |
| 302 | pin_conf(&self.pin).modify(|_, w| match polarity { | 313 | |
| 314 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||
| 315 | pin_conf(&self.pin).modify(|_, w| match self.polarity { | ||
| 303 | PortInputPolarity::Low => w.sense().low(), | 316 | PortInputPolarity::Low => w.sense().low(), |
| 304 | PortInputPolarity::High => w.sense().high(), | 317 | PortInputPolarity::High => w.sense().high(), |
| 305 | }); | 318 | }); |
| 306 | self.gpiote.port_signals[pin_num(&self.pin)].wait().await; | 319 | self.gpiote.port_signals[pin_num(&self.pin)].poll_wait(cx) |
| 307 | } | ||
| 308 | |||
| 309 | pub fn pin(&self) -> &Pin<Input<T>> { | ||
| 310 | &self.pin | ||
| 311 | } | 320 | } |
| 312 | } | 321 | } |
| 313 | 322 | ||
diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index f28166d3c..e2cd3a80f 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs | |||
| @@ -2,7 +2,6 @@ use anyfmt::panic; | |||
| 2 | use core::cell::UnsafeCell; | 2 | use core::cell::UnsafeCell; |
| 3 | use core::future::Future; | 3 | use core::future::Future; |
| 4 | use core::mem; | 4 | use core::mem; |
| 5 | use core::pin::Pin; | ||
| 6 | use core::task::{Context, Poll, Waker}; | 5 | use core::task::{Context, Poll, Waker}; |
| 7 | 6 | ||
| 8 | pub struct Signal<T> { | 7 | pub struct Signal<T> { |
| @@ -42,21 +41,9 @@ impl<T: Send> Signal<T> { | |||
| 42 | }) | 41 | }) |
| 43 | } | 42 | } |
| 44 | 43 | ||
| 45 | pub fn wait<'a>(&'a self) -> impl Future<Output = T> + 'a { | 44 | pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> { |
| 46 | WaitFuture { signal: self } | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | struct WaitFuture<'a, T> { | ||
| 51 | signal: &'a Signal<T>, | ||
| 52 | } | ||
| 53 | |||
| 54 | impl<'a, T: Send> Future for WaitFuture<'a, T> { | ||
| 55 | type Output = T; | ||
| 56 | |||
| 57 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { | ||
| 58 | cortex_m::interrupt::free(|_| unsafe { | 45 | cortex_m::interrupt::free(|_| unsafe { |
| 59 | let state = &mut *self.signal.state.get(); | 46 | let state = &mut *self.state.get(); |
| 60 | match state { | 47 | match state { |
| 61 | State::None => { | 48 | State::None => { |
| 62 | *state = State::Waiting(cx.waker().clone()); | 49 | *state = State::Waiting(cx.waker().clone()); |
| @@ -71,4 +58,8 @@ impl<'a, T: Send> Future for WaitFuture<'a, T> { | |||
| 71 | } | 58 | } |
| 72 | }) | 59 | }) |
| 73 | } | 60 | } |
| 61 | |||
| 62 | pub fn wait(&self) -> impl Future<Output = T> + '_ { | ||
| 63 | futures::future::poll_fn(move |cx| self.poll_wait(cx)) | ||
| 64 | } | ||
| 74 | } | 65 | } |
diff --git a/examples/src/bin/gpiote_port.rs b/examples/src/bin/gpiote_port.rs index bc0cb4367..585317642 100644 --- a/examples/src/bin/gpiote_port.rs +++ b/examples/src/bin/gpiote_port.rs | |||
| @@ -12,15 +12,13 @@ use nrf52840_hal::gpio; | |||
| 12 | 12 | ||
| 13 | use embassy::executor::{task, Executor}; | 13 | use embassy::executor::{task, Executor}; |
| 14 | use embassy::util::Forever; | 14 | use embassy::util::Forever; |
| 15 | use embassy_nrf::gpiote; | 15 | use embassy_nrf::gpiote::{Gpiote, PortInputPolarity}; |
| 16 | |||
| 17 | async fn button(g: &gpiote::Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) { | ||
| 18 | let ch = g.new_port_input(pin); | ||
| 19 | 16 | ||
| 17 | async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) { | ||
| 20 | loop { | 18 | loop { |
| 21 | ch.wait(gpiote::PortInputPolarity::Low).await; | 19 | g.wait_port_input(&pin, PortInputPolarity::Low).await; |
| 22 | info!("Button {:?} pressed!", n); | 20 | info!("Button {:?} pressed!", n); |
| 23 | ch.wait(gpiote::PortInputPolarity::High).await; | 21 | g.wait_port_input(&pin, PortInputPolarity::High).await; |
| 24 | info!("Button {:?} released!", n); | 22 | info!("Button {:?} released!", n); |
| 25 | } | 23 | } |
| 26 | } | 24 | } |
| @@ -30,12 +28,12 @@ async fn run() { | |||
| 30 | let p = unwrap!(embassy_nrf::pac::Peripherals::take()); | 28 | let p = unwrap!(embassy_nrf::pac::Peripherals::take()); |
| 31 | let port0 = gpio::p0::Parts::new(p.P0); | 29 | let port0 = gpio::p0::Parts::new(p.P0); |
| 32 | 30 | ||
| 33 | let g = gpiote::Gpiote::new(p.GPIOTE); | 31 | let g = Gpiote::new(p.GPIOTE); |
| 34 | info!( | 32 | info!( |
| 35 | "sizeof Signal<()> = {:usize}", | 33 | "sizeof Signal<()> = {:usize}", |
| 36 | mem::size_of::<embassy::util::Signal<()>>() | 34 | mem::size_of::<embassy::util::Signal<()>>() |
| 37 | ); | 35 | ); |
| 38 | info!("sizeof gpiote = {:usize}", mem::size_of::<gpiote::Gpiote>()); | 36 | info!("sizeof gpiote = {:usize}", mem::size_of::<Gpiote>()); |
| 39 | 37 | ||
| 40 | info!("Starting!"); | 38 | info!("Starting!"); |
| 41 | 39 | ||
