Skip to content

Commit

Permalink
Fix compilation when async feature is disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeaurivage committed Nov 9, 2024
1 parent 60bf82c commit 367d4c5
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 43 deletions.
3 changes: 3 additions & 0 deletions boards/atsame54_xpro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ rtt-target = { version = "0.3", features = ["cortex-m"] }
[features]
default = ["rt", "atsamd-hal/same54p"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
rt = ["cortex-m-rt", "atsamd-hal/same54p-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
can = ["atsamd-hal/can"]
Expand Down
2 changes: 2 additions & 0 deletions boards/feather_m4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ rt = ["cortex-m-rt", "atsamd-hal/samd51j-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/dma"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
use_semihosting = []

[[example]]
Expand Down
2 changes: 2 additions & 0 deletions boards/metro_m0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ cortex-m-rtic = "1.0"
default = ["rt", "atsamd-hal/samd21g"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
rt = ["cortex-m-rt", "atsamd-hal/samd21g-rt"]
rtic = ["atsamd-hal/rtic"]
use_rtt = ["atsamd-hal/use_rtt"]
Expand Down
1 change: 1 addition & 0 deletions boards/metro_m4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ version = "0.3"
[features]
# ask the HAL to enable atsamd51j support
default = ["rt", "atsamd-hal/samd51j"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
Expand Down
4 changes: 4 additions & 0 deletions boards/pygamer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ default = ["rt", "atsamd-hal/samd51j"]
panic_led = []
rt = ["cortex-m-rt", "atsamd-hal/samd51j-rt"]
usb = ["atsamd-hal/usb", "usb-device"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]

# for cargo flash
[package.metadata]
Expand Down
2 changes: 2 additions & 0 deletions boards/samd11_bare/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ rtt-target = { version = "0.3.0", features = ["cortex-m"] }
default = ["rt", "atsamd-hal/samd11c"]
dma = ["atsamd-hal/dma"]
max-channels = ["dma", "atsamd-hal/max-channels"]
# Enable async support from atsamd-hal
async = ["atsamd-hal/async"]
rt = ["cortex-m-rt", "atsamd-hal/samd11c-rt"]
use_semihosting = []

Expand Down
100 changes: 58 additions & 42 deletions hal/src/dmac/channel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,6 @@ impl<Id: ChId> Channel<Id, ReadyFuture> {
/// [`ManuallyDrop`]: core::mem::ManuallyDrop
/// [`Future`]: core::future::Future
/// [`poll`]: core::future::Future::poll
#[cfg(feature = "async")]
#[inline]
pub async fn transfer_future<S, D>(
&mut self,
Expand All @@ -655,7 +654,7 @@ impl<Id: ChId> Channel<Id, ReadyFuture> {

self.configure_trigger(trig_src, trig_act);

TransferFuture::start(self, trig_src).await;
transfer_future::TransferFuture::start(self, trig_src).await;

// No need to defensively disable channel here; it's automatically stopped when
// TransferFuture is dropped. Even though `stop()` is implicitly called
Expand All @@ -669,61 +668,78 @@ impl<Id: ChId> Channel<Id, ReadyFuture> {
}
}

struct TransferFuture<'a, Id: ChId> {
triggered: bool,
trig_src: TriggerSource,
chan: &'a mut Channel<Id, ReadyFuture>,
}
#[cfg(feature = "async")]
mod transfer_future {
use super::*;

impl<'a, Id: ChId> TransferFuture<'a, Id> {
fn start(chan: &'a mut Channel<Id, ReadyFuture>, trig_src: TriggerSource) -> Self {
Self {
triggered: false,
trig_src,
chan,
/// [`Future`](core::future::Future) which starts, then waits on a DMA
/// transfer.
///
/// This implementation is a standalone struct instead of using
/// [`poll_fn`](core::future::poll_fn), because we want to implement
/// [`Drop`] for the future returned by the
/// [`transfer_future`](super::Channel::transfer_future) method. This way we
/// can stop transfers when they are dropped, thus avoiding undefined
/// behaviour.
pub(super) struct TransferFuture<'a, Id: ChId> {
triggered: bool,
trig_src: TriggerSource,
chan: &'a mut Channel<Id, ReadyFuture>,
}

impl<'a, Id: ChId> TransferFuture<'a, Id> {
pub(super) fn start(
chan: &'a mut Channel<Id, ReadyFuture>,
trig_src: TriggerSource,
) -> Self {
Self {
triggered: false,
trig_src,
chan,
}
}
}
}

impl<Id: ChId> Drop for TransferFuture<'_, Id> {
fn drop(&mut self) {
self.chan.stop();
impl<Id: ChId> Drop for TransferFuture<'_, Id> {
fn drop(&mut self) {
self.chan.stop();
}
}
}

impl<Id: ChId> core::future::Future for TransferFuture<'_, Id> {
type Output = ();
impl<Id: ChId> core::future::Future for TransferFuture<'_, Id> {
type Output = ();

fn poll(
mut self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Self::Output> {
use crate::dmac::waker::WAKERS;
use core::task::Poll;
fn poll(
mut self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Self::Output> {
use crate::dmac::waker::WAKERS;
use core::task::Poll;

self.chan._enable_private();
self.chan._enable_private();

if !self.triggered && self.trig_src == TriggerSource::Disable {
self.triggered = true;
self.chan._trigger_private();
}
if !self.triggered && self.trig_src == TriggerSource::Disable {
self.triggered = true;
self.chan._trigger_private();
}

let flags_to_check = InterruptFlags::new().with_tcmpl(true).with_terr(true);
let flags_to_check = InterruptFlags::new().with_tcmpl(true).with_terr(true);

if self.chan.check_and_clear_interrupts(flags_to_check).tcmpl() {
return Poll::Ready(());
}
if self.chan.check_and_clear_interrupts(flags_to_check).tcmpl() {
return Poll::Ready(());
}

WAKERS[Id::USIZE].register(cx.waker());
self.chan.enable_interrupts(flags_to_check);
WAKERS[Id::USIZE].register(cx.waker());
self.chan.enable_interrupts(flags_to_check);

if self.chan.check_and_clear_interrupts(flags_to_check).tcmpl() {
self.chan.disable_interrupts(flags_to_check);
if self.chan.check_and_clear_interrupts(flags_to_check).tcmpl() {
self.chan.disable_interrupts(flags_to_check);

return Poll::Ready(());
}
return Poll::Ready(());
}

Poll::Pending
Poll::Pending
}
}
}

Expand Down
5 changes: 4 additions & 1 deletion hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

use embedded_hal_02 as ehal_02;
pub use embedded_hal_1 as ehal;
pub use embedded_hal_async as ehal_async;
pub use embedded_hal_nb as ehal_nb;
pub use embedded_io;
pub use fugit;
pub use nb;
pub use paste;

#[cfg(feature = "async")]
pub use embedded_hal_async as ehal_async;

pub mod typelevel;
mod util;

Expand Down

0 comments on commit 367d4c5

Please sign in to comment.