#![cfg_attr(docsrs, procmacros::doc_replace)]
use crate::peripherals::LPWR;
#[derive(Debug, Clone, Copy)]
pub enum UlpCoreWakeupSource {
HpCpu,
Timer(UlpCoreTimerCycles),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UlpCoreTimerCycles {
cycles: u32,
}
impl UlpCoreTimerCycles {
pub const fn new(cycles: u32) -> Self {
::core::assert!(
cycles <= 0xFFFFFF,
"ULP Timer cycles must be between 0 and 0xFFFFFF (inclusive)."
);
Self { cycles }
}
fn cycles(self) -> u32 {
self.cycles
}
}
impl Default for UlpCoreTimerCycles {
fn default() -> Self {
Self { cycles: 200 }
}
}
pub struct UlpCore<'d> {
_lp_core: crate::peripherals::ULP_RISCV_CORE<'d>,
}
impl<'d> UlpCore<'d> {
pub fn new(lp_core: crate::peripherals::ULP_RISCV_CORE<'d>) -> Self {
let lp_ram =
unsafe { core::slice::from_raw_parts_mut(0x5000_0000 as *mut u32, 8 * 1024 / 4) };
lp_ram.fill(0u32);
Self { _lp_core: lp_core }
}
pub fn run(&mut self, wakeup_src: UlpCoreWakeupSource) {
ulp_run(wakeup_src);
}
}
#[allow(unused)] fn ulp_stop() {
LPWR::regs()
.ulp_cp_timer()
.modify(|_, w| w.ulp_cp_slp_timer_en().clear_bit());
LPWR::regs()
.cocpu_ctrl()
.modify(|_, w| w.cocpu_done().set_bit());
LPWR::regs()
.cocpu_ctrl()
.modify(|_, w| w.cocpu_shut_reset_en().set_bit());
}
fn ulp_run(wakeup_src: UlpCoreWakeupSource) {
let rtc_cntl = LPWR::regs();
rtc_cntl
.cocpu_ctrl()
.modify(|_, w| w.cocpu_shut_reset_en().set_bit());
rtc_cntl
.ulp_cp_timer()
.modify(|_, w| w.ulp_cp_slp_timer_en().clear_bit());
crate::rom::ets_delay_us(20);
rtc_cntl
.cocpu_ctrl()
.modify(|_, w| w.cocpu_done_force().set_bit());
ulp_config_wakeup_source(wakeup_src);
rtc_cntl
.cocpu_ctrl()
.modify(|_, w| w.cocpu_sel().clear_bit());
crate::rom::ets_delay_us(20);
rtc_cntl.int_clr().write(|w| {
w.cocpu()
.clear_bit_by_one()
.cocpu_trap()
.clear_bit_by_one()
.ulp_cp()
.clear_bit_by_one()
});
}
fn ulp_config_wakeup_source(wakeup_src: UlpCoreWakeupSource) {
match wakeup_src {
UlpCoreWakeupSource::HpCpu => {
}
UlpCoreWakeupSource::Timer(sleep_cycles) => {
let cycles = sleep_cycles.cycles() << 8;
LPWR::regs()
.ulp_cp_timer_1()
.write(|w| unsafe { w.ulp_cp_timer_slp_cycle().bits(cycles) });
LPWR::regs()
.ulp_cp_ctrl()
.modify(|_, w| w.ulp_cp_force_start_top().clear_bit());
LPWR::regs()
.ulp_cp_timer()
.modify(|_, w| w.ulp_cp_slp_timer_en().set_bit());
}
}
}