aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/timer/complementary_pwm.rs
diff options
context:
space:
mode:
authorAlbin Hedman <[email protected]>2025-11-15 17:38:50 +0100
committerAlbin Hedman <[email protected]>2025-11-15 20:16:12 +0100
commit7d75dbcf00e434507e7e8a658c1ff262d1501a0d (patch)
tree5c7674bf9b1ffe0f44464f76af795874c270bcef /embassy-stm32/src/timer/complementary_pwm.rs
parent2880b00cbc59e19164574536e0f852e9aacf08b6 (diff)
Add dma waveform methods to complementary pwm too
Diffstat (limited to 'embassy-stm32/src/timer/complementary_pwm.rs')
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index cb5e34790..76cbbe91d 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -222,6 +222,54 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
222 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) { 222 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) {
223 self.inner.waveform_up(dma, channel, duty).await 223 self.inner.waveform_up(dma, channel, duty).await
224 } 224 }
225
226 /// Generate a multichannel sequence of PWM waveforms using DMA triggered by timer update events.
227 ///
228 /// This method utilizes the timer's DMA burst transfer capability to update multiple CCRx registers
229 /// in sequence on each update event (UEV). The data is written via the DMAR register using the
230 /// DMA base address (DBA) and burst length (DBL) configured in the DCR register.
231 ///
232 /// The `duty` buffer must be structured as a flattened 2D array in row-major order, where each row
233 /// represents a single update event and each column corresponds to a specific timer channel (starting
234 /// from `starting_channel` up to and including `ending_channel`).
235 ///
236 /// For example, if using channels 1 through 4, a buffer of 4 update steps might look like:
237 ///
238 /// ```rust,ignore
239 /// let dma_buf: [u16; 16] = [
240 /// ch1_duty_1, ch2_duty_1, ch3_duty_1, ch4_duty_1, // update 1
241 /// ch1_duty_2, ch2_duty_2, ch3_duty_2, ch4_duty_2, // update 2
242 /// ch1_duty_3, ch2_duty_3, ch3_duty_3, ch4_duty_3, // update 3
243 /// ch1_duty_4, ch2_duty_4, ch3_duty_4, ch4_duty_4, // update 4
244 /// ];
245 /// ```
246 ///
247 /// Each group of `N` values (where `N` is number of channels) is transferred on one update event,
248 /// updating the duty cycles of all selected channels simultaneously.
249 ///
250 /// Note:
251 /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method.
252 /// Also be aware that embassy timers use one of timers internally. It is possible to
253 /// switch this timer by using `time-driver-timX` feature.
254 ///
255 #[inline(always)]
256 pub async fn waveform_up_multi_channel(
257 &mut self,
258 dma: Peri<'_, impl super::UpDma<T>>,
259 starting_channel: Channel,
260 ending_channel: Channel,
261 duty: &[u16],
262 ) {
263 self.inner
264 .waveform_up_multi_channel(dma, starting_channel, ending_channel, duty)
265 .await;
266 }
267
268 /// Generate a sequence of PWM waveform
269 #[inline(always)]
270 pub async fn waveform<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) {
271 self.inner.waveform(dma, duty).await;
272 }
225} 273}
226 274
227impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { 275impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {