use super::*;
use crate::common::embedded_hal::pwm::{ErrorType, SetDutyCycle};
use core::convert::Infallible;
pub struct PwmTimer<TIM> {
tim: TIM,
clk: HertzU32,
}
impl<TIM: TimerWithPwm> PwmTimer<TIM> {
pub fn new(tim: TIM, clk: HertzU32) -> Self {
Self { tim, clk }
}
#[inline(always)]
pub fn start(&mut self) {
self.tim.start_pwm();
}
#[inline(always)]
pub fn stop(&mut self) {
self.tim.stop_pwm();
}
#[inline]
pub fn get_count_value(&self) -> u32 {
self.tim.read_count()
}
#[inline]
pub fn get_max_duty(&self) -> u32 {
self.tim.read_auto_reload().wrapping_add(1)
}
#[inline]
pub fn config_freq(&mut self, update_freq: HertzU32) {
self.tim.config_freq(self.clk, update_freq);
}
}
macro_rules! pwm_channel {
($name:ident, $Tim:ident, $ch:expr, $en:ident) => {
pub struct $name<TIM> {
tim: TIM,
}
impl<TIM> $name<TIM> {
pub fn new(tim: TIM) -> Self {
Self { tim }
}
}
impl<TIM: $Tim> ErrorType for $name<TIM> {
type Error = Infallible;
}
impl<TIM: $Tim> SetDutyCycle for $name<TIM> {
#[inline(always)]
fn max_duty_cycle(&self) -> u16 {
(self.tim.read_auto_reload() as u16).wrapping_add(1)
}
#[inline(always)]
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
self.tim.set_ch1_cc_value(duty as u32);
Ok(())
}
}
impl<TIM: $Tim> PwmChannel for $name<TIM> {
#[inline(always)]
fn config(&mut self, mode: PwmMode, polarity: PwmPolarity) {
self.tim.preload_output_channel_in_mode($ch, mode.into());
self.tim.set_polarity($ch, polarity);
}
#[inline(always)]
fn set_enable(&mut self, en: bool) {
self.tim.$en(en);
}
}
};
}
pwm_channel!(PwmChannel1, TimerWithPwm1Ch, Channel::C1, enable_ch1);
pwm_channel!(PwmChannel2, TimerWithPwm2Ch, Channel::C2, enable_ch2);
pwm_channel!(PwmChannel3, TimerWithPwm3Ch, Channel::C3, enable_ch3);
pwm_channel!(PwmChannel4, TimerWithPwm4Ch, Channel::C4, enable_ch4);