diff options
| author | Albin Hedman <[email protected]> | 2025-11-15 17:38:50 +0100 |
|---|---|---|
| committer | Albin Hedman <[email protected]> | 2025-11-15 20:16:12 +0100 |
| commit | 7d75dbcf00e434507e7e8a658c1ff262d1501a0d (patch) | |
| tree | 5c7674bf9b1ffe0f44464f76af795874c270bcef /embassy-stm32/src/timer/complementary_pwm.rs | |
| parent | 2880b00cbc59e19164574536e0f852e9aacf08b6 (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.rs | 48 |
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 | ||
| 227 | impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { | 275 | impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { |
