From fa7510968acb930324986309f197273177b3071c Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 2 Jun 2023 03:44:49 +0200 Subject: [PATCH] rp/spi: start rx dma first. --- embassy-rp/src/spi.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 742a35d49..2cd2aa753 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs @@ -360,18 +360,22 @@ impl<'d, T: Instance> Spi<'d, T, Async> { reg.set_txdmae(true); }) }; - let tx_ch = self.tx_dma.as_mut().unwrap(); - let tx_transfer = unsafe { - // 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_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ) - }; + + // Start RX first. Transfer starts when TX starts, if RX + // is not started yet we might lose bytes. let rx_ch = self.rx_dma.as_mut().unwrap(); let rx_transfer = unsafe { // 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 _, buffer, T::RX_DREQ) }; + + let tx_ch = self.tx_dma.as_mut().unwrap(); + let tx_transfer = unsafe { + // 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_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ) + }; join(tx_transfer, rx_transfer).await; Ok(()) } @@ -395,6 +399,15 @@ impl<'d, T: Instance> Spi<'d, T, Async> { }) }; + // Start RX first. Transfer starts when TX starts, if RX + // is not started yet we might lose bytes. + let rx_ch = self.rx_dma.as_mut().unwrap(); + let rx_transfer = unsafe { + // 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_ptr, T::RX_DREQ) + }; + let mut tx_ch = self.tx_dma.as_mut().unwrap(); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. @@ -411,13 +424,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> { } } }; - - let rx_ch = self.rx_dma.as_mut().unwrap(); - let rx_transfer = unsafe { - // 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_ptr, T::RX_DREQ) - }; join(tx_transfer, rx_transfer).await; // if tx > rx we should clear any overflow of the FIFO SPI buffer