aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThales <[email protected]>2021-07-20 13:07:28 -0300
committerGitHub <[email protected]>2021-07-20 13:07:28 -0300
commitcec26548549d4e960d65caa5660384d4e51b258f (patch)
tree40d091d6a8cd0ce049fdea76c636bb8e3300b8b8
parent25b870d811d9ac3955a69996ddf7a68a2af252f5 (diff)
parent2d3137afc7c20dd68e4a187cafd7016f5a0f4d34 (diff)
Merge pull request #304 from bobmcwhirter/async_move_dma_transfer
The `async move` portion of @thalesfragoso's i2c PR.
-rw-r--r--embassy-stm32/src/dma/bdma.rs29
-rw-r--r--embassy-stm32/src/dma/dma.rs33
2 files changed, 34 insertions, 28 deletions
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index 5063ec2e7..e2da2a8ea 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -38,7 +38,7 @@ impl State {
38static STATE: State = State::new(); 38static STATE: State = State::new();
39 39
40#[allow(unused)] 40#[allow(unused)]
41pub(crate) async unsafe fn do_transfer( 41pub(crate) unsafe fn do_transfer(
42 dma: pac::bdma::Dma, 42 dma: pac::bdma::Dma,
43 channel_number: u8, 43 channel_number: u8,
44 state_number: u8, 44 state_number: u8,
@@ -49,7 +49,7 @@ pub(crate) async unsafe fn do_transfer(
49 mem_len: usize, 49 mem_len: usize,
50 #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, 50 #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
51 #[cfg(dmamux)] dmamux_ch_num: u8, 51 #[cfg(dmamux)] dmamux_ch_num: u8,
52) { 52) -> impl Future<Output = ()> {
53 // ndtr is max 16 bits. 53 // ndtr is max 16 bits.
54 assert!(mem_len <= 0xFFFF); 54 assert!(mem_len <= 0xFFFF);
55 55
@@ -59,7 +59,7 @@ pub(crate) async unsafe fn do_transfer(
59 // Generate a DMB here to flush the store buffer (M7) before enabling the DMA 59 // Generate a DMB here to flush the store buffer (M7) before enabling the DMA
60 STATE.ch_status[state_number as usize].store(CH_STATUS_NONE, Ordering::Release); 60 STATE.ch_status[state_number as usize].store(CH_STATUS_NONE, Ordering::Release);
61 61
62 let on_drop = OnDrop::new(|| unsafe { 62 let on_drop = OnDrop::new(move || unsafe {
63 ch.cr().modify(|w| { 63 ch.cr().modify(|w| {
64 w.set_tcie(false); 64 w.set_tcie(false);
65 w.set_teie(false); 65 w.set_teie(false);
@@ -95,17 +95,20 @@ pub(crate) async unsafe fn do_transfer(
95 w.set_en(true); 95 w.set_en(true);
96 }); 96 });
97 97
98 let res = poll_fn(|cx| { 98 async move {
99 STATE.ch_wakers[state_number as usize].register(cx.waker()); 99 let res = poll_fn(|cx| {
100 match STATE.ch_status[state_number as usize].load(Ordering::Acquire) { 100 STATE.ch_wakers[state_number as usize].register(cx.waker());
101 CH_STATUS_NONE => Poll::Pending, 101 match STATE.ch_status[state_number as usize].load(Ordering::Acquire) {
102 x => Poll::Ready(x), 102 CH_STATUS_NONE => Poll::Pending,
103 } 103 x => Poll::Ready(x),
104 }) 104 }
105 .await; 105 })
106 .await;
106 107
107 // TODO handle error 108 // TODO handle error
108 assert!(res == CH_STATUS_COMPLETED); 109 assert!(res == CH_STATUS_COMPLETED);
110 drop(on_drop)
111 }
109} 112}
110 113
111macro_rules! dma_num { 114macro_rules! dma_num {
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 8634de205..cf0889a3e 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -1,7 +1,7 @@
1use core::future::Future;
1use core::task::Poll; 2use core::task::Poll;
2 3
3use atomic_polyfill::{AtomicU8, Ordering}; 4use atomic_polyfill::{AtomicU8, Ordering};
4use core::future::Future;
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::util::{AtomicWaker, OnDrop}; 6use embassy::util::{AtomicWaker, OnDrop};
7use futures::future::poll_fn; 7use futures::future::poll_fn;
@@ -39,7 +39,7 @@ static STATE: State = State::new();
39//async unsafe fn do_transfer(ch: &mut impl Channel, ch_func: u8, src: *const u8, dst: &mut [u8]) { 39//async unsafe fn do_transfer(ch: &mut impl Channel, ch_func: u8, src: *const u8, dst: &mut [u8]) {
40 40
41#[allow(unused)] 41#[allow(unused)]
42pub(crate) async unsafe fn do_transfer( 42pub(crate) unsafe fn do_transfer(
43 dma: pac::dma::Dma, 43 dma: pac::dma::Dma,
44 channel_number: u8, 44 channel_number: u8,
45 state_number: u8, 45 state_number: u8,
@@ -50,7 +50,7 @@ pub(crate) async unsafe fn do_transfer(
50 mem_len: usize, 50 mem_len: usize,
51 #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, 51 #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux,
52 #[cfg(dmamux)] dmamux_ch_num: u8, 52 #[cfg(dmamux)] dmamux_ch_num: u8,
53) { 53) -> impl Future<Output = ()> {
54 // ndtr is max 16 bits. 54 // ndtr is max 16 bits.
55 assert!(mem_len <= 0xFFFF); 55 assert!(mem_len <= 0xFFFF);
56 56
@@ -60,7 +60,7 @@ pub(crate) async unsafe fn do_transfer(
60 60
61 let ch = dma.st(channel_number as _); 61 let ch = dma.st(channel_number as _);
62 62
63 let on_drop = OnDrop::new(|| unsafe { 63 let on_drop = OnDrop::new(move || unsafe {
64 ch.cr().modify(|w| { 64 ch.cr().modify(|w| {
65 w.set_tcie(false); 65 w.set_tcie(false);
66 w.set_teie(false); 66 w.set_teie(false);
@@ -100,18 +100,21 @@ pub(crate) async unsafe fn do_transfer(
100 }); 100 });
101 } 101 }
102 102
103 let res = poll_fn(|cx| { 103 async move {
104 let n = channel_number as usize; 104 let res = poll_fn(|cx| {
105 STATE.ch_wakers[n].register(cx.waker()); 105 let n = channel_number as usize;
106 match STATE.ch_status[n].load(Ordering::Acquire) { 106 STATE.ch_wakers[n].register(cx.waker());
107 CH_STATUS_NONE => Poll::Pending, 107 match STATE.ch_status[n].load(Ordering::Acquire) {
108 x => Poll::Ready(x), 108 CH_STATUS_NONE => Poll::Pending,
109 } 109 x => Poll::Ready(x),
110 }) 110 }
111 .await; 111 })
112 .await;
112 113
113 // TODO handle error 114 // TODO handle error
114 assert!(res == CH_STATUS_COMPLETED); 115 assert!(res == CH_STATUS_COMPLETED);
116 drop(on_drop)
117 }
115} 118}
116 119
117macro_rules! dma_num { 120macro_rules! dma_num {