aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index bc33a52ea..bd0b1d7de 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -396,6 +396,59 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
396 .await; 396 .await;
397 self.inner.enable_update_dma(false); 397 self.inner.enable_update_dma(false);
398 } 398 }
399 /// Generate a sequence of PWM waveform that will run continously
400 /// You may want to start this in a new thread as this will block forever
401 #[inline(always)]
402 pub async fn waveform_continuous<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) {
403 self.inner.waveform_continuous(dma, duty).await;
404 }
405
406 /// Convert this PWM channel into a ring-buffered PWM channel.
407 ///
408 /// This allows continuous PWM waveform generation using a DMA ring buffer.
409 /// The ring buffer enables dynamic updates to the PWM duty cycle without blocking.
410 ///
411 /// # Arguments
412 /// * `tx_dma` - The DMA channel to use for transferring duty cycle values
413 /// * `dma_buf` - The buffer to use as a ring buffer (must be non-empty and <= 65535 elements)
414 ///
415 /// # Panics
416 /// Panics if `dma_buf` is empty or longer than 65535 elements.
417 pub fn into_ring_buffered_channel<C: TimerChannel>(
418 self,
419 tx_dma: Peri<'d, impl super::Dma<T, C>>,
420 dma_buf: &'d mut [u16],
421 ) -> RingBufferedPwmChannel<'d, T> {
422 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
423
424 use crate::pac::timer::vals::Ccds;
425
426 let channel = C::CHANNEL;
427 let request = tx_dma.request();
428
429 let opts = TransferOptions {
430 #[cfg(not(any(bdma, gpdma)))]
431 fifo_threshold: Some(FifoThreshold::Full),
432 #[cfg(not(any(bdma, gpdma)))]
433 mburst: Burst::Incr8,
434 ..Default::default()
435 };
436
437 self.inner.set_cc_dma_selection(Ccds::ON_UPDATE);
438 self.inner.set_cc_dma_enable_state(channel, true);
439
440 let ring_buf = unsafe {
441 WritableRingBuffer::new(
442 tx_dma,
443 request,
444 self.inner.regs_gp16().ccr(channel.index()).as_ptr() as *mut u16,
445 dma_buf,
446 opts,
447 )
448 };
449
450 RingBufferedPwmChannel::new(unsafe { self.inner.clone_unchecked() }, channel, ring_buf)
451 }
399} 452}
400 453
401impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> { 454impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> {