Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion embassy-stm32/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## 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
Expand Down
42 changes: 42 additions & 0 deletions embassy-stm32/src/timer/input_capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<M>(&mut self, dma: Peri<'_, impl super::Dma<T, M>>, 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"]
Expand Down