diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-09-11 01:53:53 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-09-11 02:35:35 +0200 |
| commit | ead987245d083b7e6be7158ea3fb63c8a47bf304 (patch) | |
| tree | 2d51b80e3d4fc2670b64cb05af22cc54202a6104 | |
| parent | 200f881048a8193c490ff5906ebf320ac98a8331 (diff) | |
embassy: Refactor module structure to remove kitchen-sink `util`.
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 @@ | |||
| 1 | use core::mem; | 1 | use core::mem; |
| 2 | use core::mem::MaybeUninit; | ||
| 3 | |||
| 4 | pub struct OnDrop<F: FnOnce()> { | ||
| 5 | f: MaybeUninit<F>, | ||
| 6 | } | ||
| 7 | |||
| 8 | impl<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 | |||
| 20 | impl<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. |
| 4 | pub(crate) mod fmt; | 4 | pub(crate) mod fmt; |
| 5 | 5 | ||
| 6 | pub mod drop; | ||
| 6 | pub mod interrupt; | 7 | pub mod interrupt; |
| 7 | mod macros; | 8 | mod macros; |
| 8 | pub mod peripheral; | 9 | pub 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; | |||
| 4 | use core::task::{Context, Poll}; | 4 | use core::task::{Context, Poll}; |
| 5 | 5 | ||
| 6 | use embassy::io::{self, AsyncBufRead, AsyncWrite}; | 6 | use embassy::io::{self, AsyncBufRead, AsyncWrite}; |
| 7 | use embassy::util::WakerRegistration; | 7 | use embassy::waitqueue::WakerRegistration; |
| 8 | use usb_device::bus::UsbBus; | 8 | use usb_device::bus::UsbBus; |
| 9 | use usb_device::class_prelude::*; | 9 | use usb_device::class_prelude::*; |
| 10 | use usb_device::UsbError; | 10 | use 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; | |||
| 2 | use core::future::Future; | 2 | use core::future::Future; |
| 3 | use core::task::Context; | 3 | use core::task::Context; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | use embassy::blocking_mutex::ThreadModeMutex; | ||
| 5 | use embassy::time::{Instant, Timer}; | 6 | use embassy::time::{Instant, Timer}; |
| 6 | use embassy::util::ThreadModeMutex; | 7 | use embassy::waitqueue::WakerRegistration; |
| 7 | use embassy::util::WakerRegistration; | ||
| 8 | use futures::pin_mut; | 8 | use futures::pin_mut; |
| 9 | use smoltcp::iface::InterfaceBuilder; | 9 | use 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}; | |||
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | use embassy::interrupt::InterruptExt; | 7 | use embassy::interrupt::InterruptExt; |
| 8 | use embassy::io::{AsyncBufRead, AsyncWrite, Result}; | 8 | use embassy::io::{AsyncBufRead, AsyncWrite, Result}; |
| 9 | use embassy::util::{Unborrow, WakerRegistration}; | 9 | use embassy::util::Unborrow; |
| 10 | use embassy::waitqueue::WakerRegistration; | ||
| 10 | use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; | 11 | use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; |
| 11 | use embassy_hal_common::ring_buffer::RingBuffer; | 12 | use embassy_hal_common::ring_buffer::RingBuffer; |
| 12 | use embassy_hal_common::{low_power_wait_until, unborrow}; | 13 | use 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; | |||
| 4 | use core::task::{Context, Poll}; | 4 | use core::task::{Context, Poll}; |
| 5 | use embassy::interrupt::{Interrupt, InterruptExt}; | 5 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow}; | 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow}; |
| 7 | use embassy::util::AtomicWaker; | 7 | use embassy::waitqueue::AtomicWaker; |
| 8 | use embassy_hal_common::unsafe_impl_unborrow; | 8 | use embassy_hal_common::unsafe_impl_unborrow; |
| 9 | use embedded_hal::digital::v2::{InputPin, StatefulOutputPin}; | 9 | use embedded_hal::digital::v2::{InputPin, StatefulOutputPin}; |
| 10 | use futures::future::poll_fn; | 10 | use 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; | |||
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | use embassy::interrupt::{Interrupt, InterruptExt}; | 7 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 8 | use embassy::traits::flash::{Error, Flash}; | 8 | use embassy::traits::flash::{Error, Flash}; |
| 9 | use embassy::util::{AtomicWaker, DropBomb, Unborrow}; | 9 | use embassy::util::Unborrow; |
| 10 | use embassy_hal_common::drop::DropBomb; | ||
| 10 | use embassy_hal_common::unborrow; | 11 | use embassy_hal_common::unborrow; |
| 11 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 12 | 13 | ||
| @@ -397,6 +398,8 @@ impl<'d, T: Instance> Flash for Qspi<'d, T> { | |||
| 397 | } | 398 | } |
| 398 | 399 | ||
| 399 | pub(crate) mod sealed { | 400 | pub(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 | ||
| 9 | use embassy::interrupt::InterruptExt; | 9 | use embassy::interrupt::InterruptExt; |
| 10 | use embassy::traits; | 10 | use embassy::traits; |
| 11 | use embassy::util::AtomicWaker; | ||
| 12 | use embassy::util::OnDrop; | ||
| 13 | use embassy::util::Unborrow; | 11 | use embassy::util::Unborrow; |
| 12 | use embassy::waitqueue::AtomicWaker; | ||
| 13 | use embassy_hal_common::drop::OnDrop; | ||
| 14 | use embassy_hal_common::unborrow; | 14 | use embassy_hal_common::unborrow; |
| 15 | use futures::future::poll_fn; | 15 | use futures::future::poll_fn; |
| 16 | use rand_core::RngCore; | 16 | use 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; | |||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | use embassy::interrupt::InterruptExt; | 5 | use embassy::interrupt::InterruptExt; |
| 6 | use embassy::util::{AtomicWaker, Unborrow}; | 6 | use embassy::util::Unborrow; |
| 7 | use embassy::waitqueue::AtomicWaker; | ||
| 7 | use embassy_hal_common::unborrow; | 8 | use embassy_hal_common::unborrow; |
| 8 | use futures::future::poll_fn; | 9 | use 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}; | |||
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | use embassy::interrupt::InterruptExt; | 7 | use embassy::interrupt::InterruptExt; |
| 8 | use embassy::traits; | 8 | use embassy::traits; |
| 9 | use embassy::util::{AtomicWaker, Unborrow}; | 9 | use embassy::util::Unborrow; |
| 10 | use embassy_hal_common::unborrow; | 10 | use embassy_hal_common::unborrow; |
| 11 | use futures::future::poll_fn; | 11 | use futures::future::poll_fn; |
| 12 | use traits::spi::{FullDuplex, Read, Spi, Write}; | 12 | use 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 | ||
| 361 | pub(crate) mod sealed { | 361 | pub(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; | |||
| 2 | use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; | 2 | use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; |
| 3 | use core::{mem, ptr}; | 3 | use core::{mem, ptr}; |
| 4 | use critical_section::CriticalSection; | 4 | use critical_section::CriticalSection; |
| 5 | use embassy::blocking_mutex::CriticalSectionMutex as Mutex; | ||
| 5 | use embassy::interrupt::{Interrupt, InterruptExt}; | 6 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 6 | use embassy::time::driver::{AlarmHandle, Driver}; | 7 | use embassy::time::driver::{AlarmHandle, Driver}; |
| 7 | use embassy::util::CriticalSectionMutex as Mutex; | ||
| 8 | 8 | ||
| 9 | use crate::interrupt; | 9 | use crate::interrupt; |
| 10 | use crate::pac; | 10 | use 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 | ||
| 6 | use embassy::interrupt::Interrupt; | 6 | use embassy::interrupt::Interrupt; |
| 7 | use embassy::interrupt::InterruptExt; | 7 | use embassy::interrupt::InterruptExt; |
| 8 | use embassy::util::OnDrop; | ||
| 9 | use embassy::util::Unborrow; | 8 | use embassy::util::Unborrow; |
| 9 | use embassy::waitqueue::AtomicWaker; | ||
| 10 | use embassy_hal_common::drop::OnDrop; | ||
| 10 | use embassy_hal_common::unborrow; | 11 | use embassy_hal_common::unborrow; |
| 11 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 12 | 13 | ||
| @@ -15,7 +16,6 @@ use crate::ppi::Event; | |||
| 15 | use crate::ppi::Task; | 16 | use crate::ppi::Task; |
| 16 | 17 | ||
| 17 | pub(crate) mod sealed { | 18 | pub(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}; | |||
| 12 | use core::task::Poll; | 12 | use core::task::Poll; |
| 13 | use embassy::interrupt::{Interrupt, InterruptExt}; | 13 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 14 | use embassy::traits; | 14 | use embassy::traits; |
| 15 | use embassy::util::{AtomicWaker, Unborrow}; | 15 | use embassy::util::Unborrow; |
| 16 | use embassy::waitqueue::AtomicWaker; | ||
| 16 | use embassy_hal_common::unborrow; | 17 | use embassy_hal_common::unborrow; |
| 17 | use futures::future::poll_fn; | 18 | use futures::future::poll_fn; |
| 18 | use traits::i2c::I2c; | 19 | use 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}; | |||
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | use embassy::interrupt::InterruptExt; | 9 | use embassy::interrupt::InterruptExt; |
| 10 | use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; | 10 | use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; |
| 11 | use embassy::util::{AtomicWaker, OnDrop, Unborrow}; | 11 | use embassy::util::Unborrow; |
| 12 | use embassy_hal_common::drop::OnDrop; | ||
| 12 | use embassy_hal_common::unborrow; | 13 | use embassy_hal_common::unborrow; |
| 13 | use futures::future::poll_fn; | 14 | use 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 | ||
| 441 | pub(crate) mod sealed { | 442 | pub(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 @@ | |||
| 1 | use atomic_polyfill::{AtomicU8, Ordering}; | 1 | use atomic_polyfill::{AtomicU8, Ordering}; |
| 2 | use core::cell::Cell; | 2 | use core::cell::Cell; |
| 3 | use critical_section::CriticalSection; | 3 | use critical_section::CriticalSection; |
| 4 | use embassy::blocking_mutex::CriticalSectionMutex as Mutex; | ||
| 4 | use embassy::interrupt::{Interrupt, InterruptExt}; | 5 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 5 | use embassy::time::driver::{AlarmHandle, Driver}; | 6 | use embassy::time::driver::{AlarmHandle, Driver}; |
| 6 | use embassy::util::CriticalSectionMutex as Mutex; | ||
| 7 | 7 | ||
| 8 | use crate::{interrupt, pac}; | 8 | use 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}; | |||
| 5 | use core::task::Poll; | 5 | use core::task::Poll; |
| 6 | 6 | ||
| 7 | use embassy::interrupt::{Interrupt, InterruptExt}; | 7 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 8 | use embassy::util::{AtomicWaker, OnDrop}; | 8 | use embassy::waitqueue::AtomicWaker; |
| 9 | use embassy_hal_common::drop::OnDrop; | ||
| 9 | use futures::future::poll_fn; | 10 | use futures::future::poll_fn; |
| 10 | 11 | ||
| 11 | use crate::dma::{Channel, Request}; | 12 | use 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}; | |||
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy::interrupt::{Interrupt, InterruptExt}; | 5 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 6 | use embassy::util::{AtomicWaker, OnDrop}; | 6 | use embassy::waitqueue::AtomicWaker; |
| 7 | use embassy_hal_common::drop::OnDrop; | ||
| 7 | use futures::future::poll_fn; | 8 | use futures::future::poll_fn; |
| 8 | 9 | ||
| 9 | use crate::interrupt; | 10 | use 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; | |||
| 2 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 3 | use core::task::Waker; | 3 | use core::task::Waker; |
| 4 | 4 | ||
| 5 | use embassy::util::{AtomicWaker, Unborrow}; | 5 | use embassy::util::Unborrow; |
| 6 | use embassy::waitqueue::AtomicWaker; | ||
| 6 | use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; | 7 | use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; |
| 7 | use embassy_hal_common::unborrow; | 8 | use embassy_hal_common::unborrow; |
| 8 | use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; | 9 | use 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; | |||
| 4 | use core::pin::Pin; | 4 | use core::pin::Pin; |
| 5 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; | 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; |
| 7 | use embassy::util::{AtomicWaker, Unborrow}; | 7 | use embassy::util::Unborrow; |
| 8 | use embassy::waitqueue::AtomicWaker; | ||
| 8 | use embassy_hal_common::unsafe_impl_unborrow; | 9 | use embassy_hal_common::unsafe_impl_unborrow; |
| 9 | use embedded_hal::digital::v2::InputPin; | 10 | use 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 | ||
| 5 | use atomic_polyfill::{AtomicUsize, Ordering}; | 5 | use atomic_polyfill::{AtomicUsize, Ordering}; |
| 6 | use embassy::interrupt::InterruptExt; | 6 | use embassy::interrupt::InterruptExt; |
| 7 | use embassy::util::{AtomicWaker, OnDrop, Unborrow}; | 7 | use embassy::util::Unborrow; |
| 8 | use embassy::waitqueue::AtomicWaker; | ||
| 9 | use embassy_hal_common::drop::OnDrop; | ||
| 8 | use embassy_hal_common::unborrow; | 10 | use embassy_hal_common::unborrow; |
| 9 | use embedded_hal::blocking::i2c::Read; | 11 | use embedded_hal::blocking::i2c::Read; |
| 10 | use embedded_hal::blocking::i2c::Write; | 12 | use 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 @@ | |||
| 3 | use core::future::Future; | 3 | use core::future::Future; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | use embassy::traits; | 5 | use embassy::traits; |
| 6 | use embassy::util::{AtomicWaker, Unborrow}; | 6 | use embassy::util::Unborrow; |
| 7 | use embassy::waitqueue::AtomicWaker; | ||
| 7 | use embassy_hal_common::unborrow; | 8 | use embassy_hal_common::unborrow; |
| 8 | use futures::future::poll_fn; | 9 | use futures::future::poll_fn; |
| 9 | use rand_core::{CryptoRng, RngCore}; | 10 | use 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; | |||
| 5 | use core::task::Poll; | 5 | use core::task::Poll; |
| 6 | 6 | ||
| 7 | use embassy::interrupt::InterruptExt; | 7 | use embassy::interrupt::InterruptExt; |
| 8 | use embassy::util::{AtomicWaker, OnDrop, Unborrow}; | 8 | use embassy::util::Unborrow; |
| 9 | use embassy::waitqueue::AtomicWaker; | ||
| 10 | use embassy_hal_common::drop::OnDrop; | ||
| 9 | use embassy_hal_common::unborrow; | 11 | use embassy_hal_common::unborrow; |
| 10 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 11 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; | 13 | use 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; | |||
| 4 | use core::pin::Pin; | 4 | use core::pin::Pin; |
| 5 | use core::task::Context; | 5 | use core::task::Context; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | use embassy::util::{Unborrow, WakerRegistration}; | 7 | use embassy::util::Unborrow; |
| 8 | use embassy::waitqueue::WakerRegistration; | ||
| 8 | use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; | 9 | use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; |
| 9 | use embassy_hal_common::ring_buffer::RingBuffer; | 10 | use embassy_hal_common::ring_buffer::RingBuffer; |
| 10 | use embassy_hal_common::unborrow; | 11 | use 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 | |||
| 1 | use core::cell::UnsafeCell; | 3 | use core::cell::UnsafeCell; |
| 2 | use critical_section::CriticalSection; | 4 | use 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 | |||
| 3 | pub mod mpsc; | ||
| 4 | pub 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 | ||
| 50 | use futures::Future; | 50 | use futures::Future; |
| 51 | 51 | ||
| 52 | use super::CriticalSectionMutex; | 52 | use crate::blocking_mutex::{CriticalSectionMutex, Mutex, NoopMutex, ThreadModeMutex}; |
| 53 | use super::Mutex; | 53 | use crate::waitqueue::WakerRegistration; |
| 54 | use super::NoopMutex; | ||
| 55 | use super::ThreadModeMutex; | ||
| 56 | use 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 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use core::future::Future; | ||
| 3 | use core::mem; | ||
| 4 | use 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. | ||
| 9 | pub struct Signal<T> { | ||
| 10 | state: UnsafeCell<State<T>>, | ||
| 11 | } | ||
| 12 | |||
| 13 | enum State<T> { | ||
| 14 | None, | ||
| 15 | Waiting(Waker), | ||
| 16 | Signaled(T), | ||
| 17 | } | ||
| 18 | |||
| 19 | unsafe impl<T: Send> Send for Signal<T> {} | ||
| 20 | unsafe impl<T: Send> Sync for Signal<T> {} | ||
| 21 | |||
| 22 | impl<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. |
| 8 | pub(crate) mod fmt; | 8 | pub(crate) mod fmt; |
| 9 | 9 | ||
| 10 | pub mod blocking_mutex; | ||
| 11 | pub mod channel; | ||
| 12 | pub mod waitqueue; | ||
| 13 | |||
| 10 | pub mod executor; | 14 | pub mod executor; |
| 11 | pub mod interrupt; | 15 | pub mod interrupt; |
| 12 | pub mod io; | 16 | pub 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 |
| 2 | mod drop_bomb; | ||
| 3 | mod forever; | 2 | mod forever; |
| 4 | mod mutex; | ||
| 5 | mod on_drop; | ||
| 6 | mod signal; | ||
| 7 | 3 | ||
| 8 | #[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")] | ||
| 9 | mod waker; | ||
| 10 | |||
| 11 | pub use drop_bomb::*; | ||
| 12 | pub use forever::*; | 4 | pub use forever::*; |
| 13 | pub mod mpsc; | ||
| 14 | pub use mutex::*; | ||
| 15 | pub use on_drop::*; | ||
| 16 | pub use signal::*; | ||
| 17 | pub 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 @@ | |||
| 1 | use core::mem; | ||
| 2 | use core::mem::MaybeUninit; | ||
| 3 | |||
| 4 | pub struct OnDrop<F: FnOnce()> { | ||
| 5 | f: MaybeUninit<F>, | ||
| 6 | } | ||
| 7 | |||
| 8 | impl<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 | |||
| 20 | impl<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 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use core::future::Future; | ||
| 3 | use core::mem; | ||
| 4 | use core::ptr; | ||
| 5 | use core::task::{Context, Poll, Waker}; | ||
| 6 | use cortex_m::peripheral::NVIC; | ||
| 7 | use cortex_m::peripheral::{scb, SCB}; | ||
| 8 | use executor::raw::TaskHeader; | ||
| 9 | use ptr::NonNull; | ||
| 10 | |||
| 11 | use crate::executor; | ||
| 12 | use 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. | ||
| 17 | pub struct Signal<T> { | ||
| 18 | state: UnsafeCell<State<T>>, | ||
| 19 | } | ||
| 20 | |||
| 21 | enum State<T> { | ||
| 22 | None, | ||
| 23 | Waiting(Waker), | ||
| 24 | Signaled(T), | ||
| 25 | } | ||
| 26 | |||
| 27 | unsafe impl<T: Send> Send for Signal<T> {} | ||
| 28 | unsafe impl<T: Send> Sync for Signal<T> {} | ||
| 29 | |||
| 30 | impl<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 | |||
| 85 | pub 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 | |||
| 92 | unsafe 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 | |||
| 107 | struct NrWrap(u8); | ||
| 108 | unsafe 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 | /// ``` | ||
| 132 | pub struct InterruptFuture<'a, I: Interrupt> { | ||
| 133 | interrupt: &'a mut I, | ||
| 134 | } | ||
| 135 | |||
| 136 | impl<'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 | |||
| 143 | impl<'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 | |||
| 155 | impl<'a, I: Interrupt> Unpin for InterruptFuture<'a, I> {} | ||
| 156 | |||
| 157 | impl<'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")] | ||
| 4 | mod waker; | ||
| 5 | pub 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 @@ | |||
| 1 | use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering}; | ||
| 1 | use core::ptr::{self, NonNull}; | 2 | use core::ptr::{self, NonNull}; |
| 2 | use core::task::Waker; | 3 | use core::task::Waker; |
| 3 | 4 | ||
| 4 | use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering}; | ||
| 5 | |||
| 6 | use crate::executor::raw::{task_from_waker, wake_task, TaskHeader}; | 5 | use 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; | |||
| 2 | use core::mem; | 2 | use core::mem; |
| 3 | use core::task::Waker; | 3 | use core::task::Waker; |
| 4 | 4 | ||
| 5 | use crate::util::CriticalSectionMutex as Mutex; | 5 | use 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 @@ | |||
| 6 | mod example_common; | 6 | mod example_common; |
| 7 | 7 | ||
| 8 | use defmt::unwrap; | 8 | use defmt::unwrap; |
| 9 | use embassy::channel::mpsc::{self, Channel, Sender, TryRecvError, WithNoThreads}; | ||
| 9 | use embassy::executor::Spawner; | 10 | use embassy::executor::Spawner; |
| 10 | use embassy::time::{Duration, Timer}; | 11 | use embassy::time::{Duration, Timer}; |
| 11 | use embassy::util::mpsc::TryRecvError; | 12 | use embassy::util::Forever; |
| 12 | use embassy::util::{mpsc, Forever}; | ||
| 13 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 13 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; |
| 14 | use embassy_nrf::Peripherals; | 14 | use embassy_nrf::Peripherals; |
| 15 | use embedded_hal::digital::v2::OutputPin; | 15 | use embedded_hal::digital::v2::OutputPin; |
| 16 | use mpsc::{Channel, Sender, WithNoThreads}; | ||
| 17 | 16 | ||
| 18 | enum LedState { | 17 | enum 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"] |
| 9 | mod example_common; | 9 | mod example_common; |
| 10 | 10 | ||
| 11 | use embassy::{traits::gpio::WaitForRisingEdge, util::InterruptFuture}; | 11 | use embassy::channel::signal::Signal; |
| 12 | use embassy_stm32::{ | 12 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 13 | dbgmcu::Dbgmcu, | 13 | use embassy::traits::gpio::WaitForRisingEdge; |
| 14 | dma::NoDma, | 14 | use embassy_stm32::dbgmcu::Dbgmcu; |
| 15 | exti::ExtiInput, | 15 | use embassy_stm32::dma::NoDma; |
| 16 | gpio::{Input, Level, Output, Pull, Speed}, | 16 | use embassy_stm32::exti::ExtiInput; |
| 17 | interrupt, | 17 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; |
| 18 | subghz::*, | 18 | use embassy_stm32::interrupt; |
| 19 | Peripherals, | 19 | use embassy_stm32::subghz::*; |
| 20 | }; | 20 | use embassy_stm32::Peripherals; |
| 21 | use embedded_hal::digital::v2::OutputPin; | 21 | use embedded_hal::digital::v2::OutputPin; |
| 22 | use example_common::unwrap; | 22 | use 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"); |
