aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs22
-rw-r--r--embassy-stm32/src/timer/low_level.rs28
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs20
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
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5pub use stm32_metapac::timer::vals::{Ckd, Mms2, Ossi, Ossr};
6
7use super::low_level::{CountingMode, OutputPolarity, Timer}; 5use super::low_level::{CountingMode, OutputPolarity, Timer};
8use super::simple_pwm::PwmPin; 6use super::simple_pwm::PwmPin;
9use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin}; 7use super::{AdvancedInstance4Channel, Ch1, Ch2, Ch3, Ch4, Channel, TimerComplementaryPin};
10use crate::Peri; 8use crate::Peri;
11use crate::dma::word::Word; 9use crate::dma::word::Word;
12use crate::gpio::{AnyPin, OutputType}; 10use crate::gpio::{AnyPin, OutputType};
11pub use crate::pac::timer::vals::{Ccds, Ckd, Mms2, Ossi, Ossr};
13use crate::time::Hertz; 12use crate::time::Hertz;
14use crate::timer::TimerChannel; 13use crate::timer::TimerChannel;
15use crate::timer::low_level::OutputCompareMode; 14use 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;
13pub use stm32_metapac::timer::vals::{FilterValue, Mms as MasterMode, Sms as SlaveMode, Ts as TriggerSource}; 13pub use stm32_metapac::timer::vals::{FilterValue, Mms as MasterMode, Sms as SlaveMode, Ts as TriggerSource};
14 14
15use super::*; 15use super::*;
16use crate::dma::{Transfer, WritableRingBuffer}; 16use crate::dma::{self, Transfer, WritableRingBuffer};
17use crate::pac::timer::vals; 17use crate::pac::timer::vals;
18use crate::rcc; 18use crate::rcc;
19use crate::time::Hertz; 19use 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)]
12use crate::gpio::Pull; 12use crate::gpio::Pull;
13use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 13use crate::gpio::{AfType, AnyPin, OutputType, Speed};
14use crate::pac::timer::vals::Ccds;
14use crate::time::Hertz; 15use 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.