diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 80261ae41a..74f0ba4e01 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - ReleaseDate - +- Add `receive_waveform` method in `InputCapture`, allowing asynchronous input capture with DMA. - fix: Fixed STM32H5 builds requiring time feature - feat: Derive Clone, Copy for QSPI Config - fix: stm32/i2c in master mode (blocking): subsequent transmissions failed after a NACK was received diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index 7a25e6c21e..e6739fbc14 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs @@ -155,6 +155,48 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) .await } + + /// Capture a sequence of timer input edges into a buffer using DMA + pub async fn receive_waveform(&mut self, dma: Peri<'_, impl super::Dma>, buf: &mut [u16]) + where + M: TimerChannel, + { + #[allow(clippy::let_unit_value)] // eg. stm32f334 + let req = dma.request(); + + let original_enable_state = self.is_enabled(M::CHANNEL); + let original_cc_dma_enable_state = self.inner.get_cc_dma_enable_state(M::CHANNEL); + + self.inner.set_input_ti_selection(M::CHANNEL, InputTISelection::Normal); + self.inner + .set_input_capture_mode(M::CHANNEL, InputCaptureMode::BothEdges); + + if !original_cc_dma_enable_state { + self.inner.set_cc_dma_enable_state(M::CHANNEL, true); + } + + if !original_enable_state { + self.enable(M::CHANNEL); + } + + unsafe { + use crate::dma::{Transfer, TransferOptions}; + + Transfer::new_read( + dma, + req, + self.inner.regs_gp16().ccr(M::CHANNEL.index()).as_ptr() as *mut u16, + buf, + TransferOptions::default(), + ) + .await + }; + + // restore output compare state + if !original_enable_state { + self.disable(M::CHANNEL); + } + } } #[must_use = "futures do nothing unless you `.await` or poll them"]