diff --git a/CHANGELOG.md b/CHANGELOG.md index 71d1a91a99b..05ea4dcf3f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add some miscellaneous examples for the ESP32-H2 (#548) - Add initial support for PCNT in ESP32-H2 (#551) - Add initial support for RMT in ESP32-H2 (#556) +- Add a fn to poll DMA transfers ### Fixed diff --git a/esp-hal-common/src/dma/mod.rs b/esp-hal-common/src/dma/mod.rs index 6574c2ae035..f4e1fbde41c 100644 --- a/esp-hal-common/src/dma/mod.rs +++ b/esp-hal-common/src/dma/mod.rs @@ -846,6 +846,8 @@ where pub trait DmaTransfer: Drop { /// Wait for the transfer to finish. fn wait(self) -> (B, T); + /// Check if the transfer is finished. + fn is_done(&self) -> bool; } /// Trait to be implemented for an in progress dma transfer. @@ -853,6 +855,8 @@ pub trait DmaTransfer: Drop { pub trait DmaTransferRxTx: Drop { /// Wait for the transfer to finish. fn wait(self) -> (BR, BT, T); + /// Check if the transfer is finished. + fn is_done(&self) -> bool; } #[cfg(feature = "async")] diff --git a/esp-hal-common/src/i2s.rs b/esp-hal-common/src/i2s.rs index fca4f4a2ebc..5889ad5fc61 100644 --- a/esp-hal-common/src/i2s.rs +++ b/esp-hal-common/src/i2s.rs @@ -326,6 +326,11 @@ where (buffer, payload) } } + + /// Check if the DMA transfer is complete + fn is_done(&self) -> bool { + self.i2s_tx.tx_channel.is_done() + } } impl<'d, T, P, TX, BUFFER> Drop for I2sWriteDmaTransfer @@ -451,6 +456,11 @@ where (buffer, payload) } } + + /// Check if the DMA transfer is complete + fn is_done(&self) -> bool { + self.i2s_rx.rx_channel.is_done() + } } impl Drop for I2sReadDmaTransfer diff --git a/esp-hal-common/src/spi.rs b/esp-hal-common/src/spi.rs index 4593fde6ef7..4c2727e422a 100644 --- a/esp-hal-common/src/spi.rs +++ b/esp-hal-common/src/spi.rs @@ -861,6 +861,12 @@ pub mod dma { (rbuffer, tbuffer, payload) } } + + /// Check if the DMA transfer is complete + fn is_done(&self) -> bool { + let ch = &self.spi_dma.channel; + ch.tx.is_done() && ch.rx.is_done() + } } impl<'d, T, TX, RX, P, RXBUF, TXBUF, M> Drop @@ -918,6 +924,12 @@ pub mod dma { (buffer, payload) } } + + /// Check if the DMA transfer is complete + fn is_done(&self) -> bool { + let ch = &self.spi_dma.channel; + ch.tx.is_done() && ch.rx.is_done() + } } impl<'d, T, TX, RX, P, BUFFER, M> Drop for SpiDmaTransfer<'d, T, TX, RX, P, BUFFER, M> diff --git a/esp32-hal/examples/spi_loopback_dma.rs b/esp32-hal/examples/spi_loopback_dma.rs index 283cd147c28..54871609470 100644 --- a/esp32-hal/examples/spi_loopback_dma.rs +++ b/esp32-hal/examples/spi_loopback_dma.rs @@ -98,6 +98,13 @@ fn main() -> ! { let transfer = spi.dma_transfer(send, receive).unwrap(); // here we could do something else while DMA transfer is in progress + let mut i = 0; + // Check is_done until the transfer is almost done (32000 bytes at 100kHz is + // 2.56 seconds), then move to wait(). + while !transfer.is_done() && i < 10 { + delay.delay_ms(250u32); + i += 1; + } // the buffers and spi is moved into the transfer and we can get it back via // `wait` (receive, send, spi) = transfer.wait(); diff --git a/esp32c2-hal/examples/spi_loopback_dma.rs b/esp32c2-hal/examples/spi_loopback_dma.rs index 79743740d5d..529ec1b0c1d 100644 --- a/esp32c2-hal/examples/spi_loopback_dma.rs +++ b/esp32c2-hal/examples/spi_loopback_dma.rs @@ -99,6 +99,13 @@ fn main() -> ! { let transfer = spi.dma_transfer(send, receive).unwrap(); // here we could do something else while DMA transfer is in progress + let mut i = 0; + // Check is_done until the transfer is almost done (32000 bytes at 100kHz is + // 2.56 seconds), then move to wait(). + while !transfer.is_done() && i < 10 { + delay.delay_ms(250u32); + i += 1; + } // the buffers and spi is moved into the transfer and we can get it back via // `wait` (receive, send, spi) = transfer.wait(); diff --git a/esp32c3-hal/examples/spi_loopback_dma.rs b/esp32c3-hal/examples/spi_loopback_dma.rs index 8bc8910fbed..f612b86013a 100644 --- a/esp32c3-hal/examples/spi_loopback_dma.rs +++ b/esp32c3-hal/examples/spi_loopback_dma.rs @@ -106,6 +106,13 @@ fn main() -> ! { let transfer = spi.dma_transfer(send, receive).unwrap(); // here we could do something else while DMA transfer is in progress + let mut i = 0; + // Check is_done until the transfer is almost done (32000 bytes at 100kHz is + // 2.56 seconds), then move to wait(). + while !transfer.is_done() && i < 10 { + delay.delay_ms(250u32); + i += 1; + } // the buffers and spi is moved into the transfer and we can get it back via // `wait` (receive, send, spi) = transfer.wait(); diff --git a/esp32c6-hal/examples/spi_loopback_dma.rs b/esp32c6-hal/examples/spi_loopback_dma.rs index 945a62bcfa9..7f72e664d4b 100644 --- a/esp32c6-hal/examples/spi_loopback_dma.rs +++ b/esp32c6-hal/examples/spi_loopback_dma.rs @@ -107,6 +107,13 @@ fn main() -> ! { let transfer = spi.dma_transfer(send, receive).unwrap(); // here we could do something else while DMA transfer is in progress + let mut i = 0; + // Check is_done until the transfer is almost done (32000 bytes at 100kHz is + // 2.56 seconds), then move to wait(). + while !transfer.is_done() && i < 10 { + delay.delay_ms(250u32); + i += 1; + } // the buffers and spi is moved into the transfer and we can get it back via // `wait` (receive, send, spi) = transfer.wait(); diff --git a/esp32s2-hal/examples/spi_loopback_dma.rs b/esp32s2-hal/examples/spi_loopback_dma.rs index 0f64b55b88f..15df558e91c 100644 --- a/esp32s2-hal/examples/spi_loopback_dma.rs +++ b/esp32s2-hal/examples/spi_loopback_dma.rs @@ -98,6 +98,13 @@ fn main() -> ! { let transfer = spi.dma_transfer(send, receive).unwrap(); // here we could do something else while DMA transfer is in progress + let mut i = 0; + // Check is_done until the transfer is almost done (32000 bytes at 100kHz is + // 2.56 seconds), then move to wait(). + while !transfer.is_done() && i < 10 { + delay.delay_ms(250u32); + i += 1; + } // the buffers and spi is moved into the transfer and we can get it back via // `wait` (receive, send, spi) = transfer.wait(); diff --git a/esp32s3-hal/examples/spi_loopback_dma.rs b/esp32s3-hal/examples/spi_loopback_dma.rs index 0e2b6d9c6ba..f71b5e21ce8 100644 --- a/esp32s3-hal/examples/spi_loopback_dma.rs +++ b/esp32s3-hal/examples/spi_loopback_dma.rs @@ -106,6 +106,13 @@ fn main() -> ! { let transfer = spi.dma_transfer(send, receive).unwrap(); // here we could do something else while DMA transfer is in progress + let mut i = 0; + // Check is_done until the transfer is almost done (32000 bytes at 100kHz is + // 2.56 seconds), then move to wait(). + while !transfer.is_done() && i < 10 { + delay.delay_ms(250u32); + i += 1; + } // the buffers and spi is moved into the transfer and we can get it back via // `wait` (receive, send, spi) = transfer.wait();