use super::{
Ext0WakeupSource,
Ext1WakeupSource,
TimerWakeupSource,
WakeSource,
WakeTriggers,
WakeupLevel,
};
use crate::{
gpio::{RtcFunction, RtcPin},
peripherals::{APB_CTRL, EXTMEM, LPWR, RTC_IO, SPI0, SPI1, SYSTEM},
rom::regi2c_write_mask,
rtc_cntl::{sleep::RtcioWakeupSource, Clock, Rtc, RtcClock},
};
const I2C_DIG_REG: u32 = 0x6d;
const I2C_DIG_REG_HOSTID: u32 = 1;
const I2C_DIG_REG_EXT_RTC_DREG: u32 = 4;
const I2C_DIG_REG_EXT_RTC_DREG_MSB: u32 = 4;
const I2C_DIG_REG_EXT_RTC_DREG_LSB: u32 = 0;
const I2C_DIG_REG_EXT_RTC_DREG_SLEEP: u32 = 5;
const I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB: u32 = 4;
const I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB: u32 = 0;
const I2C_DIG_REG_EXT_DIG_DREG: u32 = 6;
const I2C_DIG_REG_EXT_DIG_DREG_MSB: u32 = 4;
const I2C_DIG_REG_EXT_DIG_DREG_LSB: u32 = 0;
const I2C_DIG_REG_EXT_DIG_DREG_SLEEP: u32 = 7;
const I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB: u32 = 4;
const I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB: u32 = 0;
const I2C_DIG_REG_XPD_RTC_REG: u32 = 13;
const I2C_DIG_REG_XPD_RTC_REG_MSB: u32 = 2;
const I2C_DIG_REG_XPD_RTC_REG_LSB: u32 = 2;
const I2C_DIG_REG_XPD_DIG_REG: u32 = 13;
const I2C_DIG_REG_XPD_DIG_REG_MSB: u32 = 3;
const I2C_DIG_REG_XPD_DIG_REG_LSB: u32 = 3;
pub const RTC_CNTL_DBIAS_0V90: u32 = 13;
pub const RTC_CNTL_DBIAS_0V95: u32 = 16;
pub const RTC_CNTL_DBIAS_1V00: u32 = 18;
pub const RTC_CNTL_DBIAS_1V05: u32 = 20;
pub const RTC_CNTL_DBIAS_1V10: u32 = 23;
pub const RTC_CNTL_DBIAS_1V15: u32 = 25;
pub const RTC_CNTL_DBIAS_1V20: u32 = 28;
pub const RTC_CNTL_DBIAS_1V25: u32 = 30;
pub const RTC_CNTL_DBIAS_1V30: u32 = 31;
pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0;
pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP: u16 = 0xFF;
pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT: u16 = 0x10;
pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20;
pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2;
pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW: u8 = 15;
pub const OTHER_BLOCKS_POWERUP: u8 = 1;
pub const OTHER_BLOCKS_WAIT: u16 = 1;
pub const WIFI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const WIFI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
pub const BT_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const BT_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
pub const RTC_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const RTC_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
pub const CPU_TOP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const CPU_TOP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
pub const DG_WRAP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const DG_WRAP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
pub const DG_PERI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const DG_PERI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
pub const RTC_MEM_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
pub const RTC_MEM_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
impl WakeSource for TimerWakeupSource {
fn apply(
&self,
rtc: &Rtc<'_>,
triggers: &mut WakeTriggers,
_sleep_config: &mut RtcSleepConfig,
) {
triggers.set_timer(true);
let rtc_cntl = LPWR::regs();
let clock_freq = RtcClock::slow_freq();
let clock_hz = clock_freq.frequency().as_hz() as u64;
let ticks = self.duration.as_micros() as u64 * clock_hz / 1_000_000u64;
let now = rtc.time_since_boot_raw();
let time_in_ticks = now + ticks;
unsafe {
rtc_cntl
.slp_timer0()
.write(|w| w.slp_val_lo().bits((time_in_ticks & 0xffffffff) as u32));
rtc_cntl
.int_clr()
.write(|w| w.main_timer().clear_bit_by_one());
rtc_cntl.slp_timer1().write(|w| {
w.slp_val_hi()
.bits(((time_in_ticks >> 32) & 0xffff) as u16)
.main_timer_alarm_en()
.set_bit()
});
}
}
}
impl<P: RtcPin> WakeSource for Ext0WakeupSource<'_, P> {
fn apply(
&self,
_rtc: &Rtc<'_>,
triggers: &mut WakeTriggers,
sleep_config: &mut RtcSleepConfig,
) {
sleep_config.set_rtc_peri_pd_en(false);
triggers.set_ext0(true);
self.pin
.borrow_mut()
.rtc_set_config(true, true, RtcFunction::Rtc);
unsafe {
let rtc_io = RTC_IO::regs();
rtc_io
.ext_wakeup0()
.modify(|_, w| w.sel().bits(self.pin.borrow().rtc_number()));
let rtc_cntl = LPWR::regs();
rtc_cntl
.ext_wakeup_conf()
.modify(|_r, w| w.ext_wakeup0_lv().bit(self.level == WakeupLevel::High));
}
}
}
impl<P: RtcPin> Drop for Ext0WakeupSource<'_, P> {
fn drop(&mut self) {
self.pin
.borrow_mut()
.rtc_set_config(true, false, RtcFunction::Rtc);
}
}
impl WakeSource for Ext1WakeupSource<'_, '_> {
fn apply(
&self,
_rtc: &Rtc<'_>,
triggers: &mut WakeTriggers,
sleep_config: &mut RtcSleepConfig,
) {
sleep_config.set_rtc_peri_pd_en(false);
triggers.set_ext1(true);
let mut pins = self.pins.borrow_mut();
let mut bits = 0u32;
for pin in pins.iter_mut() {
pin.rtc_set_config(true, true, RtcFunction::Rtc);
bits |= 1 << pin.rtc_number();
}
unsafe {
let rtc_cntl = LPWR::regs();
rtc_cntl
.ext_wakeup1()
.modify(|_, w| w.ext_wakeup1_status_clr().set_bit());
rtc_cntl
.ext_wakeup1()
.modify(|_, w| w.ext_wakeup1_sel().bits(bits));
rtc_cntl
.ext_wakeup_conf()
.modify(|_r, w| w.ext_wakeup1_lv().bit(self.level == WakeupLevel::High));
}
}
}
impl Drop for Ext1WakeupSource<'_, '_> {
fn drop(&mut self) {
let mut pins = self.pins.borrow_mut();
for pin in pins.iter_mut() {
pin.rtc_set_config(true, false, RtcFunction::Rtc);
}
}
}
impl RtcioWakeupSource<'_, '_> {
fn apply_pin(&self, pin: &mut dyn RtcPin, level: WakeupLevel) {
let rtcio = RTC_IO::regs();
pin.rtc_set_config(true, true, RtcFunction::Rtc);
rtcio.pin(pin.number() as usize).modify(|_, w| unsafe {
w.wakeup_enable().set_bit().int_type().bits(match level {
WakeupLevel::Low => 4,
WakeupLevel::High => 5,
})
});
}
}
impl WakeSource for RtcioWakeupSource<'_, '_> {
fn apply(
&self,
_rtc: &Rtc<'_>,
triggers: &mut WakeTriggers,
sleep_config: &mut RtcSleepConfig,
) {
let mut pins = self.pins.borrow_mut();
if pins.is_empty() {
return;
}
sleep_config.set_rtc_peri_pd_en(false);
triggers.set_gpio(true);
let sens = crate::peripherals::SENS::regs();
sens.sar_peri_clk_gate_conf()
.modify(|_, w| w.iomux_clk_en().set_bit());
for (pin, level) in pins.iter_mut() {
self.apply_pin(*pin, *level);
}
}
}
impl Drop for RtcioWakeupSource<'_, '_> {
fn drop(&mut self) {
let mut pins = self.pins.borrow_mut();
for (pin, _level) in pins.iter_mut() {
pin.rtc_set_config(true, false, RtcFunction::Rtc);
}
}
}
bitfield::bitfield! {
#[derive(Clone, Copy)]
pub struct RtcSleepConfig(u64);
impl Debug;
pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 1;
pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 2;
pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 3;
pub rtc_peri_pd_en, set_rtc_peri_pd_en: 4;
pub modem_pd_en, set_modem_pd_en: 5;
pub cpu_pd_en, set_cpu_pd_en: 6;
pub int_8m_pd_en, set_int_8m_pd_en: 7;
pub dig_peri_pd_en, set_dig_peri_pd_en: 8;
pub deep_slp, set_deep_slp: 9;
pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
pub u32, dig_dbias_slp, set_dig_dbias_slp: 15, 11;
pub u32, rtc_dbias_slp, set_rtc_dbias_slp: 20, 16;
pub bias_sleep_monitor, set_bias_sleep_monitor: 21;
pub u8, dbg_atten_slp, set_dbg_atten_slp: 25, 22;
pub bias_sleep_slp, set_bias_sleep_slp: 26;
pub pd_cur_monitor, set_pd_cur_monitor: 27;
pub pd_cur_slp, set_pd_cur_slp: 28;
pub vddsdio_pd_en, set_vddsdio_pd_en: 29;
pub xtal_fpu, set_xtal_fpu: 30;
pub rtc_regulator_fpu, set_rtc_regulator_fpu: 31;
pub deep_slp_reject, set_deep_slp_reject: 32;
pub light_slp_reject, set_light_slp_reject: 33;
}
impl Default for RtcSleepConfig {
fn default() -> Self {
let mut cfg = Self(Default::default());
cfg.set_deep_slp_reject(true);
cfg.set_light_slp_reject(true);
cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
cfg
}
}
const SYSCON_SRAM_POWER_UP: u16 = 0x7FF;
const SYSCON_ROM_POWER_UP: u8 = 0x7;
fn rtc_sleep_pu(val: bool) {
let rtc_cntl = LPWR::regs();
let syscon = unsafe { &*esp32s3::APB_CTRL::ptr() };
let bb = unsafe { &*esp32s3::BB::ptr() };
let nrx = unsafe { &*esp32s3::NRX::ptr() };
let fe = unsafe { &*esp32s3::FE::ptr() };
let fe2 = unsafe { &*esp32s3::FE2::ptr() };
rtc_cntl
.dig_pwc()
.modify(|_, w| w.lslp_mem_force_pu().bit(val));
rtc_cntl
.pwc()
.modify(|_, w| w.slowmem_force_lpu().bit(val).fastmem_force_lpu().bit(val));
syscon.front_end_mem_pd().modify(|_r, w| {
w.dc_mem_force_pu()
.bit(val)
.pbus_mem_force_pu()
.bit(val)
.agc_mem_force_pu()
.bit(val)
});
bb.bbpd_ctrl()
.modify(|_r, w| w.fft_force_pu().bit(val).dc_est_force_pu().bit(val));
nrx.nrxpd_ctrl().modify(|_, w| {
w.rx_rot_force_pu()
.bit(val)
.vit_force_pu()
.bit(val)
.demap_force_pu()
.bit(val)
});
fe.gen_ctrl().modify(|_, w| w.iq_est_force_pu().bit(val));
fe2.tx_interp_ctrl()
.modify(|_, w| w.tx_inf_force_pu().bit(val));
syscon.mem_power_up().modify(|_r, w| unsafe {
w.sram_power_up()
.bits(if val { SYSCON_SRAM_POWER_UP } else { 0 })
.rom_power_up()
.bits(if val { SYSCON_ROM_POWER_UP } else { 0 })
});
}
impl RtcSleepConfig {
pub fn deep() -> Self {
let mut cfg = Self::default();
cfg.set_lslp_mem_inf_fpu(false);
cfg.set_rtc_mem_inf_follow_cpu(true); cfg.set_rtc_fastmem_pd_en(true);
cfg.set_rtc_slowmem_pd_en(true);
cfg.set_rtc_peri_pd_en(true);
cfg.set_modem_pd_en(true);
cfg.set_cpu_pd_en(true);
cfg.set_int_8m_pd_en(true);
cfg.set_dig_peri_pd_en(true);
cfg.set_dig_dbias_slp(0); cfg.set_deep_slp(true);
cfg.set_wdt_flashboot_mod_en(false);
cfg.set_vddsdio_pd_en(true);
cfg.set_xtal_fpu(false);
cfg.set_deep_slp_reject(true);
cfg.set_light_slp_reject(true);
cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
cfg.set_rtc_regulator_fpu(false);
cfg.set_dbg_atten_slp(RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW);
cfg.set_bias_sleep_monitor(true);
cfg.set_pd_cur_monitor(true);
cfg.set_bias_sleep_slp(true);
cfg.set_pd_cur_slp(true);
cfg
}
pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
unsafe {
let rtc_cntl = LPWR::regs();
let syscon = APB_CTRL::regs();
let extmem = EXTMEM::regs();
let system = SYSTEM::regs();
rtc_cntl
.dig_pwc()
.modify(|_, w| w.wifi_force_pd().clear_bit());
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
rtc_cntl.ana_conf().modify(|_, w| w.pvtmon_pu().clear_bit());
rtc_cntl.timer1().modify(|_, w| {
w.pll_buf_wait()
.bits(RTC_CNTL_PLL_BUF_WAIT_DEFAULT)
.ck8m_wait()
.bits(RTC_CNTL_CK8M_WAIT_DEFAULT)
});
rtc_cntl
.timer5()
.modify(|_, w| w.min_slp_val().bits(RTC_CNTL_MIN_SLP_VAL_MIN));
rtc_cntl.timer3().modify(|_, w| {
w
.wifi_powerup_timer()
.bits(WIFI_POWERUP_CYCLES)
.wifi_wait_timer()
.bits(WIFI_WAIT_CYCLES)
.bt_powerup_timer()
.bits(BT_POWERUP_CYCLES)
.bt_wait_timer()
.bits(BT_WAIT_CYCLES)
});
rtc_cntl.timer6().modify(|_, w| {
w.cpu_top_powerup_timer()
.bits(CPU_TOP_POWERUP_CYCLES)
.cpu_top_wait_timer()
.bits(CPU_TOP_WAIT_CYCLES)
});
rtc_cntl.timer4().modify(|_, w| {
w
.powerup_timer()
.bits(RTC_POWERUP_CYCLES)
.wait_timer()
.bits(RTC_WAIT_CYCLES)
.dg_wrap_powerup_timer()
.bits(DG_WRAP_POWERUP_CYCLES)
.dg_wrap_wait_timer()
.bits(DG_WRAP_WAIT_CYCLES)
});
rtc_cntl.timer6().modify(|_, w| {
w.dg_peri_powerup_timer()
.bits(DG_PERI_POWERUP_CYCLES)
.dg_peri_wait_timer()
.bits(DG_PERI_WAIT_CYCLES)
});
regi2c_write_mask!(
I2C_DIG_REG,
I2C_DIG_REG_EXT_RTC_DREG_SLEEP,
RTC_CNTL_DBIAS_1V10
);
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, RTC_CNTL_DBIAS_1V10);
rtc_cntl.timer2().modify(|_, w| {
w.ulpcp_touch_start_wait()
.bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
});
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, RTC_CNTL_DBIAS_1V25);
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, RTC_CNTL_DBIAS_1V25);
extmem
.cache_mmu_power_ctrl()
.modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
syscon.clkgate_force_on().write(|w| w.bits(0));
extmem
.dcache_tag_power_ctrl()
.modify(|_, w| w.dcache_tag_mem_force_on().clear_bit());
extmem
.icache_tag_power_ctrl()
.modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
SPI0::regs()
.clock_gate()
.modify(|_, w| w.clk_en().clear_bit());
SPI1::regs()
.clock_gate()
.modify(|_, w| w.clk_en().clear_bit());
rtc_cntl
.clk_conf()
.modify(|_, w| w.ck8m_force_pu().clear_bit());
rtc_cntl
.options0()
.modify(|_, w| w.xtl_force_pu().clear_bit());
rtc_cntl.ana_conf().modify(|_, w| {
w
.i2c_reset_por_force_pd()
.clear_bit()
});
rtc_cntl.options0().modify(|_, w| {
w.bbpll_force_pu()
.clear_bit()
.bbpll_i2c_force_pu()
.clear_bit()
.bb_i2c_force_pu()
.clear_bit()
});
rtc_cntl.pwc().modify(|_, w| w.force_pu().clear_bit());
rtc_cntl.rtc().modify(|_, w| {
w.regulator_force_pu()
.clear_bit()
.dboost_force_pu()
.clear_bit()
});
rtc_cntl.pwc().modify(|_, w| {
w.slowmem_force_noiso()
.clear_bit()
.fastmem_force_noiso()
.clear_bit()
});
rtc_cntl.rtc().modify(|_, w| w.dboost_force_pd().set_bit());
system
.mem_pd_mask()
.modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
rtc_sleep_pu(false);
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_wrap_force_pu().clear_bit());
rtc_cntl.dig_iso().modify(|_, w| {
w.dg_wrap_force_noiso()
.clear_bit()
.dg_wrap_force_iso()
.clear_bit()
});
rtc_cntl.dig_iso().modify(|_, w| {
w.wifi_force_noiso()
.clear_bit()
.wifi_force_iso()
.clear_bit()
});
rtc_cntl
.dig_pwc()
.modify(|_, w| w.wifi_force_pu().clear_bit());
rtc_cntl
.dig_iso()
.modify(|_, w| w.bt_force_noiso().clear_bit().bt_force_iso().clear_bit());
rtc_cntl
.dig_pwc()
.modify(|_, w| w.bt_force_pu().clear_bit());
rtc_cntl.dig_iso().modify(|_, w| {
w.cpu_top_force_noiso()
.clear_bit()
.cpu_top_force_iso()
.clear_bit()
});
rtc_cntl
.dig_pwc()
.modify(|_, w| w.cpu_top_force_pu().clear_bit());
rtc_cntl.dig_iso().modify(|_, w| {
w.dg_peri_force_noiso()
.clear_bit()
.dg_peri_force_iso()
.clear_bit()
});
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_peri_force_pu().clear_bit());
rtc_cntl.pwc().modify(|_, w| {
w.force_noiso()
.clear_bit()
.force_iso()
.clear_bit()
.force_pu()
.clear_bit()
});
system
.cpu_per_conf()
.modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
rtc_cntl.dig_iso().modify(|_, w| {
w.dg_pad_force_unhold()
.clear_bit()
.dg_pad_force_noiso()
.clear_bit()
});
rtc_cntl
.dig_iso()
.modify(|_, w| w.wifi_force_iso().set_bit());
rtc_cntl
.dig_pwc()
.modify(|_, w| w.wifi_force_pd().set_bit());
rtc_cntl.int_ena().write(|w| w.bits(0));
rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
}
}
pub(crate) fn apply(&self) {
let rtc_cntl = LPWR::regs();
if self.lslp_mem_inf_fpu() {
rtc_sleep_pu(true);
}
if self.modem_pd_en() {
rtc_cntl.dig_iso().modify(|_, w| {
w.wifi_force_noiso()
.clear_bit()
.wifi_force_iso()
.clear_bit()
});
rtc_cntl
.dig_pwc()
.modify(|_, w| w.wifi_force_pu().clear_bit().wifi_pd_en().set_bit());
} else {
rtc_cntl.dig_pwc().modify(|_, w| w.wifi_pd_en().clear_bit());
}
if self.cpu_pd_en() {
rtc_cntl.dig_iso().modify(|_, w| {
w.cpu_top_force_noiso()
.clear_bit()
.cpu_top_force_iso()
.clear_bit()
});
rtc_cntl
.dig_pwc()
.modify(|_, w| w.cpu_top_force_pu().clear_bit().cpu_top_pd_en().set_bit());
} else {
rtc_cntl
.dig_pwc()
.modify(|_, w| w.cpu_top_pd_en().clear_bit());
}
if self.dig_peri_pd_en() {
rtc_cntl.dig_iso().modify(|_, w| {
w.dg_peri_force_noiso()
.clear_bit()
.dg_peri_force_iso()
.clear_bit()
});
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_peri_force_pu().clear_bit().dg_peri_pd_en().set_bit());
} else {
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_peri_pd_en().clear_bit());
}
if self.rtc_peri_pd_en() {
rtc_cntl.pwc().modify(|_, w| {
w.force_noiso().clear_bit();
w.force_iso().clear_bit();
w.force_pu().clear_bit();
w.pd_en().set_bit()
});
} else {
rtc_cntl.pwc().modify(|_, w| w.pd_en().clear_bit());
}
unsafe {
regi2c_write_mask!(
I2C_DIG_REG,
I2C_DIG_REG_EXT_RTC_DREG_SLEEP,
self.rtc_dbias_slp()
);
regi2c_write_mask!(
I2C_DIG_REG,
I2C_DIG_REG_EXT_DIG_DREG_SLEEP,
self.dig_dbias_slp()
);
rtc_cntl.bias_conf().modify(|_, w| {
w.dbg_atten_deep_slp().bits(self.dbg_atten_slp());
w.bias_sleep_deep_slp().bit(self.bias_sleep_slp());
w.pd_cur_deep_slp().bit(self.pd_cur_slp());
w.dbg_atten_monitor()
.bits(RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
w.bias_sleep_monitor().bit(self.bias_sleep_monitor());
w.pd_cur_monitor().bit(self.pd_cur_monitor())
});
if self.deep_slp() {
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_wrap_pd_en().set_bit());
rtc_cntl.ana_conf().modify(|_, w| {
w.ckgen_i2c_pu().clear_bit();
w.pll_i2c_pu().clear_bit();
w.rfrx_pbus_pu().clear_bit();
w.txrf_i2c_pu().clear_bit()
});
rtc_cntl
.options0()
.modify(|_, w| w.bb_i2c_force_pu().clear_bit());
} else {
rtc_cntl
.regulator_drv_ctrl()
.modify(|_, w| w.dg_vdd_drv_b_slp().bits(0xF));
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_wrap_pd_en().clear_bit());
}
rtc_cntl
.dig_pwc()
.modify(|_, w| w.lslp_mem_force_pu().set_bit());
rtc_cntl
.rtc()
.modify(|_, w| w.regulator_force_pu().bit(self.rtc_regulator_fpu()));
rtc_cntl
.clk_conf()
.modify(|_, w| w.ck8m_force_pu().bit(!self.int_8m_pd_en()));
rtc_cntl.sdio_conf().modify(|_, w| {
w.sdio_force().clear_bit();
w.sdio_reg_pd_en().bit(self.vddsdio_pd_en())
});
rtc_cntl.slp_reject_conf().modify(|_, w| {
w.deep_slp_reject_en().bit(self.deep_slp_reject());
w.light_slp_reject_en().bit(self.light_slp_reject())
});
rtc_cntl.timer2().modify(|_, w| {
w.ulpcp_touch_start_wait()
.bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP)
});
rtc_cntl
.options0()
.modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
rtc_cntl
.clk_conf()
.modify(|_, w| w.xtal_global_force_nogating().bit(self.xtal_fpu()));
}
}
pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) {
unsafe {
LPWR::regs()
.reset_state()
.modify(|_, w| w.procpu_stat_vector_sel().set_bit());
LPWR::regs()
.wakeup_state()
.modify(|_, w| w.wakeup_ena().bits(wakeup_triggers.0.into()));
LPWR::regs()
.state0()
.write(|w| w.sleep_en().set_bit().slp_wakeup().set_bit());
}
}
pub(crate) fn finish_sleep(&self) {
unsafe {
LPWR::regs().int_clr().write(|w| {
w.slp_reject()
.clear_bit_by_one()
.slp_wakeup()
.clear_bit_by_one()
});
if self.lslp_mem_inf_fpu() {
rtc_sleep_pu(true);
}
LPWR::regs().timer2().modify(|_, w| {
w.ulpcp_touch_start_wait()
.bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
});
}
}
}