stm32/hrtim: first draft
This commit is contained in:
		
							parent
							
								
									45561f1622
								
							
						
					
					
						commit
						cdb3fb059f
					
				@ -589,6 +589,16 @@ fn main() {
 | 
			
		||||
        (("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)),
 | 
			
		||||
        (("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)),
 | 
			
		||||
        (("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)),
 | 
			
		||||
        (("hrtim", "CHA1"), quote!(crate::pwm::ChannelAPin)),
 | 
			
		||||
        (("hrtim", "CHA2"), quote!(crate::pwm::ChannelAComplementaryPin)),
 | 
			
		||||
        (("hrtim", "CHB1"), quote!(crate::pwm::ChannelBPin)),
 | 
			
		||||
        (("hrtim", "CHB2"), quote!(crate::pwm::ChannelBComplementaryPin)),
 | 
			
		||||
        (("hrtim", "CHC1"), quote!(crate::pwm::ChannelCPin)),
 | 
			
		||||
        (("hrtim", "CHC2"), quote!(crate::pwm::ChannelCComplementaryPin)),
 | 
			
		||||
        (("hrtim", "CHD1"), quote!(crate::pwm::ChannelDPin)),
 | 
			
		||||
        (("hrtim", "CHD2"), quote!(crate::pwm::ChannelDComplementaryPin)),
 | 
			
		||||
        (("hrtim", "CHE1"), quote!(crate::pwm::ChannelEPin)),
 | 
			
		||||
        (("hrtim", "CHE2"), quote!(crate::pwm::ChannelEComplementaryPin)),
 | 
			
		||||
        (("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)),
 | 
			
		||||
        (("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)),
 | 
			
		||||
        (("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										147
									
								
								embassy-stm32/src/pwm/advanced_pwm.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								embassy-stm32/src/pwm/advanced_pwm.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
 | 
			
		||||
use embassy_hal_common::{into_ref, PeripheralRef};
 | 
			
		||||
 | 
			
		||||
use super::simple_pwm::*;
 | 
			
		||||
use super::*;
 | 
			
		||||
#[allow(unused_imports)]
 | 
			
		||||
use crate::gpio::sealed::{AFType, Pin};
 | 
			
		||||
use crate::gpio::AnyPin;
 | 
			
		||||
use crate::time::Hertz;
 | 
			
		||||
use crate::Peripheral;
 | 
			
		||||
 | 
			
		||||
// Re-implement the channels for hrtim
 | 
			
		||||
pub struct ChA;
 | 
			
		||||
pub struct ChB;
 | 
			
		||||
pub struct ChC;
 | 
			
		||||
pub struct ChD;
 | 
			
		||||
pub struct ChE;
 | 
			
		||||
 | 
			
		||||
pub struct PwmPin<'d, Perip, Channel> {
 | 
			
		||||
    _pin: PeripheralRef<'d, AnyPin>,
 | 
			
		||||
    phantom: PhantomData<(Perip, Channel)>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct ComplementaryPwmPin<'d, Perip, Channel> {
 | 
			
		||||
    _pin: PeripheralRef<'d, AnyPin>,
 | 
			
		||||
    phantom: PhantomData<(Perip, Channel)>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! advanced_channel_impl {
 | 
			
		||||
    ($new_chx:ident, $channel:ident, $pin_trait:ident, $complementary_pin_trait:ident) => {
 | 
			
		||||
        impl<'d, Perip: AdvancedCaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> {
 | 
			
		||||
            pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
 | 
			
		||||
                into_ref!(pin);
 | 
			
		||||
                critical_section::with(|_| {
 | 
			
		||||
                    pin.set_low();
 | 
			
		||||
                    pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
 | 
			
		||||
                    #[cfg(gpio_v2)]
 | 
			
		||||
                    pin.set_speed(crate::gpio::Speed::VeryHigh);
 | 
			
		||||
                });
 | 
			
		||||
                PwmPin {
 | 
			
		||||
                    _pin: pin.map_into(),
 | 
			
		||||
                    phantom: PhantomData,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl<'d, Perip: AdvancedCaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> {
 | 
			
		||||
            pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
 | 
			
		||||
                into_ref!(pin);
 | 
			
		||||
                critical_section::with(|_| {
 | 
			
		||||
                    pin.set_low();
 | 
			
		||||
                    pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
 | 
			
		||||
                    #[cfg(gpio_v2)]
 | 
			
		||||
                    pin.set_speed(crate::gpio::Speed::VeryHigh);
 | 
			
		||||
                });
 | 
			
		||||
                ComplementaryPwmPin {
 | 
			
		||||
                    _pin: pin.map_into(),
 | 
			
		||||
                    phantom: PhantomData,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
advanced_channel_impl!(new_cha, ChA, ChannelAPin, ChannelAComplementaryPin);
 | 
			
		||||
advanced_channel_impl!(new_chb, ChB, ChannelBPin, ChannelBComplementaryPin);
 | 
			
		||||
advanced_channel_impl!(new_chc, ChC, ChannelCPin, ChannelCComplementaryPin);
 | 
			
		||||
advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin);
 | 
			
		||||
advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin);
 | 
			
		||||
 | 
			
		||||
pub struct AdvancedPwm<'d, T> {
 | 
			
		||||
    inner: PeripheralRef<'d, T>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
 | 
			
		||||
    pub fn new(
 | 
			
		||||
        tim: impl Peripheral<P = T> + 'd,
 | 
			
		||||
        _ch1: Option<PwmPin<'d, T, Ch1>>,
 | 
			
		||||
        _ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>,
 | 
			
		||||
        _ch2: Option<PwmPin<'d, T, Ch2>>,
 | 
			
		||||
        _ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>,
 | 
			
		||||
        _ch3: Option<PwmPin<'d, T, Ch3>>,
 | 
			
		||||
        _ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>,
 | 
			
		||||
        _ch4: Option<PwmPin<'d, T, Ch4>>,
 | 
			
		||||
        _ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>,
 | 
			
		||||
        freq: Hertz,
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        Self::new_inner(tim, freq)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz) -> Self {
 | 
			
		||||
        into_ref!(tim);
 | 
			
		||||
 | 
			
		||||
        T::enable();
 | 
			
		||||
        <T as crate::rcc::sealed::RccPeripheral>::reset();
 | 
			
		||||
 | 
			
		||||
        let mut this = Self { inner: tim };
 | 
			
		||||
        //
 | 
			
		||||
        //        this.inner.set_frequency(freq);
 | 
			
		||||
        //        this.inner.start();
 | 
			
		||||
        //
 | 
			
		||||
        //        this.inner.enable_outputs(true);
 | 
			
		||||
        //
 | 
			
		||||
        //        this.inner
 | 
			
		||||
        //            .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1);
 | 
			
		||||
        //        this.inner
 | 
			
		||||
        //            .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1);
 | 
			
		||||
        //        this.inner
 | 
			
		||||
        //            .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1);
 | 
			
		||||
        //        this.inner
 | 
			
		||||
        //            .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1);
 | 
			
		||||
        this
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn enable(&mut self, channel: AdvancedChannel) {
 | 
			
		||||
        // self.inner.enable_channel(channel, true);
 | 
			
		||||
        // self.inner.enable_complementary_channel(channel, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn disable(&mut self, channel: AdvancedChannel) {
 | 
			
		||||
        // self.inner.enable_complementary_channel(channel, false);
 | 
			
		||||
        // self.inner.enable_channel(channel, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_freq(&mut self, freq: Hertz) {
 | 
			
		||||
        // self.inner.set_frequency(freq);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_max_duty(&self) -> u16 {
 | 
			
		||||
        todo!()
 | 
			
		||||
        // self.inner.get_max_compare_value()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_duty(&mut self, channel: AdvancedChannel, duty: u16) {
 | 
			
		||||
        // assert!(duty < self.get_max_duty());
 | 
			
		||||
        // self.inner.set_compare_value(channel, duty)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the dead time as a proportion of max_duty
 | 
			
		||||
    pub fn set_dead_time(&mut self, value: u16) {
 | 
			
		||||
        //        let (ckd, value) = compute_dead_time_value(value);
 | 
			
		||||
        //
 | 
			
		||||
        //        self.inner.set_dead_time_clock_division(ckd);
 | 
			
		||||
        //        self.inner.set_dead_time_value(value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,5 @@
 | 
			
		||||
#[cfg(hrtim_v1)]
 | 
			
		||||
pub mod advanced_pwm;
 | 
			
		||||
pub mod complementary_pwm;
 | 
			
		||||
pub mod simple_pwm;
 | 
			
		||||
 | 
			
		||||
@ -27,6 +29,29 @@ impl Channel {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(hrtim_v1)]
 | 
			
		||||
#[derive(Clone, Copy)]
 | 
			
		||||
pub enum AdvancedChannel {
 | 
			
		||||
    ChA,
 | 
			
		||||
    ChB,
 | 
			
		||||
    ChC,
 | 
			
		||||
    ChD,
 | 
			
		||||
    ChE,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(hrtim_v1)]
 | 
			
		||||
impl AdvancedChannel {
 | 
			
		||||
    pub fn raw(&self) -> usize {
 | 
			
		||||
        match self {
 | 
			
		||||
            AdvancedChannel::ChA => 0,
 | 
			
		||||
            AdvancedChannel::ChB => 1,
 | 
			
		||||
            AdvancedChannel::ChC => 2,
 | 
			
		||||
            AdvancedChannel::ChD => 3,
 | 
			
		||||
            AdvancedChannel::ChE => 4,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Copy)]
 | 
			
		||||
pub enum OutputCompareMode {
 | 
			
		||||
    Frozen,
 | 
			
		||||
@ -57,6 +82,14 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
 | 
			
		||||
pub(crate) mod sealed {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance {
 | 
			
		||||
        fn enable_outputs(&mut self, enable: bool);
 | 
			
		||||
 | 
			
		||||
        fn set_output_compare_mode(&mut self, channel: AdvancedChannel, mode: OutputCompareMode);
 | 
			
		||||
 | 
			
		||||
        fn enable_channel(&mut self, channel: AdvancedChannel, enable: bool);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance {
 | 
			
		||||
        /// Global output enable. Does not do anything on non-advanced timers.
 | 
			
		||||
        fn enable_outputs(&mut self, enable: bool);
 | 
			
		||||
@ -89,6 +122,8 @@ pub(crate) mod sealed {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait AdvancedCaptureCompare16bitInstance: sealed::AdvancedCaptureCompare16bitInstance + 'static {}
 | 
			
		||||
 | 
			
		||||
pub trait CaptureCompare16bitInstance:
 | 
			
		||||
    sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static
 | 
			
		||||
{
 | 
			
		||||
@ -250,6 +285,20 @@ foreach_interrupt! {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
 | 
			
		||||
        impl crate::pwm::sealed::AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst {
 | 
			
		||||
            fn enable_outputs(&mut self, enable: bool) { todo!() }
 | 
			
		||||
 | 
			
		||||
            fn set_output_compare_mode(&mut self, channel: AdvancedChannel, mode: OutputCompareMode) { todo!() }
 | 
			
		||||
 | 
			
		||||
            fn enable_channel(&mut self, channel: AdvancedChannel, enable: bool) { todo!() }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
 | 
			
		||||
@ -267,3 +316,14 @@ pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
 | 
			
		||||
 | 
			
		||||
pin_trait!(ChannelAPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelAComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelBPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelBComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelCPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelCComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelDPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelDComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelEPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
pin_trait!(ChannelEComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
			
		||||
 | 
			
		||||
@ -43,6 +43,21 @@ pub(crate) mod sealed {
 | 
			
		||||
    pub trait AdvancedControlInstance: GeneralPurpose16bitInstance {
 | 
			
		||||
        fn regs_advanced() -> crate::pac::timer::TimAdv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(hrtim_v1)]
 | 
			
		||||
    pub trait HighResolutionControlInstance: RccPeripheral {
 | 
			
		||||
        type Interrupt: interrupt::typelevel::Interrupt;
 | 
			
		||||
 | 
			
		||||
        fn regs_highres() -> crate::pac::hrtim::Hrtim;
 | 
			
		||||
 | 
			
		||||
        fn start(&mut self);
 | 
			
		||||
 | 
			
		||||
        fn stop(&mut self);
 | 
			
		||||
 | 
			
		||||
        fn reset(&mut self);
 | 
			
		||||
 | 
			
		||||
        fn set_frequency(&mut self, frequency: Hertz);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {}
 | 
			
		||||
@ -51,6 +66,9 @@ pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'st
 | 
			
		||||
 | 
			
		||||
pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {}
 | 
			
		||||
 | 
			
		||||
#[cfg(hrtim_v1)]
 | 
			
		||||
pub trait HighResolutionControlInstance: sealed::HighResolutionControlInstance + 'static {}
 | 
			
		||||
 | 
			
		||||
pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {}
 | 
			
		||||
 | 
			
		||||
#[allow(unused)]
 | 
			
		||||
@ -208,4 +226,25 @@ foreach_interrupt! {
 | 
			
		||||
        impl AdvancedControlInstance for crate::peripherals::$inst {
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
 | 
			
		||||
        impl sealed::HighResolutionControlInstance for crate::peripherals::$inst {
 | 
			
		||||
            type Interrupt = crate::interrupt::typelevel::$irq;
 | 
			
		||||
 | 
			
		||||
            fn regs_highres() -> crate::pac::hrtim::Hrtim {
 | 
			
		||||
                crate::pac::$inst
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fn start(&mut self) { todo!() }
 | 
			
		||||
 | 
			
		||||
            fn stop(&mut self) { todo!() }
 | 
			
		||||
 | 
			
		||||
            fn reset(&mut self) { todo!() }
 | 
			
		||||
 | 
			
		||||
            fn set_frequency(&mut self, frequency: Hertz) { todo!() }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl HighResolutionControlInstance for crate::peripherals::$inst {
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user