stm32: rtc/low-power cleanup
This commit is contained in:
parent
5a158b94bd
commit
6da75ea285
@ -39,6 +39,9 @@ fn exticr_regs() -> pac::afio::Afio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn on_irq() {
|
pub unsafe fn on_irq() {
|
||||||
|
#[cfg(feature = "low-power")]
|
||||||
|
crate::low_power::on_wakeup_irq();
|
||||||
|
|
||||||
#[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))]
|
#[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))]
|
||||||
let bits = EXTI.pr(0).read().0;
|
let bits = EXTI.pr(0).read().0;
|
||||||
#[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))]
|
#[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))]
|
||||||
|
@ -5,7 +5,6 @@ use cortex_m::peripheral::SCB;
|
|||||||
use embassy_executor::*;
|
use embassy_executor::*;
|
||||||
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
|
||||||
use crate::rcc::low_power_ready;
|
use crate::rcc::low_power_ready;
|
||||||
use crate::time_driver::{get_driver, RtcDriver};
|
use crate::time_driver::{get_driver, RtcDriver};
|
||||||
|
|
||||||
@ -19,36 +18,20 @@ foreach_interrupt! {
|
|||||||
(RTC, rtc, $block:ident, WKUP, $irq:ident) => {
|
(RTC, rtc, $block:ident, WKUP, $irq:ident) => {
|
||||||
#[interrupt]
|
#[interrupt]
|
||||||
unsafe fn $irq() {
|
unsafe fn $irq() {
|
||||||
unsafe { EXECUTOR.as_mut().unwrap() }.on_wakeup_irq();
|
EXECUTOR.as_mut().unwrap().on_wakeup_irq();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn timer_driver_pause_time() {
|
#[allow(dead_code)]
|
||||||
// pause_time();
|
pub(crate) unsafe fn on_wakeup_irq() {
|
||||||
// }
|
EXECUTOR.as_mut().unwrap().on_wakeup_irq();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stop_with_rtc(rtc: &'static Rtc) {
|
pub fn stop_with_rtc(rtc: &'static Rtc) {
|
||||||
unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc)
|
unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn start_wakeup_alarm(requested_duration: embassy_time::Duration) {
|
|
||||||
// let rtc_instant = unsafe { EXECUTOR.as_mut().unwrap() }
|
|
||||||
// .rtc
|
|
||||||
// .unwrap()
|
|
||||||
// .start_wakeup_alarm(requested_duration);
|
|
||||||
//
|
|
||||||
// unsafe { EXECUTOR.as_mut().unwrap() }.last_stop = Some(rtc_instant);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn set_sleepdeep() {
|
|
||||||
// unsafe { EXECUTOR.as_mut().unwrap() }.scb.set_sleepdeep();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn stop_wakeup_alarm() -> RtcInstant {
|
|
||||||
// unsafe { EXECUTOR.as_mut().unwrap() }.rtc.unwrap().stop_wakeup_alarm()
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Thread mode executor, using WFE/SEV.
|
/// Thread mode executor, using WFE/SEV.
|
||||||
///
|
///
|
||||||
/// This is the simplest and most common kind of executor. It runs on
|
/// This is the simplest and most common kind of executor. It runs on
|
||||||
@ -91,27 +74,11 @@ impl Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) {
|
pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) {
|
||||||
trace!("low power: stop with rtc configured");
|
|
||||||
|
|
||||||
self.time_driver.set_rtc(rtc);
|
self.time_driver.set_rtc(rtc);
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
|
||||||
crate::interrupt::typelevel::RTC_WKUP::unpend();
|
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
|
||||||
unsafe {
|
|
||||||
crate::interrupt::typelevel::RTC_WKUP::enable()
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(stm32l0)]
|
|
||||||
crate::interrupt::typelevel::RTC::unpend();
|
|
||||||
|
|
||||||
#[cfg(stm32l0)]
|
|
||||||
unsafe {
|
|
||||||
crate::interrupt::typelevel::RTC::enable()
|
|
||||||
};
|
|
||||||
|
|
||||||
rtc.enable_wakeup_line();
|
rtc.enable_wakeup_line();
|
||||||
|
|
||||||
|
trace!("low power: stop with rtc configured");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_pwr(&mut self) {
|
fn configure_pwr(&mut self) {
|
||||||
|
@ -124,9 +124,6 @@ impl Default for RtcCalibrationCyclePeriod {
|
|||||||
|
|
||||||
impl Rtc {
|
impl Rtc {
|
||||||
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
|
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
|
||||||
#[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
|
|
||||||
use crate::rcc::get_freqs;
|
|
||||||
|
|
||||||
RTC::enable_peripheral_clk();
|
RTC::enable_peripheral_clk();
|
||||||
BackupDomain::enable_rtc();
|
BackupDomain::enable_rtc();
|
||||||
|
|
||||||
@ -135,20 +132,7 @@ impl Rtc {
|
|||||||
stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)),
|
stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
|
let frequency = Self::frequency();
|
||||||
let freqs = unsafe { get_freqs() };
|
|
||||||
|
|
||||||
// Load the clock frequency from the rcc mod, if supported
|
|
||||||
#[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
|
|
||||||
let frequency = match freqs.rtc {
|
|
||||||
Some(hertz) => hertz,
|
|
||||||
None => freqs.rtc_hse.unwrap(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Assume the default value, if not supported
|
|
||||||
#[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))]
|
|
||||||
let frequency = Hertz(32_768);
|
|
||||||
|
|
||||||
let async_psc = ((frequency.0 / rtc_config.frequency.0) - 1) as u8;
|
let async_psc = ((frequency.0 / rtc_config.frequency.0) - 1) as u8;
|
||||||
let sync_psc = (rtc_config.frequency.0 - 1) as u16;
|
let sync_psc = (rtc_config.frequency.0 - 1) as u16;
|
||||||
|
|
||||||
@ -157,6 +141,22 @@ impl Rtc {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn frequency() -> Hertz {
|
||||||
|
#[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
|
||||||
|
let freqs = unsafe { crate::rcc::get_freqs() };
|
||||||
|
|
||||||
|
// Load the clock frequency from the rcc mod, if supported
|
||||||
|
#[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
|
||||||
|
match freqs.rtc {
|
||||||
|
Some(hertz) => hertz,
|
||||||
|
None => freqs.rtc_hse.unwrap(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume the default value, if not supported
|
||||||
|
#[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))]
|
||||||
|
Hertz(32_768)
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the datetime to a new value.
|
/// Set the datetime to a new value.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
@ -264,6 +264,12 @@ pub(crate) mod sealed {
|
|||||||
pub trait Instance {
|
pub trait Instance {
|
||||||
const BACKUP_REGISTER_COUNT: usize;
|
const BACKUP_REGISTER_COUNT: usize;
|
||||||
|
|
||||||
|
#[cfg(feature = "low-power")]
|
||||||
|
const EXTI_WAKEUP_LINE: usize;
|
||||||
|
|
||||||
|
#[cfg(feature = "low-power")]
|
||||||
|
type WakeupInterrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
|
|
||||||
fn regs() -> Rtc {
|
fn regs() -> Rtc {
|
||||||
crate::pac::RTC
|
crate::pac::RTC
|
||||||
}
|
}
|
||||||
|
@ -67,15 +67,10 @@ impl super::Rtc {
|
|||||||
pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) {
|
pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) {
|
||||||
use embassy_time::{Duration, TICK_HZ};
|
use embassy_time::{Duration, TICK_HZ};
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
#[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
|
||||||
use crate::rcc::get_freqs;
|
unsafe { crate::rcc::get_freqs() }.rtc.unwrap();
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
|
||||||
let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64;
|
|
||||||
|
|
||||||
#[cfg(stm32l0)]
|
|
||||||
let rtc_hz = 32_768u64;
|
|
||||||
|
|
||||||
|
let rtc_hz = Self::frequency().0 as u64;
|
||||||
let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ;
|
let rtc_ticks = requested_duration.as_ticks() * rtc_hz / TICK_HZ;
|
||||||
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);
|
||||||
|
|
||||||
@ -112,17 +107,14 @@ impl super::Rtc {
|
|||||||
|
|
||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
pub(crate) fn enable_wakeup_line(&self) {
|
pub(crate) fn enable_wakeup_line(&self) {
|
||||||
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::pac::EXTI;
|
use crate::pac::EXTI;
|
||||||
|
|
||||||
#[cfg(stm32l0)]
|
<RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
|
||||||
EXTI.rtsr(0).modify(|w| w.set_line(20, true));
|
unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() };
|
||||||
#[cfg(stm32l0)]
|
|
||||||
EXTI.imr(0).modify(|w| w.set_line(20, true));
|
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
||||||
EXTI.rtsr(0).modify(|w| w.set_line(22, true));
|
EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
||||||
#[cfg(not(stm32l0))]
|
|
||||||
EXTI.imr(0).modify(|w| w.set_line(22, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
@ -138,17 +130,11 @@ impl super::Rtc {
|
|||||||
regs.cr().modify(|w| w.set_wute(false));
|
regs.cr().modify(|w| w.set_wute(false));
|
||||||
regs.isr().modify(|w| w.set_wutf(false));
|
regs.isr().modify(|w| w.set_wutf(false));
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
crate::pac::EXTI
|
||||||
crate::pac::EXTI.pr(0).modify(|w| w.set_line(22, true));
|
.pr(0)
|
||||||
|
.modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
||||||
|
|
||||||
#[cfg(stm32l0)]
|
<RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
|
||||||
crate::pac::EXTI.pr(0).modify(|w| w.set_line(20, true));
|
|
||||||
|
|
||||||
#[cfg(not(stm32l0))]
|
|
||||||
crate::interrupt::typelevel::RTC_WKUP::unpend();
|
|
||||||
|
|
||||||
#[cfg(stm32l0)]
|
|
||||||
crate::interrupt::typelevel::RTC::unpend();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
@ -280,6 +266,18 @@ impl super::Rtc {
|
|||||||
impl sealed::Instance for crate::peripherals::RTC {
|
impl sealed::Instance for crate::peripherals::RTC {
|
||||||
const BACKUP_REGISTER_COUNT: usize = 20;
|
const BACKUP_REGISTER_COUNT: usize = 20;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "low-power", stm32f4))]
|
||||||
|
const EXTI_WAKEUP_LINE: usize = 22;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "low-power", stm32l0))]
|
||||||
|
const EXTI_WAKEUP_LINE: usize = 20;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "low-power", stm32f4))]
|
||||||
|
type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "low-power", stm32l0))]
|
||||||
|
type WakeupInterrupt = crate::interrupt::typelevel::RTC;
|
||||||
|
|
||||||
fn enable_peripheral_clk() {
|
fn enable_peripheral_clk() {
|
||||||
#[cfg(any(rtc_v2l4, rtc_v2wb))]
|
#[cfg(any(rtc_v2l4, rtc_v2wb))]
|
||||||
{
|
{
|
||||||
|
@ -372,6 +372,12 @@ impl RtcDriver {
|
|||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
/// Resume the timer with the given offset
|
/// Resume the timer with the given offset
|
||||||
pub(crate) fn resume_time(&self) {
|
pub(crate) fn resume_time(&self) {
|
||||||
|
if T::regs_gp16().cr1().read().cen() {
|
||||||
|
// Time isn't currently stopped
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.stop_wakeup_alarm();
|
self.stop_wakeup_alarm();
|
||||||
|
|
||||||
T::regs_gp16().cr1().modify(|w| w.set_cen(true));
|
T::regs_gp16().cr1().modify(|w| w.set_cen(true));
|
||||||
|
Loading…
Reference in New Issue
Block a user