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::{
10 SleepKind,
11 pmu_common::{SleepTimeConfig, request_sleep},
12 },
13 },
14 soc::{
15 clocks::{self, ClockTree, HpRootClkConfig},
16 xtal32k,
17 },
18};
19
20#[derive(Clone, Copy)]
22pub struct AnalogSleepConfig {
24 pub hp_sys: HpAnalog,
26 pub lp_sys_sleep: LpAnalog,
29}
30
31impl AnalogSleepConfig {
32 fn defaults_deep_sleep() -> Self {
33 Self {
34 hp_sys: {
36 let mut cfg = HpAnalog::default();
37
38 cfg.bias.set_pd_cur(true); cfg.bias.set_bias_sleep(true); cfg.regulator0.set_xpd(false);
41 cfg.bias.set_dbg_atten(13); cfg
44 },
45 lp_sys_sleep: {
47 let mut cfg = LpAnalog::default();
48
49 cfg.regulator1.set_drv_b(0);
50 cfg.bias.set_pd_cur(true);
51 cfg.bias.set_bias_sleep(true);
52 cfg.regulator0.set_slp_xpd(false);
53 cfg.regulator0.set_slp_dbias(0);
54 cfg.regulator0.set_xpd(true);
55 cfg.bias.set_dbg_atten(13); cfg.regulator0.set_dbias(23); cfg
59 },
60 }
61 }
62
63 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
64 let mut this = Self {
65 hp_sys: {
67 let mut cfg = HpAnalog::default();
68
69 cfg.regulator1.set_drv_b(0);
70 cfg.bias.set_pd_cur(true);
71 cfg.bias.set_bias_sleep(true);
72 cfg.regulator0.set_xpd(true);
73 cfg.bias.set_dbg_atten(1); cfg.regulator0.set_dbias(0); cfg
77 },
78 lp_sys_sleep: {
80 let mut cfg = LpAnalog::default();
81
82 cfg.regulator1.set_drv_b(0);
83 cfg.bias.set_pd_cur(true);
84 cfg.bias.set_bias_sleep(true);
85 cfg.regulator0.set_slp_xpd(false);
86 cfg.regulator0.set_slp_dbias(0);
87 cfg.regulator0.set_xpd(true);
88 cfg.bias.set_dbg_atten(1); cfg.regulator0.set_dbias(15); cfg
92 },
93 };
94
95 if !pd_flags.pd_xtal() || !pd_flags.pd_rc_fast() {
98 this.hp_sys.bias.set_pd_cur(false); this.hp_sys.bias.set_bias_sleep(false); this.hp_sys.bias.set_dbg_atten(0);
101 this.hp_sys.regulator0.set_dbias(26); this.lp_sys_sleep.bias.set_pd_cur(false);
104 this.lp_sys_sleep.bias.set_bias_sleep(false);
105 this.lp_sys_sleep.bias.set_dbg_atten(0);
106 this.lp_sys_sleep.regulator0.set_dbias(25); }
108
109 this
110 }
111
112 fn apply(&self) {
113 unsafe {
116 PMU::regs().hp_sleep_bias().modify(|_, w| {
118 w.hp_sleep_dbg_atten().bits(self.hp_sys.bias.dbg_atten());
120 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
122 w.sleep().bit(self.hp_sys.bias.bias_sleep())
124 });
125 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| {
126 w.hp_sleep_hp_regulator_xpd()
128 .bit(self.hp_sys.regulator0.xpd());
129 w.hp_sleep_hp_regulator_dbias()
131 .bits(self.hp_sys.regulator0.dbias())
132 });
133 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| {
134 w.hp_sleep_hp_regulator_drv_b()
136 .bits(self.hp_sys.regulator1.drv_b())
137 });
138
139 PMU::regs().lp_sleep_bias().modify(|_, w| {
141 w.lp_sleep_dbg_atten()
143 .bits(self.lp_sys_sleep.bias.dbg_atten());
144 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
146 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep())
148 });
149
150 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| {
151 w.lp_sleep_lp_regulator_slp_xpd()
153 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
154 w.lp_sleep_lp_regulator_xpd()
156 .bit(self.lp_sys_sleep.regulator0.xpd());
157 w.lp_sleep_lp_regulator_slp_dbias()
159 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
160 w.lp_sleep_lp_regulator_dbias()
162 .bits(self.lp_sys_sleep.regulator0.dbias())
163 });
164
165 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| {
166 w.lp_sleep_lp_regulator_drv_b()
168 .bits(self.lp_sys_sleep.regulator1.drv_b())
169 });
170 }
171 }
172}
173
174#[derive(Clone, Copy)]
177pub struct DigitalSleepConfig {
179 pub syscntl: HpSysCntlReg,
181}
182
183impl DigitalSleepConfig {
184 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
185 Self {
186 syscntl: {
188 let mut cfg = HpSysCntlReg::default();
189
190 cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not());
191
192 cfg
193 },
194 }
195 }
196
197 fn apply(&self) {
198 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
200 w.hp_sleep_dig_pad_slp_sel()
201 .bit(self.syscntl.dig_pad_slp_sel())
202 });
203 }
204}
205
206#[derive(Clone, Copy)]
209pub struct PowerSleepConfig {
211 pub hp_sys: HpSysPower,
213 pub lp_sys_active: LpSysPower,
215 pub lp_sys_sleep: LpSysPower,
217}
218
219impl PowerSleepConfig {
220 fn defaults(pd_flags: PowerDownFlags) -> Self {
221 let mut this = Self {
222 hp_sys: HpSysPower::default(),
223 lp_sys_active: LpSysPower::default(),
224 lp_sys_sleep: LpSysPower::default(),
225 };
226 this.apply_flags(pd_flags);
227 this
228 }
229
230 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
231 self.hp_sys
233 .dig_power
234 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
235 self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem());
236 self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
237 self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon());
238 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
239
240 self.hp_sys.clk.set_i2c_iso_en(true);
241 self.hp_sys.clk.set_i2c_retention(true);
242
243 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
244
245 self.lp_sys_active
246 .clk_power
247 .set_xpd_xtal32k(xtal32k::use_xtal32k());
248 self.lp_sys_active.clk_power.set_xpd_rc32k(true);
249 self.lp_sys_active.clk_power.set_xpd_fosc(true);
250
251 self.lp_sys_sleep
252 .dig_power
253 .set_peri_pd_en(pd_flags.pd_lp_periph());
254 self.lp_sys_sleep.dig_power.set_mem_dslp(true);
255
256 self.lp_sys_sleep
257 .clk_power
258 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
259 self.lp_sys_sleep
260 .clk_power
261 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
262 self.lp_sys_sleep
263 .clk_power
264 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
265
266 self.lp_sys_sleep
267 .xtal
268 .set_xpd_xtal(pd_flags.pd_xtal().not());
269 }
270
271 fn apply(&self) {
272 PMU::regs()
276 .hp_sleep_dig_power()
277 .modify(|_, w| unsafe { w.bits(self.hp_sys.dig_power.0) });
278 PMU::regs()
279 .hp_sleep_hp_ck_power()
280 .modify(|_, w| unsafe { w.bits(self.hp_sys.clk.0) });
281 PMU::regs()
282 .hp_sleep_xtal()
283 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
284
285 PMU::regs()
287 .hp_sleep_lp_dig_power()
288 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
289 PMU::regs()
290 .hp_sleep_lp_ck_power()
291 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
292
293 PMU::regs()
295 .lp_sleep_lp_dig_power()
296 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
297 PMU::regs()
298 .lp_sleep_lp_ck_power()
299 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
300 PMU::regs()
301 .lp_sleep_xtal()
302 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
303 }
304}
305
306#[derive(Clone, Copy)]
308pub struct HpParam {
310 pub modem_wakeup_wait_cycle: u32,
312 pub analog_wait_target_cycle: u16,
314 pub digital_power_down_wait_cycle: u16,
316 pub digital_power_supply_wait_cycle: u16,
318 pub digital_power_up_wait_cycle: u16,
320 pub pll_stable_wait_cycle: u16,
322 pub modify_icg_cntl_wait_cycle: u8,
324 pub switch_icg_cntl_wait_cycle: u8,
326 pub min_slp_slow_clk_cycle: u8,
328 pub isolate_wait_cycle: u8,
330 pub reset_wait_cycle: u8,
332}
333
334#[derive(Clone, Copy)]
336pub struct LpParam {
338 pub digital_power_supply_wait_cycle: u16,
340 pub min_slp_slow_clk_cycle: u8,
342 pub analog_wait_target_cycle: u8,
344 pub digital_power_down_wait_cycle: u8,
346 pub digital_power_up_wait_cycle: u8,
348 pub isolate_wait_cycle: u8,
350 pub reset_wait_cycle: u8,
352}
353
354#[derive(Clone, Copy)]
357pub struct HpLpParam {
359 pub xtal_stable_wait_cycle: u16,
361}
362
363#[derive(Clone, Copy)]
365pub struct ParamSleepConfig {
367 pub hp_sys: HpParam,
369 pub lp_sys: LpParam,
371 pub hp_lp: HpLpParam,
373}
374impl ParamSleepConfig {
375 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
376 hp_sys: HpParam {
377 min_slp_slow_clk_cycle: 10,
378 analog_wait_target_cycle: 2419,
379 digital_power_supply_wait_cycle: 32,
380 digital_power_up_wait_cycle: 32,
381 modem_wakeup_wait_cycle: 20700,
382 pll_stable_wait_cycle: 2,
383
384 digital_power_down_wait_cycle: 0,
385 modify_icg_cntl_wait_cycle: 0,
386 switch_icg_cntl_wait_cycle: 0,
387 isolate_wait_cycle: 0,
388 reset_wait_cycle: 0,
389 },
390 lp_sys: LpParam {
391 min_slp_slow_clk_cycle: 10,
392 analog_wait_target_cycle: 23,
393 digital_power_supply_wait_cycle: 32,
394 digital_power_up_wait_cycle: 32,
395
396 digital_power_down_wait_cycle: 0,
397 isolate_wait_cycle: 0,
398 reset_wait_cycle: 0,
399 },
400 hp_lp: HpLpParam {
401 xtal_stable_wait_cycle: 30,
402 },
403 };
404
405 fn apply(&self) {
406 PMU::regs().slp_wakeup_cntl3().modify(|_, w| unsafe {
409 w.hp_min_slp_val().bits(self.hp_sys.min_slp_slow_clk_cycle);
411 w.lp_min_slp_val().bits(self.lp_sys.min_slp_slow_clk_cycle)
413 });
414
415 PMU::regs().slp_wakeup_cntl7().modify(|_, w| unsafe {
416 w.ana_wait_target()
418 .bits(self.hp_sys.analog_wait_target_cycle)
419 });
420
421 PMU::regs().power_wait_timer0().modify(|_, w| unsafe {
422 w.dg_hp_pd_wait_timer()
424 .bits(self.hp_sys.digital_power_supply_wait_cycle);
425 w.dg_hp_powerup_timer()
427 .bits(self.hp_sys.digital_power_up_wait_cycle)
428 });
429
430 PMU::regs().power_wait_timer1().modify(|_, w| unsafe {
431 w.dg_lp_pd_wait_timer()
433 .bits(self.lp_sys.digital_power_supply_wait_cycle);
434 w.dg_lp_powerup_timer()
436 .bits(self.lp_sys.digital_power_up_wait_cycle)
437 });
438
439 PMU::regs().power_wait_timer2().modify(|_, w| unsafe {
441 w.dg_hp_iso_wait_timer()
442 .bits(self.hp_sys.isolate_wait_cycle);
443 w.dg_hp_rst_wait_timer().bits(self.hp_sys.reset_wait_cycle);
444 w.dg_lp_iso_wait_timer()
445 .bits(self.lp_sys.isolate_wait_cycle);
446 w.dg_lp_rst_wait_timer().bits(self.lp_sys.reset_wait_cycle)
447 });
448
449 PMU::regs().slp_wakeup_cntl5().modify(|_, w| unsafe {
450 w.lp_ana_wait_target()
452 .bits(self.lp_sys.analog_wait_target_cycle);
453 w.modem_wait_target()
455 .bits(self.hp_sys.modem_wakeup_wait_cycle)
456 });
457 PMU::regs().power_ck_wait_cntl().modify(|_, w| unsafe {
458 w.wait_xtl_stable().bits(self.hp_lp.xtal_stable_wait_cycle);
460 w.wait_pll_stable().bits(self.hp_sys.pll_stable_wait_cycle)
462 });
463 }
464
465 fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self {
466 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
467
468 param.hp_sys.min_slp_slow_clk_cycle =
470 config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8;
471 param.hp_sys.analog_wait_target_cycle =
472 config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16;
473 param.hp_sys.digital_power_supply_wait_cycle =
474 config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
475 param.hp_sys.digital_power_up_wait_cycle =
476 config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16;
477 param.hp_sys.pll_stable_wait_cycle =
478 config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
479 param.hp_sys.isolate_wait_cycle =
480 config.us_to_fastclk(MachineConstants::HP_ISOLATE_WAIT_TIME_US) as u8;
481 param.hp_sys.reset_wait_cycle =
482 config.us_to_fastclk(MachineConstants::HP_RESET_WAIT_TIME_US) as u8;
483
484 let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags);
485
486 let modem_wakeup_wait_time_us = (config.sleep_time_adjustment
487 + MachineConstants::MODEM_STATE_SKIP_TIME_US
488 + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US)
489 .saturating_sub(hw_wait_time_us);
490 param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us);
491
492 param.lp_sys.min_slp_slow_clk_cycle =
493 config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8;
494 param.lp_sys.analog_wait_target_cycle =
495 config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8;
496 param.lp_sys.digital_power_supply_wait_cycle =
497 config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
498 param.lp_sys.digital_power_up_wait_cycle =
499 config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8;
500 param.lp_sys.isolate_wait_cycle =
501 config.us_to_fastclk(MachineConstants::LP_ISOLATE_WAIT_TIME_US) as u8;
502 param.lp_sys.reset_wait_cycle =
503 config.us_to_fastclk(MachineConstants::LP_RESET_WAIT_TIME_US) as u8;
504
505 param.hp_lp.xtal_stable_wait_cycle = if pd_xtal {
509 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
510 } else {
511 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
512 };
513
514 param
515 }
516}
517
518impl SleepTimeConfig {
519 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160;
520 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56;
521
522 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
523 let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE);
525 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
526 let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() {
527 MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US
528 } else {
529 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE)
530 };
531
532 let lp_control_wait_time_us =
534 MachineConstants::LP_ISOLATE_WAIT_TIME_US + MachineConstants::LP_RESET_WAIT_TIME_US;
535 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
536 + MachineConstants::LP_ANALOG_WAIT_TIME_US
537 + lp_clk_power_on_wait_time_us
538 + lp_wakeup_wait_time_us
539 + lp_clk_switch_time_us
540 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
541 + MachineConstants::LP_POWER_UP_WAIT_TIME_US
542 + lp_control_wait_time_us;
543
544 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
546 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
547 let hp_control_wait_time_us =
548 MachineConstants::HP_ISOLATE_WAIT_TIME_US + MachineConstants::HP_RESET_WAIT_TIME_US;
549 let hp_regdma_wait_time_us = u32::max(
550 MachineConstants::HP_REGDMA_S2M_WORK_TIME_US
551 + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US,
552 MachineConstants::HP_REGDMA_S2A_WORK_TIME_US,
553 );
554 let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
555 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US;
556
557 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
558 + u32::max(
559 hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us,
560 hp_clock_wait_time_us,
561 )
562 + hp_control_wait_time_us;
563
564 #[rustfmt::skip] const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true;
583
584 let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP {
585 (
586 MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US,
587 MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US,
588 )
589 } else {
590 (0, 0)
591 };
592
593 lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us
594 }
595}
596
597#[derive(Clone, Copy)]
599pub struct RtcSleepConfig {
601 pub deep: bool,
603 pub pd_flags: PowerDownFlags,
605}
606
607impl Default for RtcSleepConfig {
608 fn default() -> Self {
609 Self {
613 deep: false,
614 pd_flags: PowerDownFlags(0),
615 }
616 }
617}
618
619bitfield::bitfield! {
620 #[derive(Clone, Copy)]
621 pub struct PowerDownFlags(u32);
623
624 pub u32, pd_top , set_pd_top : 0;
626 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
628 pub u32, pd_modem , set_pd_modem : 2;
630 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
632 pub(crate) u32, pd_cpu, set_pd_cpu: 4;
637 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
639 pub u32, pd_mem_g0 , set_pd_mem_g0 : 6;
641 pub u32, pd_mem_g1 , set_pd_mem_g1 : 7;
643 pub u32, pd_mem_g2 , set_pd_mem_g2 : 8;
645 pub u32, pd_mem_g3 , set_pd_mem_g3 : 9;
647 pub u32, pd_xtal , set_pd_xtal : 10;
649 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
651 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
653 pub u32, pd_rc32k , set_pd_rc32k : 13;
655 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
657}
658
659impl PowerDownFlags {
660 pub fn pd_mem(self) -> bool {
662 self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3()
663 }
664
665 pub fn set_pd_mem(&mut self, value: bool) {
668 self.set_pd_mem_g0(value);
669 self.set_pd_mem_g1(value);
670 self.set_pd_mem_g2(value);
671 self.set_pd_mem_g3(value);
672 }
673}
674
675struct MachineConstants;
677impl MachineConstants {
678 const LP_MIN_SLP_TIME_US: u32 = 450;
679 const LP_WAKEUP_WAIT_CYCLE: u32 = 4;
680 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
681 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
682 const LP_CLK_SWITCH_CYCLE: u32 = 1;
683 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
684 const LP_ISOLATE_WAIT_TIME_US: u32 = 1;
685 const LP_RESET_WAIT_TIME_US: u32 = 1;
686 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
687 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
688
689 const HP_MIN_SLP_TIME_US: u32 = 450;
690 const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 35;
691 const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124;
692 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
693 const HP_ISOLATE_WAIT_TIME_US: u32 = 1;
694 const HP_RESET_WAIT_TIME_US: u32 = 1;
695 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 20;
696 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
697 const HP_REGDMA_S2M_WORK_TIME_US: u32 = 270;
698 const HP_REGDMA_S2A_WORK_TIME_US: u32 = 800;
699 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 296;
700 const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 138;
703 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
706 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 50;
707
708 const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US
709 + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US
710 + Self::LP_MIN_SLP_TIME_US;
711}
712
713impl RtcSleepConfig {
714 pub fn deep_slp(&self) -> bool {
716 self.deep
717 }
718
719 pub fn deep() -> Self {
721 Self {
723 deep: true,
724 ..Self::default()
725 }
726 }
727
728 pub(crate) fn is_deep_sleep(&self) -> bool {
729 self.deep
730 }
731
732 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
733
734 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
739 self.deep = kind == SleepKind::Deep;
740
741 let lp_slow_uses_xtal32k = cfg_select! {
742 use_xtal32k => ClockTree::with(|clocks| {
743 matches!(
744 clocks::lp_slow_clk_config(clocks),
745 Some(clocks::LpSlowClkConfig::Xtal32k)
746 )
747 }),
748 _ => false,
749 };
750
751 if self.deep {
752 self.pd_flags.set_pd_top(true);
754 self.pd_flags.set_pd_vddsdio(true);
755 self.pd_flags.set_pd_modem(true);
756 self.pd_flags.set_pd_hp_periph(true);
757 self.pd_flags.set_pd_cpu(true);
758 self.pd_flags.set_pd_mem(true);
759 self.pd_flags.set_pd_xtal(true);
760 self.pd_flags.set_pd_hp_aon(true);
761 self.pd_flags.set_pd_lp_periph(true);
762 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
763 self.pd_flags.set_pd_rc32k(true);
764 self.pd_flags.set_pd_rc_fast(true);
765 } else {
766 self.pd_flags.set_pd_xtal(true);
774 self.pd_flags.set_pd_rc_fast(true);
775 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
776 }
777 }
778
779 #[crate::ram]
785 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
786 let restore_clock_config = ClockTree::with(|clocks| {
787 let old_root = clocks.hp_root_clk();
788
789 clocks::configure_hp_root_clk(clocks, HpRootClkConfig::Xtal);
790
791 DropGuard::new((), move |_| {
793 ClockTree::with(|clocks| {
794 crate::soc::clocks::reconfigure_pll(clocks);
795 if let Some(old_root) = old_root {
796 clocks::configure_hp_root_clk(clocks, old_root);
797 }
798 });
799 })
800 });
801
802 let power = PowerSleepConfig::defaults(self.pd_flags);
805 power.apply();
806
807 let config = if self.deep {
809 SleepTimeConfig::deep_sleep()
810 } else {
811 SleepTimeConfig::light_sleep(self.pd_flags)
812 };
813
814 let mut param =
815 ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal());
816
817 if self.deep {
818 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
819 param.lp_sys.analog_wait_target_cycle =
820 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
821
822 AnalogSleepConfig::defaults_deep_sleep().apply();
823 } else {
824 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
825 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
826 }
827
828 param.apply();
829
830 LP_AON::regs()
834 .store9()
835 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
836
837 PMU::regs()
839 .slp_wakeup_cntl2()
840 .write(|w| unsafe { w.bits(wakeup_mask) });
841
842 PMU::regs().slp_wakeup_cntl1().modify(|_, w| unsafe {
844 w.slp_reject_en().bit(reject_mask != 0);
845 w.sleep_reject_ena().bits(reject_mask)
846 });
847
848 PMU::regs()
850 .slp_wakeup_cntl4()
851 .write(|w| w.slp_reject_cause_clr().bit(true));
852
853 PMU::regs().int_clr().write(|w| {
854 w.sw().clear_bit_by_one();
856 w.soc_sleep_reject().clear_bit_by_one();
858 w.soc_wakeup().clear_bit_by_one()
860 });
861
862 restore_clock_config
867 }
868
869 #[inline(always)]
873 pub(crate) fn enter_sleep(&self) -> bool {
874 request_sleep()
875 }
876
877 #[inline(always)]
879 pub(crate) fn finish_sleep(&self) {
880 }
886}