diff options
| -rw-r--r-- | embassy-stm32/src/dma/bdma.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/dma.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/mod.rs | 49 |
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() { | |||
| 84 | pac::dma_channels! { | 84 | pac::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 | ||
| 11 | use core::future::Future; | 11 | use core::future::Future; |
| 12 | use core::marker::PhantomData; | 12 | use core::marker::PhantomData; |
| 13 | use core::mem; | ||
| 13 | use core::pin::Pin; | 14 | use core::pin::Pin; |
| 14 | use core::task::Waker; | 15 | use core::task::Waker; |
| 15 | use core::task::{Context, Poll}; | 16 | use 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)] | ||
| 231 | pub(crate) fn slice_ptr_parts<T>(slice: *const [T]) -> (usize, usize) { | ||
| 232 | unsafe { mem::transmute(slice) } | ||
| 233 | } | ||
| 234 | |||
| 235 | #[allow(unused)] | ||
| 236 | pub(crate) fn slice_ptr_parts_mut<T>(slice: *mut [T]) -> (usize, usize) { | ||
| 237 | unsafe { mem::transmute(slice) } | ||
| 238 | } | ||
