1use core::ops::Not;
2
3use crate::{
4 peripherals::{LP_AON, PMU},
5 private::DropGuard,
6 rtc_cntl::{
7 Rtc,
8 rtc::{HpAnalog, HpSysCntlReg, HpSysPower, LpAnalog, LpSysPower},
9 sleep::{SleepKind, pmu_common::SleepTimeConfig},
10 },
11 soc::{
12 clocks::{self, ClockTree, LpSlowClkConfig, SocRootClkConfig},
13 xtal32k,
14 },
15};
16
17#[derive(Clone, Copy)]
19pub struct AnalogSleepConfig {
21 pub hp_sys: HpAnalog,
23 pub lp_sys_sleep: LpAnalog,
26}
27
28impl AnalogSleepConfig {
29 fn defaults_deep_sleep() -> Self {
30 Self {
31 hp_sys: {
33 let mut cfg = HpAnalog::default();
34
35 cfg.bias.set_pd_cur(false);
36 cfg.bias.set_bias_sleep(false);
37 cfg.regulator0.set_xpd(false);
38 cfg.bias.set_dbg_atten(0);
39
40 cfg
41 },
42 lp_sys_sleep: {
44 let mut cfg = LpAnalog::default();
45
46 cfg.regulator1.set_drv_b(0);
47 cfg.bias.set_pd_cur(true);
48 cfg.bias.set_bias_sleep(true);
49 cfg.regulator0.set_slp_xpd(false);
50 cfg.regulator0.set_slp_dbias(0);
51 cfg.regulator0.set_xpd(true);
52 cfg.bias.set_dbg_atten(12);
53 cfg.regulator0.set_dbias(23); cfg
56 },
57 }
58 }
59
60 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
61 let mut this = Self {
62 hp_sys: {
64 let mut cfg = HpAnalog::default();
65
66 cfg.regulator1.set_drv_b(0);
67 cfg.bias.set_pd_cur(true);
68 cfg.bias.set_bias_sleep(true);
69 cfg.regulator0.set_xpd(true);
70 cfg.bias.set_dbg_atten(0);
71 cfg.regulator0.set_dbias(1); cfg
74 },
75 lp_sys_sleep: {
77 let mut cfg = LpAnalog::default();
78
79 cfg.regulator1.set_drv_b(0);
80 cfg.bias.set_pd_cur(true);
81 cfg.bias.set_bias_sleep(true);
82 cfg.regulator0.set_slp_xpd(false);
83 cfg.regulator0.set_slp_dbias(0);
84 cfg.regulator0.set_xpd(true);
85 cfg.bias.set_dbg_atten(0);
86 cfg.regulator0.set_dbias(12); cfg
89 },
90 };
91
92 if !pd_flags.pd_xtal() {
93 this.hp_sys.bias.set_pd_cur(false);
94 this.hp_sys.bias.set_bias_sleep(false);
95 this.hp_sys.regulator0.set_dbias(25);
96
97 this.lp_sys_sleep.bias.set_pd_cur(false);
98 this.lp_sys_sleep.bias.set_bias_sleep(false);
99 this.lp_sys_sleep.regulator0.set_dbias(26);
100 }
101
102 this
103 }
104
105 fn apply(&self) {
106 unsafe {
109 PMU::regs().hp_sleep_bias().modify(|_, w| {
111 w.hp_sleep_dbg_atten().bits(self.hp_sys.bias.dbg_atten());
113 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
115 w.sleep().bit(self.hp_sys.bias.bias_sleep())
117 });
118 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| {
119 w.hp_sleep_hp_regulator_xpd()
121 .bit(self.hp_sys.regulator0.xpd());
122 w.hp_sleep_hp_regulator_dbias()
124 .bits(self.hp_sys.regulator0.dbias())
125 });
126 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| {
127 w.hp_sleep_hp_regulator_drv_b()
129 .bits(self.hp_sys.regulator1.drv_b())
130 });
131
132 PMU::regs().lp_sleep_bias().modify(|_, w| {
134 w.lp_sleep_dbg_atten()
136 .bits(self.lp_sys_sleep.bias.dbg_atten());
137 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
139 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep())
141 });
142
143 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| {
144 w.lp_sleep_lp_regulator_slp_xpd()
146 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
147 w.lp_sleep_lp_regulator_xpd()
149 .bit(self.lp_sys_sleep.regulator0.xpd());
150 w.lp_sleep_lp_regulator_slp_dbias()
152 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
153 w.lp_sleep_lp_regulator_dbias()
155 .bits(self.lp_sys_sleep.regulator0.dbias())
156 });
157
158 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| {
159 w.lp_sleep_lp_regulator_drv_b()
161 .bits(self.lp_sys_sleep.regulator1.drv_b())
162 });
163 }
164 }
165}
166
167#[derive(Clone, Copy)]
170pub struct DigitalSleepConfig {
172 pub syscntl: HpSysCntlReg,
174}
175
176impl DigitalSleepConfig {
177 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
178 Self {
179 syscntl: {
181 let mut cfg = HpSysCntlReg::default();
182
183 cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not());
184
185 cfg
186 },
187 }
188 }
189
190 fn apply(&self) {
191 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
193 w.hp_sleep_dig_pad_slp_sel()
194 .bit(self.syscntl.dig_pad_slp_sel())
195 });
196 }
197}
198
199#[derive(Clone, Copy)]
202pub struct PowerSleepConfig {
204 pub hp_sys: HpSysPower,
206 pub lp_sys_active: LpSysPower,
208 pub lp_sys_sleep: LpSysPower,
210}
211
212impl PowerSleepConfig {
213 fn defaults(pd_flags: PowerDownFlags) -> Self {
214 let mut this = Self {
215 hp_sys: HpSysPower::default(),
216 lp_sys_active: LpSysPower::default(),
217 lp_sys_sleep: LpSysPower::default(),
218 };
219 this.apply_flags(pd_flags);
220 this
221 }
222
223 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
224 self.hp_sys
226 .dig_power
227 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
228 self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem());
229 self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
230 self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon());
231 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
232
233 if pd_flags.pd_modem() {
234 self.hp_sys.clk.set_i2c_iso_en(true);
237 self.hp_sys.clk.set_i2c_retention(true);
238 } else {
239 self.hp_sys.clk.set_i2c_iso_en(false);
246 self.hp_sys.clk.set_i2c_retention(false);
247 self.hp_sys.clk.set_xpd_bb_i2c(true);
248 self.hp_sys.clk.set_xpd_bbpll_i2c(true);
249 self.hp_sys.clk.set_xpd_bbpll(true);
250 }
251
252 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
253
254 self.lp_sys_active
255 .clk_power
256 .set_xpd_xtal32k(xtal32k::use_xtal32k());
257 self.lp_sys_active.clk_power.set_xpd_rc32k(true);
258 self.lp_sys_active.clk_power.set_xpd_fosc(true);
259
260 self.lp_sys_sleep
261 .dig_power
262 .set_peri_pd_en(pd_flags.pd_lp_periph());
263 self.lp_sys_sleep.dig_power.set_mem_dslp(true);
264
265 self.lp_sys_sleep
266 .clk_power
267 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
268 self.lp_sys_sleep
269 .clk_power
270 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
271 self.lp_sys_sleep
272 .clk_power
273 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
274
275 self.lp_sys_sleep
276 .xtal
277 .set_xpd_xtal(pd_flags.pd_xtal().not());
278 }
279
280 fn apply(&self) {
281 PMU::regs()
285 .hp_sleep_dig_power()
286 .modify(|_, w| unsafe { w.bits(self.hp_sys.dig_power.0) });
287 PMU::regs()
288 .hp_sleep_hp_ck_power()
289 .modify(|_, w| unsafe { w.bits(self.hp_sys.clk.0) });
290 PMU::regs()
291 .hp_sleep_xtal()
292 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
293
294 PMU::regs()
296 .hp_sleep_lp_dig_power()
297 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
298 PMU::regs()
299 .hp_sleep_lp_ck_power()
300 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
301
302 PMU::regs()
304 .lp_sleep_lp_dig_power()
305 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
306 PMU::regs()
307 .lp_sleep_lp_ck_power()
308 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
309 PMU::regs()
310 .lp_sleep_xtal()
311 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
312 }
313}
314
315#[derive(Clone, Copy)]
317pub struct HpParam {
319 pub modem_wakeup_wait_cycle: u32,
321 pub analog_wait_target_cycle: u16,
323 pub digital_power_down_wait_cycle: u16,
325 pub digital_power_supply_wait_cycle: u16,
327 pub digital_power_up_wait_cycle: u16,
329 pub pll_stable_wait_cycle: u16,
331 pub modify_icg_cntl_wait_cycle: u8,
333 pub switch_icg_cntl_wait_cycle: u8,
335 pub min_slp_slow_clk_cycle: u8,
337}
338
339#[derive(Clone, Copy)]
341pub struct LpParam {
343 pub digital_power_supply_wait_cycle: u16,
345 pub min_slp_slow_clk_cycle: u8,
347 pub analog_wait_target_cycle: u8,
349 pub digital_power_down_wait_cycle: u8,
351 pub digital_power_up_wait_cycle: u8,
353}
354
355#[derive(Clone, Copy)]
358pub struct HpLpParam {
360 pub xtal_stable_wait_cycle: u16,
362}
363
364#[derive(Clone, Copy)]
366pub struct ParamSleepConfig {
368 pub hp_sys: HpParam,
370 pub lp_sys: LpParam,
372 pub hp_lp: HpLpParam,
374}
375impl ParamSleepConfig {
376 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
377 hp_sys: HpParam {
378 min_slp_slow_clk_cycle: 10,
379 analog_wait_target_cycle: 2419,
380 digital_power_supply_wait_cycle: 32,
381 digital_power_up_wait_cycle: 32,
382 modem_wakeup_wait_cycle: 20700,
383 pll_stable_wait_cycle: 2,
384
385 digital_power_down_wait_cycle: 0,
386 modify_icg_cntl_wait_cycle: 0,
387 switch_icg_cntl_wait_cycle: 0,
388 },
389 lp_sys: LpParam {
390 min_slp_slow_clk_cycle: 10,
391 analog_wait_target_cycle: 23,
392 digital_power_supply_wait_cycle: 32,
393 digital_power_up_wait_cycle: 32,
394
395 digital_power_down_wait_cycle: 0,
396 },
397 hp_lp: HpLpParam {
398 xtal_stable_wait_cycle: 30,
399 },
400 };
401
402 fn apply(&self) {
403 unsafe {
406 PMU::regs().slp_wakeup_cntl3().modify(|_, w| {
407 w.hp_min_slp_val().bits(self.hp_sys.min_slp_slow_clk_cycle);
409 w.lp_min_slp_val().bits(self.lp_sys.min_slp_slow_clk_cycle)
411 });
412
413 PMU::regs().slp_wakeup_cntl7().modify(|_, w| {
414 w.ana_wait_target() .bits(self.hp_sys.analog_wait_target_cycle)
416 });
417
418 PMU::regs().power_wait_timer0().modify(|_, w| {
419 w.dg_hp_wait_timer()
421 .bits(self.hp_sys.digital_power_supply_wait_cycle);
422 w.dg_hp_powerup_timer()
424 .bits(self.hp_sys.digital_power_up_wait_cycle)
425 });
426
427 PMU::regs().power_wait_timer1().modify(|_, w| {
428 w.dg_lp_wait_timer()
430 .bits(self.lp_sys.digital_power_supply_wait_cycle);
431 w.dg_lp_powerup_timer()
433 .bits(self.lp_sys.digital_power_up_wait_cycle)
434 });
435
436 PMU::regs().slp_wakeup_cntl5().modify(|_, w| {
437 w.lp_ana_wait_target()
439 .bits(self.lp_sys.analog_wait_target_cycle);
440 w.modem_wait_target()
442 .bits(self.hp_sys.modem_wakeup_wait_cycle)
443 });
444 PMU::regs().power_ck_wait_cntl().modify(|_, w| {
445 w.wait_xtl_stable().bits(self.hp_lp.xtal_stable_wait_cycle);
447 w.wait_pll_stable().bits(self.hp_sys.pll_stable_wait_cycle)
449 });
450 }
451 }
452
453 fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self {
454 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
455
456 param.hp_sys.min_slp_slow_clk_cycle =
458 config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8;
459 param.hp_sys.analog_wait_target_cycle =
460 config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16;
461 param.hp_sys.digital_power_supply_wait_cycle =
462 config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
463 param.hp_sys.digital_power_up_wait_cycle =
464 config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16;
465 param.hp_sys.pll_stable_wait_cycle =
466 config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
467
468 let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags);
469
470 let modem_wakeup_wait_time_us = (config.sleep_time_adjustment
471 + MachineConstants::MODEM_STATE_SKIP_TIME_US
472 + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US)
473 .saturating_sub(hw_wait_time_us);
474 param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us);
475
476 param.lp_sys.min_slp_slow_clk_cycle =
477 config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8;
478 param.lp_sys.analog_wait_target_cycle =
479 config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8;
480 param.lp_sys.digital_power_supply_wait_cycle =
481 config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
482 param.lp_sys.digital_power_up_wait_cycle =
483 config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8;
484
485 param.hp_lp.xtal_stable_wait_cycle = if pd_xtal {
489 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
490 } else {
491 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
492 };
493
494 param
495 }
496}
497
498impl SleepTimeConfig {
499 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160;
500 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56;
501
502 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
503 let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE);
505 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
506 let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() {
507 MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US
508 } else {
509 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE)
510 };
511
512 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
513 + MachineConstants::LP_ANALOG_WAIT_TIME_US
514 + lp_clk_power_on_wait_time_us
515 + lp_wakeup_wait_time_us
516 + lp_clk_switch_time_us
517 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
518 + MachineConstants::LP_POWER_UP_WAIT_TIME_US;
519
520 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
522 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
523 let hp_regdma_wait_time_us = u32::max(
524 MachineConstants::HP_REGDMA_S2M_WORK_TIME_US
525 + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US,
526 MachineConstants::HP_REGDMA_S2A_WORK_TIME_US,
527 );
528 let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
529 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US;
530
531 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
532 + u32::max(
533 hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us,
534 hp_clock_wait_time_us,
535 );
536
537 #[rustfmt::skip] const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true;
556
557 let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP {
558 (
559 MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US,
560 MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US,
561 )
562 } else {
563 (0, 0)
564 };
565
566 lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us
567 }
568}
569
570#[derive(Clone, Copy)]
572pub struct RtcSleepConfig {
574 pub deep: bool,
576 pub pd_flags: PowerDownFlags,
578}
579
580impl Default for RtcSleepConfig {
581 fn default() -> Self {
582 Self {
586 deep: false,
587 pd_flags: PowerDownFlags(0),
588 }
589 }
590}
591
592bitfield::bitfield! {
593 #[derive(Clone, Copy)]
594 pub struct PowerDownFlags(u32);
596
597 pub u32, pd_top , set_pd_top : 0;
599 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
601 pub u32, pd_modem , set_pd_modem : 2;
603 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
605 pub u32, pd_cpu , set_pd_cpu : 4;
607 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
609 pub u32, pd_mem_g0 , set_pd_mem_g0 : 6;
611 pub u32, pd_mem_g1 , set_pd_mem_g1 : 7;
613 pub u32, pd_mem_g2 , set_pd_mem_g2 : 8;
615 pub u32, pd_mem_g3 , set_pd_mem_g3 : 9;
617 pub u32, pd_xtal , set_pd_xtal : 10;
619 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
621 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
623 pub u32, pd_rc32k , set_pd_rc32k : 13;
625 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
627}
628
629impl PowerDownFlags {
630 pub fn pd_mem(self) -> bool {
632 self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3()
633 }
634
635 pub fn set_pd_mem(&mut self, value: bool) {
638 self.set_pd_mem_g0(value);
639 self.set_pd_mem_g1(value);
640 self.set_pd_mem_g2(value);
641 self.set_pd_mem_g3(value);
642 }
643}
644
645struct MachineConstants;
647impl MachineConstants {
648 const LP_MIN_SLP_TIME_US: u32 = 450;
649 const LP_WAKEUP_WAIT_CYCLE: u32 = 4;
650 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
651 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
652 const LP_CLK_SWITCH_CYCLE: u32 = 1;
653 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
654 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
655 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
656
657 const HP_MIN_SLP_TIME_US: u32 = 450;
658 const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 150;
659 const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124;
660 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
661 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
662 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
663 const HP_REGDMA_S2M_WORK_TIME_US: u32 = 172;
664 const HP_REGDMA_S2A_WORK_TIME_US: u32 = 480;
665 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 278;
666 const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 70;
669 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
672 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 1;
673
674 const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US
675 + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US
676 + Self::LP_MIN_SLP_TIME_US;
677}
678
679impl RtcSleepConfig {
680 pub fn deep_slp(&self) -> bool {
682 self.deep
683 }
684
685 pub fn deep() -> Self {
687 Self {
689 deep: true,
690 ..Self::default()
691 }
692 }
693
694 pub(crate) fn is_deep_sleep(&self) -> bool {
695 self.deep
696 }
697
698 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
699 self.deep = kind == SleepKind::Deep;
700 }
701
702 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
703
704 pub(crate) fn apply(&mut self) {
706 let lp_slow_uses_xtal32k = ClockTree::with(|clocks| {
707 matches!(
708 clocks::lp_slow_clk_config(clocks),
709 Some(LpSlowClkConfig::Xtal32k)
710 )
711 });
712
713 if self.deep {
714 self.pd_flags.set_pd_top(true);
716 self.pd_flags.set_pd_vddsdio(true);
717 self.pd_flags.set_pd_modem(true);
718 self.pd_flags.set_pd_hp_periph(true);
719 self.pd_flags.set_pd_cpu(true);
720 self.pd_flags.set_pd_mem(true);
721 self.pd_flags.set_pd_xtal(true);
722 self.pd_flags.set_pd_hp_aon(true);
723 self.pd_flags.set_pd_lp_periph(true);
724 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
725 self.pd_flags.set_pd_rc32k(true);
726 self.pd_flags.set_pd_rc_fast(true);
727 } else {
728 self.pd_flags.set_pd_xtal(true);
736 self.pd_flags.set_pd_rc_fast(true);
737 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
738 }
739 }
740
741 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
746 let restore_clock_config = ClockTree::with(|clocks| {
747 let old_root = clocks.soc_root_clk();
748
749 clocks::configure_soc_root_clk(clocks, SocRootClkConfig::Xtal);
750
751 DropGuard::new((), move |_| {
753 ClockTree::with(|clocks| {
754 if let Some(old_root) = old_root {
755 clocks::configure_soc_root_clk(clocks, old_root);
756 }
757 });
758 })
759 });
760
761 let power = PowerSleepConfig::defaults(self.pd_flags);
764 power.apply();
765
766 let config = if self.deep {
768 SleepTimeConfig::deep_sleep()
769 } else {
770 SleepTimeConfig::light_sleep(self.pd_flags)
771 };
772
773 let mut param =
774 ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal());
775
776 if self.deep {
777 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
778 param.lp_sys.analog_wait_target_cycle =
779 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
780
781 AnalogSleepConfig::defaults_deep_sleep().apply();
782 } else {
783 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
784 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
785 }
786
787 param.apply();
788
789 LP_AON::regs()
793 .store9()
794 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
795
796 PMU::regs()
798 .slp_wakeup_cntl2()
799 .write(|w| unsafe { w.bits(wakeup_mask) });
800
801 PMU::regs().slp_wakeup_cntl1().modify(|_, w| unsafe {
803 w.slp_reject_en().bit(reject_mask != 0);
804 w.sleep_reject_ena().bits(reject_mask)
805 });
806
807 PMU::regs()
809 .slp_wakeup_cntl4()
810 .write(|w| w.slp_reject_cause_clr().bit(true));
811
812 PMU::regs().int_clr().write(|w| {
813 w.sw().clear_bit_by_one();
815 w.soc_sleep_reject().clear_bit_by_one();
817 w.soc_wakeup().clear_bit_by_one()
819 });
820
821 PMU::regs()
827 .slp_wakeup_cntl0()
828 .write(|w| w.sleep_req().bit(true));
829
830 restore_clock_config
831 }
832
833 pub(crate) fn finish_sleep(&self) {
835 }
841}