#![no_std] #![no_main] #![feature(type_alias_impl_trait)] use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::low_level::AFType; use embassy_stm32::gpio::Speed; use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::timer::*; use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; config.rcc.hsi = Some(Hsi::Mhz64); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.voltage_scale = VoltageScale::Scale1; } let p = embassy_stm32::init(config); info!("Hello World!"); let mut pwm = SimplePwm32::new(p.TIM5, p.PA0, p.PA1, p.PA2, p.PA3, khz(10)); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); info!("PWM initialized"); info!("PWM max duty {}", max); loop { pwm.set_duty(Channel::Ch1, 0); Timer::after(Duration::from_millis(300)).await; pwm.set_duty(Channel::Ch1, max / 4); Timer::after(Duration::from_millis(300)).await; pwm.set_duty(Channel::Ch1, max / 2); Timer::after(Duration::from_millis(300)).await; pwm.set_duty(Channel::Ch1, max - 1); Timer::after(Duration::from_millis(300)).await; } } pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { inner: PeripheralRef<'d, T>, } impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { pub fn new( tim: impl Peripheral
+ 'd, ch1: impl Peripheral
> + 'd, ch2: impl Peripheral
> + 'd, ch3: impl Peripheral
> + 'd, ch4: impl Peripheral
> + 'd,
freq: Hertz,
) -> Self {
into_ref!(tim, ch1, ch2, ch3, ch4);
T::reset_and_enable();
ch1.set_speed(Speed::VeryHigh);
ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch2.set_speed(Speed::VeryHigh);
ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch3.set_speed(Speed::VeryHigh);
ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull);
ch4.set_speed(Speed::VeryHigh);
ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull);
let mut this = Self { inner: tim };
this.set_freq(freq);
this.inner.start();
let r = T::regs_gp32();
r.ccmr_output(0)
.modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into()));
r.ccmr_output(0)
.modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into()));
r.ccmr_output(1)
.modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into()));
r.ccmr_output(1)
.modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into()));
this
}
pub fn enable(&mut self, channel: Channel) {
T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), true));
}
pub fn disable(&mut self, channel: Channel) {
T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), false));
}
pub fn set_freq(&mut self, freq: Hertz) {