diff options
| author | Eicke Hecht <[email protected]> | 2025-11-24 21:54:25 +0100 |
|---|---|---|
| committer | Eicke Hecht <[email protected]> | 2025-11-24 21:54:25 +0100 |
| commit | 05417e91093dfd7e150083738988259d66ee4e37 (patch) | |
| tree | 3aa5418141c88327073722d942f588965e159c4b | |
| parent | d45376583386272bc49fecc7eed8951067f84ac8 (diff) | |
fix: Warnings and formatting all fixed
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/ringbuffered.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 31 |
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 | ||
| 6 | use super::low_level::Timer; | 6 | use super::low_level::Timer; |
| 7 | use super::{Channel, GeneralInstance4Channel}; | 7 | use super::{Channel, GeneralInstance4Channel}; |
| 8 | use crate::dma::ringbuffer::Error; | ||
| 9 | use crate::dma::WritableRingBuffer; | 8 | use crate::dma::WritableRingBuffer; |
| 9 | use 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 | /// ``` | ||
| 11 | pub struct RingBufferedPwmChannel<'d, T: GeneralInstance4Channel> { | 26 | pub 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 | ||
| 17 | impl<'d, T: GeneralInstance4Channel> RingBufferedPwmChannel<'d, T> { | 32 | impl<'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; | |||
| 6 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; | 6 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; |
| 7 | use super::ringbuffered::RingBufferedPwmChannel; | 7 | use super::ringbuffered::RingBufferedPwmChannel; |
| 8 | use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerChannel, TimerPin}; | 8 | use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerChannel, TimerPin}; |
| 9 | use crate::dma::WritableRingBuffer; | ||
| 10 | use crate::Peri; | 9 | use crate::Peri; |
| 10 | use crate::dma::TransferOptions; | ||
| 11 | use crate::dma::WritableRingBuffer; | ||
| 11 | #[cfg(not(any(bdma, gpdma)))] | 12 | #[cfg(not(any(bdma, gpdma)))] |
| 12 | use crate::dma::{Burst, FifoThreshold}; | 13 | use crate::dma::{Burst, FifoThreshold}; |
| 13 | use crate::dma::TransferOptions; | ||
| 14 | #[cfg(gpio_v2)] | 14 | #[cfg(gpio_v2)] |
| 15 | use crate::gpio::Pull; | 15 | use crate::gpio::Pull; |
| 16 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 16 | use 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 | ||
