aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-25 10:18:35 -0600
committerxoviat <[email protected]>2025-11-25 10:18:35 -0600
commitdb8fd86808be9a2b64c561d09869988188e59f8f (patch)
treea69e55d29cab499ce0368255ee63ba214d7f43af
parent2e70c376c884a64fc931406350fecb6c0314dcf0 (diff)
parentff939095a2a883361346ea0cf6f2b6f9d1d24936 (diff)
Merge branch 'feat/pwm_waveform_continuous' of github.com:KorribanMaster/embassy into pwm
-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> {