aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/gpiote.rs68
1 files changed, 62 insertions, 6 deletions
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 91944d8cd..d4f6668f3 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -349,16 +349,73 @@ impl<'d> InputChannel<'d> {
349 } 349 }
350 350
351 /// Asynchronously wait for an event in this channel. 351 /// Asynchronously wait for an event in this channel.
352 pub async fn wait(&self) { 352 ///
353 let g = self.ch.regs(); 353 /// It is possible to call this function and await the returned future later.
354 let num = self.ch.number(); 354 /// If an even occurs in the mean time, the future will immediately report ready.
355 let waker = self.ch.waker(); 355 pub fn wait(&mut self) -> impl Future<Output = ()> {
356 // NOTE: This is `-> impl Future` and not an `async fn` on purpose.
357 // Otherwise, events will only be detected starting at the first poll of the returned future.
358 Self::wait_internal(&mut self.ch)
359 }
360
361 /// Asynchronously wait for the pin to become high.
362 ///
363 /// The channel must be configured with [`InputChannelPolarity::LoToHi`] or [`InputChannelPolarity::Toggle`].
364 /// If the channel is not configured to detect rising edges, it is unspecified when the returned future completes.
365 ///
366 /// It is possible to call this function and await the returned future later.
367 /// If an even occurs in the mean time, the future will immediately report ready.
368 pub fn wait_for_high(&mut self) -> impl Future<Output = ()> {
369 // NOTE: This is `-> impl Future` and not an `async fn` on purpose.
370 // Otherwise, events will only be detected starting at the first poll of the returned future.
371
372 // Subscribe to the event before checking the pin level.
373 let wait = Self::wait_internal(&mut self.ch);
374 let pin = &self.pin;
375 async move {
376 if pin.is_high() {
377 return;
378 }
379 wait.await;
380 }
381 }
382
383 /// Asynchronously wait for the pin to become low.
384 ///
385 /// The channel must be configured with [`InputChannelPolarity::HiToLo`] or [`InputChannelPolarity::Toggle`].
386 /// If the channel is not configured to detect falling edges, it is unspecified when the returned future completes.
387 ///
388 /// It is possible to call this function and await the returned future later.
389 /// If an even occurs in the mean time, the future will immediately report ready.
390 pub fn wait_for_low(&mut self) -> impl Future<Output = ()> {
391 // NOTE: This is `-> impl Future` and not an `async fn` on purpose.
392 // Otherwise, events will only be detected starting at the first poll of the returned future.
393
394 // Subscribe to the event before checking the pin level.
395 let wait = Self::wait_internal(&mut self.ch);
396 let pin = &self.pin;
397 async move {
398 if pin.is_low() {
399 return;
400 }
401 wait.await;
402 }
403 }
404
405 /// Internal implementation for `wait()` and friends.
406 fn wait_internal(channel: &mut Peri<'_, AnyChannel>) -> impl Future<Output = ()> {
407 // NOTE: This is `-> impl Future` and not an `async fn` on purpose.
408 // Otherwise, events will only be detected starting at the first poll of the returned future.
409
410 let g = channel.regs();
411 let num = channel.number();
412 let waker = channel.waker();
356 413
357 // Enable interrupt 414 // Enable interrupt
358 g.events_in(num).write_value(0); 415 g.events_in(num).write_value(0);
359 g.intenset(INTNUM).write(|w| w.0 = 1 << num); 416 g.intenset(INTNUM).write(|w| w.0 = 1 << num);
360 417
361 poll_fn(|cx| { 418 poll_fn(move |cx| {
362 CHANNEL_WAKERS[waker].register(cx.waker()); 419 CHANNEL_WAKERS[waker].register(cx.waker());
363 420
364 if g.events_in(num).read() != 0 { 421 if g.events_in(num).read() != 0 {
@@ -367,7 +424,6 @@ impl<'d> InputChannel<'d> {
367 Poll::Pending 424 Poll::Pending
368 } 425 }
369 }) 426 })
370 .await;
371 } 427 }
372 428
373 /// Get the associated input pin. 429 /// Get the associated input pin.