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, HpRootClkConfig, LpSlowClkConfig},
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(9); cfg.regulator0.set_dbias(15); 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(1); cfg.regulator0.set_dbias(0); 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(1); cfg.regulator0.set_dbias(15); cfg
89 },
90 };
91
92 if !pd_flags.pd_xtal() {
95 this.hp_sys.bias.set_pd_cur(false);
96 this.hp_sys.bias.set_bias_sleep(false);
97 this.hp_sys.bias.set_dbg_atten(0);
98 this.hp_sys.regulator0.set_dbias(28); this.lp_sys_sleep.bias.set_pd_cur(false);
101 this.lp_sys_sleep.bias.set_bias_sleep(false);
102 this.lp_sys_sleep.bias.set_dbg_atten(0);
103 this.lp_sys_sleep.regulator0.set_dbias(28); }
105
106 this
107 }
108
109 fn apply(&self) {
110 PMU::regs().hp_sleep_bias().modify(|_, w| unsafe {
114 w.hp_sleep_dbg_atten().bits(self.hp_sys.bias.dbg_atten());
116 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
118 w.sleep().bit(self.hp_sys.bias.bias_sleep())
120 });
121 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| unsafe {
122 w.hp_sleep_hp_regulator_xpd()
124 .bit(self.hp_sys.regulator0.xpd());
125 w.hp_sleep_hp_regulator_dbias()
127 .bits(self.hp_sys.regulator0.dbias())
128 });
129 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| unsafe {
130 w.hp_sleep_hp_regulator_drv_b()
132 .bits(self.hp_sys.regulator1.drv_b())
133 });
134
135 PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
137 w.lp_sleep_dbg_atten()
139 .bits(self.lp_sys_sleep.bias.dbg_atten());
140 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
142 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep())
144 });
145
146 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| unsafe {
147 w.lp_sleep_lp_regulator_slp_xpd()
149 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
150 w.lp_sleep_lp_regulator_xpd()
152 .bit(self.lp_sys_sleep.regulator0.xpd());
153 w.lp_sleep_lp_regulator_slp_dbias()
155 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
156 w.lp_sleep_lp_regulator_dbias()
158 .bits(self.lp_sys_sleep.regulator0.dbias())
159 });
160
161 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| unsafe {
162 w.lp_sleep_lp_regulator_drv_b()
164 .bits(self.lp_sys_sleep.regulator1.drv_b())
165 });
166 }
167}
168
169#[derive(Clone, Copy)]
172pub struct DigitalSleepConfig {
174 pub syscntl: HpSysCntlReg,
176}
177
178impl DigitalSleepConfig {
179 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
180 Self {
181 syscntl: {
183 let mut cfg = HpSysCntlReg::default();
184
185 cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not());
186
187 cfg
188 },
189 }
190 }
191
192 fn apply(&self) {
193 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
195 w.hp_sleep_dig_pad_slp_sel()
196 .bit(self.syscntl.dig_pad_slp_sel())
197 });
198 }
199}
200
201#[derive(Clone, Copy)]
204pub struct PowerSleepConfig {
206 pub hp_sys: HpSysPower,
208 pub lp_sys_active: LpSysPower,
210 pub lp_sys_sleep: LpSysPower,
212}
213
214impl PowerSleepConfig {
215 fn defaults(pd_flags: PowerDownFlags) -> Self {
216 let mut this = Self {
217 hp_sys: HpSysPower::default(),
218 lp_sys_active: LpSysPower::default(),
219 lp_sys_sleep: LpSysPower::default(),
220 };
221 this.apply_flags(pd_flags);
222 this
223 }
224
225 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
226 self.hp_sys
228 .dig_power
229 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
230 self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem());
231 self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
232 self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon());
233 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
234
235 self.hp_sys.clk.set_i2c_iso_en(true);
236 self.hp_sys.clk.set_i2c_retention(true);
237
238 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
239
240 self.lp_sys_active
241 .clk_power
242 .set_xpd_xtal32k(xtal32k::use_xtal32k());
243 self.lp_sys_active.clk_power.set_xpd_rc32k(true);
244 self.lp_sys_active.clk_power.set_xpd_fosc(true);
245
246 self.lp_sys_sleep
247 .dig_power
248 .set_peri_pd_en(pd_flags.pd_lp_periph());
249 self.lp_sys_sleep.dig_power.set_mem_dslp(true);
250
251 self.lp_sys_sleep
252 .clk_power
253 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
254 self.lp_sys_sleep
255 .clk_power
256 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
257 self.lp_sys_sleep
258 .clk_power
259 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
260
261 self.lp_sys_sleep
262 .xtal
263 .set_xpd_xtal(pd_flags.pd_xtal().not());
264 }
265
266 fn apply(&self) {
267 PMU::regs()
271 .hp_sleep_dig_power()
272 .modify(|_, w| unsafe { w.bits(self.hp_sys.dig_power.0) });
273 PMU::regs()
274 .hp_sleep_hp_ck_power()
275 .modify(|_, w| unsafe { w.bits(self.hp_sys.clk.0) });
276 PMU::regs()
277 .hp_sleep_xtal()
278 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
279
280 PMU::regs()
282 .hp_sleep_lp_dig_power()
283 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
284 PMU::regs()
285 .hp_sleep_lp_ck_power()
286 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
287
288 PMU::regs()
290 .lp_sleep_lp_dig_power()
291 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
292 PMU::regs()
293 .lp_sleep_lp_ck_power()
294 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
295 PMU::regs()
296 .lp_sleep_xtal()
297 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
298 }
299}
300
301#[derive(Clone, Copy)]
303pub struct HpParam {
305 pub modem_wakeup_wait_cycle: u32,
307 pub analog_wait_target_cycle: u16,
309 pub digital_power_down_wait_cycle: u16,
311 pub digital_power_supply_wait_cycle: u16,
313 pub digital_power_up_wait_cycle: u16,
315 pub pll_stable_wait_cycle: u16,
317 pub modify_icg_cntl_wait_cycle: u8,
319 pub switch_icg_cntl_wait_cycle: u8,
321 pub min_slp_slow_clk_cycle: u8,
323 pub isolate_wait_cycle: u8,
325 pub reset_wait_cycle: u8,
327}
328
329#[derive(Clone, Copy)]
331pub struct LpParam {
333 pub digital_power_supply_wait_cycle: u16,
335 pub min_slp_slow_clk_cycle: u8,
337 pub analog_wait_target_cycle: u8,
339 pub digital_power_down_wait_cycle: u8,
341 pub digital_power_up_wait_cycle: u8,
343 pub isolate_wait_cycle: u8,
345 pub reset_wait_cycle: u8,
347}
348
349#[derive(Clone, Copy)]
352pub struct HpLpParam {
354 pub xtal_stable_wait_cycle: u16,
356}
357
358#[derive(Clone, Copy)]
360pub struct ParamSleepConfig {
362 pub hp_sys: HpParam,
364 pub lp_sys: LpParam,
366 pub hp_lp: HpLpParam,
368}
369impl ParamSleepConfig {
370 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
371 hp_sys: HpParam {
372 min_slp_slow_clk_cycle: 10,
373 analog_wait_target_cycle: 2419,
374 digital_power_supply_wait_cycle: 32,
375 digital_power_up_wait_cycle: 32,
376 modem_wakeup_wait_cycle: 20700,
377 pll_stable_wait_cycle: 2,
378
379 digital_power_down_wait_cycle: 0,
380 modify_icg_cntl_wait_cycle: 0,
381 switch_icg_cntl_wait_cycle: 0,
382 isolate_wait_cycle: 0,
383 reset_wait_cycle: 0,
384 },
385 lp_sys: LpParam {
386 min_slp_slow_clk_cycle: 10,
387 analog_wait_target_cycle: 23,
388 digital_power_supply_wait_cycle: 32,
389 digital_power_up_wait_cycle: 32,
390
391 digital_power_down_wait_cycle: 0,
392 isolate_wait_cycle: 0,
393 reset_wait_cycle: 0,
394 },
395 hp_lp: HpLpParam {
396 xtal_stable_wait_cycle: 30,
397 },
398 };
399
400 fn apply(&self) {
401 PMU::regs().slp_wakeup_cntl3().modify(|_, w| unsafe {
404 w.hp_min_slp_val().bits(self.hp_sys.min_slp_slow_clk_cycle);
406 w.lp_min_slp_val().bits(self.lp_sys.min_slp_slow_clk_cycle)
408 });
409
410 PMU::regs().slp_wakeup_cntl7().modify(|_, w| unsafe {
411 w.ana_wait_target()
413 .bits(self.hp_sys.analog_wait_target_cycle)
414 });
415
416 PMU::regs().power_wait_timer0().modify(|_, w| unsafe {
417 w.dg_hp_pd_wait_timer()
419 .bits(self.hp_sys.digital_power_supply_wait_cycle);
420 w.dg_hp_powerup_timer()
422 .bits(self.hp_sys.digital_power_up_wait_cycle)
423 });
424
425 PMU::regs().power_wait_timer1().modify(|_, w| unsafe {
426 w.dg_lp_pd_wait_timer()
428 .bits(self.lp_sys.digital_power_supply_wait_cycle);
429 w.dg_lp_powerup_timer()
431 .bits(self.lp_sys.digital_power_up_wait_cycle)
432 });
433
434 PMU::regs().power_wait_timer2().modify(|_, w| unsafe {
436 w.dg_hp_iso_wait_timer()
437 .bits(self.hp_sys.isolate_wait_cycle);
438 w.dg_hp_rst_wait_timer().bits(self.hp_sys.reset_wait_cycle);
439 w.dg_lp_iso_wait_timer()
440 .bits(self.lp_sys.isolate_wait_cycle);
441 w.dg_lp_rst_wait_timer().bits(self.lp_sys.reset_wait_cycle)
442 });
443
444 PMU::regs().slp_wakeup_cntl5().modify(|_, w| unsafe {
445 w.lp_ana_wait_target()
447 .bits(self.lp_sys.analog_wait_target_cycle);
448 w.modem_wait_target()
450 .bits(self.hp_sys.modem_wakeup_wait_cycle)
451 });
452 PMU::regs().power_ck_wait_cntl().modify(|_, w| unsafe {
453 w.wait_xtl_stable().bits(self.hp_lp.xtal_stable_wait_cycle);
455 w.wait_pll_stable().bits(self.hp_sys.pll_stable_wait_cycle)
457 });
458 }
459
460 fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self {
461 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
462
463 param.hp_sys.min_slp_slow_clk_cycle =
465 config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8;
466 param.hp_sys.analog_wait_target_cycle =
467 config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16;
468 param.hp_sys.digital_power_supply_wait_cycle =
469 config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
470 param.hp_sys.digital_power_up_wait_cycle =
471 config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16;
472 param.hp_sys.pll_stable_wait_cycle =
473 config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
474 param.hp_sys.isolate_wait_cycle =
475 config.us_to_fastclk(MachineConstants::HP_ISOLATE_WAIT_TIME_US) as u8;
476 param.hp_sys.reset_wait_cycle =
477 config.us_to_fastclk(MachineConstants::HP_RESET_WAIT_TIME_US) as u8;
478
479 let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags);
480
481 let modem_wakeup_wait_time_us = (config.sleep_time_adjustment
482 + MachineConstants::MODEM_STATE_SKIP_TIME_US
483 + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US)
484 .saturating_sub(hw_wait_time_us);
485 param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us);
486
487 param.lp_sys.min_slp_slow_clk_cycle =
488 config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8;
489 param.lp_sys.analog_wait_target_cycle =
490 config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8;
491 param.lp_sys.digital_power_supply_wait_cycle =
492 config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
493 param.lp_sys.digital_power_up_wait_cycle =
494 config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8;
495 param.lp_sys.isolate_wait_cycle =
496 config.us_to_fastclk(MachineConstants::LP_ISOLATE_WAIT_TIME_US) as u8;
497 param.lp_sys.reset_wait_cycle =
498 config.us_to_fastclk(MachineConstants::LP_RESET_WAIT_TIME_US) as u8;
499
500 param.hp_lp.xtal_stable_wait_cycle = if pd_xtal {
504 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
505 } else {
506 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
507 };
508
509 param
510 }
511}
512
513impl SleepTimeConfig {
514 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160;
515 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56;
516
517 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
518 let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE);
520 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
521 let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() {
522 MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US
523 } else {
524 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE)
525 };
526
527 let lp_control_wait_time_us =
529 MachineConstants::LP_ISOLATE_WAIT_TIME_US + MachineConstants::LP_RESET_WAIT_TIME_US;
530 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
531 + MachineConstants::LP_ANALOG_WAIT_TIME_US
532 + lp_clk_power_on_wait_time_us
533 + lp_wakeup_wait_time_us
534 + lp_clk_switch_time_us
535 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
536 + MachineConstants::LP_POWER_UP_WAIT_TIME_US
537 + lp_control_wait_time_us;
538
539 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
541 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
542 let hp_control_wait_time_us =
543 MachineConstants::HP_ISOLATE_WAIT_TIME_US + MachineConstants::HP_RESET_WAIT_TIME_US;
544 let hp_regdma_wait_time_us = u32::max(
545 MachineConstants::HP_REGDMA_S2M_WORK_TIME_US
546 + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US,
547 MachineConstants::HP_REGDMA_S2A_WORK_TIME_US,
548 );
549 let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
550 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US;
551
552 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
553 + u32::max(
554 hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us,
555 hp_clock_wait_time_us,
556 )
557 + hp_control_wait_time_us;
558
559 #[rustfmt::skip] const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true;
578
579 let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP {
580 (
581 MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US,
582 MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US,
583 )
584 } else {
585 (0, 0)
586 };
587
588 lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us
589 }
590}
591
592#[derive(Clone, Copy)]
594pub struct RtcSleepConfig {
596 pub deep: bool,
598 pub pd_flags: PowerDownFlags,
600}
601
602impl Default for RtcSleepConfig {
603 fn default() -> Self {
604 Self {
608 deep: false,
609 pd_flags: PowerDownFlags(0),
610 }
611 }
612}
613
614bitfield::bitfield! {
615 #[derive(Clone, Copy)]
616 pub struct PowerDownFlags(u32);
618
619 pub u32, pd_top , set_pd_top : 0;
621 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
623 pub u32, pd_modem , set_pd_modem : 2;
625 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
627 pub u32, pd_cpu , set_pd_cpu : 4;
629 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
631 pub u32, pd_mem_g0 , set_pd_mem_g0 : 6;
633 pub u32, pd_mem_g1 , set_pd_mem_g1 : 7;
635 pub u32, pd_mem_g2 , set_pd_mem_g2 : 8;
637 pub u32, pd_mem_g3 , set_pd_mem_g3 : 9;
639 pub u32, pd_xtal , set_pd_xtal : 10;
641 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
643 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
645 pub u32, pd_rc32k , set_pd_rc32k : 13;
647 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
649}
650
651impl PowerDownFlags {
652 pub fn pd_mem(self) -> bool {
654 self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3()
655 }
656
657 pub fn set_pd_mem(&mut self, value: bool) {
660 self.set_pd_mem_g0(value);
661 self.set_pd_mem_g1(value);
662 self.set_pd_mem_g2(value);
663 self.set_pd_mem_g3(value);
664 }
665}
666
667struct MachineConstants;
669impl MachineConstants {
670 const LP_MIN_SLP_TIME_US: u32 = 450;
671 const LP_WAKEUP_WAIT_CYCLE: u32 = 4;
672 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
673 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
674 const LP_CLK_SWITCH_CYCLE: u32 = 1;
675 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
676 const LP_ISOLATE_WAIT_TIME_US: u32 = 1;
677 const LP_RESET_WAIT_TIME_US: u32 = 1;
678 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
679 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
680
681 const HP_MIN_SLP_TIME_US: u32 = 450;
682 const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 2;
683 const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124;
684 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
685 const HP_ISOLATE_WAIT_TIME_US: u32 = 1;
686 const HP_RESET_WAIT_TIME_US: u32 = 1;
687 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
688 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
689 const HP_REGDMA_S2M_WORK_TIME_US: u32 = 287;
690 const HP_REGDMA_S2A_WORK_TIME_US: u32 = 720;
691 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 430;
692 const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 68;
695 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
698 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 50;
699
700 const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US
701 + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US
702 + Self::LP_MIN_SLP_TIME_US;
703}
704
705impl RtcSleepConfig {
706 pub fn deep_slp(&self) -> bool {
708 self.deep
709 }
710
711 pub fn deep() -> Self {
713 Self {
715 deep: true,
716 ..Self::default()
717 }
718 }
719
720 pub(crate) fn is_deep_sleep(&self) -> bool {
721 self.deep
722 }
723
724 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
725 self.deep = kind == SleepKind::Deep;
726 }
727
728 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
729
730 pub(crate) fn apply(&mut self) {
732 let lp_slow_uses_xtal32k = ClockTree::with(|clocks| {
733 matches!(
734 clocks::lp_slow_clk_config(clocks),
735 Some(LpSlowClkConfig::Xtal32k)
736 )
737 });
738
739 if self.deep {
740 self.pd_flags.set_pd_top(true);
742 self.pd_flags.set_pd_vddsdio(true);
743 self.pd_flags.set_pd_modem(true);
744 self.pd_flags.set_pd_hp_periph(true);
745 self.pd_flags.set_pd_cpu(true);
746 self.pd_flags.set_pd_mem(true);
747 self.pd_flags.set_pd_xtal(true);
748 self.pd_flags.set_pd_hp_aon(true);
749 self.pd_flags.set_pd_lp_periph(true);
750 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
751 self.pd_flags.set_pd_rc32k(true);
752 self.pd_flags.set_pd_rc_fast(true);
753 } else {
754 self.pd_flags.set_pd_xtal(true);
762 self.pd_flags.set_pd_rc_fast(true);
763 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
764 }
765 }
766
767 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
772 let restore_clock_config = ClockTree::with(|clocks| {
773 let old_root = clocks.hp_root_clk();
774
775 clocks::configure_hp_root_clk(clocks, HpRootClkConfig::Xtal);
776
777 DropGuard::new((), move |_| {
779 ClockTree::with(|clocks| {
780 if let Some(old_root) = old_root {
781 clocks::configure_hp_root_clk(clocks, old_root);
782 }
783 });
784 })
785 });
786
787 let power = PowerSleepConfig::defaults(self.pd_flags);
790 power.apply();
791
792 let config = if self.deep {
794 SleepTimeConfig::deep_sleep()
795 } else {
796 SleepTimeConfig::light_sleep(self.pd_flags)
797 };
798
799 let mut param =
800 ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal());
801
802 if self.deep {
803 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
804 param.lp_sys.analog_wait_target_cycle =
805 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
806
807 AnalogSleepConfig::defaults_deep_sleep().apply();
808 } else {
809 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
810 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
811 }
812
813 param.apply();
814
815 LP_AON::regs()
819 .store9()
820 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
821
822 PMU::regs()
824 .slp_wakeup_cntl2()
825 .write(|w| unsafe { w.bits(wakeup_mask) });
826
827 PMU::regs().slp_wakeup_cntl1().modify(|_, w| unsafe {
829 w.slp_reject_en().bit(reject_mask != 0);
830 w.sleep_reject_ena().bits(reject_mask)
831 });
832
833 PMU::regs()
835 .slp_wakeup_cntl4()
836 .write(|w| w.slp_reject_cause_clr().bit(true));
837
838 PMU::regs().int_clr().write(|w| {
839 w.sw().clear_bit_by_one();
841 w.soc_sleep_reject().clear_bit_by_one();
843 w.soc_wakeup().clear_bit_by_one()
845 });
846
847 PMU::regs()
853 .slp_wakeup_cntl0()
854 .write(|w| w.sleep_req().bit(true));
855
856 restore_clock_config
857 }
858
859 pub(crate) fn finish_sleep(&self) {
861 }
867}