aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorEicke Hecht <[email protected]>2025-11-24 21:54:25 +0100
committerEicke Hecht <[email protected]>2025-11-24 21:54:25 +0100
commit05417e91093dfd7e150083738988259d66ee4e37 (patch)
tree3aa5418141c88327073722d942f588965e159c4b /embassy-stm32/src
parentd45376583386272bc49fecc7eed8951067f84ac8 (diff)
fix: Warnings and formatting all fixed
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/timer/low_level.rs4
-rw-r--r--embassy-stm32/src/timer/ringbuffered.rs25
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs31
3 files changed, 45 insertions, 15 deletions
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs
index 2cee5f1f5..d1cf11386 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -812,8 +812,6 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
812 /// You may want to start this in a new thread as this will block forever 812 /// You may want to start this in a new thread as this will block forever
813 813
814 pub async fn waveform_continuous<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) { 814 pub async fn waveform_continuous<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) {
815
816
817 use crate::pac::timer::vals::Ccds; 815 use crate::pac::timer::vals::Ccds;
818 816
819 #[allow(clippy::let_unit_value)] // eg. stm32f334 817 #[allow(clippy::let_unit_value)] // eg. stm32f334
@@ -855,7 +853,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> {
855 req: dma::Request, 853 req: dma::Request,
856 channel: Channel, 854 channel: Channel,
857 duty: &[u16], 855 duty: &[u16],
858 circular: bool, 856 #[allow(unused_variables)] circular: bool,
859 ) { 857 ) {
860 let original_duty_state = self.get_compare_value(channel); 858 let original_duty_state = self.get_compare_value(channel);
861 let original_enable_state = self.get_channel_enable_state(channel); 859 let original_enable_state = self.get_channel_enable_state(channel);
diff --git a/embassy-stm32/src/timer/ringbuffered.rs b/embassy-stm32/src/timer/ringbuffered.rs
index bb602f8a7..e8f97bf59 100644
--- a/embassy-stm32/src/timer/ringbuffered.rs
+++ b/embassy-stm32/src/timer/ringbuffered.rs
@@ -5,9 +5,24 @@ use core::task::Waker;
5 5
6use super::low_level::Timer; 6use super::low_level::Timer;
7use super::{Channel, GeneralInstance4Channel}; 7use super::{Channel, GeneralInstance4Channel};
8use crate::dma::ringbuffer::Error;
9use crate::dma::WritableRingBuffer; 8use crate::dma::WritableRingBuffer;
9use crate::dma::ringbuffer::Error;
10 10
11/// A PWM channel that uses a DMA ring buffer for continuous waveform generation.
12///
13/// This allows you to continuously update PWM duty cycles via DMA without blocking the CPU.
14/// The ring buffer enables smooth, uninterrupted waveform generation by automatically cycling
15/// through duty cycle values stored in memory.
16///
17/// You can write new duty cycle values to the ring buffer while it's running, enabling
18/// dynamic waveform generation for applications like motor control, LED dimming, or audio output.
19///
20/// # Example
21/// ```ignore
22/// let mut channel = pwm.ch1().into_ring_buffered_channel(dma_ch, &mut buffer);
23/// channel.start(); // Start DMA transfer
24/// channel.write(&[100, 200, 300]).ok(); // Update duty cycles
25/// ```
11pub struct RingBufferedPwmChannel<'d, T: GeneralInstance4Channel> { 26pub struct RingBufferedPwmChannel<'d, T: GeneralInstance4Channel> {
12 timer: ManuallyDrop<Timer<'d, T>>, 27 timer: ManuallyDrop<Timer<'d, T>>,
13 ring_buf: WritableRingBuffer<'d, u16>, 28 ring_buf: WritableRingBuffer<'d, u16>,
@@ -15,7 +30,11 @@ pub struct RingBufferedPwmChannel<'d, T: GeneralInstance4Channel> {
15} 30}
16 31
17impl<'d, T: GeneralInstance4Channel> RingBufferedPwmChannel<'d, T> { 32impl<'d, T: GeneralInstance4Channel> RingBufferedPwmChannel<'d, T> {
18 pub(crate) fn new(timer: ManuallyDrop<Timer<'d, T>>, channel: Channel, ring_buf: WritableRingBuffer<'d, u16>) -> Self { 33 pub(crate) fn new(
34 timer: ManuallyDrop<Timer<'d, T>>,
35 channel: Channel,
36 ring_buf: WritableRingBuffer<'d, u16>,
37 ) -> Self {
19 Self { 38 Self {
20 timer, 39 timer,
21 ring_buf, 40 ring_buf,
@@ -148,5 +167,3 @@ pub struct RingBufferedPwmChannels<'d, T: GeneralInstance4Channel> {
148 /// Channel 4 167 /// Channel 4
149 pub ch4: RingBufferedPwmChannel<'d, T>, 168 pub ch4: RingBufferedPwmChannel<'d, T>,
150} 169}
151
152
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index 53e0345ea..f4656b7bd 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -6,11 +6,11 @@ use core::mem::ManuallyDrop;
6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; 6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
7use super::ringbuffered::RingBufferedPwmChannel; 7use super::ringbuffered::RingBufferedPwmChannel;
8use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerChannel, TimerPin}; 8use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerChannel, TimerPin};
9use crate::dma::WritableRingBuffer;
10use crate::Peri; 9use crate::Peri;
10use crate::dma::TransferOptions;
11use crate::dma::WritableRingBuffer;
11#[cfg(not(any(bdma, gpdma)))] 12#[cfg(not(any(bdma, gpdma)))]
12use crate::dma::{Burst, FifoThreshold}; 13use crate::dma::{Burst, FifoThreshold};
13use crate::dma::TransferOptions;
14#[cfg(gpio_v2)] 14#[cfg(gpio_v2)]
15use crate::gpio::Pull; 15use crate::gpio::Pull;
16use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 16use crate::gpio::{AfType, AnyPin, OutputType, Speed};
@@ -379,9 +379,27 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
379 pub async fn waveform_continuous<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) { 379 pub async fn waveform_continuous<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) {
380 self.inner.waveform_continuous(dma, duty).await; 380 self.inner.waveform_continuous(dma, duty).await;
381 } 381 }
382 pub fn into_ring_buffered_channel<C: TimerChannel>(self, tx_dma: Peri<'d, impl super::Dma<T, C>>, dma_buf: &'d mut [u16]) -> RingBufferedPwmChannel<'d, T> { 382
383 /// Convert this PWM channel into a ring-buffered PWM channel.
384 ///
385 /// This allows continuous PWM waveform generation using a DMA ring buffer.
386 /// The ring buffer enables dynamic updates to the PWM duty cycle without blocking.
387 ///
388 /// # Arguments
389 /// * `tx_dma` - The DMA channel to use for transferring duty cycle values
390 /// * `dma_buf` - The buffer to use as a ring buffer (must be non-empty and <= 65535 elements)
391 ///
392 /// # Panics
393 /// Panics if `dma_buf` is empty or longer than 65535 elements.
394 pub fn into_ring_buffered_channel<C: TimerChannel>(
395 self,
396 tx_dma: Peri<'d, impl super::Dma<T, C>>,
397 dma_buf: &'d mut [u16],
398 ) -> RingBufferedPwmChannel<'d, T> {
383 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 399 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
384 400
401 use crate::pac::timer::vals::Ccds;
402
385 let channel = C::CHANNEL; 403 let channel = C::CHANNEL;
386 let request = tx_dma.request(); 404 let request = tx_dma.request();
387 405
@@ -393,6 +411,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
393 ..Default::default() 411 ..Default::default()
394 }; 412 };
395 413
414 self.inner.set_cc_dma_selection(Ccds::ON_UPDATE);
396 let ring_buf = unsafe { 415 let ring_buf = unsafe {
397 WritableRingBuffer::new( 416 WritableRingBuffer::new(
398 tx_dma, 417 tx_dma,
@@ -403,11 +422,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
403 ) 422 )
404 }; 423 };
405 424
406 RingBufferedPwmChannel::new( 425 RingBufferedPwmChannel::new(unsafe { self.inner.clone_unchecked() }, channel, ring_buf)
407 unsafe { self.inner.clone_unchecked() },
408 channel,
409 ring_buf
410 )
411 } 426 }
412} 427}
413 428