stm32: cleanup psc design
This commit is contained in:
parent
ac11635b0b
commit
2e6f4237f2
@ -1,31 +1,17 @@
|
|||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::sealed::RccPeripheral;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) enum Prescaler {
|
pub(crate) enum Prescaler {
|
||||||
Div1,
|
Div1 = 1,
|
||||||
Div2,
|
Div2 = 2,
|
||||||
Div4,
|
Div4 = 4,
|
||||||
Div8,
|
Div8 = 8,
|
||||||
Div16,
|
Div16 = 16,
|
||||||
Div32,
|
Div32 = 32,
|
||||||
Div64,
|
Div64 = 64,
|
||||||
Div128,
|
Div128 = 128,
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Prescaler> for u32 {
|
|
||||||
fn from(val: Prescaler) -> Self {
|
|
||||||
match val {
|
|
||||||
Prescaler::Div1 => 1,
|
|
||||||
Prescaler::Div2 => 2,
|
|
||||||
Prescaler::Div4 => 4,
|
|
||||||
Prescaler::Div8 => 8,
|
|
||||||
Prescaler::Div16 => 16,
|
|
||||||
Prescaler::Div32 => 32,
|
|
||||||
Prescaler::Div64 => 64,
|
|
||||||
Prescaler::Div128 => 128,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Prescaler> for u8 {
|
impl From<Prescaler> for u8 {
|
||||||
@ -72,7 +58,7 @@ impl Prescaler {
|
|||||||
Prescaler::Div128,
|
Prescaler::Div128,
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.skip_while(|psc| <Prescaler as Into<u32>>::into(**psc) <= val)
|
.skip_while(|psc| **psc as u32 <= val)
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@ -80,7 +66,7 @@ impl Prescaler {
|
|||||||
pub fn compute_min_low_res(val: u32) -> Self {
|
pub fn compute_min_low_res(val: u32) -> Self {
|
||||||
*[Prescaler::Div32, Prescaler::Div64, Prescaler::Div128]
|
*[Prescaler::Div32, Prescaler::Div64, Prescaler::Div128]
|
||||||
.iter()
|
.iter()
|
||||||
.skip_while(|psc| <Prescaler as Into<u32>>::into(**psc) <= val)
|
.skip_while(|psc| **psc as u32 <= val)
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@ -126,8 +112,7 @@ foreach_interrupt! {
|
|||||||
Prescaler::compute_min_low_res(psc_min)
|
Prescaler::compute_min_low_res(psc_min)
|
||||||
};
|
};
|
||||||
|
|
||||||
let psc_val: u32 = psc.into();
|
let timer_f = 32 * (timer_f / psc as u32);
|
||||||
let timer_f = 32 * (timer_f / psc_val);
|
|
||||||
let per: u16 = (timer_f / f) as u16;
|
let per: u16 = (timer_f / f) as u16;
|
||||||
|
|
||||||
let regs = Self::regs();
|
let regs = Self::regs();
|
||||||
@ -148,8 +133,7 @@ foreach_interrupt! {
|
|||||||
Prescaler::compute_min_low_res(psc_min)
|
Prescaler::compute_min_low_res(psc_min)
|
||||||
};
|
};
|
||||||
|
|
||||||
let psc_val: u32 = psc.into();
|
let timer_f = 32 * (timer_f / psc as u32);
|
||||||
let timer_f = 32 * (timer_f / psc_val);
|
|
||||||
let per: u16 = (timer_f / f) as u16;
|
let per: u16 = (timer_f / f) as u16;
|
||||||
|
|
||||||
let regs = Self::regs();
|
let regs = Self::regs();
|
||||||
@ -163,20 +147,17 @@ foreach_interrupt! {
|
|||||||
let regs = Self::regs();
|
let regs = Self::regs();
|
||||||
|
|
||||||
let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into();
|
let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into();
|
||||||
let psc_val: u32 = channel_psc.into();
|
|
||||||
|
|
||||||
|
|
||||||
// The dead-time base clock runs 4 times slower than the hrtim base clock
|
// The dead-time base clock runs 4 times slower than the hrtim base clock
|
||||||
// u9::MAX = 511
|
// u9::MAX = 511
|
||||||
let psc_min = (psc_val * dead_time as u32) / (4 * 511);
|
let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511);
|
||||||
let psc = if Self::regs().isr().read().dllrdy() {
|
let psc = if Self::regs().isr().read().dllrdy() {
|
||||||
Prescaler::compute_min_high_res(psc_min)
|
Prescaler::compute_min_high_res(psc_min)
|
||||||
} else {
|
} else {
|
||||||
Prescaler::compute_min_low_res(psc_min)
|
Prescaler::compute_min_low_res(psc_min)
|
||||||
};
|
};
|
||||||
|
|
||||||
let dt_psc_val: u32 = psc.into();
|
let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32);
|
||||||
let dt_val = (dt_psc_val * dead_time as u32) / (4 * psc_val);
|
|
||||||
|
|
||||||
regs.tim(channel).dt().modify(|w| {
|
regs.tim(channel).dt().modify(|w| {
|
||||||
w.set_dtprsc(psc.into());
|
w.set_dtprsc(psc.into());
|
||||||
|
@ -6,12 +6,13 @@ use crate::peripherals::RTC;
|
|||||||
use crate::rtc::sealed::Instance;
|
use crate::rtc::sealed::Instance;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
#[repr(u8)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub(crate) enum WakeupPrescaler {
|
pub(crate) enum WakeupPrescaler {
|
||||||
Div2,
|
Div2 = 2,
|
||||||
Div4,
|
Div4 = 4,
|
||||||
Div8,
|
Div8 = 8,
|
||||||
Div16,
|
Div16 = 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(stm32wb, stm32f4))]
|
#[cfg(any(stm32wb, stm32f4))]
|
||||||
@ -43,17 +44,6 @@ impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WakeupPrescaler> for u32 {
|
|
||||||
fn from(val: WakeupPrescaler) -> Self {
|
|
||||||
match val {
|
|
||||||
WakeupPrescaler::Div2 => 2,
|
|
||||||
WakeupPrescaler::Div4 => 4,
|
|
||||||
WakeupPrescaler::Div8 => 8,
|
|
||||||
WakeupPrescaler::Div16 => 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl WakeupPrescaler {
|
impl WakeupPrescaler {
|
||||||
pub fn compute_min(val: u32) -> Self {
|
pub fn compute_min(val: u32) -> Self {
|
||||||
@ -64,7 +54,7 @@ impl WakeupPrescaler {
|
|||||||
WakeupPrescaler::Div16,
|
WakeupPrescaler::Div16,
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.skip_while(|psc| <WakeupPrescaler as Into<u32>>::into(**psc) <= val)
|
.skip_while(|psc| **psc as u32 <= val)
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or(&WakeupPrescaler::Div16)
|
.unwrap_or(&WakeupPrescaler::Div16)
|
||||||
}
|
}
|
||||||
@ -85,7 +75,7 @@ impl super::Rtc {
|
|||||||
let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32);
|
let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32);
|
||||||
|
|
||||||
// adjust the rtc ticks to the prescaler and subtract one rtc tick
|
// adjust the rtc ticks to the prescaler and subtract one rtc tick
|
||||||
let rtc_ticks = rtc_ticks / (<WakeupPrescaler as Into<u32>>::into(prescaler) as u64);
|
let rtc_ticks = rtc_ticks / prescaler as u64;
|
||||||
let rtc_ticks = if rtc_ticks >= u16::MAX as u64 {
|
let rtc_ticks = if rtc_ticks >= u16::MAX as u64 {
|
||||||
u16::MAX - 1
|
u16::MAX - 1
|
||||||
} else {
|
} else {
|
||||||
@ -106,11 +96,8 @@ impl super::Rtc {
|
|||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
"rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}",
|
"rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}",
|
||||||
Duration::from_ticks(
|
Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(),
|
||||||
rtc_ticks as u64 * TICK_HZ * (<WakeupPrescaler as Into<u32>>::into(prescaler) as u64) / rtc_hz,
|
prescaler as u32,
|
||||||
)
|
|
||||||
.as_millis(),
|
|
||||||
<WakeupPrescaler as Into<u32>>::into(prescaler),
|
|
||||||
rtc_ticks,
|
rtc_ticks,
|
||||||
self.instant(),
|
self.instant(),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user