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…
Reference in New Issue
Block a user