stm32/hrtim: impl. draft frequency computation
This commit is contained in:
		
							parent
							
								
									cdb3fb059f
								
							
						
					
					
						commit
						71513ccb39
					
				@ -29,7 +29,6 @@ impl Channel {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(hrtim_v1)]
 | 
					 | 
				
			||||||
#[derive(Clone, Copy)]
 | 
					#[derive(Clone, Copy)]
 | 
				
			||||||
pub enum AdvancedChannel {
 | 
					pub enum AdvancedChannel {
 | 
				
			||||||
    ChA,
 | 
					    ChA,
 | 
				
			||||||
@ -39,7 +38,6 @@ pub enum AdvancedChannel {
 | 
				
			|||||||
    ChE,
 | 
					    ChE,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(hrtim_v1)]
 | 
					 | 
				
			||||||
impl AdvancedChannel {
 | 
					impl AdvancedChannel {
 | 
				
			||||||
    pub fn raw(&self) -> usize {
 | 
					    pub fn raw(&self) -> usize {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
@ -82,6 +80,7 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
 | 
				
			|||||||
pub(crate) mod sealed {
 | 
					pub(crate) mod sealed {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(hrtim_v1)]
 | 
				
			||||||
    pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance {
 | 
					    pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance {
 | 
				
			||||||
        fn enable_outputs(&mut self, enable: bool);
 | 
					        fn enable_outputs(&mut self, enable: bool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -122,6 +121,7 @@ pub(crate) mod sealed {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
pub trait AdvancedCaptureCompare16bitInstance: sealed::AdvancedCaptureCompare16bitInstance + 'static {}
 | 
					pub trait AdvancedCaptureCompare16bitInstance: sealed::AdvancedCaptureCompare16bitInstance + 'static {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait CaptureCompare16bitInstance:
 | 
					pub trait CaptureCompare16bitInstance:
 | 
				
			||||||
@ -317,13 +317,21 @@ pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
 | 
				
			|||||||
pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
 | 
					pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
 | 
				
			||||||
pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
 | 
					pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pin_trait!(ChannelAPin, AdvancedCaptureCompare16bitInstance);
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
pin_trait!(ChannelAComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
					mod hrtim_pins {
 | 
				
			||||||
pin_trait!(ChannelBPin, AdvancedCaptureCompare16bitInstance);
 | 
					    use super::*;
 | 
				
			||||||
pin_trait!(ChannelBComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
					
 | 
				
			||||||
pin_trait!(ChannelCPin, AdvancedCaptureCompare16bitInstance);
 | 
					    pin_trait!(ChannelAPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
pin_trait!(ChannelCComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
					    pin_trait!(ChannelAComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
pin_trait!(ChannelDPin, AdvancedCaptureCompare16bitInstance);
 | 
					    pin_trait!(ChannelBPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
pin_trait!(ChannelDComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
					    pin_trait!(ChannelBComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
pin_trait!(ChannelEPin, AdvancedCaptureCompare16bitInstance);
 | 
					    pin_trait!(ChannelCPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
pin_trait!(ChannelEComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
					    pin_trait!(ChannelCComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
 | 
					    pin_trait!(ChannelDPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
 | 
					    pin_trait!(ChannelDComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
 | 
					    pin_trait!(ChannelEPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
 | 
					    pin_trait!(ChannelEComplementaryPin, AdvancedCaptureCompare16bitInstance);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
 | 
					pub use hrtim_pins::*;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
 | 
					use core::ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use stm32_metapac::timer::vals;
 | 
					use stm32_metapac::timer::vals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::interrupt;
 | 
					use crate::interrupt;
 | 
				
			||||||
@ -50,13 +53,64 @@ pub(crate) mod sealed {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        fn regs_highres() -> crate::pac::hrtim::Hrtim;
 | 
					        fn regs_highres() -> crate::pac::hrtim::Hrtim;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn set_master_frequency(&mut self, frequency: Hertz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn set_channel_frequency(&mut self, channel: usize, frequency: Hertz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn start(&mut self);
 | 
					        fn start(&mut self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn stop(&mut self);
 | 
					        fn stop(&mut self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn reset(&mut self);
 | 
					        fn reset(&mut self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn set_frequency(&mut self, frequency: Hertz);
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
 | 
					#[derive(Clone, Copy)]
 | 
				
			||||||
 | 
					pub(crate) enum HighResolutionControlPrescaler {
 | 
				
			||||||
 | 
					    Div1,
 | 
				
			||||||
 | 
					    Div2,
 | 
				
			||||||
 | 
					    Div4,
 | 
				
			||||||
 | 
					    Div8,
 | 
				
			||||||
 | 
					    Div16,
 | 
				
			||||||
 | 
					    Div32,
 | 
				
			||||||
 | 
					    Div64,
 | 
				
			||||||
 | 
					    Div128,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
 | 
					impl ops::Div<HighResolutionControlPrescaler> for Hertz {
 | 
				
			||||||
 | 
					    type Output = Hertz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn div(self, rhs: HighResolutionControlPrescaler) -> Self::Output {
 | 
				
			||||||
 | 
					        let divisor = match rhs {
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div1 => 1,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div2 => 2,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div4 => 4,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div8 => 8,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div16 => 16,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div32 => 32,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div64 => 64,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div128 => 128,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Hertz(self.0 / divisor)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(hrtim_v1)]
 | 
				
			||||||
 | 
					impl From<HighResolutionControlPrescaler> for u8 {
 | 
				
			||||||
 | 
					    fn from(val: HighResolutionControlPrescaler) -> Self {
 | 
				
			||||||
 | 
					        match val {
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div1 => 0b000,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div2 => 0b001,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div4 => 0b010,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div8 => 0b011,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div16 => 0b100,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div32 => 0b101,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div64 => 0b110,
 | 
				
			||||||
 | 
					            HighResolutionControlPrescaler::Div128 => 0b111,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -235,13 +289,91 @@ foreach_interrupt! {
 | 
				
			|||||||
                crate::pac::$inst
 | 
					                crate::pac::$inst
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn set_master_frequency(&mut self, frequency: Hertz) {
 | 
				
			||||||
 | 
					                use crate::rcc::sealed::RccPeripheral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // TODO: fix frequency source
 | 
				
			||||||
 | 
					                let f = frequency.0;
 | 
				
			||||||
 | 
					                let timer_f = Self::frequency().0;
 | 
				
			||||||
 | 
					                // Ratio taken from RM0364 Table 81
 | 
				
			||||||
 | 
					                let base_f = Hertz(timer_f * (70_300 / 144_000_000));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /*
 | 
				
			||||||
 | 
					                    Find the smallest prescaler that allows us to acheive our frequency
 | 
				
			||||||
 | 
					                */
 | 
				
			||||||
 | 
					                let psc = [
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div1,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div2,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div4,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div8,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div16,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div32,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div64,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div128,
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					                .iter()
 | 
				
			||||||
 | 
					                .skip_while(|psc| frequency < base_f / **psc)
 | 
				
			||||||
 | 
					                .next()
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let psc_timer_f = Hertz(timer_f) / *psc;
 | 
				
			||||||
 | 
					                let per: u16 = (psc_timer_f / f).0 as u16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let regs = Self::regs_highres();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                regs.mcr().modify(|w| w.set_ckpsc(((*psc).into())));
 | 
				
			||||||
 | 
					                regs.mper().modify(|w| w.set_mper(per));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY));
 | 
				
			||||||
 | 
					                // regs.egr().write(|r| r.set_ug(true));
 | 
				
			||||||
 | 
					                // regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn set_channel_frequency(&mut self, channel: usize, frequency: Hertz) {
 | 
				
			||||||
 | 
					                use crate::rcc::sealed::RccPeripheral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // TODO: fix frequency source
 | 
				
			||||||
 | 
					                let f = frequency.0;
 | 
				
			||||||
 | 
					                let timer_f = Self::frequency().0;
 | 
				
			||||||
 | 
					                // Ratio taken from RM0364 Table 81
 | 
				
			||||||
 | 
					                let base_f = Hertz(timer_f * (70_300 / 144_000_000));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /*
 | 
				
			||||||
 | 
					                    Find the smallest prescaler that allows us to acheive our frequency
 | 
				
			||||||
 | 
					                */
 | 
				
			||||||
 | 
					                let psc = [
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div1,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div2,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div4,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div8,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div16,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div32,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div64,
 | 
				
			||||||
 | 
					                    HighResolutionControlPrescaler::Div128,
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					                .iter()
 | 
				
			||||||
 | 
					                .skip_while(|psc| frequency < base_f / **psc)
 | 
				
			||||||
 | 
					                .next()
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let psc_timer_f = Hertz(timer_f) / *psc;
 | 
				
			||||||
 | 
					                let per: u16 = (psc_timer_f / f).0 as u16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let regs = Self::regs_highres();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                regs.tim(channel).cr().modify(|w| w.set_ckpsc(((*psc).into())));
 | 
				
			||||||
 | 
					                regs.tim(channel).per().modify(|w| w.set_per(per));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY));
 | 
				
			||||||
 | 
					                // regs.egr().write(|r| r.set_ug(true));
 | 
				
			||||||
 | 
					                // regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn start(&mut self) { todo!() }
 | 
					            fn start(&mut self) { todo!() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn stop(&mut self) { todo!() }
 | 
					            fn stop(&mut self) { todo!() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn reset(&mut self) { todo!() }
 | 
					            fn reset(&mut self) { todo!() }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            fn set_frequency(&mut self, frequency: Hertz) { todo!() }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        impl HighResolutionControlInstance for crate::peripherals::$inst {
 | 
					        impl HighResolutionControlInstance for crate::peripherals::$inst {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user