aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Alsér <[email protected]>2022-08-31 19:54:38 +0200
committerHenrik Alsér <[email protected]>2022-09-01 15:12:44 +0200
commit27905f1be1e2404952b1a5c333d4a07f2e4c18f2 (patch)
treef749418596538bf389d7e80686fcd5525dfff832
parent7954cbc4e7f44ff5292052da00b1ced857d3183a (diff)
Change DMA write/read to use raw pointers
-rw-r--r--embassy-rp/src/dma.rs12
-rw-r--r--embassy-rp/src/spi.rs39
-rw-r--r--embassy-rp/src/uart.rs6
3 files changed, 39 insertions, 18 deletions
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index 75d7492e0..526c83822 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -40,14 +40,14 @@ pub(crate) unsafe fn init() {
40pub unsafe fn read<'a, C: Channel, W: Word>( 40pub unsafe fn read<'a, C: Channel, W: Word>(
41 ch: impl Peripheral<P = C> + 'a, 41 ch: impl Peripheral<P = C> + 'a,
42 from: *const W, 42 from: *const W,
43 to: &mut [W], 43 to: *mut W,
44 len: usize,
44 dreq: u8, 45 dreq: u8,
45) -> Transfer<'a, C> { 46) -> Transfer<'a, C> {
46 let (to_ptr, len) = crate::dma::slice_ptr_parts_mut(to);
47 copy_inner( 47 copy_inner(
48 ch, 48 ch,
49 from as *const u32, 49 from as *const u32,
50 to_ptr as *mut u32, 50 to as *mut u32,
51 len, 51 len,
52 W::size(), 52 W::size(),
53 false, 53 false,
@@ -58,14 +58,14 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
58 58
59pub unsafe fn write<'a, C: Channel, W: Word>( 59pub unsafe fn write<'a, C: Channel, W: Word>(
60 ch: impl Peripheral<P = C> + 'a, 60 ch: impl Peripheral<P = C> + 'a,
61 from: &[W], 61 from: *const W,
62 to: *mut W, 62 to: *mut W,
63 len: usize,
63 dreq: u8, 64 dreq: u8,
64) -> Transfer<'a, C> { 65) -> Transfer<'a, C> {
65 let (from_ptr, len) = crate::dma::slice_ptr_parts(from);
66 copy_inner( 66 copy_inner(
67 ch, 67 ch,
68 from_ptr as *const u32, 68 from as *const u32,
69 to as *mut u32, 69 to as *mut u32,
70 len, 70 len,
71 W::size(), 71 W::size(),
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index 6f68777b2..720aad0e5 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -285,6 +285,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
285 } 285 }
286 286
287 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 287 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
288 let (from_ptr, len) = crate::dma::slice_ptr_parts(buffer);
288 let ch = self.tx_dma.as_mut().unwrap(); 289 let ch = self.tx_dma.as_mut().unwrap();
289 let transfer = unsafe { 290 let transfer = unsafe {
290 self.inner.regs().dmacr().modify(|reg| { 291 self.inner.regs().dmacr().modify(|reg| {
@@ -292,13 +293,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
292 }); 293 });
293 // If we don't assign future to a variable, the data register pointer 294 // If we don't assign future to a variable, the data register pointer
294 // is held across an await and makes the future non-Send. 295 // is held across an await and makes the future non-Send.
295 crate::dma::write(ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) 296 crate::dma::write(ch, from_ptr as *const u32, self.inner.regs().dr().ptr() as *mut _, len, T::TX_DREQ)
296 }; 297 };
297 transfer.await; 298 transfer.await;
298 Ok(()) 299 Ok(())
299 } 300 }
300 301
301 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 302 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
303 let (to_ptr, len) = crate::dma::slice_ptr_parts_mut(buffer);
302 let ch = self.rx_dma.as_mut().unwrap(); 304 let ch = self.rx_dma.as_mut().unwrap();
303 let transfer = unsafe { 305 let transfer = unsafe {
304 self.inner.regs().dmacr().modify(|reg| { 306 self.inner.regs().dmacr().modify(|reg| {
@@ -306,13 +308,24 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
306 }); 308 });
307 // If we don't assign future to a variable, the data register pointer 309 // If we don't assign future to a variable, the data register pointer
308 // is held across an await and makes the future non-Send. 310 // is held across an await and makes the future non-Send.
309 crate::dma::read(ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ) 311 crate::dma::read(ch, self.inner.regs().dr().ptr() as *const _, to_ptr as *mut u32, len, T::RX_DREQ)
310 }; 312 };
311 transfer.await; 313 transfer.await;
312 Ok(()) 314 Ok(())
313 } 315 }
314 316
315 pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> { 317 pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> {
318 self.transfer_inner(rx_buffer, tx_buffer).await
319 }
320
321 pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
322 self.transfer_inner(words, words).await
323 }
324
325 async fn transfer_inner(&mut self, rx_ptr: *mut [u8], tx_ptr: *const [u8]) -> Result<(), Error> {
326 let (from_ptr, from_len) = crate::dma::slice_ptr_parts(tx_ptr);
327 let (to_ptr, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr);
328 assert_eq!(from_len, to_len);
316 let tx_ch = self.tx_dma.as_mut().unwrap(); 329 let tx_ch = self.tx_dma.as_mut().unwrap();
317 let tx_transfer = unsafe { 330 let tx_transfer = unsafe {
318 self.inner.regs().dmacr().modify(|reg| { 331 self.inner.regs().dmacr().modify(|reg| {
@@ -320,7 +333,13 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
320 }); 333 });
321 // If we don't assign future to a variable, the data register pointer 334 // If we don't assign future to a variable, the data register pointer
322 // is held across an await and makes the future non-Send. 335 // is held across an await and makes the future non-Send.
323 crate::dma::write(tx_ch, tx_buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) 336 crate::dma::write(
337 tx_ch,
338 from_ptr as *const u32,
339 self.inner.regs().dr().ptr() as *mut _,
340 from_len,
341 T::TX_DREQ,
342 )
324 }; 343 };
325 let rx_ch = self.rx_dma.as_mut().unwrap(); 344 let rx_ch = self.rx_dma.as_mut().unwrap();
326 let rx_transfer = unsafe { 345 let rx_transfer = unsafe {
@@ -329,17 +348,17 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
329 }); 348 });
330 // If we don't assign future to a variable, the data register pointer 349 // If we don't assign future to a variable, the data register pointer
331 // is held across an await and makes the future non-Send. 350 // is held across an await and makes the future non-Send.
332 crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_buffer, T::RX_DREQ) 351 crate::dma::read(
352 rx_ch,
353 self.inner.regs().dr().ptr() as *const _,
354 to_ptr as *mut u32,
355 to_len,
356 T::RX_DREQ,
357 )
333 }; 358 };
334 join(tx_transfer, rx_transfer).await; 359 join(tx_transfer, rx_transfer).await;
335 Ok(()) 360 Ok(())
336 } 361 }
337
338 pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
339 let (ptr, len) = crate::dma::slice_ptr_parts(words);
340 let tx_buffer = unsafe { core::slice::from_raw_parts(ptr as *const _, len) };
341 self.transfer(words, tx_buffer).await
342 }
343} 362}
344 363
345mod sealed { 364mod sealed {
diff --git a/embassy-rp/src/uart.rs b/embassy-rp/src/uart.rs
index 987b716b4..f8a10bd9d 100644
--- a/embassy-rp/src/uart.rs
+++ b/embassy-rp/src/uart.rs
@@ -120,6 +120,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
120 120
121impl<'d, T: Instance> UartTx<'d, T, Async> { 121impl<'d, T: Instance> UartTx<'d, T, Async> {
122 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 122 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
123 let (from_ptr, len) = crate::dma::slice_ptr_parts(buffer);
123 let ch = self.tx_dma.as_mut().unwrap(); 124 let ch = self.tx_dma.as_mut().unwrap();
124 let transfer = unsafe { 125 let transfer = unsafe {
125 T::regs().uartdmacr().modify(|reg| { 126 T::regs().uartdmacr().modify(|reg| {
@@ -127,7 +128,7 @@ impl<'d, T: Instance> UartTx<'d, T, Async> {
127 }); 128 });
128 // If we don't assign future to a variable, the data register pointer 129 // If we don't assign future to a variable, the data register pointer
129 // is held across an await and makes the future non-Send. 130 // is held across an await and makes the future non-Send.
130 crate::dma::write(ch, buffer, T::regs().uartdr().ptr() as *mut _, T::TX_DREQ) 131 crate::dma::write(ch, from_ptr as *const u32, T::regs().uartdr().ptr() as *mut _, len, T::TX_DREQ)
131 }; 132 };
132 transfer.await; 133 transfer.await;
133 Ok(()) 134 Ok(())
@@ -173,6 +174,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
173 174
174impl<'d, T: Instance> UartRx<'d, T, Async> { 175impl<'d, T: Instance> UartRx<'d, T, Async> {
175 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 176 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
177 let (to_ptr, len) = crate::dma::slice_ptr_parts_mut(buffer);
176 let ch = self.rx_dma.as_mut().unwrap(); 178 let ch = self.rx_dma.as_mut().unwrap();
177 let transfer = unsafe { 179 let transfer = unsafe {
178 T::regs().uartdmacr().modify(|reg| { 180 T::regs().uartdmacr().modify(|reg| {
@@ -180,7 +182,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
180 }); 182 });
181 // If we don't assign future to a variable, the data register pointer 183 // If we don't assign future to a variable, the data register pointer
182 // is held across an await and makes the future non-Send. 184 // is held across an await and makes the future non-Send.
183 crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, buffer, T::RX_DREQ) 185 crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, to_ptr as *mut u32, len, T::RX_DREQ)
184 }; 186 };
185 transfer.await; 187 transfer.await;
186 Ok(()) 188 Ok(())