diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 75d7492e..526c8382 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs @@ -40,14 +40,14 @@ pub(crate) unsafe fn init() { pub unsafe fn read<'a, C: Channel, W: Word>( ch: impl Peripheral

+ 'a, from: *const W, - to: &mut [W], + to: *mut W, + len: usize, dreq: u8, ) -> Transfer<'a, C> { - let (to_ptr, len) = crate::dma::slice_ptr_parts_mut(to); copy_inner( ch, from as *const u32, - to_ptr as *mut u32, + to as *mut u32, len, W::size(), false, @@ -58,14 +58,14 @@ pub unsafe fn read<'a, C: Channel, W: Word>( pub unsafe fn write<'a, C: Channel, W: Word>( ch: impl Peripheral

+ 'a, - from: &[W], + from: *const W, to: *mut W, + len: usize, dreq: u8, ) -> Transfer<'a, C> { - let (from_ptr, len) = crate::dma::slice_ptr_parts(from); copy_inner( ch, - from_ptr as *const u32, + from as *const u32, to as *mut u32, len, W::size(), diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 6f68777b..720aad0e 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> { } pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { + let (from_ptr, len) = crate::dma::slice_ptr_parts(buffer); let ch = self.tx_dma.as_mut().unwrap(); let transfer = unsafe { self.inner.regs().dmacr().modify(|reg| { @@ -292,13 +293,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> { }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - crate::dma::write(ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) + crate::dma::write(ch, from_ptr as *const u32, self.inner.regs().dr().ptr() as *mut _, len, T::TX_DREQ) }; transfer.await; Ok(()) } pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + let (to_ptr, len) = crate::dma::slice_ptr_parts_mut(buffer); let ch = self.rx_dma.as_mut().unwrap(); let transfer = unsafe { self.inner.regs().dmacr().modify(|reg| { @@ -306,13 +308,24 @@ impl<'d, T: Instance> Spi<'d, T, Async> { }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - crate::dma::read(ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ) + crate::dma::read(ch, self.inner.regs().dr().ptr() as *const _, to_ptr as *mut u32, len, T::RX_DREQ) }; transfer.await; Ok(()) } pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> { + self.transfer_inner(rx_buffer, tx_buffer).await + } + + pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> { + self.transfer_inner(words, words).await + } + + async fn transfer_inner(&mut self, rx_ptr: *mut [u8], tx_ptr: *const [u8]) -> Result<(), Error> { + let (from_ptr, from_len) = crate::dma::slice_ptr_parts(tx_ptr); + let (to_ptr, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr); + assert_eq!(from_len, to_len); let tx_ch = self.tx_dma.as_mut().unwrap(); let tx_transfer = unsafe { self.inner.regs().dmacr().modify(|reg| { @@ -320,7 +333,13 @@ impl<'d, T: Instance> Spi<'d, T, Async> { }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - crate::dma::write(tx_ch, tx_buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ) + crate::dma::write( + tx_ch, + from_ptr as *const u32, + self.inner.regs().dr().ptr() as *mut _, + from_len, + T::TX_DREQ, + ) }; let rx_ch = self.rx_dma.as_mut().unwrap(); let rx_transfer = unsafe { @@ -329,17 +348,17 @@ impl<'d, T: Instance> Spi<'d, T, Async> { }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_buffer, T::RX_DREQ) + crate::dma::read( + rx_ch, + self.inner.regs().dr().ptr() as *const _, + to_ptr as *mut u32, + to_len, + T::RX_DREQ, + ) }; join(tx_transfer, rx_transfer).await; Ok(()) } - - pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> { - let (ptr, len) = crate::dma::slice_ptr_parts(words); - let tx_buffer = unsafe { core::slice::from_raw_parts(ptr as *const _, len) }; - self.transfer(words, tx_buffer).await - } } mod sealed { diff --git a/embassy-rp/src/uart.rs b/embassy-rp/src/uart.rs index 987b716b..f8a10bd9 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> { impl<'d, T: Instance> UartTx<'d, T, Async> { pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { + let (from_ptr, len) = crate::dma::slice_ptr_parts(buffer); let ch = self.tx_dma.as_mut().unwrap(); let transfer = unsafe { T::regs().uartdmacr().modify(|reg| { @@ -127,7 +128,7 @@ impl<'d, T: Instance> UartTx<'d, T, Async> { }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - crate::dma::write(ch, buffer, T::regs().uartdr().ptr() as *mut _, T::TX_DREQ) + crate::dma::write(ch, from_ptr as *const u32, T::regs().uartdr().ptr() as *mut _, len, T::TX_DREQ) }; transfer.await; Ok(()) @@ -173,6 +174,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { impl<'d, T: Instance> UartRx<'d, T, Async> { pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + let (to_ptr, len) = crate::dma::slice_ptr_parts_mut(buffer); let ch = self.rx_dma.as_mut().unwrap(); let transfer = unsafe { T::regs().uartdmacr().modify(|reg| { @@ -180,7 +182,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, buffer, T::RX_DREQ) + crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, to_ptr as *mut u32, len, T::RX_DREQ) }; transfer.await; Ok(())