diff options
| author | Lachezar Lechev <[email protected]> | 2023-03-26 18:14:17 +0300 |
|---|---|---|
| committer | Lachezar Lechev <[email protected]> | 2023-03-26 18:14:17 +0300 |
| commit | 7be63b3468f72fc684267c90093a00e77cff1bdc (patch) | |
| tree | e0d3ba0505dd665d14460b14fc016b3d055bd1d1 | |
| parent | cd2f28d2abb5b66981b7fdbb32566e6b942c7a54 (diff) | |
fix: spi transfer bug and additions to test
Signed-off-by: Lachezar Lechev <[email protected]>
| -rw-r--r-- | embassy-rp/src/spi.rs | 10 | ||||
| -rw-r--r-- | tests/rp/src/bin/spi_async.rs | 26 |
2 files changed, 28 insertions, 8 deletions
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index e6682ad6a..ebd621ecf 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs | |||
| @@ -384,8 +384,8 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | async fn transfer_inner(&mut self, rx_ptr: *mut [u8], tx_ptr: *const [u8]) -> Result<(), Error> { | 386 | async fn transfer_inner(&mut self, rx_ptr: *mut [u8], tx_ptr: *const [u8]) -> Result<(), Error> { |
| 387 | let (_, from_len) = crate::dma::slice_ptr_parts(tx_ptr); | 387 | let (_, tx_len) = crate::dma::slice_ptr_parts(tx_ptr); |
| 388 | let (_, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr); | 388 | let (_, rx_len) = crate::dma::slice_ptr_parts_mut(rx_ptr); |
| 389 | 389 | ||
| 390 | unsafe { | 390 | unsafe { |
| 391 | self.inner.regs().dmacr().write(|reg| { | 391 | self.inner.regs().dmacr().write(|reg| { |
| @@ -402,8 +402,8 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 402 | unsafe { | 402 | unsafe { |
| 403 | crate::dma::write(&mut tx_ch, tx_ptr, p.dr().ptr() as *mut _, T::TX_DREQ).await; | 403 | crate::dma::write(&mut tx_ch, tx_ptr, p.dr().ptr() as *mut _, T::TX_DREQ).await; |
| 404 | 404 | ||
| 405 | if from_len > to_len { | 405 | if rx_len > tx_len { |
| 406 | let write_bytes_len = from_len - to_len; | 406 | let write_bytes_len = rx_len - tx_len; |
| 407 | // write dummy data | 407 | // write dummy data |
| 408 | // this will disable incrementation of the buffers | 408 | // this will disable incrementation of the buffers |
| 409 | crate::dma::write_repeated(tx_ch, p.dr().ptr() as *mut u8, write_bytes_len, T::TX_DREQ).await | 409 | crate::dma::write_repeated(tx_ch, p.dr().ptr() as *mut u8, write_bytes_len, T::TX_DREQ).await |
| @@ -420,7 +420,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 420 | join(tx_transfer, rx_transfer).await; | 420 | join(tx_transfer, rx_transfer).await; |
| 421 | 421 | ||
| 422 | // if tx > rx we should clear any overflow of the FIFO SPI buffer | 422 | // if tx > rx we should clear any overflow of the FIFO SPI buffer |
| 423 | if from_len > to_len { | 423 | if tx_len > rx_len { |
| 424 | let p = self.inner.regs(); | 424 | let p = self.inner.regs(); |
| 425 | unsafe { | 425 | unsafe { |
| 426 | while p.sr().read().bsy() {} | 426 | while p.sr().read().bsy() {} |
diff --git a/tests/rp/src/bin/spi_async.rs b/tests/rp/src/bin/spi_async.rs index e3fe6e84c..2e22c9de7 100644 --- a/tests/rp/src/bin/spi_async.rs +++ b/tests/rp/src/bin/spi_async.rs | |||
| @@ -33,9 +33,11 @@ async fn main(_spawner: Spawner) { | |||
| 33 | { | 33 | { |
| 34 | let tx_buf = [7_u8, 8, 9, 10, 11, 12]; | 34 | let tx_buf = [7_u8, 8, 9, 10, 11, 12]; |
| 35 | 35 | ||
| 36 | let mut rx_buf = [0_u8, 3]; | 36 | let mut rx_buf = [0_u8; 3]; |
| 37 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); | 37 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); |
| 38 | assert_eq!(rx_buf, tx_buf[..3]); | 38 | assert_eq!(rx_buf, tx_buf[..3]); |
| 39 | |||
| 40 | defmt::info!("tx > rx buffer - OK"); | ||
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | // we make sure to that clearing FIFO works after the uneven buffers | 43 | // we make sure to that clearing FIFO works after the uneven buffers |
| @@ -45,18 +47,36 @@ async fn main(_spawner: Spawner) { | |||
| 45 | let tx_buf = [13_u8, 14, 15, 16, 17, 18]; | 47 | let tx_buf = [13_u8, 14, 15, 16, 17, 18]; |
| 46 | let mut rx_buf = [0_u8; 6]; | 48 | let mut rx_buf = [0_u8; 6]; |
| 47 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); | 49 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); |
| 48 | |||
| 49 | assert_eq!(rx_buf, tx_buf); | 50 | assert_eq!(rx_buf, tx_buf); |
| 51 | |||
| 52 | defmt::info!("buffer rx length == tx length - OK"); | ||
| 50 | } | 53 | } |
| 51 | 54 | ||
| 52 | // rx > tx buffer | 55 | // rx > tx buffer |
| 53 | { | 56 | { |
| 54 | let tx_buf = [19_u8, 20, 21]; | 57 | let tx_buf = [19_u8, 20, 21]; |
| 55 | let mut rx_buf = [0_u8; 6]; | 58 | let mut rx_buf = [0_u8; 6]; |
| 59 | |||
| 60 | // we should have written dummy data to tx buffer to sync clock. | ||
| 56 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); | 61 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); |
| 57 | 62 | ||
| 58 | assert_eq!(rx_buf[..3], tx_buf, "only the first 3 TX bytes should have been received in the RX buffer"); | 63 | assert_eq!( |
| 64 | rx_buf[..3], | ||
| 65 | tx_buf, | ||
| 66 | "only the first 3 TX bytes should have been received in the RX buffer" | ||
| 67 | ); | ||
| 59 | assert_eq!(rx_buf[3..], [0, 0, 0], "the rest of the RX bytes should be empty"); | 68 | assert_eq!(rx_buf[3..], [0, 0, 0], "the rest of the RX bytes should be empty"); |
| 69 | defmt::info!("buffer rx length > tx length - OK"); | ||
| 70 | } | ||
| 71 | |||
| 72 | // equal rx & tx buffers | ||
| 73 | { | ||
| 74 | let tx_buf = [22_u8, 23, 24, 25, 26, 27]; | ||
| 75 | let mut rx_buf = [0_u8; 6]; | ||
| 76 | spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); | ||
| 77 | |||
| 78 | assert_eq!(rx_buf, tx_buf); | ||
| 79 | defmt::info!("buffer rx length = tx length - OK"); | ||
| 60 | } | 80 | } |
| 61 | 81 | ||
| 62 | info!("Test OK"); | 82 | info!("Test OK"); |
