stm32: impl. draft cfgr pwr
This commit is contained in:
parent
faab2d0d53
commit
1ea4c58c39
@ -1,15 +1,33 @@
|
|||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
use cortex_m::peripheral::SCB;
|
||||||
use embassy_executor::*;
|
use embassy_executor::*;
|
||||||
|
use embassy_time::Duration;
|
||||||
|
|
||||||
|
use crate::interrupt;
|
||||||
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
|
|
||||||
const THREAD_PENDER: usize = usize::MAX;
|
const THREAD_PENDER: usize = usize::MAX;
|
||||||
|
const THRESHOLD: Duration = Duration::from_millis(500);
|
||||||
|
|
||||||
use crate::rtc::{Rtc, RtcInstant};
|
use crate::rtc::{Rtc, RtcInstant};
|
||||||
|
|
||||||
static mut RTC: Option<&'static Rtc> = None;
|
static mut RTC: Option<&'static Rtc> = None;
|
||||||
|
|
||||||
|
foreach_interrupt! {
|
||||||
|
(RTC, rtc, $block:ident, WKUP, $irq:ident) => {
|
||||||
|
#[interrupt]
|
||||||
|
unsafe fn $irq() {
|
||||||
|
Executor::on_wakeup_irq();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stop_with_rtc(rtc: &'static Rtc) {
|
pub fn stop_with_rtc(rtc: &'static Rtc) {
|
||||||
|
crate::interrupt::typelevel::RTC_WKUP::unpend();
|
||||||
|
unsafe { crate::interrupt::typelevel::RTC_WKUP::enable() };
|
||||||
|
|
||||||
unsafe { RTC = Some(rtc) };
|
unsafe { RTC = Some(rtc) };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,8 +63,47 @@ impl Executor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_power(&self) {
|
unsafe fn on_wakeup_irq() {
|
||||||
todo!()
|
info!("on wakeup irq");
|
||||||
|
|
||||||
|
cortex_m::asm::bkpt();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn low_power_ready(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn time_until_next_alarm(&self) -> Duration {
|
||||||
|
Duration::from_secs(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_scb(&self) -> SCB {
|
||||||
|
unsafe { cortex_m::Peripherals::steal() }.SCB
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configure_pwr(&self) {
|
||||||
|
trace!("low power before wfe");
|
||||||
|
|
||||||
|
if !self.low_power_ready() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let time_until_next_alarm = self.time_until_next_alarm();
|
||||||
|
if time_until_next_alarm < THRESHOLD {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("low power stop required");
|
||||||
|
|
||||||
|
critical_section::with(|_| {
|
||||||
|
trace!("executor: set wakeup alarm...");
|
||||||
|
|
||||||
|
start_wakeup_alarm(time_until_next_alarm);
|
||||||
|
|
||||||
|
trace!("low power wait for rtc ready...");
|
||||||
|
|
||||||
|
self.get_scb().set_sleepdeep();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the executor.
|
/// Run the executor.
|
||||||
@ -73,7 +130,7 @@ impl Executor {
|
|||||||
loop {
|
loop {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.inner.poll();
|
self.inner.poll();
|
||||||
self.configure_power();
|
self.configure_pwr();
|
||||||
asm!("wfe");
|
asm!("wfe");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,6 @@ impl super::Rtc {
|
|||||||
pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) -> RtcInstant {
|
pub(crate) fn start_wakeup_alarm(&self, requested_duration: embassy_time::Duration) -> RtcInstant {
|
||||||
use embassy_time::{Duration, TICK_HZ};
|
use embassy_time::{Duration, TICK_HZ};
|
||||||
|
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
|
||||||
use crate::rcc::get_freqs;
|
use crate::rcc::get_freqs;
|
||||||
|
|
||||||
let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64;
|
let rtc_hz = unsafe { get_freqs() }.rtc.unwrap().0 as u64;
|
||||||
@ -205,9 +204,6 @@ impl super::Rtc {
|
|||||||
trace!("wakeup timer enabled");
|
trace!("wakeup timer enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::interrupt::typelevel::RTC_WKUP::unpend();
|
|
||||||
unsafe { crate::interrupt::typelevel::RTC_WKUP::enable() };
|
|
||||||
|
|
||||||
RtcInstant::now()
|
RtcInstant::now()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,10 +214,6 @@ impl super::Rtc {
|
|||||||
/// note: this api is exposed for testing purposes until low power is implemented.
|
/// note: this api is exposed for testing purposes until low power is implemented.
|
||||||
/// it is not intended to be public
|
/// it is not intended to be public
|
||||||
pub(crate) fn stop_wakeup_alarm(&self) -> RtcInstant {
|
pub(crate) fn stop_wakeup_alarm(&self) -> RtcInstant {
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
|
||||||
|
|
||||||
crate::interrupt::typelevel::RTC_WKUP::disable();
|
|
||||||
|
|
||||||
trace!("disable wakeup timer...");
|
trace!("disable wakeup timer...");
|
||||||
|
|
||||||
RTC::regs().cr().modify(|w| {
|
RTC::regs().cr().modify(|w| {
|
||||||
|
Loading…
Reference in New Issue
Block a user