Merge pull request #304 from bobmcwhirter/async_move_dma_transfer
The `async move` portion of @thalesfragoso's i2c PR.
This commit is contained in:
commit
cec2654854
@ -38,7 +38,7 @@ impl State {
|
|||||||
static STATE: State = State::new();
|
static STATE: State = State::new();
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) async unsafe fn do_transfer(
|
pub(crate) unsafe fn do_transfer(
|
||||||
dma: pac::bdma::Dma,
|
dma: pac::bdma::Dma,
|
||||||
channel_number: u8,
|
channel_number: u8,
|
||||||
state_number: u8,
|
state_number: u8,
|
||||||
@ -49,7 +49,7 @@ pub(crate) async unsafe fn do_transfer(
|
|||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
#[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
|
#[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
|
||||||
#[cfg(dmamux)] dmamux_ch_num: u8,
|
#[cfg(dmamux)] dmamux_ch_num: u8,
|
||||||
) {
|
) -> impl Future<Output = ()> {
|
||||||
// ndtr is max 16 bits.
|
// ndtr is max 16 bits.
|
||||||
assert!(mem_len <= 0xFFFF);
|
assert!(mem_len <= 0xFFFF);
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ pub(crate) async unsafe fn do_transfer(
|
|||||||
// Generate a DMB here to flush the store buffer (M7) before enabling the DMA
|
// Generate a DMB here to flush the store buffer (M7) before enabling the DMA
|
||||||
STATE.ch_status[state_number as usize].store(CH_STATUS_NONE, Ordering::Release);
|
STATE.ch_status[state_number as usize].store(CH_STATUS_NONE, Ordering::Release);
|
||||||
|
|
||||||
let on_drop = OnDrop::new(|| unsafe {
|
let on_drop = OnDrop::new(move || unsafe {
|
||||||
ch.cr().modify(|w| {
|
ch.cr().modify(|w| {
|
||||||
w.set_tcie(false);
|
w.set_tcie(false);
|
||||||
w.set_teie(false);
|
w.set_teie(false);
|
||||||
@ -95,17 +95,20 @@ pub(crate) async unsafe fn do_transfer(
|
|||||||
w.set_en(true);
|
w.set_en(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = poll_fn(|cx| {
|
async move {
|
||||||
STATE.ch_wakers[state_number as usize].register(cx.waker());
|
let res = poll_fn(|cx| {
|
||||||
match STATE.ch_status[state_number as usize].load(Ordering::Acquire) {
|
STATE.ch_wakers[state_number as usize].register(cx.waker());
|
||||||
CH_STATUS_NONE => Poll::Pending,
|
match STATE.ch_status[state_number as usize].load(Ordering::Acquire) {
|
||||||
x => Poll::Ready(x),
|
CH_STATUS_NONE => Poll::Pending,
|
||||||
}
|
x => Poll::Ready(x),
|
||||||
})
|
}
|
||||||
.await;
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
// TODO handle error
|
// TODO handle error
|
||||||
assert!(res == CH_STATUS_COMPLETED);
|
assert!(res == CH_STATUS_COMPLETED);
|
||||||
|
drop(on_drop)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! dma_num {
|
macro_rules! dma_num {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
use core::future::Future;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use atomic_polyfill::{AtomicU8, Ordering};
|
use atomic_polyfill::{AtomicU8, Ordering};
|
||||||
use core::future::Future;
|
|
||||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||||
use embassy::util::{AtomicWaker, OnDrop};
|
use embassy::util::{AtomicWaker, OnDrop};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
@ -39,7 +39,7 @@ static STATE: State = State::new();
|
|||||||
//async unsafe fn do_transfer(ch: &mut impl Channel, ch_func: u8, src: *const u8, dst: &mut [u8]) {
|
//async unsafe fn do_transfer(ch: &mut impl Channel, ch_func: u8, src: *const u8, dst: &mut [u8]) {
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) async unsafe fn do_transfer(
|
pub(crate) unsafe fn do_transfer(
|
||||||
dma: pac::dma::Dma,
|
dma: pac::dma::Dma,
|
||||||
channel_number: u8,
|
channel_number: u8,
|
||||||
state_number: u8,
|
state_number: u8,
|
||||||
@ -50,7 +50,7 @@ pub(crate) async unsafe fn do_transfer(
|
|||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
#[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
|
#[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
|
||||||
#[cfg(dmamux)] dmamux_ch_num: u8,
|
#[cfg(dmamux)] dmamux_ch_num: u8,
|
||||||
) {
|
) -> impl Future<Output = ()> {
|
||||||
// ndtr is max 16 bits.
|
// ndtr is max 16 bits.
|
||||||
assert!(mem_len <= 0xFFFF);
|
assert!(mem_len <= 0xFFFF);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ pub(crate) async unsafe fn do_transfer(
|
|||||||
|
|
||||||
let ch = dma.st(channel_number as _);
|
let ch = dma.st(channel_number as _);
|
||||||
|
|
||||||
let on_drop = OnDrop::new(|| unsafe {
|
let on_drop = OnDrop::new(move || unsafe {
|
||||||
ch.cr().modify(|w| {
|
ch.cr().modify(|w| {
|
||||||
w.set_tcie(false);
|
w.set_tcie(false);
|
||||||
w.set_teie(false);
|
w.set_teie(false);
|
||||||
@ -100,18 +100,21 @@ pub(crate) async unsafe fn do_transfer(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = poll_fn(|cx| {
|
async move {
|
||||||
let n = channel_number as usize;
|
let res = poll_fn(|cx| {
|
||||||
STATE.ch_wakers[n].register(cx.waker());
|
let n = channel_number as usize;
|
||||||
match STATE.ch_status[n].load(Ordering::Acquire) {
|
STATE.ch_wakers[n].register(cx.waker());
|
||||||
CH_STATUS_NONE => Poll::Pending,
|
match STATE.ch_status[n].load(Ordering::Acquire) {
|
||||||
x => Poll::Ready(x),
|
CH_STATUS_NONE => Poll::Pending,
|
||||||
}
|
x => Poll::Ready(x),
|
||||||
})
|
}
|
||||||
.await;
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
// TODO handle error
|
// TODO handle error
|
||||||
assert!(res == CH_STATUS_COMPLETED);
|
assert!(res == CH_STATUS_COMPLETED);
|
||||||
|
drop(on_drop)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! dma_num {
|
macro_rules! dma_num {
|
||||||
|
Loading…
Reference in New Issue
Block a user