diff options
| author | xoviat <[email protected]> | 2025-12-03 09:36:58 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-12-03 09:36:58 -0600 |
| commit | 077e59a192ca4cb096a9ef939d06ebefebbac42d (patch) | |
| tree | d77ac51522f10bd3b10e49cf76880d17a1808ddc /embassy-stm32/src | |
| parent | 424522b0975b449bc62854c271b196cd9ed192d7 (diff) | |
timer: restore waveform method
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 24 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 22 |
3 files changed, 65 insertions, 6 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 6ca13820a..4f2ac4079 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -2,14 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | 4 | ||
| 5 | pub use stm32_metapac::timer::vals::{Ckd, Mms2, Ossi, Ossr}; | ||
| 6 | |||
| 7 | use super::low_level::{CountingMode, OutputPolarity, Timer}; | 5 | use super::low_level::{CountingMode, OutputPolarity, Timer}; |
| 8 | use super::simple_pwm::PwmPin; | 6 | use super::simple_pwm::PwmPin; |
| 9 | use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; | 7 | use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; |
| 10 | use crate::Peri; | 8 | use crate::Peri; |
| 11 | use crate::dma::word::Word; | 9 | use crate::dma::word::Word; |
| 12 | use crate::gpio::{AnyPin, OutputType}; | 10 | use crate::gpio::{AnyPin, OutputType}; |
| 11 | pub use crate::pac::timer::vals::{Ccds, Ckd, Mms2, Ossi, Ossr}; | ||
| 13 | use crate::time::Hertz; | 12 | use crate::time::Hertz; |
| 14 | use crate::timer::TimerChannel; | 13 | use crate::timer::TimerChannel; |
| 15 | use crate::timer::low_level::OutputCompareMode; | 14 | use crate::timer::low_level::OutputCompareMode; |
| @@ -220,6 +219,27 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | |||
| 220 | /// Generate a sequence of PWM waveform | 219 | /// Generate a sequence of PWM waveform |
| 221 | /// | 220 | /// |
| 222 | /// Note: | 221 | /// Note: |
| 222 | /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method. | ||
| 223 | /// Also be aware that embassy timers use one of timers internally. It is possible to | ||
| 224 | /// switch this timer by using `time-driver-timX` feature. | ||
| 225 | pub async fn waveform<C: TimerChannel, W: Word + Into<T::Word>>( | ||
| 226 | &mut self, | ||
| 227 | dma: Peri<'_, impl super::Dma<T, C>>, | ||
| 228 | channel: Channel, | ||
| 229 | duty: &[W], | ||
| 230 | ) { | ||
| 231 | self.inner.enable_channel(channel, true); | ||
| 232 | self.inner.enable_channel(C::CHANNEL, true); | ||
| 233 | self.inner.clamp_compare_value::<W>(channel); | ||
| 234 | self.inner.set_cc_dma_selection(Ccds::ON_UPDATE); | ||
| 235 | self.inner.set_cc_dma_enable_state(C::CHANNEL, true); | ||
| 236 | self.inner.setup_channel_update_dma(dma, channel, duty).await; | ||
| 237 | self.inner.set_cc_dma_enable_state(C::CHANNEL, false); | ||
| 238 | } | ||
| 239 | |||
| 240 | /// Generate a sequence of PWM waveform | ||
| 241 | /// | ||
| 242 | /// Note: | ||
| 223 | /// you will need to provide corresponding TIMx_UP DMA channel to use this method. | 243 | /// you will need to provide corresponding TIMx_UP DMA channel to use this method. |
| 224 | pub async fn waveform_up<W: Word + Into<T::Word>>( | 244 | pub async fn waveform_up<W: Word + Into<T::Word>>( |
| 225 | &mut self, | 245 | &mut self, |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 6a70d2a40..da1bfac5f 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -13,7 +13,7 @@ use embassy_hal_internal::Peri; | |||
| 13 | pub use stm32_metapac::timer::vals::{FilterValue, Mms as MasterMode, Sms as SlaveMode, Ts as TriggerSource}; | 13 | pub use stm32_metapac::timer::vals::{FilterValue, Mms as MasterMode, Sms as SlaveMode, Ts as TriggerSource}; |
| 14 | 14 | ||
| 15 | use super::*; | 15 | use super::*; |
| 16 | use crate::dma::{Transfer, WritableRingBuffer}; | 16 | use crate::dma::{self, Transfer, WritableRingBuffer}; |
| 17 | use crate::pac::timer::vals; | 17 | use crate::pac::timer::vals; |
| 18 | use crate::rcc; | 18 | use crate::rcc; |
| 19 | use crate::time::Hertz; | 19 | use crate::time::Hertz; |
| @@ -682,9 +682,26 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 682 | channel: Channel, | 682 | channel: Channel, |
| 683 | duty: &'a [W], | 683 | duty: &'a [W], |
| 684 | ) -> Transfer<'a> { | 684 | ) -> Transfer<'a> { |
| 685 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 685 | self.setup_update_dma_inner(dma.request(), dma, channel, duty) |
| 686 | let req = dma.request(); | 686 | } |
| 687 | 687 | ||
| 688 | /// Generate a sequence of PWM waveform | ||
| 689 | pub fn setup_channel_update_dma<'a, C: TimerChannel, W: Word + Into<T::Word>>( | ||
| 690 | &mut self, | ||
| 691 | dma: Peri<'a, impl super::Dma<T, C>>, | ||
| 692 | channel: Channel, | ||
| 693 | duty: &'a [W], | ||
| 694 | ) -> Transfer<'a> { | ||
| 695 | self.setup_update_dma_inner(dma.request(), dma, channel, duty) | ||
| 696 | } | ||
| 697 | |||
| 698 | fn setup_update_dma_inner<'a, W: Word + Into<T::Word>>( | ||
| 699 | &mut self, | ||
| 700 | request: dma::Request, | ||
| 701 | dma: Peri<'a, impl dma::Channel>, | ||
| 702 | channel: Channel, | ||
| 703 | duty: &'a [W], | ||
| 704 | ) -> Transfer<'a> { | ||
| 688 | unsafe { | 705 | unsafe { |
| 689 | #[cfg(not(any(bdma, gpdma)))] | 706 | #[cfg(not(any(bdma, gpdma)))] |
| 690 | use crate::dma::{Burst, FifoThreshold}; | 707 | use crate::dma::{Burst, FifoThreshold}; |
| @@ -700,7 +717,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 700 | 717 | ||
| 701 | Transfer::new_write( | 718 | Transfer::new_write( |
| 702 | dma, | 719 | dma, |
| 703 | req, | 720 | request, |
| 704 | duty, | 721 | duty, |
| 705 | self.regs_gp16().ccr(channel.index()).as_ptr() as *mut W, | 722 | self.regs_gp16().ccr(channel.index()).as_ptr() as *mut W, |
| 706 | dma_transfer_option, | 723 | dma_transfer_option, |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index b79ed364b..3f050a366 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -11,6 +11,7 @@ use crate::dma::word::Word; | |||
| 11 | #[cfg(gpio_v2)] | 11 | #[cfg(gpio_v2)] |
| 12 | use crate::gpio::Pull; | 12 | use crate::gpio::Pull; |
| 13 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 13 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; |
| 14 | use crate::pac::timer::vals::Ccds; | ||
| 14 | use crate::time::Hertz; | 15 | use crate::time::Hertz; |
| 15 | 16 | ||
| 16 | /// PWM pin wrapper. | 17 | /// PWM pin wrapper. |
| @@ -342,6 +343,27 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 342 | /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method. | 343 | /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method. |
| 343 | /// Also be aware that embassy timers use one of timers internally. It is possible to | 344 | /// Also be aware that embassy timers use one of timers internally. It is possible to |
| 344 | /// switch this timer by using `time-driver-timX` feature. | 345 | /// switch this timer by using `time-driver-timX` feature. |
| 346 | pub async fn waveform<C: TimerChannel, W: Word + Into<T::Word>>( | ||
| 347 | &mut self, | ||
| 348 | dma: Peri<'_, impl super::Dma<T, C>>, | ||
| 349 | channel: Channel, | ||
| 350 | duty: &[W], | ||
| 351 | ) { | ||
| 352 | self.inner.enable_channel(channel, true); | ||
| 353 | self.inner.enable_channel(C::CHANNEL, true); | ||
| 354 | self.inner.clamp_compare_value::<W>(channel); | ||
| 355 | self.inner.set_cc_dma_selection(Ccds::ON_UPDATE); | ||
| 356 | self.inner.set_cc_dma_enable_state(C::CHANNEL, true); | ||
| 357 | self.inner.setup_channel_update_dma(dma, channel, duty).await; | ||
| 358 | self.inner.set_cc_dma_enable_state(C::CHANNEL, false); | ||
| 359 | } | ||
| 360 | |||
| 361 | /// Generate a sequence of PWM waveform | ||
| 362 | /// | ||
| 363 | /// Note: | ||
| 364 | /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method. | ||
| 365 | /// Also be aware that embassy timers use one of timers internally. It is possible to | ||
| 366 | /// switch this timer by using `time-driver-timX` feature. | ||
| 345 | pub async fn waveform_up<W: Word + Into<T::Word>>( | 367 | pub async fn waveform_up<W: Word + Into<T::Word>>( |
| 346 | &mut self, | 368 | &mut self, |
| 347 | dma: Peri<'_, impl super::UpDma<T>>, | 369 | dma: Peri<'_, impl super::UpDma<T>>, |
