diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-06-02 01:47:15 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-06-02 01:47:15 +0000 |
| commit | f901cf57e56d3080c4722d8753c3f31819f520cc (patch) | |
| tree | 586a1d83f054fbcf9be3a3eba2bbb21b05fc1c9c | |
| parent | d36feb64059423b37f9100ab1af08ee23e4d747e (diff) | |
| parent | fa7510968acb930324986309f197273177b3071c (diff) | |
Merge pull request #1526 from embassy-rs/rp-spi-fix
rp/spi: start rx dma first.
| -rw-r--r-- | embassy-rp/src/spi.rs | 32 |
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 |
