aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-05 16:56:18 +0200
committerGitHub <[email protected]>2025-09-05 16:56:18 +0200
commit6438068c162298e1820875f31f61bae6a7e994d5 (patch)
tree2c71ac1d269356a3dd683a8e9462ab1c414f7dcb
parent4b27444e1cd8f56ec620a75275c22846b7f782d1 (diff)
parent71ad56357925a3f2b98a20bcce3c1bdb0ac63be5 (diff)
Merge pull request #4368 from nikvoid/stm32-complementary-pwm-dma
stm32: add `waveform_up` function for complementary PWM too
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 7d6c2273e..68cdec302 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -202,6 +202,66 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
202 self.inner.set_dead_time_clock_division(ckd); 202 self.inner.set_dead_time_clock_division(ckd);
203 self.inner.set_dead_time_value(value); 203 self.inner.set_dead_time_value(value);
204 } 204 }
205
206 /// Generate a sequence of PWM waveform
207 ///
208 /// Note:
209 /// you will need to provide corresponding TIMx_UP DMA channel to use this method.
210 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) {
211 #[allow(clippy::let_unit_value)] // eg. stm32f334
212 let req = dma.request();
213
214 let original_duty_state = self.inner.get_compare_value(channel);
215 let original_enable_state = self.inner.get_channel_enable_state(channel);
216 let original_update_dma_state = self.inner.get_update_dma_state();
217
218 if !original_update_dma_state {
219 self.inner.enable_update_dma(true);
220 }
221
222 if !original_enable_state {
223 self.inner.enable_channel(channel, true);
224 }
225
226 unsafe {
227 #[cfg(not(any(bdma, gpdma)))]
228 use crate::dma::{Burst, FifoThreshold};
229 use crate::dma::{Transfer, TransferOptions};
230
231 let dma_transfer_option = TransferOptions {
232 #[cfg(not(any(bdma, gpdma)))]
233 fifo_threshold: Some(FifoThreshold::Full),
234 #[cfg(not(any(bdma, gpdma)))]
235 mburst: Burst::Incr8,
236 ..Default::default()
237 };
238
239 Transfer::new_write(
240 dma,
241 req,
242 duty,
243 self.inner.regs_gp16().ccr(channel.index()).as_ptr() as *mut u16,
244 dma_transfer_option,
245 )
246 .await
247 };
248
249 // restore output compare state
250 if !original_enable_state {
251 self.inner.enable_channel(channel, false);
252 }
253
254 self.inner.set_compare_value(channel, original_duty_state);
255
256 // Since DMA is closed before timer update event trigger DMA is turn off,
257 // this can almost always trigger a DMA FIFO error.
258 //
259 // optional TODO:
260 // clean FEIF after disable UDE
261 if !original_update_dma_state {
262 self.inner.enable_update_dma(false);
263 }
264 }
205} 265}
206 266
207impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { 267impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {