embassy: Refactor module structure to remove kitchen-sink util
.
This commit is contained in:
parent
200f881048
commit
ead987245d
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -6,11 +6,12 @@
|
|||||||
"rust-analyzer.checkOnSave.allTargets": false,
|
"rust-analyzer.checkOnSave.allTargets": false,
|
||||||
"rust-analyzer.cargo.noDefaultFeatures": true,
|
"rust-analyzer.cargo.noDefaultFeatures": true,
|
||||||
"rust-analyzer.checkOnSave.noDefaultFeatures": true,
|
"rust-analyzer.checkOnSave.noDefaultFeatures": true,
|
||||||
//"rust-analyzer.cargo.target": "thumbv7em-none-eabi",
|
"rust-analyzer.cargo.target": "thumbv7em-none-eabi",
|
||||||
"rust-analyzer.cargo.features": [
|
"rust-analyzer.cargo.features": [
|
||||||
// These are needed to prevent embassy-net from failing to build
|
// These are needed to prevent embassy-net from failing to build
|
||||||
"embassy-net/medium-ethernet",
|
"embassy-net/medium-ethernet",
|
||||||
"embassy-net/tcp",
|
"embassy-net/tcp",
|
||||||
|
"embassy-net/pool-16",
|
||||||
],
|
],
|
||||||
"rust-analyzer.procMacro.enable": true,
|
"rust-analyzer.procMacro.enable": true,
|
||||||
"rust-analyzer.cargo.runBuildScripts": true,
|
"rust-analyzer.cargo.runBuildScripts": true,
|
||||||
|
@ -1,4 +1,27 @@
|
|||||||
use core::mem;
|
use core::mem;
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
|
pub struct OnDrop<F: FnOnce()> {
|
||||||
|
f: MaybeUninit<F>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: FnOnce()> OnDrop<F> {
|
||||||
|
pub fn new(f: F) -> Self {
|
||||||
|
Self {
|
||||||
|
f: MaybeUninit::new(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn defuse(self) {
|
||||||
|
mem::forget(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: FnOnce()> Drop for OnDrop<F> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { self.f.as_ptr().read()() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An explosive ordinance that panics if it is improperly disposed of.
|
/// An explosive ordinance that panics if it is improperly disposed of.
|
||||||
///
|
///
|
@ -3,6 +3,7 @@
|
|||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
|
pub mod drop;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
mod macros;
|
mod macros;
|
||||||
pub mod peripheral;
|
pub mod peripheral;
|
||||||
|
@ -4,7 +4,7 @@ use core::pin::Pin;
|
|||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
use embassy::io::{self, AsyncBufRead, AsyncWrite};
|
use embassy::io::{self, AsyncBufRead, AsyncWrite};
|
||||||
use embassy::util::WakerRegistration;
|
use embassy::waitqueue::WakerRegistration;
|
||||||
use usb_device::bus::UsbBus;
|
use usb_device::bus::UsbBus;
|
||||||
use usb_device::class_prelude::*;
|
use usb_device::class_prelude::*;
|
||||||
use usb_device::UsbError;
|
use usb_device::UsbError;
|
||||||
|
@ -2,9 +2,9 @@ use core::cell::RefCell;
|
|||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::task::Context;
|
use core::task::Context;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
use embassy::blocking_mutex::ThreadModeMutex;
|
||||||
use embassy::time::{Instant, Timer};
|
use embassy::time::{Instant, Timer};
|
||||||
use embassy::util::ThreadModeMutex;
|
use embassy::waitqueue::WakerRegistration;
|
||||||
use embassy::util::WakerRegistration;
|
|
||||||
use futures::pin_mut;
|
use futures::pin_mut;
|
||||||
use smoltcp::iface::InterfaceBuilder;
|
use smoltcp::iface::InterfaceBuilder;
|
||||||
#[cfg(feature = "medium-ethernet")]
|
#[cfg(feature = "medium-ethernet")]
|
||||||
|
@ -6,7 +6,8 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
|||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::io::{AsyncBufRead, AsyncWrite, Result};
|
use embassy::io::{AsyncBufRead, AsyncWrite, Result};
|
||||||
use embassy::util::{Unborrow, WakerRegistration};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::WakerRegistration;
|
||||||
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||||
use embassy_hal_common::ring_buffer::RingBuffer;
|
use embassy_hal_common::ring_buffer::RingBuffer;
|
||||||
use embassy_hal_common::{low_power_wait_until, unborrow};
|
use embassy_hal_common::{low_power_wait_until, unborrow};
|
||||||
|
@ -4,7 +4,7 @@ use core::marker::PhantomData;
|
|||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow};
|
use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow};
|
||||||
use embassy::util::AtomicWaker;
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unsafe_impl_unborrow;
|
use embassy_hal_common::unsafe_impl_unborrow;
|
||||||
use embedded_hal::digital::v2::{InputPin, StatefulOutputPin};
|
use embedded_hal::digital::v2::{InputPin, StatefulOutputPin};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
@ -6,7 +6,8 @@ use core::ptr;
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::traits::flash::{Error, Flash};
|
use embassy::traits::flash::{Error, Flash};
|
||||||
use embassy::util::{AtomicWaker, DropBomb, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy_hal_common::drop::DropBomb;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
@ -397,6 +398,8 @@ impl<'d, T: Instance> Flash for Qspi<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
@ -8,9 +8,9 @@ use core::task::Poll;
|
|||||||
|
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::traits;
|
use embassy::traits;
|
||||||
use embassy::util::AtomicWaker;
|
|
||||||
use embassy::util::OnDrop;
|
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
|
@ -3,7 +3,8 @@ use core::marker::PhantomData;
|
|||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::util::{AtomicWaker, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::traits;
|
use embassy::traits;
|
||||||
use embassy::util::{AtomicWaker, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use traits::spi::{FullDuplex, Read, Spi, Write};
|
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> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
@ -2,9 +2,9 @@ use core::cell::Cell;
|
|||||||
use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
|
use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
|
||||||
use core::{mem, ptr};
|
use core::{mem, ptr};
|
||||||
use critical_section::CriticalSection;
|
use critical_section::CriticalSection;
|
||||||
|
use embassy::blocking_mutex::CriticalSectionMutex as Mutex;
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::time::driver::{AlarmHandle, Driver};
|
use embassy::time::driver::{AlarmHandle, Driver};
|
||||||
use embassy::util::CriticalSectionMutex as Mutex;
|
|
||||||
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::pac;
|
use crate::pac;
|
||||||
|
@ -5,8 +5,9 @@ use core::task::Poll;
|
|||||||
|
|
||||||
use embassy::interrupt::Interrupt;
|
use embassy::interrupt::Interrupt;
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::util::OnDrop;
|
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
@ -15,7 +16,6 @@ use crate::ppi::Event;
|
|||||||
use crate::ppi::Task;
|
use crate::ppi::Task;
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
use embassy::util::AtomicWaker;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -43,8 +43,8 @@ macro_rules! impl_timer {
|
|||||||
fn regs() -> &'static pac::timer0::RegisterBlock {
|
fn regs() -> &'static pac::timer0::RegisterBlock {
|
||||||
unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) }
|
unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) }
|
||||||
}
|
}
|
||||||
fn waker(n: usize) -> &'static ::embassy::util::AtomicWaker {
|
fn waker(n: usize) -> &'static ::embassy::waitqueue::AtomicWaker {
|
||||||
use ::embassy::util::AtomicWaker;
|
use ::embassy::waitqueue::AtomicWaker;
|
||||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||||
static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs];
|
static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs];
|
||||||
&WAKERS[n]
|
&WAKERS[n]
|
||||||
|
@ -12,7 +12,8 @@ use core::sync::atomic::{compiler_fence, Ordering::SeqCst};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::traits;
|
use embassy::traits;
|
||||||
use embassy::util::{AtomicWaker, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use traits::i2c::I2c;
|
use traits::i2c::I2c;
|
||||||
|
@ -8,7 +8,8 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write};
|
use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write};
|
||||||
use embassy::util::{AtomicWaker, OnDrop, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
@ -439,6 +440,8 @@ impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use atomic_polyfill::{AtomicU8, Ordering};
|
use atomic_polyfill::{AtomicU8, Ordering};
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
use critical_section::CriticalSection;
|
use critical_section::CriticalSection;
|
||||||
|
use embassy::blocking_mutex::CriticalSectionMutex as Mutex;
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::time::driver::{AlarmHandle, Driver};
|
use embassy::time::driver::{AlarmHandle, Driver};
|
||||||
use embassy::util::CriticalSectionMutex as Mutex;
|
|
||||||
|
|
||||||
use crate::{interrupt, pac};
|
use crate::{interrupt, pac};
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ use core::sync::atomic::{fence, Ordering};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::util::{AtomicWaker, OnDrop};
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
use crate::dma::{Channel, Request};
|
use crate::dma::{Channel, Request};
|
||||||
|
@ -3,7 +3,8 @@ use core::sync::atomic::{fence, Ordering};
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::util::{AtomicWaker, OnDrop};
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
|
@ -2,7 +2,8 @@ use core::marker::PhantomData;
|
|||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
use embassy::util::{AtomicWaker, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
|
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
|
||||||
|
@ -4,7 +4,8 @@ use core::marker::PhantomData;
|
|||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
|
use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
|
||||||
use embassy::util::{AtomicWaker, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unsafe_impl_unborrow;
|
use embassy_hal_common::unsafe_impl_unborrow;
|
||||||
use embedded_hal::digital::v2::InputPin;
|
use embedded_hal::digital::v2::InputPin;
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@ use core::task::Poll;
|
|||||||
|
|
||||||
use atomic_polyfill::{AtomicUsize, Ordering};
|
use atomic_polyfill::{AtomicUsize, Ordering};
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::util::{AtomicWaker, OnDrop, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use embedded_hal::blocking::i2c::Read;
|
use embedded_hal::blocking::i2c::Read;
|
||||||
use embedded_hal::blocking::i2c::Write;
|
use embedded_hal::blocking::i2c::Write;
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::traits;
|
use embassy::traits;
|
||||||
use embassy::util::{AtomicWaker, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
|
@ -5,7 +5,9 @@ use core::marker::PhantomData;
|
|||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::util::{AtomicWaker, OnDrop, Unborrow};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
use embassy_hal_common::drop::OnDrop;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
|
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
|
||||||
@ -1479,8 +1481,8 @@ crate::pac::peripherals!(
|
|||||||
INNER
|
INNER
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state() -> &'static ::embassy::util::AtomicWaker {
|
fn state() -> &'static ::embassy::waitqueue::AtomicWaker {
|
||||||
static WAKER: ::embassy::util::AtomicWaker = ::embassy::util::AtomicWaker::new();
|
static WAKER: ::embassy::waitqueue::AtomicWaker = ::embassy::waitqueue::AtomicWaker::new();
|
||||||
&WAKER
|
&WAKER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@ use core::marker::PhantomData;
|
|||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::Context;
|
use core::task::Context;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use embassy::util::{Unborrow, WakerRegistration};
|
use embassy::util::Unborrow;
|
||||||
|
use embassy::waitqueue::WakerRegistration;
|
||||||
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||||
use embassy_hal_common::ring_buffer::RingBuffer;
|
use embassy_hal_common::ring_buffer::RingBuffer;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! Blocking mutex (not async)
|
||||||
|
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use critical_section::CriticalSection;
|
use critical_section::CriticalSection;
|
||||||
|
|
4
embassy/src/channel/mod.rs
Normal file
4
embassy/src/channel/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
//! Async channels
|
||||||
|
|
||||||
|
pub mod mpsc;
|
||||||
|
pub mod signal;
|
@ -49,11 +49,8 @@ use core::task::Waker;
|
|||||||
|
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
use super::CriticalSectionMutex;
|
use crate::blocking_mutex::{CriticalSectionMutex, Mutex, NoopMutex, ThreadModeMutex};
|
||||||
use super::Mutex;
|
use crate::waitqueue::WakerRegistration;
|
||||||
use super::NoopMutex;
|
|
||||||
use super::ThreadModeMutex;
|
|
||||||
use super::WakerRegistration;
|
|
||||||
|
|
||||||
/// Send values to the associated `Receiver`.
|
/// Send values to the associated `Receiver`.
|
||||||
///
|
///
|
||||||
@ -108,8 +105,8 @@ unsafe impl<'ch, M, T, const N: usize> Sync for Receiver<'ch, M, T, N> where
|
|||||||
/// their channel. The following will therefore fail compilation:
|
/// their channel. The following will therefore fail compilation:
|
||||||
////
|
////
|
||||||
/// ```compile_fail
|
/// ```compile_fail
|
||||||
/// use embassy::util::mpsc;
|
/// use embassy::channel::mpsc;
|
||||||
/// use embassy::util::mpsc::{Channel, WithThreadModeOnly};
|
/// use embassy::channel::mpsc::{Channel, WithThreadModeOnly};
|
||||||
///
|
///
|
||||||
/// let (sender, receiver) = {
|
/// let (sender, receiver) = {
|
||||||
/// let mut channel = Channel::<WithThreadModeOnly, u32, 3>::with_thread_mode_only();
|
/// let mut channel = Channel::<WithThreadModeOnly, u32, 3>::with_thread_mode_only();
|
||||||
@ -635,8 +632,8 @@ where
|
|||||||
/// Establish a new bounded channel. For example, to create one with a NoopMutex:
|
/// Establish a new bounded channel. For example, to create one with a NoopMutex:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use embassy::util::mpsc;
|
/// use embassy::channel::mpsc;
|
||||||
/// use embassy::util::mpsc::{Channel, WithNoThreads};
|
/// use embassy::channel::mpsc::{Channel, WithNoThreads};
|
||||||
///
|
///
|
||||||
/// // Declare a bounded channel of 3 u32s.
|
/// // Declare a bounded channel of 3 u32s.
|
||||||
/// let mut channel = Channel::<WithNoThreads, u32, 3>::new();
|
/// let mut channel = Channel::<WithNoThreads, u32, 3>::new();
|
73
embassy/src/channel/signal.rs
Normal file
73
embassy/src/channel/signal.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use core::cell::UnsafeCell;
|
||||||
|
use core::future::Future;
|
||||||
|
use core::mem;
|
||||||
|
use core::task::{Context, Poll, Waker};
|
||||||
|
|
||||||
|
/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks.
|
||||||
|
///
|
||||||
|
/// For more advanced use cases, please consider [futures-intrusive](https://crates.io/crates/futures-intrusive) channels or mutexes.
|
||||||
|
pub struct Signal<T> {
|
||||||
|
state: UnsafeCell<State<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum State<T> {
|
||||||
|
None,
|
||||||
|
Waiting(Waker),
|
||||||
|
Signaled(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: Send> Send for Signal<T> {}
|
||||||
|
unsafe impl<T: Send> Sync for Signal<T> {}
|
||||||
|
|
||||||
|
impl<T: Send> Signal<T> {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state: UnsafeCell::new(State::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark this Signal as completed.
|
||||||
|
pub fn signal(&self, val: T) {
|
||||||
|
critical_section::with(|_| unsafe {
|
||||||
|
let state = &mut *self.state.get();
|
||||||
|
if let State::Waiting(waker) = mem::replace(state, State::Signaled(val)) {
|
||||||
|
waker.wake();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&self) {
|
||||||
|
critical_section::with(|_| unsafe {
|
||||||
|
let state = &mut *self.state.get();
|
||||||
|
*state = State::None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> {
|
||||||
|
critical_section::with(|_| unsafe {
|
||||||
|
let state = &mut *self.state.get();
|
||||||
|
match state {
|
||||||
|
State::None => {
|
||||||
|
*state = State::Waiting(cx.waker().clone());
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
State::Waiting(w) if w.will_wake(cx.waker()) => Poll::Pending,
|
||||||
|
State::Waiting(_) => panic!("waker overflow"),
|
||||||
|
State::Signaled(_) => match mem::replace(state, State::None) {
|
||||||
|
State::Signaled(res) => Poll::Ready(res),
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Future that completes when this Signal has been signaled.
|
||||||
|
pub fn wait(&self) -> impl Future<Output = T> + '_ {
|
||||||
|
futures::future::poll_fn(move |cx| self.poll_wait(cx))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// non-blocking method to check whether this signal has been signaled.
|
||||||
|
pub fn signaled(&self) -> bool {
|
||||||
|
critical_section::with(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_)))
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,10 @@
|
|||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
|
pub mod blocking_mutex;
|
||||||
|
pub mod channel;
|
||||||
|
pub mod waitqueue;
|
||||||
|
|
||||||
pub mod executor;
|
pub mod executor;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
|
@ -1,21 +1,7 @@
|
|||||||
//! Async utilities
|
//! Misc utilities
|
||||||
mod drop_bomb;
|
|
||||||
mod forever;
|
mod forever;
|
||||||
mod mutex;
|
|
||||||
mod on_drop;
|
|
||||||
mod signal;
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")]
|
|
||||||
mod waker;
|
|
||||||
|
|
||||||
pub use drop_bomb::*;
|
|
||||||
pub use forever::*;
|
pub use forever::*;
|
||||||
pub mod mpsc;
|
|
||||||
pub use mutex::*;
|
|
||||||
pub use on_drop::*;
|
|
||||||
pub use signal::*;
|
|
||||||
pub use waker::*;
|
|
||||||
|
|
||||||
/// Unsafely unborrow an owned singleton out of a `&mut`.
|
/// Unsafely unborrow an owned singleton out of a `&mut`.
|
||||||
///
|
///
|
||||||
/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
|
/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
use core::mem;
|
|
||||||
use core::mem::MaybeUninit;
|
|
||||||
|
|
||||||
pub struct OnDrop<F: FnOnce()> {
|
|
||||||
f: MaybeUninit<F>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F: FnOnce()> OnDrop<F> {
|
|
||||||
pub fn new(f: F) -> Self {
|
|
||||||
Self {
|
|
||||||
f: MaybeUninit::new(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn defuse(self) {
|
|
||||||
mem::forget(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F: FnOnce()> Drop for OnDrop<F> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { self.f.as_ptr().read()() }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,171 +0,0 @@
|
|||||||
use core::cell::UnsafeCell;
|
|
||||||
use core::future::Future;
|
|
||||||
use core::mem;
|
|
||||||
use core::ptr;
|
|
||||||
use core::task::{Context, Poll, Waker};
|
|
||||||
use cortex_m::peripheral::NVIC;
|
|
||||||
use cortex_m::peripheral::{scb, SCB};
|
|
||||||
use executor::raw::TaskHeader;
|
|
||||||
use ptr::NonNull;
|
|
||||||
|
|
||||||
use crate::executor;
|
|
||||||
use crate::interrupt::{Interrupt, InterruptExt};
|
|
||||||
|
|
||||||
/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks.
|
|
||||||
///
|
|
||||||
/// For more advanced use cases, please consider [futures-intrusive](https://crates.io/crates/futures-intrusive) channels or mutexes.
|
|
||||||
pub struct Signal<T> {
|
|
||||||
state: UnsafeCell<State<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum State<T> {
|
|
||||||
None,
|
|
||||||
Waiting(Waker),
|
|
||||||
Signaled(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: Send> Send for Signal<T> {}
|
|
||||||
unsafe impl<T: Send> Sync for Signal<T> {}
|
|
||||||
|
|
||||||
impl<T: Send> Signal<T> {
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state: UnsafeCell::new(State::None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mark this Signal as completed.
|
|
||||||
pub fn signal(&self, val: T) {
|
|
||||||
critical_section::with(|_| unsafe {
|
|
||||||
let state = &mut *self.state.get();
|
|
||||||
if let State::Waiting(waker) = mem::replace(state, State::Signaled(val)) {
|
|
||||||
waker.wake();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset(&self) {
|
|
||||||
critical_section::with(|_| unsafe {
|
|
||||||
let state = &mut *self.state.get();
|
|
||||||
*state = State::None
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> {
|
|
||||||
critical_section::with(|_| unsafe {
|
|
||||||
let state = &mut *self.state.get();
|
|
||||||
match state {
|
|
||||||
State::None => {
|
|
||||||
*state = State::Waiting(cx.waker().clone());
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
State::Waiting(w) if w.will_wake(cx.waker()) => Poll::Pending,
|
|
||||||
State::Waiting(_) => panic!("waker overflow"),
|
|
||||||
State::Signaled(_) => match mem::replace(state, State::None) {
|
|
||||||
State::Signaled(res) => Poll::Ready(res),
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Future that completes when this Signal has been signaled.
|
|
||||||
pub fn wait(&self) -> impl Future<Output = T> + '_ {
|
|
||||||
futures::future::poll_fn(move |cx| self.poll_wait(cx))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// non-blocking method to check whether this signal has been signaled.
|
|
||||||
pub fn signaled(&self) -> bool {
|
|
||||||
critical_section::with(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========
|
|
||||||
|
|
||||||
pub fn wake_on_interrupt(interrupt: &mut impl Interrupt, waker: &Waker) {
|
|
||||||
interrupt.disable();
|
|
||||||
interrupt.set_handler(irq_wake_handler);
|
|
||||||
interrupt.set_handler_context(unsafe { executor::raw::task_from_waker(waker) }.as_ptr() as _);
|
|
||||||
interrupt.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn irq_wake_handler(ctx: *mut ()) {
|
|
||||||
if let Some(task) = NonNull::new(ctx as *mut TaskHeader) {
|
|
||||||
executor::raw::wake_task(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
let irq = match SCB::vect_active() {
|
|
||||||
scb::VectActive::Interrupt { irqn } => irqn,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
NVIC::mask(crate::interrupt::NrWrap(irq as u16));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========
|
|
||||||
|
|
||||||
struct NrWrap(u8);
|
|
||||||
unsafe impl cortex_m::interrupt::Nr for NrWrap {
|
|
||||||
fn nr(&self) -> u8 {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a future that completes when the specified Interrupt is triggered.
|
|
||||||
///
|
|
||||||
/// The input handler is unregistered when this Future is dropped.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
/// ``` no_compile
|
|
||||||
/// use embassy::traits::*;
|
|
||||||
/// use embassy::util::InterruptFuture;
|
|
||||||
/// use embassy_stm32::interrupt; // Adjust this to your MCU's embassy HAL.
|
|
||||||
/// #[embassy::task]
|
|
||||||
/// async fn demo_interrupt_future() {
|
|
||||||
/// // Using STM32f446 interrupt names, adjust this to your application as necessary.
|
|
||||||
/// // Wait for TIM2 to tick.
|
|
||||||
/// let mut tim2_interrupt = interrupt::take!(TIM2);
|
|
||||||
/// InterruptFuture::new(&mut tim2_interrupt).await;
|
|
||||||
/// // TIM2 interrupt went off, do something...
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub struct InterruptFuture<'a, I: Interrupt> {
|
|
||||||
interrupt: &'a mut I,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, I: Interrupt> Drop for InterruptFuture<'a, I> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.interrupt.disable();
|
|
||||||
self.interrupt.remove_handler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, I: Interrupt> InterruptFuture<'a, I> {
|
|
||||||
pub fn new(interrupt: &'a mut I) -> Self {
|
|
||||||
interrupt.disable();
|
|
||||||
interrupt.set_handler(irq_wake_handler);
|
|
||||||
interrupt.set_handler_context(ptr::null_mut());
|
|
||||||
interrupt.unpend();
|
|
||||||
interrupt.enable();
|
|
||||||
|
|
||||||
Self { interrupt }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, I: Interrupt> Unpin for InterruptFuture<'a, I> {}
|
|
||||||
|
|
||||||
impl<'a, I: Interrupt> Future for InterruptFuture<'a, I> {
|
|
||||||
type Output = ();
|
|
||||||
|
|
||||||
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
|
||||||
let s = unsafe { self.get_unchecked_mut() };
|
|
||||||
s.interrupt.set_handler_context(unsafe {
|
|
||||||
executor::raw::task_from_waker(&cx.waker()).cast().as_ptr()
|
|
||||||
});
|
|
||||||
if s.interrupt.is_enabled() {
|
|
||||||
Poll::Pending
|
|
||||||
} else {
|
|
||||||
Poll::Ready(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
5
embassy/src/waitqueue/mod.rs
Normal file
5
embassy/src/waitqueue/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//! Async low-level wait queues
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")]
|
||||||
|
mod waker;
|
||||||
|
pub use waker::*;
|
@ -1,8 +1,7 @@
|
|||||||
|
use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
|
||||||
use core::ptr::{self, NonNull};
|
use core::ptr::{self, NonNull};
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
|
|
||||||
|
|
||||||
use crate::executor::raw::{task_from_waker, wake_task, TaskHeader};
|
use crate::executor::raw::{task_from_waker, wake_task, TaskHeader};
|
||||||
|
|
||||||
/// Utility struct to register and wake a waker.
|
/// Utility struct to register and wake a waker.
|
@ -2,7 +2,7 @@ use core::cell::Cell;
|
|||||||
use core::mem;
|
use core::mem;
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
use crate::util::CriticalSectionMutex as Mutex;
|
use crate::blocking_mutex::CriticalSectionMutex as Mutex;
|
||||||
|
|
||||||
/// Utility struct to register and wake a waker.
|
/// Utility struct to register and wake a waker.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
@ -6,14 +6,13 @@
|
|||||||
mod example_common;
|
mod example_common;
|
||||||
|
|
||||||
use defmt::unwrap;
|
use defmt::unwrap;
|
||||||
|
use embassy::channel::mpsc::{self, Channel, Sender, TryRecvError, WithNoThreads};
|
||||||
use embassy::executor::Spawner;
|
use embassy::executor::Spawner;
|
||||||
use embassy::time::{Duration, Timer};
|
use embassy::time::{Duration, Timer};
|
||||||
use embassy::util::mpsc::TryRecvError;
|
use embassy::util::Forever;
|
||||||
use embassy::util::{mpsc, Forever};
|
|
||||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||||
use embassy_nrf::Peripherals;
|
use embassy_nrf::Peripherals;
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
use mpsc::{Channel, Sender, WithNoThreads};
|
|
||||||
|
|
||||||
enum LedState {
|
enum LedState {
|
||||||
On,
|
On,
|
||||||
|
@ -8,16 +8,16 @@
|
|||||||
#[path = "../example_common.rs"]
|
#[path = "../example_common.rs"]
|
||||||
mod example_common;
|
mod example_common;
|
||||||
|
|
||||||
use embassy::{traits::gpio::WaitForRisingEdge, util::InterruptFuture};
|
use embassy::channel::signal::Signal;
|
||||||
use embassy_stm32::{
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
dbgmcu::Dbgmcu,
|
use embassy::traits::gpio::WaitForRisingEdge;
|
||||||
dma::NoDma,
|
use embassy_stm32::dbgmcu::Dbgmcu;
|
||||||
exti::ExtiInput,
|
use embassy_stm32::dma::NoDma;
|
||||||
gpio::{Input, Level, Output, Pull, Speed},
|
use embassy_stm32::exti::ExtiInput;
|
||||||
interrupt,
|
use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
|
||||||
subghz::*,
|
use embassy_stm32::interrupt;
|
||||||
Peripherals,
|
use embassy_stm32::subghz::*;
|
||||||
};
|
use embassy_stm32::Peripherals;
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
use example_common::unwrap;
|
use example_common::unwrap;
|
||||||
|
|
||||||
@ -83,7 +83,13 @@ async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) {
|
|||||||
let button = Input::new(p.PA0, Pull::Up);
|
let button = Input::new(p.PA0, Pull::Up);
|
||||||
let mut pin = ExtiInput::new(button, p.EXTI0);
|
let mut pin = ExtiInput::new(button, p.EXTI0);
|
||||||
|
|
||||||
let mut radio_irq = interrupt::take!(SUBGHZ_RADIO);
|
static IRQ_SIGNAL: Signal<()> = Signal::new();
|
||||||
|
let radio_irq = interrupt::take!(SUBGHZ_RADIO);
|
||||||
|
radio_irq.set_handler(|_| {
|
||||||
|
IRQ_SIGNAL.signal(());
|
||||||
|
unsafe { interrupt::SUBGHZ_RADIO::steal() }.disable();
|
||||||
|
});
|
||||||
|
|
||||||
let mut radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma);
|
let mut radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma);
|
||||||
|
|
||||||
defmt::info!("Radio ready for use");
|
defmt::info!("Radio ready for use");
|
||||||
@ -118,7 +124,9 @@ async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) {
|
|||||||
unwrap!(radio.write_buffer(TX_BUF_OFFSET, PING_DATA_BYTES));
|
unwrap!(radio.write_buffer(TX_BUF_OFFSET, PING_DATA_BYTES));
|
||||||
unwrap!(radio.set_tx(Timeout::DISABLED));
|
unwrap!(radio.set_tx(Timeout::DISABLED));
|
||||||
|
|
||||||
InterruptFuture::new(&mut radio_irq).await;
|
radio_irq.enable();
|
||||||
|
IRQ_SIGNAL.wait().await;
|
||||||
|
|
||||||
let (_, irq_status) = unwrap!(radio.irq_status());
|
let (_, irq_status) = unwrap!(radio.irq_status());
|
||||||
if irq_status & Irq::TxDone.mask() != 0 {
|
if irq_status & Irq::TxDone.mask() != 0 {
|
||||||
defmt::info!("TX done");
|
defmt::info!("TX done");
|
||||||
|
Loading…
Reference in New Issue
Block a user