aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Salzedo <[email protected]>2021-09-28 17:37:39 -0700
committerDario Nieuwenhuis <[email protected]>2021-12-07 21:43:47 +0100
commit2d2c6d0e01bc21b2207bb629030809be35ed4235 (patch)
tree8a0db08fc5b76f3c5e496f80b3ea53824359672e
parent3272987d9281590b0326f0ce6b577ad6f24d06bb (diff)
Implement extended Channel trait to dma.rs
-rw-r--r--embassy-stm32/src/dma/dma.rs64
-rw-r--r--embassy-stm32/src/dma/mod.rs2
2 files changed, 56 insertions, 10 deletions
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index ec5ac98a0..754685c24 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -1,6 +1,6 @@
1use core::future::Future; 1use core::future::Future;
2use core::sync::atomic::{fence, Ordering}; 2use core::sync::atomic::{fence, Ordering};
3use core::task::Poll; 3use core::task::{Poll, Waker};
4 4
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
@@ -61,14 +61,7 @@ pub(crate) unsafe fn do_transfer(
61 let ch = dma.st(channel_number as _); 61 let ch = dma.st(channel_number as _);
62 62
63 let on_drop = OnDrop::new(move || unsafe { 63 let on_drop = OnDrop::new(move || unsafe {
64 // Disable the channel and interrupts with the default value. 64 _stop(&dma, channel_number);
65 ch.cr().write(|_| ());
66
67 // Wait for the transfer to complete when it was ongoing.
68 while ch.cr().read().en() {}
69
70 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
71 fence(Ordering::Acquire);
72 }); 65 });
73 66
74 #[cfg(dmamux)] 67 #[cfg(dmamux)]
@@ -125,6 +118,47 @@ pub(crate) unsafe fn do_transfer(
125 } 118 }
126} 119}
127 120
121/// Stops the DMA channel.
122unsafe fn _stop(dma: &pac::dma::Dma, ch: u8) {
123 // get a handle on the channel itself
124 let ch = dma.st(ch as _);
125
126 // Disable the channel and interrupts with the default value.
127 ch.cr().write(|_| ());
128
129 // Wait for the transfer to complete when it was ongoing.
130 while ch.cr().read().en() {}
131
132 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
133 fence(Ordering::Acquire);
134}
135
136/// Gets the running status of the channel
137unsafe fn _is_stopped(dma: &pac::dma::Dma, ch: u8) -> bool{
138 // get a handle on the channel itself
139 let ch = dma.st(ch as _);
140
141 // Wait for the transfer to complete when it was ongoing.
142 ch.cr().read().en()
143}
144
145/// Gets the total remaining transfers for the channel
146/// Note: this will be zero for transfers that completed without cancellation.
147unsafe fn _get_remaining_transfers(dma: &pac::dma::Dma, ch: u8) -> u16{
148 // get a handle on the channel itself
149 let ch = dma.st(ch as _);
150 // read the remaining transfer count. If this is zero, the transfer completed fully.
151 ch.ndtr().read().ndt()
152}
153
154/// Sets the waker for the specified DMA channel
155unsafe fn _set_waker(dma: &pac::dma::Dma, state_number: u8, waker: &Waker){
156 let n = state_number as usize;
157 STATE.ch_wakers[n].register(waker);
158
159}
160
161
128macro_rules! dma_num { 162macro_rules! dma_num {
129 (DMA1) => { 163 (DMA1) => {
130 0 164 0
@@ -251,6 +285,18 @@ pac::dma_channels! {
251 ) 285 )
252 } 286 }
253 } 287 }
288 fn stop <'a>(&'a mut self){
289 unsafe {_stop(&crate::pac::$dma_peri, $channel_num);}
290 }
291 fn is_stopped<'a>(&'a self) -> bool {
292 unsafe {_is_stopped(&crate::pac::$dma_peri, $channel_num)}
293 }
294 fn remaining_transfers<'a>(&'a mut self) -> u16 {
295 unsafe {_get_remaining_transfers(&crate::pac::$dma_peri, $channel_num)}
296 }
297 fn set_waker<'a>(&'a mut self, waker: &'a Waker) {
298 unsafe {_set_waker(&crate::pac::$dma_peri, $channel_num, waker )}
299 }
254 } 300 }
255 }; 301 };
256} 302}
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 0ecd6d864..aa2da1fa9 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -55,7 +55,7 @@ pub trait Channel: sealed::Channel {
55 fn stop<'a>(&'a mut self); 55 fn stop<'a>(&'a mut self);
56 56
57 fn is_stopped<'a>(&self) -> bool; 57 fn is_stopped<'a>(&self) -> bool;
58 fn remaining_transfers<'a>(&'a mut self) -> usize; 58 fn remaining_transfers<'a>(&'a mut self) -> u16;
59 fn set_waker(&mut self, waker: &Waker); 59 fn set_waker(&mut self, waker: &Waker);
60} 60}
61 61