aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/settings.json3
-rw-r--r--embassy-hal-common/src/drop.rs (renamed from embassy/src/util/drop_bomb.rs)23
-rw-r--r--embassy-hal-common/src/lib.rs1
-rw-r--r--embassy-hal-common/src/usb/usb_serial.rs2
-rw-r--r--embassy-net/src/stack.rs4
-rw-r--r--embassy-nrf/src/buffered_uarte.rs3
-rw-r--r--embassy-nrf/src/gpiote.rs2
-rw-r--r--embassy-nrf/src/qspi.rs5
-rw-r--r--embassy-nrf/src/rng.rs4
-rw-r--r--embassy-nrf/src/saadc.rs3
-rw-r--r--embassy-nrf/src/spim.rs4
-rw-r--r--embassy-nrf/src/time_driver.rs2
-rw-r--r--embassy-nrf/src/timer.rs8
-rw-r--r--embassy-nrf/src/twim.rs3
-rw-r--r--embassy-nrf/src/uarte.rs5
-rw-r--r--embassy-rp/src/timer.rs2
-rw-r--r--embassy-stm32/src/dma/bdma.rs3
-rw-r--r--embassy-stm32/src/dma/dma.rs3
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs3
-rw-r--r--embassy-stm32/src/exti.rs3
-rw-r--r--embassy-stm32/src/i2c/v2.rs4
-rw-r--r--embassy-stm32/src/rng.rs3
-rw-r--r--embassy-stm32/src/sdmmc/v2.rs8
-rw-r--r--embassy-stm32/src/usart/v2.rs3
-rw-r--r--embassy/src/blocking_mutex/mod.rs (renamed from embassy/src/util/mutex.rs)2
-rw-r--r--embassy/src/channel/mod.rs4
-rw-r--r--embassy/src/channel/mpsc.rs (renamed from embassy/src/util/mpsc.rs)15
-rw-r--r--embassy/src/channel/signal.rs73
-rw-r--r--embassy/src/lib.rs4
-rw-r--r--embassy/src/util/mod.rs16
-rw-r--r--embassy/src/util/on_drop.rs24
-rw-r--r--embassy/src/util/signal.rs171
-rw-r--r--embassy/src/waitqueue/mod.rs5
-rw-r--r--embassy/src/waitqueue/waker.rs (renamed from embassy/src/util/waker.rs)3
-rw-r--r--embassy/src/waitqueue/waker_agnostic.rs (renamed from embassy/src/util/waker_agnostic.rs)2
-rw-r--r--examples/nrf/src/bin/mpsc.rs5
-rw-r--r--examples/stm32wl55/src/bin/subghz.rs32
37 files changed, 194 insertions, 266 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ed01f7557..a5a656637 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -6,11 +6,12 @@
6 "rust-analyzer.checkOnSave.allTargets": false, 6 "rust-analyzer.checkOnSave.allTargets": false,
7 "rust-analyzer.cargo.noDefaultFeatures": true, 7 "rust-analyzer.cargo.noDefaultFeatures": true,
8 "rust-analyzer.checkOnSave.noDefaultFeatures": true, 8 "rust-analyzer.checkOnSave.noDefaultFeatures": true,
9 //"rust-analyzer.cargo.target": "thumbv7em-none-eabi", 9 "rust-analyzer.cargo.target": "thumbv7em-none-eabi",
10 "rust-analyzer.cargo.features": [ 10 "rust-analyzer.cargo.features": [
11 // These are needed to prevent embassy-net from failing to build 11 // These are needed to prevent embassy-net from failing to build
12 "embassy-net/medium-ethernet", 12 "embassy-net/medium-ethernet",
13 "embassy-net/tcp", 13 "embassy-net/tcp",
14 "embassy-net/pool-16",
14 ], 15 ],
15 "rust-analyzer.procMacro.enable": true, 16 "rust-analyzer.procMacro.enable": true,
16 "rust-analyzer.cargo.runBuildScripts": true, 17 "rust-analyzer.cargo.runBuildScripts": true,
diff --git a/embassy/src/util/drop_bomb.rs b/embassy-hal-common/src/drop.rs
index efb36a97d..74a484de7 100644
--- a/embassy/src/util/drop_bomb.rs
+++ b/embassy-hal-common/src/drop.rs
@@ -1,4 +1,27 @@
1use core::mem; 1use core::mem;
2use core::mem::MaybeUninit;
3
4pub struct OnDrop<F: FnOnce()> {
5 f: MaybeUninit<F>,
6}
7
8impl<F: FnOnce()> OnDrop<F> {
9 pub fn new(f: F) -> Self {
10 Self {
11 f: MaybeUninit::new(f),
12 }
13 }
14
15 pub fn defuse(self) {
16 mem::forget(self)
17 }
18}
19
20impl<F: FnOnce()> Drop for OnDrop<F> {
21 fn drop(&mut self) {
22 unsafe { self.f.as_ptr().read()() }
23 }
24}
2 25
3/// An explosive ordinance that panics if it is improperly disposed of. 26/// An explosive ordinance that panics if it is improperly disposed of.
4/// 27///
diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-common/src/lib.rs
index ea20747eb..01e2d3aee 100644
--- a/embassy-hal-common/src/lib.rs
+++ b/embassy-hal-common/src/lib.rs
@@ -3,6 +3,7 @@
3// This mod MUST go first, so that the others see its macros. 3// This mod MUST go first, so that the others see its macros.
4pub(crate) mod fmt; 4pub(crate) mod fmt;
5 5
6pub mod drop;
6pub mod interrupt; 7pub mod interrupt;
7mod macros; 8mod macros;
8pub mod peripheral; 9pub mod peripheral;
diff --git a/embassy-hal-common/src/usb/usb_serial.rs b/embassy-hal-common/src/usb/usb_serial.rs
index 8b27152b5..ca43a4d73 100644
--- a/embassy-hal-common/src/usb/usb_serial.rs
+++ b/embassy-hal-common/src/usb/usb_serial.rs
@@ -4,7 +4,7 @@ use core::pin::Pin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
6use embassy::io::{self, AsyncBufRead, AsyncWrite}; 6use embassy::io::{self, AsyncBufRead, AsyncWrite};
7use embassy::util::WakerRegistration; 7use embassy::waitqueue::WakerRegistration;
8use usb_device::bus::UsbBus; 8use usb_device::bus::UsbBus;
9use usb_device::class_prelude::*; 9use usb_device::class_prelude::*;
10use usb_device::UsbError; 10use usb_device::UsbError;
diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs
index 5f871bd1f..f26808cd0 100644
--- a/embassy-net/src/stack.rs
+++ b/embassy-net/src/stack.rs
@@ -2,9 +2,9 @@ use core::cell::RefCell;
2use core::future::Future; 2use core::future::Future;
3use core::task::Context; 3use core::task::Context;
4use core::task::Poll; 4use core::task::Poll;
5use embassy::blocking_mutex::ThreadModeMutex;
5use embassy::time::{Instant, Timer}; 6use embassy::time::{Instant, Timer};
6use embassy::util::ThreadModeMutex; 7use embassy::waitqueue::WakerRegistration;
7use embassy::util::WakerRegistration;
8use futures::pin_mut; 8use futures::pin_mut;
9use smoltcp::iface::InterfaceBuilder; 9use smoltcp::iface::InterfaceBuilder;
10#[cfg(feature = "medium-ethernet")] 10#[cfg(feature = "medium-ethernet")]
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 90ce49582..cd08875cd 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -6,7 +6,8 @@ use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7use embassy::interrupt::InterruptExt; 7use embassy::interrupt::InterruptExt;
8use embassy::io::{AsyncBufRead, AsyncWrite, Result}; 8use embassy::io::{AsyncBufRead, AsyncWrite, Result};
9use embassy::util::{Unborrow, WakerRegistration}; 9use embassy::util::Unborrow;
10use embassy::waitqueue::WakerRegistration;
10use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 11use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
11use embassy_hal_common::ring_buffer::RingBuffer; 12use embassy_hal_common::ring_buffer::RingBuffer;
12use embassy_hal_common::{low_power_wait_until, unborrow}; 13use embassy_hal_common::{low_power_wait_until, unborrow};
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 847b2fbf3..001ee7fb8 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -4,7 +4,7 @@ use core::marker::PhantomData;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow}; 6use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow};
7use embassy::util::AtomicWaker; 7use embassy::waitqueue::AtomicWaker;
8use embassy_hal_common::unsafe_impl_unborrow; 8use embassy_hal_common::unsafe_impl_unborrow;
9use embedded_hal::digital::v2::{InputPin, StatefulOutputPin}; 9use embedded_hal::digital::v2::{InputPin, StatefulOutputPin};
10use futures::future::poll_fn; 10use futures::future::poll_fn;
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 28becfd56..e87094250 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -6,7 +6,8 @@ use core::ptr;
6use core::task::Poll; 6use core::task::Poll;
7use embassy::interrupt::{Interrupt, InterruptExt}; 7use embassy::interrupt::{Interrupt, InterruptExt};
8use embassy::traits::flash::{Error, Flash}; 8use embassy::traits::flash::{Error, Flash};
9use embassy::util::{AtomicWaker, DropBomb, Unborrow}; 9use embassy::util::Unborrow;
10use embassy_hal_common::drop::DropBomb;
10use embassy_hal_common::unborrow; 11use embassy_hal_common::unborrow;
11use futures::future::poll_fn; 12use futures::future::poll_fn;
12 13
@@ -397,6 +398,8 @@ impl<'d, T: Instance> Flash for Qspi<'d, T> {
397} 398}
398 399
399pub(crate) mod sealed { 400pub(crate) mod sealed {
401 use embassy::waitqueue::AtomicWaker;
402
400 use super::*; 403 use super::*;
401 404
402 pub struct State { 405 pub struct State {
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index 6cdcccf3b..20d033a12 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -8,9 +8,9 @@ use core::task::Poll;
8 8
9use embassy::interrupt::InterruptExt; 9use embassy::interrupt::InterruptExt;
10use embassy::traits; 10use embassy::traits;
11use embassy::util::AtomicWaker;
12use embassy::util::OnDrop;
13use embassy::util::Unborrow; 11use embassy::util::Unborrow;
12use embassy::waitqueue::AtomicWaker;
13use embassy_hal_common::drop::OnDrop;
14use embassy_hal_common::unborrow; 14use embassy_hal_common::unborrow;
15use futures::future::poll_fn; 15use futures::future::poll_fn;
16use rand_core::RngCore; 16use rand_core::RngCore;
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index bc7f34716..e909e7d5a 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -3,7 +3,8 @@ use core::marker::PhantomData;
3use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5use embassy::interrupt::InterruptExt; 5use embassy::interrupt::InterruptExt;
6use embassy::util::{AtomicWaker, Unborrow}; 6use embassy::util::Unborrow;
7use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::unborrow; 8use embassy_hal_common::unborrow;
8use futures::future::poll_fn; 9use futures::future::poll_fn;
9 10
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 9a7fb4f67..e88fb460c 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7use embassy::interrupt::InterruptExt; 7use embassy::interrupt::InterruptExt;
8use embassy::traits; 8use embassy::traits;
9use embassy::util::{AtomicWaker, Unborrow}; 9use embassy::util::Unborrow;
10use embassy_hal_common::unborrow; 10use embassy_hal_common::unborrow;
11use futures::future::poll_fn; 11use futures::future::poll_fn;
12use traits::spi::{FullDuplex, Read, Spi, Write}; 12use traits::spi::{FullDuplex, Read, Spi, Write};
@@ -359,6 +359,8 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spim<'d, T> {
359} 359}
360 360
361pub(crate) mod sealed { 361pub(crate) mod sealed {
362 use embassy::waitqueue::AtomicWaker;
363
362 use super::*; 364 use super::*;
363 365
364 pub struct State { 366 pub struct State {
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs
index f93ebb54a..19356c2d2 100644
--- a/embassy-nrf/src/time_driver.rs
+++ b/embassy-nrf/src/time_driver.rs
@@ -2,9 +2,9 @@ use core::cell::Cell;
2use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; 2use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
3use core::{mem, ptr}; 3use core::{mem, ptr};
4use critical_section::CriticalSection; 4use critical_section::CriticalSection;
5use embassy::blocking_mutex::CriticalSectionMutex as Mutex;
5use embassy::interrupt::{Interrupt, InterruptExt}; 6use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::time::driver::{AlarmHandle, Driver}; 7use embassy::time::driver::{AlarmHandle, Driver};
7use embassy::util::CriticalSectionMutex as Mutex;
8 8
9use crate::interrupt; 9use crate::interrupt;
10use crate::pac; 10use crate::pac;
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index 638fd8229..5690ff0d8 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -5,8 +5,9 @@ use core::task::Poll;
5 5
6use embassy::interrupt::Interrupt; 6use embassy::interrupt::Interrupt;
7use embassy::interrupt::InterruptExt; 7use embassy::interrupt::InterruptExt;
8use embassy::util::OnDrop;
9use embassy::util::Unborrow; 8use embassy::util::Unborrow;
9use embassy::waitqueue::AtomicWaker;
10use embassy_hal_common::drop::OnDrop;
10use embassy_hal_common::unborrow; 11use embassy_hal_common::unborrow;
11use futures::future::poll_fn; 12use futures::future::poll_fn;
12 13
@@ -15,7 +16,6 @@ use crate::ppi::Event;
15use crate::ppi::Task; 16use crate::ppi::Task;
16 17
17pub(crate) mod sealed { 18pub(crate) mod sealed {
18 use embassy::util::AtomicWaker;
19 19
20 use super::*; 20 use super::*;
21 21
@@ -43,8 +43,8 @@ macro_rules! impl_timer {
43 fn regs() -> &'static pac::timer0::RegisterBlock { 43 fn regs() -> &'static pac::timer0::RegisterBlock {
44 unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } 44 unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) }
45 } 45 }
46 fn waker(n: usize) -> &'static ::embassy::util::AtomicWaker { 46 fn waker(n: usize) -> &'static ::embassy::waitqueue::AtomicWaker {
47 use ::embassy::util::AtomicWaker; 47 use ::embassy::waitqueue::AtomicWaker;
48 const NEW_AW: AtomicWaker = AtomicWaker::new(); 48 const NEW_AW: AtomicWaker = AtomicWaker::new();
49 static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs]; 49 static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs];
50 &WAKERS[n] 50 &WAKERS[n]
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index ac263bad7..8173f66b0 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -12,7 +12,8 @@ use core::sync::atomic::{compiler_fence, Ordering::SeqCst};
12use core::task::Poll; 12use core::task::Poll;
13use embassy::interrupt::{Interrupt, InterruptExt}; 13use embassy::interrupt::{Interrupt, InterruptExt};
14use embassy::traits; 14use embassy::traits;
15use embassy::util::{AtomicWaker, Unborrow}; 15use embassy::util::Unborrow;
16use embassy::waitqueue::AtomicWaker;
16use embassy_hal_common::unborrow; 17use embassy_hal_common::unborrow;
17use futures::future::poll_fn; 18use futures::future::poll_fn;
18use traits::i2c::I2c; 19use traits::i2c::I2c;
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index a6909be68..320426060 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -8,7 +8,8 @@ use core::sync::atomic::{compiler_fence, Ordering};
8use core::task::Poll; 8use core::task::Poll;
9use embassy::interrupt::InterruptExt; 9use embassy::interrupt::InterruptExt;
10use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; 10use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write};
11use embassy::util::{AtomicWaker, OnDrop, Unborrow}; 11use embassy::util::Unborrow;
12use embassy_hal_common::drop::OnDrop;
12use embassy_hal_common::unborrow; 13use embassy_hal_common::unborrow;
13use futures::future::poll_fn; 14use futures::future::poll_fn;
14 15
@@ -439,6 +440,8 @@ impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> {
439} 440}
440 441
441pub(crate) mod sealed { 442pub(crate) mod sealed {
443 use embassy::waitqueue::AtomicWaker;
444
442 use super::*; 445 use super::*;
443 446
444 pub struct State { 447 pub struct State {
diff --git a/embassy-rp/src/timer.rs b/embassy-rp/src/timer.rs
index ed265c47f..b3c047ca4 100644
--- a/embassy-rp/src/timer.rs
+++ b/embassy-rp/src/timer.rs
@@ -1,9 +1,9 @@
1use atomic_polyfill::{AtomicU8, Ordering}; 1use atomic_polyfill::{AtomicU8, Ordering};
2use core::cell::Cell; 2use core::cell::Cell;
3use critical_section::CriticalSection; 3use critical_section::CriticalSection;
4use embassy::blocking_mutex::CriticalSectionMutex as Mutex;
4use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
5use embassy::time::driver::{AlarmHandle, Driver}; 6use embassy::time::driver::{AlarmHandle, Driver};
6use embassy::util::CriticalSectionMutex as Mutex;
7 7
8use crate::{interrupt, pac}; 8use crate::{interrupt, pac};
9 9
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index fbd753a71..35c0b3ee7 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -5,7 +5,8 @@ use core::sync::atomic::{fence, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy::interrupt::{Interrupt, InterruptExt}; 7use embassy::interrupt::{Interrupt, InterruptExt};
8use embassy::util::{AtomicWaker, OnDrop}; 8use embassy::waitqueue::AtomicWaker;
9use embassy_hal_common::drop::OnDrop;
9use futures::future::poll_fn; 10use futures::future::poll_fn;
10 11
11use crate::dma::{Channel, Request}; 12use crate::dma::{Channel, Request};
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index bce9656d1..ec5ac98a0 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -3,7 +3,8 @@ use core::sync::atomic::{fence, Ordering};
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::util::{AtomicWaker, OnDrop}; 6use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::drop::OnDrop;
7use futures::future::poll_fn; 8use futures::future::poll_fn;
8 9
9use crate::interrupt; 10use crate::interrupt;
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 42eb0680c..ff734f78c 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -2,7 +2,8 @@ use core::marker::PhantomData;
2use core::sync::atomic::{fence, Ordering}; 2use core::sync::atomic::{fence, Ordering};
3use core::task::Waker; 3use core::task::Waker;
4 4
5use embassy::util::{AtomicWaker, Unborrow}; 5use embassy::util::Unborrow;
6use embassy::waitqueue::AtomicWaker;
6use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 7use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
7use embassy_hal_common::unborrow; 8use embassy_hal_common::unborrow;
8use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; 9use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index 8e4989a3e..6d3de3a15 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -4,7 +4,8 @@ use core::marker::PhantomData;
4use core::pin::Pin; 4use core::pin::Pin;
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; 6use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
7use embassy::util::{AtomicWaker, Unborrow}; 7use embassy::util::Unborrow;
8use embassy::waitqueue::AtomicWaker;
8use embassy_hal_common::unsafe_impl_unborrow; 9use embassy_hal_common::unsafe_impl_unborrow;
9use embedded_hal::digital::v2::InputPin; 10use embedded_hal::digital::v2::InputPin;
10 11
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index fc4f52cf3..5e9e24392 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -4,7 +4,9 @@ use core::task::Poll;
4 4
5use atomic_polyfill::{AtomicUsize, Ordering}; 5use atomic_polyfill::{AtomicUsize, Ordering};
6use embassy::interrupt::InterruptExt; 6use embassy::interrupt::InterruptExt;
7use embassy::util::{AtomicWaker, OnDrop, Unborrow}; 7use embassy::util::Unborrow;
8use embassy::waitqueue::AtomicWaker;
9use embassy_hal_common::drop::OnDrop;
8use embassy_hal_common::unborrow; 10use embassy_hal_common::unborrow;
9use embedded_hal::blocking::i2c::Read; 11use embedded_hal::blocking::i2c::Read;
10use embedded_hal::blocking::i2c::Write; 12use embedded_hal::blocking::i2c::Write;
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 0afba3ba7..5655ed967 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -3,7 +3,8 @@
3use core::future::Future; 3use core::future::Future;
4use core::task::Poll; 4use core::task::Poll;
5use embassy::traits; 5use embassy::traits;
6use embassy::util::{AtomicWaker, Unborrow}; 6use embassy::util::Unborrow;
7use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::unborrow; 8use embassy_hal_common::unborrow;
8use futures::future::poll_fn; 9use futures::future::poll_fn;
9use rand_core::{CryptoRng, RngCore}; 10use rand_core::{CryptoRng, RngCore};
diff --git a/embassy-stm32/src/sdmmc/v2.rs b/embassy-stm32/src/sdmmc/v2.rs
index aa1d68ae7..6032c2bb1 100644
--- a/embassy-stm32/src/sdmmc/v2.rs
+++ b/embassy-stm32/src/sdmmc/v2.rs
@@ -5,7 +5,9 @@ use core::marker::PhantomData;
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy::interrupt::InterruptExt; 7use embassy::interrupt::InterruptExt;
8use embassy::util::{AtomicWaker, OnDrop, Unborrow}; 8use embassy::util::Unborrow;
9use embassy::waitqueue::AtomicWaker;
10use embassy_hal_common::drop::OnDrop;
9use embassy_hal_common::unborrow; 11use embassy_hal_common::unborrow;
10use futures::future::poll_fn; 12use futures::future::poll_fn;
11use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
@@ -1479,8 +1481,8 @@ crate::pac::peripherals!(
1479 INNER 1481 INNER
1480 } 1482 }
1481 1483
1482 fn state() -> &'static ::embassy::util::AtomicWaker { 1484 fn state() -> &'static ::embassy::waitqueue::AtomicWaker {
1483 static WAKER: ::embassy::util::AtomicWaker = ::embassy::util::AtomicWaker::new(); 1485 static WAKER: ::embassy::waitqueue::AtomicWaker = ::embassy::waitqueue::AtomicWaker::new();
1484 &WAKER 1486 &WAKER
1485 } 1487 }
1486 } 1488 }
diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs
index 92c0cbc2e..fc3036404 100644
--- a/embassy-stm32/src/usart/v2.rs
+++ b/embassy-stm32/src/usart/v2.rs
@@ -4,7 +4,8 @@ use core::marker::PhantomData;
4use core::pin::Pin; 4use core::pin::Pin;
5use core::task::Context; 5use core::task::Context;
6use core::task::Poll; 6use core::task::Poll;
7use embassy::util::{Unborrow, WakerRegistration}; 7use embassy::util::Unborrow;
8use embassy::waitqueue::WakerRegistration;
8use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 9use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
9use embassy_hal_common::ring_buffer::RingBuffer; 10use embassy_hal_common::ring_buffer::RingBuffer;
10use embassy_hal_common::unborrow; 11use embassy_hal_common::unborrow;
diff --git a/embassy/src/util/mutex.rs b/embassy/src/blocking_mutex/mod.rs
index 9a00a409e..d112d2ede 100644
--- a/embassy/src/util/mutex.rs
+++ b/embassy/src/blocking_mutex/mod.rs
@@ -1,3 +1,5 @@
1//! Blocking mutex (not async)
2
1use core::cell::UnsafeCell; 3use core::cell::UnsafeCell;
2use critical_section::CriticalSection; 4use critical_section::CriticalSection;
3 5
diff --git a/embassy/src/channel/mod.rs b/embassy/src/channel/mod.rs
new file mode 100644
index 000000000..9e8c67ee9
--- /dev/null
+++ b/embassy/src/channel/mod.rs
@@ -0,0 +1,4 @@
1//! Async channels
2
3pub mod mpsc;
4pub mod signal;
diff --git a/embassy/src/util/mpsc.rs b/embassy/src/channel/mpsc.rs
index a0f884ec6..b20d48a95 100644
--- a/embassy/src/util/mpsc.rs
+++ b/embassy/src/channel/mpsc.rs
@@ -49,11 +49,8 @@ use core::task::Waker;
49 49
50use futures::Future; 50use futures::Future;
51 51
52use super::CriticalSectionMutex; 52use crate::blocking_mutex::{CriticalSectionMutex, Mutex, NoopMutex, ThreadModeMutex};
53use super::Mutex; 53use crate::waitqueue::WakerRegistration;
54use super::NoopMutex;
55use super::ThreadModeMutex;
56use super::WakerRegistration;
57 54
58/// Send values to the associated `Receiver`. 55/// Send values to the associated `Receiver`.
59/// 56///
@@ -108,8 +105,8 @@ unsafe impl<'ch, M, T, const N: usize> Sync for Receiver<'ch, M, T, N> where
108/// their channel. The following will therefore fail compilation: 105/// their channel. The following will therefore fail compilation:
109//// 106////
110/// ```compile_fail 107/// ```compile_fail
111/// use embassy::util::mpsc; 108/// use embassy::channel::mpsc;
112/// use embassy::util::mpsc::{Channel, WithThreadModeOnly}; 109/// use embassy::channel::mpsc::{Channel, WithThreadModeOnly};
113/// 110///
114/// let (sender, receiver) = { 111/// let (sender, receiver) = {
115/// let mut channel = Channel::<WithThreadModeOnly, u32, 3>::with_thread_mode_only(); 112/// let mut channel = Channel::<WithThreadModeOnly, u32, 3>::with_thread_mode_only();
@@ -635,8 +632,8 @@ where
635 /// Establish a new bounded channel. For example, to create one with a NoopMutex: 632 /// Establish a new bounded channel. For example, to create one with a NoopMutex:
636 /// 633 ///
637 /// ``` 634 /// ```
638 /// use embassy::util::mpsc; 635 /// use embassy::channel::mpsc;
639 /// use embassy::util::mpsc::{Channel, WithNoThreads}; 636 /// use embassy::channel::mpsc::{Channel, WithNoThreads};
640 /// 637 ///
641 /// // Declare a bounded channel of 3 u32s. 638 /// // Declare a bounded channel of 3 u32s.
642 /// let mut channel = Channel::<WithNoThreads, u32, 3>::new(); 639 /// let mut channel = Channel::<WithNoThreads, u32, 3>::new();
diff --git a/embassy/src/channel/signal.rs b/embassy/src/channel/signal.rs
new file mode 100644
index 000000000..d5698732c
--- /dev/null
+++ b/embassy/src/channel/signal.rs
@@ -0,0 +1,73 @@
1use core::cell::UnsafeCell;
2use core::future::Future;
3use core::mem;
4use core::task::{Context, Poll, Waker};
5
6/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks.
7///
8/// For more advanced use cases, please consider [futures-intrusive](https://crates.io/crates/futures-intrusive) channels or mutexes.
9pub struct Signal<T> {
10 state: UnsafeCell<State<T>>,
11}
12
13enum State<T> {
14 None,
15 Waiting(Waker),
16 Signaled(T),
17}
18
19unsafe impl<T: Send> Send for Signal<T> {}
20unsafe impl<T: Send> Sync for Signal<T> {}
21
22impl<T: Send> Signal<T> {
23 pub const fn new() -> Self {
24 Self {
25 state: UnsafeCell::new(State::None),
26 }
27 }
28
29 /// Mark this Signal as completed.
30 pub fn signal(&self, val: T) {
31 critical_section::with(|_| unsafe {
32 let state = &mut *self.state.get();
33 if let State::Waiting(waker) = mem::replace(state, State::Signaled(val)) {
34 waker.wake();
35 }
36 })
37 }
38
39 pub fn reset(&self) {
40 critical_section::with(|_| unsafe {
41 let state = &mut *self.state.get();
42 *state = State::None
43 })
44 }
45
46 pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> {
47 critical_section::with(|_| unsafe {
48 let state = &mut *self.state.get();
49 match state {
50 State::None => {
51 *state = State::Waiting(cx.waker().clone());
52 Poll::Pending
53 }
54 State::Waiting(w) if w.will_wake(cx.waker()) => Poll::Pending,
55 State::Waiting(_) => panic!("waker overflow"),
56 State::Signaled(_) => match mem::replace(state, State::None) {
57 State::Signaled(res) => Poll::Ready(res),
58 _ => unreachable!(),
59 },
60 }
61 })
62 }
63
64 /// Future that completes when this Signal has been signaled.
65 pub fn wait(&self) -> impl Future<Output = T> + '_ {
66 futures::future::poll_fn(move |cx| self.poll_wait(cx))
67 }
68
69 /// non-blocking method to check whether this signal has been signaled.
70 pub fn signaled(&self) -> bool {
71 critical_section::with(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_)))
72 }
73}
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index 9e050a57a..847142285 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -7,6 +7,10 @@
7// This mod MUST go first, so that the others see its macros. 7// This mod MUST go first, so that the others see its macros.
8pub(crate) mod fmt; 8pub(crate) mod fmt;
9 9
10pub mod blocking_mutex;
11pub mod channel;
12pub mod waitqueue;
13
10pub mod executor; 14pub mod executor;
11pub mod interrupt; 15pub mod interrupt;
12pub mod io; 16pub mod io;
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs
index e66576b33..f832fa2f6 100644
--- a/embassy/src/util/mod.rs
+++ b/embassy/src/util/mod.rs
@@ -1,21 +1,7 @@
1//! Async utilities 1//! Misc utilities
2mod drop_bomb;
3mod forever; 2mod forever;
4mod mutex;
5mod on_drop;
6mod signal;
7 3
8#[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")]
9mod waker;
10
11pub use drop_bomb::*;
12pub use forever::*; 4pub use forever::*;
13pub mod mpsc;
14pub use mutex::*;
15pub use on_drop::*;
16pub use signal::*;
17pub use waker::*;
18
19/// Unsafely unborrow an owned singleton out of a `&mut`. 5/// Unsafely unborrow an owned singleton out of a `&mut`.
20/// 6///
21/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`. 7/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
diff --git a/embassy/src/util/on_drop.rs b/embassy/src/util/on_drop.rs
deleted file mode 100644
index 10f3407f4..000000000
--- a/embassy/src/util/on_drop.rs
+++ /dev/null
@@ -1,24 +0,0 @@
1use core::mem;
2use core::mem::MaybeUninit;
3
4pub struct OnDrop<F: FnOnce()> {
5 f: MaybeUninit<F>,
6}
7
8impl<F: FnOnce()> OnDrop<F> {
9 pub fn new(f: F) -> Self {
10 Self {
11 f: MaybeUninit::new(f),
12 }
13 }
14
15 pub fn defuse(self) {
16 mem::forget(self)
17 }
18}
19
20impl<F: FnOnce()> Drop for OnDrop<F> {
21 fn drop(&mut self) {
22 unsafe { self.f.as_ptr().read()() }
23 }
24}
diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs
deleted file mode 100644
index bb832533c..000000000
--- a/embassy/src/util/signal.rs
+++ /dev/null
@@ -1,171 +0,0 @@
1use core::cell::UnsafeCell;
2use core::future::Future;
3use core::mem;
4use core::ptr;
5use core::task::{Context, Poll, Waker};
6use cortex_m::peripheral::NVIC;
7use cortex_m::peripheral::{scb, SCB};
8use executor::raw::TaskHeader;
9use ptr::NonNull;
10
11use crate::executor;
12use crate::interrupt::{Interrupt, InterruptExt};
13
14/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks.
15///
16/// For more advanced use cases, please consider [futures-intrusive](https://crates.io/crates/futures-intrusive) channels or mutexes.
17pub struct Signal<T> {
18 state: UnsafeCell<State<T>>,
19}
20
21enum State<T> {
22 None,
23 Waiting(Waker),
24 Signaled(T),
25}
26
27unsafe impl<T: Send> Send for Signal<T> {}
28unsafe impl<T: Send> Sync for Signal<T> {}
29
30impl<T: Send> Signal<T> {
31 pub const fn new() -> Self {
32 Self {
33 state: UnsafeCell::new(State::None),
34 }
35 }
36
37 /// Mark this Signal as completed.
38 pub fn signal(&self, val: T) {
39 critical_section::with(|_| unsafe {
40 let state = &mut *self.state.get();
41 if let State::Waiting(waker) = mem::replace(state, State::Signaled(val)) {
42 waker.wake();
43 }
44 })
45 }
46
47 pub fn reset(&self) {
48 critical_section::with(|_| unsafe {
49 let state = &mut *self.state.get();
50 *state = State::None
51 })
52 }
53
54 pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> {
55 critical_section::with(|_| unsafe {
56 let state = &mut *self.state.get();
57 match state {
58 State::None => {
59 *state = State::Waiting(cx.waker().clone());
60 Poll::Pending
61 }
62 State::Waiting(w) if w.will_wake(cx.waker()) => Poll::Pending,
63 State::Waiting(_) => panic!("waker overflow"),
64 State::Signaled(_) => match mem::replace(state, State::None) {
65 State::Signaled(res) => Poll::Ready(res),
66 _ => unreachable!(),
67 },
68 }
69 })
70 }
71
72 /// Future that completes when this Signal has been signaled.
73 pub fn wait(&self) -> impl Future<Output = T> + '_ {
74 futures::future::poll_fn(move |cx| self.poll_wait(cx))
75 }
76
77 /// non-blocking method to check whether this signal has been signaled.
78 pub fn signaled(&self) -> bool {
79 critical_section::with(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_)))
80 }
81}
82
83// ==========
84
85pub fn wake_on_interrupt(interrupt: &mut impl Interrupt, waker: &Waker) {
86 interrupt.disable();
87 interrupt.set_handler(irq_wake_handler);
88 interrupt.set_handler_context(unsafe { executor::raw::task_from_waker(waker) }.as_ptr() as _);
89 interrupt.enable();
90}
91
92unsafe fn irq_wake_handler(ctx: *mut ()) {
93 if let Some(task) = NonNull::new(ctx as *mut TaskHeader) {
94 executor::raw::wake_task(task);
95 }
96
97 let irq = match SCB::vect_active() {
98 scb::VectActive::Interrupt { irqn } => irqn,
99 _ => unreachable!(),
100 };
101
102 NVIC::mask(crate::interrupt::NrWrap(irq as u16));
103}
104
105// ==========
106
107struct NrWrap(u8);
108unsafe impl cortex_m::interrupt::Nr for NrWrap {
109 fn nr(&self) -> u8 {
110 self.0
111 }
112}
113
114/// Creates a future that completes when the specified Interrupt is triggered.
115///
116/// The input handler is unregistered when this Future is dropped.
117///
118/// Example:
119/// ``` no_compile
120/// use embassy::traits::*;
121/// use embassy::util::InterruptFuture;
122/// use embassy_stm32::interrupt; // Adjust this to your MCU's embassy HAL.
123/// #[embassy::task]
124/// async fn demo_interrupt_future() {
125/// // Using STM32f446 interrupt names, adjust this to your application as necessary.
126/// // Wait for TIM2 to tick.
127/// let mut tim2_interrupt = interrupt::take!(TIM2);
128/// InterruptFuture::new(&mut tim2_interrupt).await;
129/// // TIM2 interrupt went off, do something...
130/// }
131/// ```
132pub struct InterruptFuture<'a, I: Interrupt> {
133 interrupt: &'a mut I,
134}
135
136impl<'a, I: Interrupt> Drop for InterruptFuture<'a, I> {
137 fn drop(&mut self) {
138 self.interrupt.disable();
139 self.interrupt.remove_handler();
140 }
141}
142
143impl<'a, I: Interrupt> InterruptFuture<'a, I> {
144 pub fn new(interrupt: &'a mut I) -> Self {
145 interrupt.disable();
146 interrupt.set_handler(irq_wake_handler);
147 interrupt.set_handler_context(ptr::null_mut());
148 interrupt.unpend();
149 interrupt.enable();
150
151 Self { interrupt }
152 }
153}
154
155impl<'a, I: Interrupt> Unpin for InterruptFuture<'a, I> {}
156
157impl<'a, I: Interrupt> Future for InterruptFuture<'a, I> {
158 type Output = ();
159
160 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
161 let s = unsafe { self.get_unchecked_mut() };
162 s.interrupt.set_handler_context(unsafe {
163 executor::raw::task_from_waker(&cx.waker()).cast().as_ptr()
164 });
165 if s.interrupt.is_enabled() {
166 Poll::Pending
167 } else {
168 Poll::Ready(())
169 }
170 }
171}
diff --git a/embassy/src/waitqueue/mod.rs b/embassy/src/waitqueue/mod.rs
new file mode 100644
index 000000000..a2bafad99
--- /dev/null
+++ b/embassy/src/waitqueue/mod.rs
@@ -0,0 +1,5 @@
1//! Async low-level wait queues
2
3#[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")]
4mod waker;
5pub use waker::*;
diff --git a/embassy/src/util/waker.rs b/embassy/src/waitqueue/waker.rs
index 1ac6054f9..9eddbdaa1 100644
--- a/embassy/src/util/waker.rs
+++ b/embassy/src/waitqueue/waker.rs
@@ -1,8 +1,7 @@
1use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
1use core::ptr::{self, NonNull}; 2use core::ptr::{self, NonNull};
2use core::task::Waker; 3use core::task::Waker;
3 4
4use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
5
6use crate::executor::raw::{task_from_waker, wake_task, TaskHeader}; 5use crate::executor::raw::{task_from_waker, wake_task, TaskHeader};
7 6
8/// Utility struct to register and wake a waker. 7/// Utility struct to register and wake a waker.
diff --git a/embassy/src/util/waker_agnostic.rs b/embassy/src/waitqueue/waker_agnostic.rs
index 1675c53a0..f583fa6f4 100644
--- a/embassy/src/util/waker_agnostic.rs
+++ b/embassy/src/waitqueue/waker_agnostic.rs
@@ -2,7 +2,7 @@ use core::cell::Cell;
2use core::mem; 2use core::mem;
3use core::task::Waker; 3use core::task::Waker;
4 4
5use crate::util::CriticalSectionMutex as Mutex; 5use crate::blocking_mutex::CriticalSectionMutex as Mutex;
6 6
7/// Utility struct to register and wake a waker. 7/// Utility struct to register and wake a waker.
8#[derive(Debug)] 8#[derive(Debug)]
diff --git a/examples/nrf/src/bin/mpsc.rs b/examples/nrf/src/bin/mpsc.rs
index c8cc67d77..79fa3dfb9 100644
--- a/examples/nrf/src/bin/mpsc.rs
+++ b/examples/nrf/src/bin/mpsc.rs
@@ -6,14 +6,13 @@
6mod example_common; 6mod example_common;
7 7
8use defmt::unwrap; 8use defmt::unwrap;
9use embassy::channel::mpsc::{self, Channel, Sender, TryRecvError, WithNoThreads};
9use embassy::executor::Spawner; 10use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 11use embassy::time::{Duration, Timer};
11use embassy::util::mpsc::TryRecvError; 12use embassy::util::Forever;
12use embassy::util::{mpsc, Forever};
13use embassy_nrf::gpio::{Level, Output, OutputDrive}; 13use embassy_nrf::gpio::{Level, Output, OutputDrive};
14use embassy_nrf::Peripherals; 14use embassy_nrf::Peripherals;
15use embedded_hal::digital::v2::OutputPin; 15use embedded_hal::digital::v2::OutputPin;
16use mpsc::{Channel, Sender, WithNoThreads};
17 16
18enum LedState { 17enum LedState {
19 On, 18 On,
diff --git a/examples/stm32wl55/src/bin/subghz.rs b/examples/stm32wl55/src/bin/subghz.rs
index 1e406886a..89549c766 100644
--- a/examples/stm32wl55/src/bin/subghz.rs
+++ b/examples/stm32wl55/src/bin/subghz.rs
@@ -8,16 +8,16 @@
8#[path = "../example_common.rs"] 8#[path = "../example_common.rs"]
9mod example_common; 9mod example_common;
10 10
11use embassy::{traits::gpio::WaitForRisingEdge, util::InterruptFuture}; 11use embassy::channel::signal::Signal;
12use embassy_stm32::{ 12use embassy::interrupt::{Interrupt, InterruptExt};
13 dbgmcu::Dbgmcu, 13use embassy::traits::gpio::WaitForRisingEdge;
14 dma::NoDma, 14use embassy_stm32::dbgmcu::Dbgmcu;
15 exti::ExtiInput, 15use embassy_stm32::dma::NoDma;
16 gpio::{Input, Level, Output, Pull, Speed}, 16use embassy_stm32::exti::ExtiInput;
17 interrupt, 17use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
18 subghz::*, 18use embassy_stm32::interrupt;
19 Peripherals, 19use embassy_stm32::subghz::*;
20}; 20use embassy_stm32::Peripherals;
21use embedded_hal::digital::v2::OutputPin; 21use embedded_hal::digital::v2::OutputPin;
22use example_common::unwrap; 22use example_common::unwrap;
23 23
@@ -83,7 +83,13 @@ async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) {
83 let button = Input::new(p.PA0, Pull::Up); 83 let button = Input::new(p.PA0, Pull::Up);
84 let mut pin = ExtiInput::new(button, p.EXTI0); 84 let mut pin = ExtiInput::new(button, p.EXTI0);
85 85
86 let mut radio_irq = interrupt::take!(SUBGHZ_RADIO); 86 static IRQ_SIGNAL: Signal<()> = Signal::new();
87 let radio_irq = interrupt::take!(SUBGHZ_RADIO);
88 radio_irq.set_handler(|_| {
89 IRQ_SIGNAL.signal(());
90 unsafe { interrupt::SUBGHZ_RADIO::steal() }.disable();
91 });
92
87 let mut radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma); 93 let mut radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma);
88 94
89 defmt::info!("Radio ready for use"); 95 defmt::info!("Radio ready for use");
@@ -118,7 +124,9 @@ async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) {
118 unwrap!(radio.write_buffer(TX_BUF_OFFSET, PING_DATA_BYTES)); 124 unwrap!(radio.write_buffer(TX_BUF_OFFSET, PING_DATA_BYTES));
119 unwrap!(radio.set_tx(Timeout::DISABLED)); 125 unwrap!(radio.set_tx(Timeout::DISABLED));
120 126
121 InterruptFuture::new(&mut radio_irq).await; 127 radio_irq.enable();
128 IRQ_SIGNAL.wait().await;
129
122 let (_, irq_status) = unwrap!(radio.irq_status()); 130 let (_, irq_status) = unwrap!(radio.irq_status());
123 if irq_status & Irq::TxDone.mask() != 0 { 131 if irq_status & Irq::TxDone.mask() != 0 {
124 defmt::info!("TX done"); 132 defmt::info!("TX done");