diff options
| author | Henrik Alsér <[email protected]> | 2022-08-31 19:54:38 +0200 |
|---|---|---|
| committer | Henrik Alsér <[email protected]> | 2022-09-01 15:12:44 +0200 |
| commit | 27905f1be1e2404952b1a5c333d4a07f2e4c18f2 (patch) | |
| tree | f749418596538bf389d7e80686fcd5525dfff832 | |
| parent | 7954cbc4e7f44ff5292052da00b1ced857d3183a (diff) | |
Change DMA write/read to use raw pointers
| -rw-r--r-- | embassy-rp/src/dma.rs | 12 | ||||
| -rw-r--r-- | embassy-rp/src/spi.rs | 39 | ||||
| -rw-r--r-- | embassy-rp/src/uart.rs | 6 |
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() { | |||
| 40 | pub unsafe fn read<'a, C: Channel, W: Word>( | 40 | pub 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 | ||
| 59 | pub unsafe fn write<'a, C: Channel, W: Word>( | 59 | pub 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 | ||
| 345 | mod sealed { | 364 | mod 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 | ||
| 121 | impl<'d, T: Instance> UartTx<'d, T, Async> { | 121 | impl<'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 | ||
| 174 | impl<'d, T: Instance> UartRx<'d, T, Async> { | 175 | impl<'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(()) |
