diff options
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 22 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 28 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 20 |
3 files changed, 64 insertions, 6 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 6ca13820a..19211d933 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,25 @@ 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 | /// The DMA channel provided does not need to correspond to the requested channel. | ||
| 223 | pub async fn waveform<C: TimerChannel, W: Word + Into<T::Word>>( | ||
| 224 | &mut self, | ||
| 225 | dma: Peri<'_, impl super::Dma<T, C>>, | ||
| 226 | channel: Channel, | ||
| 227 | duty: &[W], | ||
| 228 | ) { | ||
| 229 | self.inner.enable_channel(channel, true); | ||
| 230 | self.inner.enable_channel(C::CHANNEL, true); | ||
| 231 | self.inner.clamp_compare_value::<W>(channel); | ||
| 232 | self.inner.set_cc_dma_selection(Ccds::ON_UPDATE); | ||
| 233 | self.inner.set_cc_dma_enable_state(C::CHANNEL, true); | ||
| 234 | self.inner.setup_channel_update_dma(dma, channel, duty).await; | ||
| 235 | self.inner.set_cc_dma_enable_state(C::CHANNEL, false); | ||
| 236 | } | ||
| 237 | |||
| 238 | /// Generate a sequence of PWM waveform | ||
| 239 | /// | ||
| 240 | /// Note: | ||
| 223 | /// you will need to provide corresponding TIMx_UP DMA channel to use this method. | 241 | /// 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>>( | 242 | pub async fn waveform_up<W: Word + Into<T::Word>>( |
| 225 | &mut self, | 243 | &mut self, |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 6a70d2a40..82e936f3a 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,29 @@ 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 | /// | ||
| 690 | /// Note: | ||
| 691 | /// The DMA channel provided does not need to correspond to the requested channel. | ||
| 692 | pub fn setup_channel_update_dma<'a, C: TimerChannel, W: Word + Into<T::Word>>( | ||
| 693 | &mut self, | ||
| 694 | dma: Peri<'a, impl super::Dma<T, C>>, | ||
| 695 | channel: Channel, | ||
| 696 | duty: &'a [W], | ||
| 697 | ) -> Transfer<'a> { | ||
| 698 | self.setup_update_dma_inner(dma.request(), dma, channel, duty) | ||
| 699 | } | ||
| 700 | |||
| 701 | fn setup_update_dma_inner<'a, W: Word + Into<T::Word>>( | ||
| 702 | &mut self, | ||
| 703 | request: dma::Request, | ||
| 704 | dma: Peri<'a, impl dma::Channel>, | ||
| 705 | channel: Channel, | ||
| 706 | duty: &'a [W], | ||
| 707 | ) -> Transfer<'a> { | ||
| 688 | unsafe { | 708 | unsafe { |
| 689 | #[cfg(not(any(bdma, gpdma)))] | 709 | #[cfg(not(any(bdma, gpdma)))] |
| 690 | use crate::dma::{Burst, FifoThreshold}; | 710 | use crate::dma::{Burst, FifoThreshold}; |
| @@ -700,7 +720,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 700 | 720 | ||
| 701 | Transfer::new_write( | 721 | Transfer::new_write( |
| 702 | dma, | 722 | dma, |
| 703 | req, | 723 | request, |
| 704 | duty, | 724 | duty, |
| 705 | self.regs_gp16().ccr(channel.index()).as_ptr() as *mut W, | 725 | self.regs_gp16().ccr(channel.index()).as_ptr() as *mut W, |
| 706 | dma_transfer_option, | 726 | dma_transfer_option, |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index b79ed364b..9a5f0fd1d 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. |
| @@ -339,6 +340,25 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 339 | /// Generate a sequence of PWM waveform | 340 | /// Generate a sequence of PWM waveform |
| 340 | /// | 341 | /// |
| 341 | /// Note: | 342 | /// Note: |
| 343 | /// The DMA channel provided does not need to correspond to the requested channel. | ||
| 344 | pub async fn waveform<C: TimerChannel, W: Word + Into<T::Word>>( | ||
| 345 | &mut self, | ||
| 346 | dma: Peri<'_, impl super::Dma<T, C>>, | ||
| 347 | channel: Channel, | ||
| 348 | duty: &[W], | ||
| 349 | ) { | ||
| 350 | self.inner.enable_channel(channel, true); | ||
| 351 | self.inner.enable_channel(C::CHANNEL, true); | ||
| 352 | self.inner.clamp_compare_value::<W>(channel); | ||
| 353 | self.inner.set_cc_dma_selection(Ccds::ON_UPDATE); | ||
| 354 | self.inner.set_cc_dma_enable_state(C::CHANNEL, true); | ||
| 355 | self.inner.setup_channel_update_dma(dma, channel, duty).await; | ||
| 356 | self.inner.set_cc_dma_enable_state(C::CHANNEL, false); | ||
| 357 | } | ||
| 358 | |||
| 359 | /// Generate a sequence of PWM waveform | ||
| 360 | /// | ||
| 361 | /// Note: | ||
| 342 | /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method. | 362 | /// 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 | 363 | /// 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. | 364 | /// switch this timer by using `time-driver-timX` feature. |
