Get rid of some warnings
This commit is contained in:
parent
a7797a918d
commit
b69f72e055
@ -3,7 +3,7 @@
|
|||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
use darling::FromMeta;
|
use darling::FromMeta;
|
||||||
use proc_macro::{Diagnostic, Level, Span, TokenStream};
|
use proc_macro::{Span, TokenStream};
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
.emit();
|
.emit();
|
||||||
fail = true;
|
fail = true;
|
||||||
}
|
}
|
||||||
if task_fn.sig.generics.params.len() != 0 {
|
if !task_fn.sig.generics.params.is_empty() {
|
||||||
task_fn
|
task_fn
|
||||||
.sig
|
.sig
|
||||||
.span()
|
.span()
|
||||||
|
@ -66,9 +66,7 @@ async fn run() {
|
|||||||
|
|
||||||
// Reverse buf
|
// Reverse buf
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
let tmp = buf[i];
|
buf.swap(i, 7 - i);
|
||||||
buf[i] = buf[7 - i];
|
|
||||||
buf[7 - i] = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("writing...");
|
info!("writing...");
|
||||||
|
@ -12,7 +12,7 @@ use nrf52840_hal::gpio;
|
|||||||
|
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_nrf::gpiote::{Channels, Gpiote, InputChannel, InputChannelPolarity};
|
use embassy_nrf::gpiote::{Gpiote, InputChannel, InputChannelPolarity};
|
||||||
use embassy_nrf::interrupt;
|
use embassy_nrf::interrupt;
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
mod example_common;
|
mod example_common;
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use core::mem;
|
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use defmt::panic;
|
use defmt::panic;
|
||||||
|
@ -61,7 +61,6 @@
|
|||||||
mod example_common;
|
mod example_common;
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use cortex_m::peripheral::NVIC;
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use defmt::panic;
|
use defmt::panic;
|
||||||
use nrf52840_hal::clocks;
|
use nrf52840_hal::clocks;
|
||||||
|
@ -7,7 +7,7 @@ mod example_common;
|
|||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use defmt::{assert_eq, panic, *};
|
use defmt::{assert_eq, panic};
|
||||||
use nrf52840_hal::gpio;
|
use nrf52840_hal::gpio;
|
||||||
|
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
mod example_common;
|
mod example_common;
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use core::mem::MaybeUninit;
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use defmt::panic;
|
use defmt::panic;
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
use embassy::time::{Clock, Duration, Timer};
|
use embassy::time::{Duration, Timer};
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_nrf::pac;
|
use embassy_nrf::pac;
|
||||||
use embassy_nrf::{interrupt, rtc};
|
use embassy_nrf::{interrupt, rtc};
|
||||||
|
@ -75,7 +75,7 @@ async fn run(uart: pac::UARTE0, port: pac::P0) {
|
|||||||
};
|
};
|
||||||
let received = &mut buf[..received_len];
|
let received = &mut buf[..received_len];
|
||||||
|
|
||||||
if received.len() > 0 {
|
if !received.is_empty() {
|
||||||
info!("read done, got {:[u8]}", received);
|
info!("read done, got {:[u8]}", received);
|
||||||
|
|
||||||
// Echo back received data
|
// Echo back received data
|
||||||
|
@ -20,10 +20,7 @@ use crate::interrupt::{self, OwnedInterrupt};
|
|||||||
use crate::pac;
|
use crate::pac;
|
||||||
use crate::util::peripheral::{PeripheralMutex, PeripheralState};
|
use crate::util::peripheral::{PeripheralMutex, PeripheralState};
|
||||||
use crate::util::ring_buffer::RingBuffer;
|
use crate::util::ring_buffer::RingBuffer;
|
||||||
use crate::{
|
use crate::{fmt::*, util::low_power_wait_until};
|
||||||
fmt::{panic, todo, *},
|
|
||||||
util::low_power_wait_until,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Re-export SVD variants to allow user to directly set values
|
// Re-export SVD variants to allow user to directly set values
|
||||||
pub use crate::hal::uarte::Pins;
|
pub use crate::hal::uarte::Pins;
|
||||||
@ -257,7 +254,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
|
|||||||
|
|
||||||
// We have data ready in buffer? Return it.
|
// We have data ready in buffer? Return it.
|
||||||
let buf = state.rx.pop_buf();
|
let buf = state.rx.pop_buf();
|
||||||
if buf.len() != 0 {
|
if !buf.is_empty() {
|
||||||
trace!(" got {:?} {:?}", buf.as_ptr() as u32, buf.len());
|
trace!(" got {:?} {:?}", buf.as_ptr() as u32, buf.len());
|
||||||
let buf: &[u8] = buf;
|
let buf: &[u8] = buf;
|
||||||
let buf: &[u8] = unsafe { mem::transmute(buf) };
|
let buf: &[u8] = unsafe { mem::transmute(buf) };
|
||||||
@ -287,7 +284,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
|
|||||||
trace!("poll_write: {:?}", buf.len());
|
trace!("poll_write: {:?}", buf.len());
|
||||||
|
|
||||||
let tx_buf = state.tx.push_buf();
|
let tx_buf = state.tx.push_buf();
|
||||||
if tx_buf.len() == 0 {
|
if tx_buf.is_empty() {
|
||||||
trace!("poll_write: pending");
|
trace!("poll_write: pending");
|
||||||
state.tx_waker.register(cx.waker());
|
state.tx_waker.register(cx.waker());
|
||||||
return Poll::Pending;
|
return Poll::Pending;
|
||||||
@ -343,7 +340,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
|
|||||||
trace!(" irq_rx: in state idle");
|
trace!(" irq_rx: in state idle");
|
||||||
|
|
||||||
let buf = self.rx.push_buf();
|
let buf = self.rx.push_buf();
|
||||||
if buf.len() != 0 {
|
if !buf.is_empty() {
|
||||||
trace!(" irq_rx: starting {:?}", buf.len());
|
trace!(" irq_rx: starting {:?}", buf.len());
|
||||||
self.rx_state = RxState::Receiving;
|
self.rx_state = RxState::Receiving;
|
||||||
|
|
||||||
@ -394,7 +391,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
|
|||||||
TxState::Idle => {
|
TxState::Idle => {
|
||||||
trace!(" irq_tx: in state Idle");
|
trace!(" irq_tx: in state Idle");
|
||||||
let buf = self.tx.pop_buf();
|
let buf = self.tx.pop_buf();
|
||||||
if buf.len() != 0 {
|
if !buf.is_empty() {
|
||||||
trace!(" irq_tx: starting {:?}", buf.len());
|
trace!(" irq_tx: starting {:?}", buf.len());
|
||||||
self.tx_state = TxState::Transmitting(buf.len());
|
self.tx_state = TxState::Transmitting(buf.len());
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
#[cfg(all(feature = "defmt", feature = "log"))]
|
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||||
compile_error!("You may not enable both `defmt` and `log` features.");
|
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||||
|
@ -7,7 +7,6 @@ use core::task::{Context, Poll};
|
|||||||
use embassy::gpio::{WaitForHigh, WaitForLow};
|
use embassy::gpio::{WaitForHigh, WaitForLow};
|
||||||
use embassy::util::Signal;
|
use embassy::util::Signal;
|
||||||
|
|
||||||
use crate::fmt::{panic, *};
|
|
||||||
use crate::hal::gpio::{Input, Level, Output, Pin as GpioPin, Port};
|
use crate::hal::gpio::{Input, Level, Output, Pin as GpioPin, Port};
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::interrupt::OwnedInterrupt;
|
use crate::interrupt::OwnedInterrupt;
|
||||||
@ -141,10 +140,10 @@ impl Gpiote {
|
|||||||
unsafe fn on_irq(_ctx: *mut ()) {
|
unsafe fn on_irq(_ctx: *mut ()) {
|
||||||
let g = &*GPIOTE::ptr();
|
let g = &*GPIOTE::ptr();
|
||||||
|
|
||||||
for i in 0..8 {
|
for (event_in, signal) in g.events_in.iter().zip(CHANNEL_SIGNALS.iter()) {
|
||||||
if g.events_in[i].read().bits() != 0 {
|
if event_in.read().bits() != 0 {
|
||||||
g.events_in[i].write(|w| w);
|
event_in.write(|w| w);
|
||||||
CHANNEL_SIGNALS[i].signal(());
|
signal.signal(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::fmt::{assert, assert_eq, panic, *};
|
use crate::fmt::{assert, assert_eq, *};
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
|
||||||
use crate::hal::gpio::{Output, Pin as GpioPin, Port as GpioPort, PushPull};
|
use crate::hal::gpio::{Output, Pin as GpioPin, Port as GpioPort, PushPull};
|
||||||
use crate::interrupt::{OwnedInterrupt, QSPIInterrupt};
|
use crate::interrupt::{OwnedInterrupt, QSPIInterrupt};
|
||||||
use crate::pac::{Interrupt, QSPI};
|
use crate::pac::QSPI;
|
||||||
|
|
||||||
pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode;
|
pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode;
|
||||||
pub use crate::pac::qspi::ifconfig0::PPSIZE_A as WritePageSize;
|
pub use crate::pac::qspi::ifconfig0::PPSIZE_A as WritePageSize;
|
||||||
@ -156,7 +156,7 @@ impl Qspi {
|
|||||||
pub fn sleep(&mut self) {
|
pub fn sleep(&mut self) {
|
||||||
info!("flash: sleeping");
|
info!("flash: sleeping");
|
||||||
info!("flash: state = {:?}", self.inner.status.read().bits());
|
info!("flash: state = {:?}", self.inner.status.read().bits());
|
||||||
self.inner.ifconfig1.modify(|r, w| w.dpmen().enter());
|
self.inner.ifconfig1.modify(|_, w| w.dpmen().enter());
|
||||||
info!("flash: state = {:?}", self.inner.status.read().bits());
|
info!("flash: state = {:?}", self.inner.status.read().bits());
|
||||||
cortex_m::asm::delay(1000000);
|
cortex_m::asm::delay(1000000);
|
||||||
info!("flash: state = {:?}", self.inner.status.read().bits());
|
info!("flash: state = {:?}", self.inner.status.read().bits());
|
||||||
@ -166,68 +166,66 @@ impl Qspi {
|
|||||||
.write(|w| w.tasks_deactivate().set_bit());
|
.write(|w| w.tasks_deactivate().set_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn custom_instruction<'a>(
|
pub async fn custom_instruction<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
opcode: u8,
|
opcode: u8,
|
||||||
req: &'a [u8],
|
req: &'a [u8],
|
||||||
resp: &'a mut [u8],
|
resp: &'a mut [u8],
|
||||||
) -> impl Future<Output = Result<(), Error>> + 'a {
|
) -> Result<(), Error> {
|
||||||
async move {
|
let bomb = DropBomb::new();
|
||||||
let bomb = DropBomb::new();
|
|
||||||
|
|
||||||
assert!(req.len() <= 8);
|
assert!(req.len() <= 8);
|
||||||
assert!(resp.len() <= 8);
|
assert!(resp.len() <= 8);
|
||||||
|
|
||||||
let mut dat0: u32 = 0;
|
let mut dat0: u32 = 0;
|
||||||
let mut dat1: u32 = 0;
|
let mut dat1: u32 = 0;
|
||||||
|
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
if i < req.len() {
|
if i < req.len() {
|
||||||
dat0 |= (req[i] as u32) << (i * 8);
|
dat0 |= (req[i] as u32) << (i * 8);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for i in 0..4 {
|
|
||||||
if i + 4 < req.len() {
|
|
||||||
dat1 |= (req[i + 4] as u32) << (i * 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let len = core::cmp::max(req.len(), resp.len()) as u8;
|
|
||||||
|
|
||||||
self.inner.cinstrdat0.write(|w| unsafe { w.bits(dat0) });
|
|
||||||
self.inner.cinstrdat1.write(|w| unsafe { w.bits(dat1) });
|
|
||||||
self.inner.events_ready.reset();
|
|
||||||
self.inner.cinstrconf.write(|w| {
|
|
||||||
let w = unsafe { w.opcode().bits(opcode) };
|
|
||||||
let w = unsafe { w.length().bits(len + 1) };
|
|
||||||
let w = w.lio2().bit(true);
|
|
||||||
let w = w.lio3().bit(true);
|
|
||||||
let w = w.wipwait().bit(true);
|
|
||||||
let w = w.wren().bit(true);
|
|
||||||
let w = w.lfen().bit(false);
|
|
||||||
let w = w.lfstop().bit(false);
|
|
||||||
w
|
|
||||||
});
|
|
||||||
|
|
||||||
SIGNAL.wait().await;
|
|
||||||
|
|
||||||
let dat0 = self.inner.cinstrdat0.read().bits();
|
|
||||||
let dat1 = self.inner.cinstrdat1.read().bits();
|
|
||||||
for i in 0..4 {
|
|
||||||
if i < resp.len() {
|
|
||||||
resp[i] = (dat0 >> (i * 8)) as u8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i in 0..4 {
|
|
||||||
if i + 4 < resp.len() {
|
|
||||||
resp[i] = (dat1 >> (i * 8)) as u8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bomb.defuse();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
for i in 0..4 {
|
||||||
|
if i + 4 < req.len() {
|
||||||
|
dat1 |= (req[i + 4] as u32) << (i * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = core::cmp::max(req.len(), resp.len()) as u8;
|
||||||
|
|
||||||
|
self.inner.cinstrdat0.write(|w| unsafe { w.bits(dat0) });
|
||||||
|
self.inner.cinstrdat1.write(|w| unsafe { w.bits(dat1) });
|
||||||
|
self.inner.events_ready.reset();
|
||||||
|
self.inner.cinstrconf.write(|w| {
|
||||||
|
let w = unsafe { w.opcode().bits(opcode) };
|
||||||
|
let w = unsafe { w.length().bits(len + 1) };
|
||||||
|
let w = w.lio2().bit(true);
|
||||||
|
let w = w.lio3().bit(true);
|
||||||
|
let w = w.wipwait().bit(true);
|
||||||
|
let w = w.wren().bit(true);
|
||||||
|
let w = w.lfen().bit(false);
|
||||||
|
let w = w.lfstop().bit(false);
|
||||||
|
w
|
||||||
|
});
|
||||||
|
|
||||||
|
SIGNAL.wait().await;
|
||||||
|
|
||||||
|
let dat0 = self.inner.cinstrdat0.read().bits();
|
||||||
|
let dat1 = self.inner.cinstrdat1.read().bits();
|
||||||
|
for i in 0..4 {
|
||||||
|
if i < resp.len() {
|
||||||
|
resp[i] = (dat0 >> (i * 8)) as u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..4 {
|
||||||
|
if i + 4 < resp.len() {
|
||||||
|
resp[i] = (dat1 >> (i * 8)) as u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bomb.defuse();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ use core::sync::atomic::{AtomicU32, Ordering};
|
|||||||
|
|
||||||
use embassy::time::Clock;
|
use embassy::time::Clock;
|
||||||
|
|
||||||
use crate::fmt::*;
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::interrupt::{CriticalSection, Mutex, OwnedInterrupt};
|
use crate::interrupt::{CriticalSection, Mutex, OwnedInterrupt};
|
||||||
use crate::pac::rtc0;
|
use crate::pac::rtc0;
|
||||||
@ -19,6 +18,7 @@ fn compare_n(n: usize) -> u32 {
|
|||||||
1 << (n + 16)
|
1 << (n + 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(tests)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -159,7 +159,9 @@ impl<T: Instance> RTC<T> {
|
|||||||
alarm.timestamp.set(u64::MAX);
|
alarm.timestamp.set(u64::MAX);
|
||||||
|
|
||||||
// Call after clearing alarm, so the callback can set another alarm.
|
// Call after clearing alarm, so the callback can set another alarm.
|
||||||
alarm.callback.get().map(|(f, ctx)| f(ctx));
|
if let Some((f, ctx)) = alarm.callback.get() {
|
||||||
|
f(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
|
fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
|
||||||
|
@ -68,7 +68,7 @@ impl<S: PeripheralState> PeripheralMutex<S> {
|
|||||||
|
|
||||||
impl<S: PeripheralState> Drop for PeripheralMutex<S> {
|
impl<S: PeripheralState> Drop for PeripheralMutex<S> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some((state, irq)) = &mut self.inner {
|
if let Some((_state, irq)) = &mut self.inner {
|
||||||
irq.disable();
|
irq.disable();
|
||||||
irq.remove_handler();
|
irq.remove_handler();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::fmt::{assert, panic, todo, *};
|
use crate::fmt::{assert, *};
|
||||||
|
|
||||||
pub struct RingBuffer<'a> {
|
pub struct RingBuffer<'a> {
|
||||||
buf: &'a mut [u8],
|
buf: &'a mut [u8],
|
||||||
|
@ -5,7 +5,7 @@ mod serial_port;
|
|||||||
|
|
||||||
use async_io::Async;
|
use async_io::Async;
|
||||||
use embassy::executor::task;
|
use embassy::executor::task;
|
||||||
use embassy::io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
|
use embassy::io::AsyncBufReadExt;
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_std::Executor;
|
use embassy_std::Executor;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
@ -7,25 +7,20 @@
|
|||||||
mod example_common;
|
mod example_common;
|
||||||
use example_common::{panic, *};
|
use example_common::{panic, *};
|
||||||
|
|
||||||
use cortex_m::singleton;
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
use embassy::gpio::*;
|
use embassy::gpio::*;
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_stm32f4::exti;
|
use embassy_stm32f4::exti;
|
||||||
use embassy_stm32f4::exti::*;
|
|
||||||
use embassy_stm32f4::interrupt;
|
use embassy_stm32f4::interrupt;
|
||||||
use embassy_stm32f4::serial;
|
|
||||||
use futures::pin_mut;
|
use futures::pin_mut;
|
||||||
use stm32f4xx_hal::serial::config::Config;
|
use stm32f4xx_hal::prelude::*;
|
||||||
use stm32f4xx_hal::stm32;
|
use stm32f4xx_hal::stm32;
|
||||||
use stm32f4xx_hal::syscfg;
|
|
||||||
use stm32f4xx_hal::{prelude::*, serial::config};
|
|
||||||
|
|
||||||
static EXTI: Forever<exti::ExtiManager> = Forever::new();
|
static EXTI: Forever<exti::ExtiManager> = Forever::new();
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
async fn run(dp: stm32::Peripherals, cp: cortex_m::Peripherals) {
|
async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) {
|
||||||
let gpioa = dp.GPIOA.split();
|
let gpioa = dp.GPIOA.split();
|
||||||
|
|
||||||
let button = gpioa.pa0.into_pull_up_input();
|
let button = gpioa.pa0.into_pull_up_input();
|
||||||
|
@ -5,18 +5,10 @@
|
|||||||
|
|
||||||
#[path = "../example_common.rs"]
|
#[path = "../example_common.rs"]
|
||||||
mod example_common;
|
mod example_common;
|
||||||
use example_common::{panic, *};
|
use example_common::*;
|
||||||
|
|
||||||
use cortex_m::singleton;
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use embassy::executor::{task, Executor};
|
use stm32f4xx_hal::prelude::*;
|
||||||
use embassy::uart::Uart;
|
|
||||||
use embassy::util::Forever;
|
|
||||||
use embassy_stm32f4::interrupt;
|
|
||||||
use embassy_stm32f4::serial;
|
|
||||||
use stm32f4xx_hal::serial::config::Config;
|
|
||||||
use stm32f4xx_hal::stm32;
|
|
||||||
use stm32f4xx_hal::{prelude::*, serial::config};
|
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
@ -14,12 +14,12 @@ use embassy::uart::Uart;
|
|||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_stm32f4::interrupt;
|
use embassy_stm32f4::interrupt;
|
||||||
use embassy_stm32f4::serial;
|
use embassy_stm32f4::serial;
|
||||||
|
use stm32f4xx_hal::prelude::*;
|
||||||
use stm32f4xx_hal::serial::config::Config;
|
use stm32f4xx_hal::serial::config::Config;
|
||||||
use stm32f4xx_hal::stm32;
|
use stm32f4xx_hal::stm32;
|
||||||
use stm32f4xx_hal::{prelude::*, serial::config};
|
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
async fn run(dp: stm32::Peripherals, cp: cortex_m::Peripherals) {
|
async fn run(dp: stm32::Peripherals, _cp: cortex_m::Peripherals) {
|
||||||
// https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1
|
// https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1
|
||||||
let gpioa = dp.GPIOA.split();
|
let gpioa = dp.GPIOA.split();
|
||||||
let rcc = dp.RCC.constrain();
|
let rcc = dp.RCC.constrain();
|
||||||
|
@ -19,7 +19,7 @@ pub struct ExtiManager {
|
|||||||
|
|
||||||
impl<'a> ExtiManager {
|
impl<'a> ExtiManager {
|
||||||
pub fn new(_exti: EXTI, syscfg: SysCfg) -> Self {
|
pub fn new(_exti: EXTI, syscfg: SysCfg) -> Self {
|
||||||
Self { syscfg: syscfg }
|
Self { syscfg }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_pin<T, I>(&'static mut self, mut pin: T, interrupt: I) -> ExtiPin<T, I>
|
pub fn new_pin<T, I>(&'static mut self, mut pin: T, interrupt: I) -> ExtiPin<T, I>
|
||||||
@ -30,8 +30,8 @@ impl<'a> ExtiManager {
|
|||||||
pin.make_interrupt_source(&mut self.syscfg);
|
pin.make_interrupt_source(&mut self.syscfg);
|
||||||
|
|
||||||
ExtiPin {
|
ExtiPin {
|
||||||
pin: pin,
|
pin,
|
||||||
interrupt: interrupt,
|
interrupt,
|
||||||
_mgr: self,
|
_mgr: self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
#[cfg(all(feature = "defmt", feature = "log"))]
|
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||||
compile_error!("You may not enable both `defmt` and `log` features.");
|
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(let_chains)]
|
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
feature = "stm32f401",
|
feature = "stm32f401",
|
||||||
|
@ -7,32 +7,21 @@
|
|||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::sync::atomic::{self, Ordering};
|
use core::sync::atomic::{self, Ordering};
|
||||||
use core::task::{Context, Poll};
|
|
||||||
|
|
||||||
use embassy::interrupt::OwnedInterrupt;
|
use embassy::interrupt::OwnedInterrupt;
|
||||||
use embassy::uart::{Error, Uart};
|
use embassy::uart::{Error, Uart};
|
||||||
use embassy::util::Signal;
|
use embassy::util::Signal;
|
||||||
use embedded_dma::StaticWriteBuffer;
|
|
||||||
|
|
||||||
use crate::hal::dma::config::DmaConfig;
|
use crate::hal::dma::config::DmaConfig;
|
||||||
use crate::hal::dma::traits::{PeriAddress, Stream};
|
use crate::hal::dma::traits::{PeriAddress, Stream};
|
||||||
use crate::hal::dma::{
|
use crate::hal::dma::{Stream2, Stream7, StreamsTuple, Transfer};
|
||||||
Channel4, MemoryToPeripheral, PeripheralToMemory, Stream2, Stream7, StreamsTuple, Transfer,
|
|
||||||
};
|
|
||||||
use crate::hal::gpio::gpioa::{PA10, PA9};
|
|
||||||
use crate::hal::gpio::{Alternate, AF7};
|
|
||||||
use crate::hal::prelude::*;
|
|
||||||
use crate::hal::rcc::Clocks;
|
use crate::hal::rcc::Clocks;
|
||||||
use crate::hal::serial::config::{
|
use crate::hal::serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig};
|
||||||
Config as SerialConfig, DmaConfig as SerialDmaConfig, Parity, StopBits, WordLength,
|
|
||||||
};
|
|
||||||
use crate::hal::serial::Pins;
|
use crate::hal::serial::Pins;
|
||||||
use crate::hal::serial::{Event as SerialEvent, Serial as HalSerial};
|
use crate::hal::serial::{Event as SerialEvent, Serial as HalSerial};
|
||||||
use crate::hal::time::Bps;
|
|
||||||
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
|
|
||||||
use crate::pac::Interrupt;
|
|
||||||
use crate::pac::{DMA2, USART1};
|
use crate::pac::{DMA2, USART1};
|
||||||
|
|
||||||
/// Interface to the Serial peripheral
|
/// Interface to the Serial peripheral
|
||||||
|
@ -16,7 +16,7 @@ mod util;
|
|||||||
mod waker;
|
mod waker;
|
||||||
|
|
||||||
use self::util::UninitCell;
|
use self::util::UninitCell;
|
||||||
use crate::fmt::{panic, *};
|
use crate::fmt::panic;
|
||||||
use crate::interrupt::OwnedInterrupt;
|
use crate::interrupt::OwnedInterrupt;
|
||||||
use crate::time::Alarm;
|
use crate::time::Alarm;
|
||||||
|
|
||||||
@ -56,10 +56,10 @@ impl<F: Future + 'static> Task<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SpawnToken {
|
SpawnToken {
|
||||||
raw_task: None,
|
raw_task: None,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn poll(p: NonNull<raw::Task>) {
|
unsafe fn poll(p: NonNull<raw::Task>) {
|
||||||
|
@ -2,7 +2,7 @@ use core::cell::Cell;
|
|||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
use core::sync::atomic::{AtomicPtr, Ordering};
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use super::raw::{Task, STATE_TIMER_QUEUED};
|
use super::raw::{Task, STATE_TIMER_QUEUED};
|
||||||
use crate::time::Instant;
|
use crate::time::Instant;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
#[cfg(all(feature = "defmt", feature = "log"))]
|
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||||
compile_error!("You may not enable both `defmt` and `log` features.");
|
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use core::mem;
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
|
use core::sync::atomic::{AtomicPtr, Ordering};
|
||||||
use cortex_m::peripheral::NVIC;
|
use cortex_m::peripheral::NVIC;
|
||||||
|
|
||||||
pub use embassy_macros::interrupt_declare as declare;
|
pub use embassy_macros::interrupt_declare as declare;
|
||||||
|
@ -71,7 +71,7 @@ where
|
|||||||
|
|
||||||
let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
|
let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return Poll::Ready(Err(Error::WriteZero.into()));
|
return Poll::Ready(Err(Error::WriteZero));
|
||||||
}
|
}
|
||||||
*this.amt += i;
|
*this.amt += i;
|
||||||
this.reader.as_mut().consume(i);
|
this.reader.as_mut().consume(i);
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
use core::iter::Iterator;
|
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use futures::future::Future;
|
use futures::future::Future;
|
||||||
use futures::ready;
|
|
||||||
use futures::task::{Context, Poll};
|
use futures::task::{Context, Poll};
|
||||||
|
|
||||||
use super::super::error::{Error, Result};
|
use super::super::error::Result;
|
||||||
use super::super::traits::AsyncBufRead;
|
use super::super::traits::AsyncBufRead;
|
||||||
|
|
||||||
pub struct Drain<'a, R: ?Sized> {
|
pub struct Drain<'a, R: ?Sized> {
|
||||||
|
@ -75,14 +75,14 @@ pub trait AsyncBufReadExt: AsyncBufRead {
|
|||||||
ReadWhile::new(self, f, buf)
|
ReadWhile::new(self, f, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_while<'a, F: Fn(u8) -> bool>(&'a mut self, f: F) -> SkipWhile<'a, Self, F>
|
fn skip_while<F: Fn(u8) -> bool>(&mut self, f: F) -> SkipWhile<Self, F>
|
||||||
where
|
where
|
||||||
Self: Unpin,
|
Self: Unpin,
|
||||||
{
|
{
|
||||||
SkipWhile::new(self, f)
|
SkipWhile::new(self, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drain<'a>(&'a mut self) -> Drain<'a, Self>
|
fn drain(&mut self) -> Drain<Self>
|
||||||
where
|
where
|
||||||
Self: Unpin,
|
Self: Unpin,
|
||||||
{
|
{
|
||||||
@ -96,14 +96,14 @@ pub trait AsyncBufReadExt: AsyncBufRead {
|
|||||||
Read::new(self, buf)
|
Read::new(self, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_buf<'a>(&'a mut self) -> ReadBuf<'a, Self>
|
fn read_buf(&mut self) -> ReadBuf<Self>
|
||||||
where
|
where
|
||||||
Self: Unpin,
|
Self: Unpin,
|
||||||
{
|
{
|
||||||
ReadBuf::new(self)
|
ReadBuf::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_byte<'a>(&'a mut self) -> ReadByte<'a, Self>
|
fn read_byte(&mut self) -> ReadByte<Self>
|
||||||
where
|
where
|
||||||
Self: Unpin,
|
Self: Unpin,
|
||||||
{
|
{
|
||||||
@ -147,12 +147,19 @@ pub trait AsyncWriteExt: AsyncWrite {
|
|||||||
WriteAll::new(self, buf)
|
WriteAll::new(self, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_byte<'a>(&'a mut self, byte: u8) -> WriteByte<'a, Self>
|
fn write_byte(&mut self, byte: u8) -> WriteByte<Self>
|
||||||
where
|
where
|
||||||
Self: Unpin,
|
Self: Unpin,
|
||||||
{
|
{
|
||||||
WriteByte::new(self, byte)
|
WriteByte::new(self, byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self>
|
||||||
|
where
|
||||||
|
Self: Unpin,
|
||||||
|
{
|
||||||
|
Write::new(self, buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: AsyncWrite + ?Sized> AsyncWriteExt for R {}
|
impl<R: AsyncWrite + ?Sized> AsyncWriteExt for R {}
|
||||||
|
@ -25,7 +25,7 @@ impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for ReadByte<'a, R> {
|
|||||||
let Self { reader } = &mut *self;
|
let Self { reader } = &mut *self;
|
||||||
let mut reader = Pin::new(reader);
|
let mut reader = Pin::new(reader);
|
||||||
let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
||||||
if rbuf.len() == 0 {
|
if rbuf.is_empty() {
|
||||||
return Poll::Ready(Err(Error::UnexpectedEof));
|
return Poll::Ready(Err(Error::UnexpectedEof));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadExact<'_, R> {
|
|||||||
let this = &mut *self;
|
let this = &mut *self;
|
||||||
while !this.buf.is_empty() {
|
while !this.buf.is_empty() {
|
||||||
let buf = ready!(Pin::new(&mut this.reader).poll_fill_buf(cx))?;
|
let buf = ready!(Pin::new(&mut this.reader).poll_fill_buf(cx))?;
|
||||||
if buf.len() == 0 {
|
if buf.is_empty() {
|
||||||
return Poll::Ready(Err(Error::UnexpectedEof));
|
return Poll::Ready(Err(Error::UnexpectedEof));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for ReadToEnd<'a, R> {
|
|||||||
let mut reader = Pin::new(reader);
|
let mut reader = Pin::new(reader);
|
||||||
loop {
|
loop {
|
||||||
let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
||||||
if rbuf.len() == 0 {
|
if rbuf.is_empty() {
|
||||||
return Poll::Ready(Ok(*n));
|
return Poll::Ready(Ok(*n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ impl<'a, R: AsyncBufRead + ?Sized + Unpin, F: Fn(u8) -> bool> Future for ReadWhi
|
|||||||
let mut reader = Pin::new(reader);
|
let mut reader = Pin::new(reader);
|
||||||
loop {
|
loop {
|
||||||
let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
||||||
if rbuf.len() == 0 {
|
if rbuf.is_empty() {
|
||||||
return Poll::Ready(Err(Error::UnexpectedEof));
|
return Poll::Ready(Err(Error::UnexpectedEof));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ impl<'a, R: AsyncBufRead + ?Sized + Unpin, F: Fn(u8) -> bool> Future for SkipWhi
|
|||||||
let mut reader = Pin::new(reader);
|
let mut reader = Pin::new(reader);
|
||||||
loop {
|
loop {
|
||||||
let buf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
let buf = ready!(reader.as_mut().poll_fill_buf(cx))?;
|
||||||
if buf.len() == 0 {
|
if buf.is_empty() {
|
||||||
return Poll::Ready(Err(Error::UnexpectedEof));
|
return Poll::Ready(Err(Error::UnexpectedEof));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ impl Instant {
|
|||||||
|
|
||||||
pub fn duration_since(&self, earlier: Instant) -> Duration {
|
pub fn duration_since(&self, earlier: Instant) -> Duration {
|
||||||
Duration {
|
Duration {
|
||||||
ticks: (self.ticks - earlier.ticks).try_into().unwrap(),
|
ticks: self.ticks.checked_sub(earlier.ticks).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ impl Instant {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Duration {
|
Some(Duration {
|
||||||
ticks: (self.ticks - earlier.ticks).try_into().unwrap(),
|
ticks: self.ticks - earlier.ticks,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,7 +67,7 @@ impl Instant {
|
|||||||
ticks: if self.ticks < earlier.ticks {
|
ticks: if self.ticks < earlier.ticks {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
(self.ticks - earlier.ticks).try_into().unwrap()
|
self.ticks - earlier.ticks
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,12 +78,12 @@ impl Instant {
|
|||||||
|
|
||||||
pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
|
pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
|
||||||
self.ticks
|
self.ticks
|
||||||
.checked_add(duration.ticks.into())
|
.checked_add(duration.ticks)
|
||||||
.map(|ticks| Instant { ticks })
|
.map(|ticks| Instant { ticks })
|
||||||
}
|
}
|
||||||
pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
|
pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
|
||||||
self.ticks
|
self.ticks
|
||||||
.checked_sub(duration.ticks.into())
|
.checked_sub(duration.ticks)
|
||||||
.map(|ticks| Instant { ticks })
|
.map(|ticks| Instant { ticks })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use cortex_m::interrupt::CriticalSection;
|
use cortex_m::interrupt::CriticalSection;
|
||||||
|
|
||||||
use crate::fmt::{assert, panic, *};
|
use crate::fmt::assert;
|
||||||
|
|
||||||
/// A "mutex" based on critical sections
|
/// A "mutex" based on critical sections
|
||||||
///
|
///
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::fmt::panic;
|
use crate::fmt::panic;
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::future::Future;
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
@ -34,93 +33,89 @@ impl<T> Portal<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_once<'a, R, F>(&'a self, mut func: F) -> impl Future<Output = R> + 'a
|
pub async fn wait_once<'a, R, F>(&'a self, mut func: F) -> R
|
||||||
where
|
where
|
||||||
F: FnMut(T) -> R + 'a,
|
F: FnMut(T) -> R + 'a,
|
||||||
{
|
{
|
||||||
async move {
|
let bomb = DropBomb::new();
|
||||||
let bomb = DropBomb::new();
|
|
||||||
|
|
||||||
let signal = Signal::new();
|
|
||||||
let mut result: MaybeUninit<R> = MaybeUninit::uninit();
|
|
||||||
let mut call_func = |val: T| {
|
|
||||||
unsafe {
|
|
||||||
let state = &mut *self.state.get();
|
|
||||||
*state = State::None;
|
|
||||||
result.as_mut_ptr().write(func(val))
|
|
||||||
};
|
|
||||||
signal.signal(());
|
|
||||||
};
|
|
||||||
|
|
||||||
let func_ptr: *mut dyn FnMut(T) = &mut call_func as _;
|
|
||||||
let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) };
|
|
||||||
|
|
||||||
|
let signal = Signal::new();
|
||||||
|
let mut result: MaybeUninit<R> = MaybeUninit::uninit();
|
||||||
|
let mut call_func = |val: T| {
|
||||||
unsafe {
|
unsafe {
|
||||||
let state = &mut *self.state.get();
|
let state = &mut *self.state.get();
|
||||||
match state {
|
*state = State::None;
|
||||||
State::None => {}
|
result.as_mut_ptr().write(func(val))
|
||||||
_ => panic!("Multiple tasks waiting on same portal"),
|
};
|
||||||
}
|
signal.signal(());
|
||||||
*state = State::Waiting(func_ptr);
|
};
|
||||||
|
|
||||||
|
let func_ptr: *mut dyn FnMut(T) = &mut call_func as _;
|
||||||
|
let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let state = &mut *self.state.get();
|
||||||
|
match state {
|
||||||
|
State::None => {}
|
||||||
|
_ => panic!("Multiple tasks waiting on same portal"),
|
||||||
}
|
}
|
||||||
|
*state = State::Waiting(func_ptr);
|
||||||
signal.wait().await;
|
|
||||||
|
|
||||||
bomb.defuse();
|
|
||||||
|
|
||||||
unsafe { result.assume_init() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signal.wait().await;
|
||||||
|
|
||||||
|
bomb.defuse();
|
||||||
|
|
||||||
|
unsafe { result.assume_init() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_many<'a, R, F>(&'a self, mut func: F) -> impl Future<Output = R> + 'a
|
pub async fn wait_many<'a, R, F>(&'a self, mut func: F) -> R
|
||||||
where
|
where
|
||||||
F: FnMut(T) -> Option<R> + 'a,
|
F: FnMut(T) -> Option<R> + 'a,
|
||||||
{
|
{
|
||||||
async move {
|
let bomb = DropBomb::new();
|
||||||
let bomb = DropBomb::new();
|
|
||||||
|
|
||||||
let signal = Signal::new();
|
|
||||||
let mut result: MaybeUninit<R> = MaybeUninit::uninit();
|
|
||||||
let mut call_func = |val: T| {
|
|
||||||
unsafe {
|
|
||||||
let state = &mut *self.state.get();
|
|
||||||
|
|
||||||
let func_ptr = match *state {
|
|
||||||
State::Waiting(p) => p,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set state to Running while running the function to avoid reentrancy.
|
|
||||||
*state = State::Running;
|
|
||||||
|
|
||||||
*state = match func(val) {
|
|
||||||
None => State::Waiting(func_ptr),
|
|
||||||
Some(res) => {
|
|
||||||
result.as_mut_ptr().write(res);
|
|
||||||
signal.signal(());
|
|
||||||
State::None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
let func_ptr: *mut dyn FnMut(T) = &mut call_func as _;
|
|
||||||
let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) };
|
|
||||||
|
|
||||||
|
let signal = Signal::new();
|
||||||
|
let mut result: MaybeUninit<R> = MaybeUninit::uninit();
|
||||||
|
let mut call_func = |val: T| {
|
||||||
unsafe {
|
unsafe {
|
||||||
let state = &mut *self.state.get();
|
let state = &mut *self.state.get();
|
||||||
match *state {
|
|
||||||
State::None => {}
|
let func_ptr = match *state {
|
||||||
_ => panic!("Multiple tasks waiting on same portal"),
|
State::Waiting(p) => p,
|
||||||
}
|
_ => unreachable!(),
|
||||||
*state = State::Waiting(func_ptr);
|
};
|
||||||
|
|
||||||
|
// Set state to Running while running the function to avoid reentrancy.
|
||||||
|
*state = State::Running;
|
||||||
|
|
||||||
|
*state = match func(val) {
|
||||||
|
None => State::Waiting(func_ptr),
|
||||||
|
Some(res) => {
|
||||||
|
result.as_mut_ptr().write(res);
|
||||||
|
signal.signal(());
|
||||||
|
State::None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let func_ptr: *mut dyn FnMut(T) = &mut call_func as _;
|
||||||
|
let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let state = &mut *self.state.get();
|
||||||
|
match *state {
|
||||||
|
State::None => {}
|
||||||
|
_ => panic!("Multiple tasks waiting on same portal"),
|
||||||
}
|
}
|
||||||
|
*state = State::Waiting(func_ptr);
|
||||||
signal.wait().await;
|
|
||||||
|
|
||||||
bomb.defuse();
|
|
||||||
|
|
||||||
unsafe { result.assume_init() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signal.wait().await;
|
||||||
|
|
||||||
|
bomb.defuse();
|
||||||
|
|
||||||
|
unsafe { result.assume_init() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,8 @@ impl<T: Send> Signal<T> {
|
|||||||
pub fn signal(&self, val: T) {
|
pub fn signal(&self, val: T) {
|
||||||
cortex_m::interrupt::free(|_| unsafe {
|
cortex_m::interrupt::free(|_| unsafe {
|
||||||
let state = &mut *self.state.get();
|
let state = &mut *self.state.get();
|
||||||
match mem::replace(state, State::Signaled(val)) {
|
if let State::Waiting(waker) = mem::replace(state, State::Signaled(val)) {
|
||||||
State::Waiting(waker) => waker.wake(),
|
waker.wake();
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -98,9 +97,7 @@ impl<'a, I: OwnedInterrupt> InterruptFuture<'a, I> {
|
|||||||
interrupt.unpend();
|
interrupt.unpend();
|
||||||
interrupt.enable();
|
interrupt.enable();
|
||||||
|
|
||||||
Self {
|
Self { interrupt }
|
||||||
interrupt: interrupt,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn interrupt_handler(ctx: *mut ()) {
|
unsafe fn interrupt_handler(ctx: *mut ()) {
|
||||||
@ -109,7 +106,7 @@ impl<'a, I: OwnedInterrupt> InterruptFuture<'a, I> {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if ctx as *const _ != ptr::null() {
|
if !ctx.is_null() {
|
||||||
executor::raw::wake_task(ptr::NonNull::new_unchecked(ctx as _));
|
executor::raw::wake_task(ptr::NonNull::new_unchecked(ctx as _));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,9 @@ impl WakerRegistration {
|
|||||||
|
|
||||||
/// Wake the registered waker, if any.
|
/// Wake the registered waker, if any.
|
||||||
pub fn wake(&mut self) {
|
pub fn wake(&mut self) {
|
||||||
self.waker.take().map(|w| w.wake());
|
if let Some(w) = self.waker.take() {
|
||||||
|
w.wake()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context(&self) -> Option<Context<'_>> {
|
pub fn context(&self) -> Option<Context<'_>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user