diff options
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 12 | ||||
| -rw-r--r-- | examples/stm32f7/src/bin/pwm.rs | 65 |
2 files changed, 74 insertions, 3 deletions
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 670298d23..307d614bf 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -781,7 +781,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 781 | let cc_channel = C::CHANNEL; | 781 | let cc_channel = C::CHANNEL; |
| 782 | 782 | ||
| 783 | let original_cc_dma_on_update = self.get_cc_dma_selection() == Ccds::ON_UPDATE; | 783 | let original_cc_dma_on_update = self.get_cc_dma_selection() == Ccds::ON_UPDATE; |
| 784 | let original_cc_dma_enabled = self.get_c fsc_dma_enable_state(cc_channel); | 784 | let original_cc_dma_enabled = self.get_cc_dma_enable_state(cc_channel); |
| 785 | 785 | ||
| 786 | // redirect CC DMA request onto Update Event | 786 | // redirect CC DMA request onto Update Event |
| 787 | if !original_cc_dma_on_update { | 787 | if !original_cc_dma_on_update { |
| @@ -810,7 +810,12 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 810 | 810 | ||
| 811 | /// Generate a sequence of PWM waveform that will run continously | 811 | /// Generate a sequence of PWM waveform that will run continously |
| 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 | 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 | #[cfg(any(bdma, gpdma))] | ||
| 817 | panic!("unsupported DMA"); | ||
| 818 | |||
| 814 | use crate::pac::timer::vals::Ccds; | 819 | use crate::pac::timer::vals::Ccds; |
| 815 | 820 | ||
| 816 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 821 | #[allow(clippy::let_unit_value)] // eg. stm32f334 |
| @@ -871,6 +876,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 871 | fifo_threshold: Some(FifoThreshold::Full), | 876 | fifo_threshold: Some(FifoThreshold::Full), |
| 872 | #[cfg(not(any(bdma, gpdma)))] | 877 | #[cfg(not(any(bdma, gpdma)))] |
| 873 | mburst: Burst::Incr8, | 878 | mburst: Burst::Incr8, |
| 879 | #[cfg(not(any(bdma, gpdma)))] | ||
| 874 | circular: circular, | 880 | circular: circular, |
| 875 | ..Default::default() | 881 | ..Default::default() |
| 876 | }; | 882 | }; |
| @@ -881,7 +887,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 881 | dma, | 887 | dma, |
| 882 | req, | 888 | req, |
| 883 | duty, | 889 | duty, |
| 884 | self.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16, | 890 | self.regs_gp16().ccr(channel.index()).as_ptr() as *mut u16, |
| 885 | dma_transfer_option, | 891 | dma_transfer_option, |
| 886 | ) | 892 | ) |
| 887 | .await | 893 | .await |
| @@ -896,7 +902,7 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 896 | dma, | 902 | dma, |
| 897 | req, | 903 | req, |
| 898 | duty, | 904 | duty, |
| 899 | self.regs_1ch().ccr(channel.index()).as_ptr() as *mut u32, | 905 | self.regs_gp16().ccr(channel.index()).as_ptr() as *mut u32, |
| 900 | dma_transfer_option, | 906 | dma_transfer_option, |
| 901 | ) | 907 | ) |
| 902 | .await | 908 | .await |
diff --git a/examples/stm32f7/src/bin/pwm.rs b/examples/stm32f7/src/bin/pwm.rs new file mode 100644 index 000000000..872d99859 --- /dev/null +++ b/examples/stm32f7/src/bin/pwm.rs | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{panic, *}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_futures::join::join; | ||
| 7 | use embassy_stm32::time::Hertz; | ||
| 8 | use embassy_stm32::{Config, peripherals}; | ||
| 9 | use embassy_stm32::gpio::OutputType; | ||
| 10 | use embassy_stm32::time::mhz; | ||
| 11 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; | ||
| 12 | use embassy_time::Timer; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | // If you are trying this and your USB device doesn't connect, the most | ||
| 16 | // common issues are the RCC config and vbus_detection | ||
| 17 | // | ||
| 18 | // See https://embassy.dev/book/#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 19 | // for more information. | ||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(_spawner: Spawner) { | ||
| 22 | info!("Hello World!"); | ||
| 23 | |||
| 24 | let mut config = Config::default(); | ||
| 25 | { | ||
| 26 | use embassy_stm32::rcc::*; | ||
| 27 | config.rcc.hse = Some(Hse { | ||
| 28 | freq: Hertz(8_000_000), | ||
| 29 | mode: HseMode::Bypass, | ||
| 30 | }); | ||
| 31 | config.rcc.pll_src = PllSource::HSE; | ||
| 32 | config.rcc.pll = Some(Pll { | ||
| 33 | prediv: PllPreDiv::DIV4, | ||
| 34 | mul: PllMul::MUL200, | ||
| 35 | divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 200 / 2 = 200Mhz | ||
| 36 | divq: Some(PllQDiv::DIV4), // 8mhz / 4 * 200 / 4 = 100Mhz | ||
| 37 | divr: None, | ||
| 38 | }); | ||
| 39 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 40 | config.rcc.apb1_pre = APBPrescaler::DIV4; | ||
| 41 | config.rcc.apb2_pre = APBPrescaler::DIV2; | ||
| 42 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 43 | } | ||
| 44 | let p = embassy_stm32::init(config); | ||
| 45 | let ch1_pin = PwmPin::new(p.PE9, OutputType::PushPull); | ||
| 46 | let ch2_pin = PwmPin::new(p.PE11, OutputType::PushPull); | ||
| 47 | let mut pwm = SimplePwm::new(p.TIM1, Some(ch1_pin), Some(ch2_pin), None, None, mhz(1), Default::default()); | ||
| 48 | let mut ch1 = pwm.ch1(); | ||
| 49 | ch1.enable(); | ||
| 50 | info!("PWM initialized"); | ||
| 51 | info!("PWM max duty {}", ch1.max_duty_cycle()); | ||
| 52 | |||
| 53 | info!("PWM duty on channel 1 (D6) 50%"); | ||
| 54 | ch1.set_duty_cycle_fraction(1, 2); | ||
| 55 | info!("PWM waveform on channel 2 (D5)"); | ||
| 56 | const max_duty: usize = 200; | ||
| 57 | let mut duty = [0u16;max_duty]; | ||
| 58 | for i in 0..max_duty { | ||
| 59 | duty[i] = i as u16; | ||
| 60 | } | ||
| 61 | pwm.waveform_continuous::<embassy_stm32::timer::Ch2>(p.DMA2_CH6, &duty).await; | ||
| 62 | |||
| 63 | |||
| 64 | } | ||
| 65 | |||
