Skip to content

Commit 7d75dbc

Browse files
committed
Add dma waveform methods to complementary pwm too
1 parent 2880b00 commit 7d75dbc

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

embassy-stm32/src/timer/complementary_pwm.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,54 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
222222
pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) {
223223
self.inner.waveform_up(dma, channel, duty).await
224224
}
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+
}
225273
}
226274

227275
impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {

0 commit comments

Comments
 (0)