aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/gpiote.rs35
-rw-r--r--embassy/src/util/signal.rs21
-rw-r--r--examples/src/bin/gpiote_port.rs14
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 @@
1use anyfmt::{panic, *}; 1use anyfmt::{panic, *};
2use core::cell::Cell; 2use core::cell::Cell;
3use core::future::Future;
3use core::ptr; 4use core::ptr;
5use core::task::{Context, Poll};
4use embassy::util::Signal; 6use embassy::util::Signal;
5 7
6use crate::hal::gpio::{Input, Level, Output, Pin, Port}; 8use 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
288pub struct PortInput<'a, T> { 298pub 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
293impl<'a, T> Drop for PortInput<'a, T> { 304impl<'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
300impl<'a, T> PortInput<'a, T> { 311impl<'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;
2use core::cell::UnsafeCell; 2use core::cell::UnsafeCell;
3use core::future::Future; 3use core::future::Future;
4use core::mem; 4use core::mem;
5use core::pin::Pin;
6use core::task::{Context, Poll, Waker}; 5use core::task::{Context, Poll, Waker};
7 6
8pub struct Signal<T> { 7pub 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
50struct WaitFuture<'a, T> {
51 signal: &'a Signal<T>,
52}
53
54impl<'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
13use embassy::executor::{task, Executor}; 13use embassy::executor::{task, Executor};
14use embassy::util::Forever; 14use embassy::util::Forever;
15use embassy_nrf::gpiote; 15use embassy_nrf::gpiote::{Gpiote, PortInputPolarity};
16
17async fn button(g: &gpiote::Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
18 let ch = g.new_port_input(pin);
19 16
17async 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