aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/bdma.rs14
-rw-r--r--embassy-stm32/src/dma/dma.rs14
-rw-r--r--embassy-stm32/src/dma/mod.rs49
3 files changed, 48 insertions, 29 deletions
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index b4c77757e..e06ce8c36 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -89,7 +89,8 @@ pac::dma_channels! {
89 ($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => { 89 ($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => {
90 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { 90 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
91 91
92 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) { 92 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: *const[W], reg_addr: *mut W) {
93 let (ptr, len) = super::slice_ptr_parts(buf);
93 low_level_api::start_transfer( 94 low_level_api::start_transfer(
94 pac::$dma_peri, 95 pac::$dma_peri,
95 $channel_num, 96 $channel_num,
@@ -97,8 +98,8 @@ pac::dma_channels! {
97 request, 98 request,
98 vals::Dir::FROMMEMORY, 99 vals::Dir::FROMMEMORY,
99 reg_addr as *const u32, 100 reg_addr as *const u32,
100 buf.as_ptr() as *mut u32, 101 ptr as *mut u32,
101 buf.len(), 102 len,
102 true, 103 true,
103 vals::Size::from(W::bits()), 104 vals::Size::from(W::bits()),
104 #[cfg(dmamux)] 105 #[cfg(dmamux)]
@@ -129,7 +130,8 @@ pac::dma_channels! {
129 ) 130 )
130 } 131 }
131 132
132 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) { 133 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *const W, buf: *mut [W]) {
134 let (ptr, len) = super::slice_ptr_parts_mut(buf);
133 low_level_api::start_transfer( 135 low_level_api::start_transfer(
134 pac::$dma_peri, 136 pac::$dma_peri,
135 $channel_num, 137 $channel_num,
@@ -137,8 +139,8 @@ pac::dma_channels! {
137 request, 139 request,
138 vals::Dir::FROMPERIPHERAL, 140 vals::Dir::FROMPERIPHERAL,
139 reg_addr as *const u32, 141 reg_addr as *const u32,
140 buf.as_ptr() as *mut u32, 142 ptr as *mut u32,
141 buf.len(), 143 len,
142 true, 144 true,
143 vals::Size::from(W::bits()), 145 vals::Size::from(W::bits()),
144 #[cfg(dmamux)] 146 #[cfg(dmamux)]
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index efe4d1d9d..8e48bb26f 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -84,15 +84,16 @@ pub(crate) unsafe fn init() {
84pac::dma_channels! { 84pac::dma_channels! {
85 ($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => { 85 ($channel_peri:ident, $dma_peri:ident, dma, $channel_num:expr, $dmamux:tt) => {
86 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { 86 impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
87 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: &[W], reg_addr: *mut W) { 87 unsafe fn start_write<W: Word>(&mut self, request: Request, buf: *const [W], reg_addr: *mut W) {
88 let (ptr, len) = super::slice_ptr_parts(buf);
88 low_level_api::start_transfer( 89 low_level_api::start_transfer(
89 pac::$dma_peri, 90 pac::$dma_peri,
90 $channel_num, 91 $channel_num,
91 request, 92 request,
92 vals::Dir::MEMORYTOPERIPHERAL, 93 vals::Dir::MEMORYTOPERIPHERAL,
93 reg_addr as *const u32, 94 reg_addr as *const u32,
94 buf.as_ptr() as *mut u32, 95 ptr as *mut u32,
95 buf.len(), 96 len,
96 true, 97 true,
97 vals::Size::from(W::bits()), 98 vals::Size::from(W::bits()),
98 #[cfg(dmamux)] 99 #[cfg(dmamux)]
@@ -121,15 +122,16 @@ pac::dma_channels! {
121 ) 122 )
122 } 123 }
123 124
124 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *mut W, buf: &mut [W]) { 125 unsafe fn start_read<W: Word>(&mut self, request: Request, reg_addr: *const W, buf: *mut [W]) {
126 let (ptr, len) = super::slice_ptr_parts_mut(buf);
125 low_level_api::start_transfer( 127 low_level_api::start_transfer(
126 pac::$dma_peri, 128 pac::$dma_peri,
127 $channel_num, 129 $channel_num,
128 request, 130 request,
129 vals::Dir::PERIPHERALTOMEMORY, 131 vals::Dir::PERIPHERALTOMEMORY,
130 reg_addr as *const u32, 132 reg_addr as *const u32,
131 buf.as_ptr() as *mut u32, 133 ptr as *mut u32,
132 buf.len(), 134 len,
133 true, 135 true,
134 vals::Size::from(W::bits()), 136 vals::Size::from(W::bits()),
135 #[cfg(dmamux)] 137 #[cfg(dmamux)]
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index accc55653..b7067a9c4 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -10,6 +10,7 @@ pub use dmamux::*;
10 10
11use core::future::Future; 11use core::future::Future;
12use core::marker::PhantomData; 12use core::marker::PhantomData;
13use core::mem;
13use core::pin::Pin; 14use core::pin::Pin;
14use core::task::Waker; 15use core::task::Waker;
15use core::task::{Context, Poll}; 16use core::task::{Context, Poll};
@@ -36,12 +37,13 @@ pub(crate) mod sealed {
36 /// Starts this channel for writing a stream of words. 37 /// Starts this channel for writing a stream of words.
37 /// 38 ///
38 /// Safety: 39 /// Safety:
40 /// - `buf` must point to a valid buffer for DMA reading.
39 /// - `buf` must be alive for the entire duration of the DMA transfer. 41 /// - `buf` must be alive for the entire duration of the DMA transfer.
40 /// - `reg_addr` must be a valid peripheral register address to write to. 42 /// - `reg_addr` must be a valid peripheral register address to write to.
41 unsafe fn start_write<W: super::Word>( 43 unsafe fn start_write<W: super::Word>(
42 &mut self, 44 &mut self,
43 request: Request, 45 request: Request,
44 buf: &[W], 46 buf: *const [W],
45 reg_addr: *mut W, 47 reg_addr: *mut W,
46 ); 48 );
47 49
@@ -60,13 +62,14 @@ pub(crate) mod sealed {
60 /// Starts this channel for reading a stream of words. 62 /// Starts this channel for reading a stream of words.
61 /// 63 ///
62 /// Safety: 64 /// Safety:
65 /// - `buf` must point to a valid buffer for DMA writing.
63 /// - `buf` must be alive for the entire duration of the DMA transfer. 66 /// - `buf` must be alive for the entire duration of the DMA transfer.
64 /// - `reg_addr` must be a valid peripheral register address to write to. 67 /// - `reg_addr` must be a valid peripheral register address to read from.
65 unsafe fn start_read<W: super::Word>( 68 unsafe fn start_read<W: super::Word>(
66 &mut self, 69 &mut self,
67 request: Request, 70 request: Request,
68 reg_addr: *mut W, 71 reg_addr: *const W,
69 buf: &mut [W], 72 buf: *mut [W],
70 ); 73 );
71 74
72 /// Requests the channel to stop. 75 /// Requests the channel to stop.
@@ -132,10 +135,7 @@ mod transfers {
132 135
133 unsafe { channel.start_read::<W>(request, reg_addr, buf) }; 136 unsafe { channel.start_read::<W>(request, reg_addr, buf) };
134 137
135 Transfer { 138 Transfer::new(channel)
136 channel,
137 _phantom: PhantomData,
138 }
139 } 139 }
140 140
141 #[allow(unused)] 141 #[allow(unused)]
@@ -150,10 +150,7 @@ mod transfers {
150 150
151 unsafe { channel.start_write::<W>(request, buf, reg_addr) }; 151 unsafe { channel.start_write::<W>(request, buf, reg_addr) };
152 152
153 Transfer { 153 Transfer::new(channel)
154 channel,
155 _phantom: PhantomData,
156 }
157 } 154 }
158 155
159 #[allow(unused)] 156 #[allow(unused)]
@@ -168,17 +165,24 @@ mod transfers {
168 165
169 unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr) }; 166 unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr) };
170 167
171 Transfer { 168 Transfer::new(channel)
172 channel,
173 _phantom: PhantomData,
174 }
175 } 169 }
176 170
177 struct Transfer<'a, C: Channel> { 171 pub(crate) struct Transfer<'a, C: Channel> {
178 channel: C, 172 channel: C,
179 _phantom: PhantomData<&'a mut C>, 173 _phantom: PhantomData<&'a mut C>,
180 } 174 }
181 175
176 impl<'a, C: Channel> Transfer<'a, C> {
177 pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self {
178 unborrow!(channel);
179 Self {
180 channel,
181 _phantom: PhantomData,
182 }
183 }
184 }
185
182 impl<'a, C: Channel> Drop for Transfer<'a, C> { 186 impl<'a, C: Channel> Drop for Transfer<'a, C> {
183 fn drop(&mut self) { 187 fn drop(&mut self) {
184 self.channel.request_stop(); 188 self.channel.request_stop();
@@ -221,3 +225,14 @@ pub(crate) unsafe fn init() {
221 #[cfg(dmamux)] 225 #[cfg(dmamux)]
222 dmamux::init(); 226 dmamux::init();
223} 227}
228
229// TODO: replace transmutes with core::ptr::metadata once it's stable
230#[allow(unused)]
231pub(crate) fn slice_ptr_parts<T>(slice: *const [T]) -> (usize, usize) {
232 unsafe { mem::transmute(slice) }
233}
234
235#[allow(unused)]
236pub(crate) fn slice_ptr_parts_mut<T>(slice: *mut [T]) -> (usize, usize) {
237 unsafe { mem::transmute(slice) }
238}