aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-06-02 01:47:15 +0000
committerGitHub <[email protected]>2023-06-02 01:47:15 +0000
commitf901cf57e56d3080c4722d8753c3f31819f520cc (patch)
tree586a1d83f054fbcf9be3a3eba2bbb21b05fc1c9c
parentd36feb64059423b37f9100ab1af08ee23e4d747e (diff)
parentfa7510968acb930324986309f197273177b3071c (diff)
Merge pull request #1526 from embassy-rs/rp-spi-fix
rp/spi: start rx dma first.
-rw-r--r--embassy-rp/src/spi.rs32
1 files 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> {
360 reg.set_txdmae(true); 360 reg.set_txdmae(true);
361 }) 361 })
362 }; 362 };
363 let tx_ch = self.tx_dma.as_mut().unwrap(); 363
364 let tx_transfer = unsafe { 364 // Start RX first. Transfer starts when TX starts, if RX
365 // If we don't assign future to a variable, the data register pointer 365 // is not started yet we might lose bytes.
366 // is held across an await and makes the future non-Send.
367 crate::dma::write_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ)
368 };
369 let rx_ch = self.rx_dma.as_mut().unwrap(); 366 let rx_ch = self.rx_dma.as_mut().unwrap();
370 let rx_transfer = unsafe { 367 let rx_transfer = unsafe {
371 // If we don't assign future to a variable, the data register pointer 368 // If we don't assign future to a variable, the data register pointer
372 // is held across an await and makes the future non-Send. 369 // is held across an await and makes the future non-Send.
373 crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ) 370 crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ)
374 }; 371 };
372
373 let tx_ch = self.tx_dma.as_mut().unwrap();
374 let tx_transfer = unsafe {
375 // If we don't assign future to a variable, the data register pointer
376 // is held across an await and makes the future non-Send.
377 crate::dma::write_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ)
378 };
375 join(tx_transfer, rx_transfer).await; 379 join(tx_transfer, rx_transfer).await;
376 Ok(()) 380 Ok(())
377 } 381 }
@@ -395,6 +399,15 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
395 }) 399 })
396 }; 400 };
397 401
402 // Start RX first. Transfer starts when TX starts, if RX
403 // is not started yet we might lose bytes.
404 let rx_ch = self.rx_dma.as_mut().unwrap();
405 let rx_transfer = unsafe {
406 // If we don't assign future to a variable, the data register pointer
407 // is held across an await and makes the future non-Send.
408 crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ)
409 };
410
398 let mut tx_ch = self.tx_dma.as_mut().unwrap(); 411 let mut tx_ch = self.tx_dma.as_mut().unwrap();
399 // If we don't assign future to a variable, the data register pointer 412 // If we don't assign future to a variable, the data register pointer
400 // is held across an await and makes the future non-Send. 413 // is held across an await and makes the future non-Send.
@@ -411,13 +424,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
411 } 424 }
412 } 425 }
413 }; 426 };
414
415 let rx_ch = self.rx_dma.as_mut().unwrap();
416 let rx_transfer = unsafe {
417 // If we don't assign future to a variable, the data register pointer
418 // is held across an await and makes the future non-Send.
419 crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ)
420 };
421 join(tx_transfer, rx_transfer).await; 427 join(tx_transfer, rx_transfer).await;
422 428
423 // if tx > rx we should clear any overflow of the FIFO SPI buffer 429 // if tx > rx we should clear any overflow of the FIFO SPI buffer