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(false);
39 cfg.bias.set_bias_sleep(false);
40 cfg.regulator0.set_xpd(false);
41 cfg.bias.set_dbg_atten(0);
42
43 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(9); cfg.regulator0.set_dbias(15); 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() {
98 this.hp_sys.bias.set_pd_cur(false);
99 this.hp_sys.bias.set_bias_sleep(false);
100 this.hp_sys.bias.set_dbg_atten(0);
101 this.hp_sys.regulator0.set_dbias(28); 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(28); }
108
109 this
110 }
111
112 fn apply(&self) {
113 PMU::regs().hp_sleep_bias().modify(|_, w| unsafe {
117 w.hp_sleep_dbg_atten().bits(self.hp_sys.bias.dbg_atten());
119 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
121 w.sleep().bit(self.hp_sys.bias.bias_sleep())
123 });
124 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| unsafe {
125 w.hp_sleep_hp_regulator_xpd()
127 .bit(self.hp_sys.regulator0.xpd());
128 w.hp_sleep_hp_regulator_dbias()
130 .bits(self.hp_sys.regulator0.dbias())
131 });
132 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| unsafe {
133 w.hp_sleep_hp_regulator_drv_b()
135 .bits(self.hp_sys.regulator1.drv_b())
136 });
137
138 PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
140 w.lp_sleep_dbg_atten()
142 .bits(self.lp_sys_sleep.bias.dbg_atten());
143 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
145 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep())
147 });
148
149 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| unsafe {
150 w.lp_sleep_lp_regulator_slp_xpd()
152 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
153 w.lp_sleep_lp_regulator_xpd()
155 .bit(self.lp_sys_sleep.regulator0.xpd());
156 w.lp_sleep_lp_regulator_slp_dbias()
158 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
159 w.lp_sleep_lp_regulator_dbias()
161 .bits(self.lp_sys_sleep.regulator0.dbias())
162 });
163
164 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| unsafe {
165 w.lp_sleep_lp_regulator_drv_b()
167 .bits(self.lp_sys_sleep.regulator1.drv_b())
168 });
169 }
170}
171
172#[derive(Clone, Copy)]
175pub struct DigitalSleepConfig {
177 pub syscntl: HpSysCntlReg,
179}
180
181impl DigitalSleepConfig {
182 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
183 Self {
184 syscntl: {
186 let mut cfg = HpSysCntlReg::default();
187
188 cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not());
189
190 cfg
191 },
192 }
193 }
194
195 fn apply(&self) {
196 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
198 w.hp_sleep_dig_pad_slp_sel()
199 .bit(self.syscntl.dig_pad_slp_sel())
200 });
201 }
202}
203
204#[derive(Clone, Copy)]
207pub struct PowerSleepConfig {
209 pub hp_sys: HpSysPower,
211 pub lp_sys_active: LpSysPower,
213 pub lp_sys_sleep: LpSysPower,
215}
216
217impl PowerSleepConfig {
218 fn defaults(pd_flags: PowerDownFlags) -> Self {
219 let mut this = Self {
220 hp_sys: HpSysPower::default(),
221 lp_sys_active: LpSysPower::default(),
222 lp_sys_sleep: LpSysPower::default(),
223 };
224 this.apply_flags(pd_flags);
225 this
226 }
227
228 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
229 self.hp_sys
231 .dig_power
232 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
233 self.hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem());
234 self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
235 self.hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon());
236 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
237
238 self.hp_sys.clk.set_i2c_iso_en(true);
239 self.hp_sys.clk.set_i2c_retention(true);
240
241 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
242
243 self.lp_sys_active
244 .clk_power
245 .set_xpd_xtal32k(xtal32k::use_xtal32k());
246 self.lp_sys_active.clk_power.set_xpd_rc32k(true);
247 self.lp_sys_active.clk_power.set_xpd_fosc(true);
248
249 self.lp_sys_sleep
250 .dig_power
251 .set_peri_pd_en(pd_flags.pd_lp_periph());
252 self.lp_sys_sleep.dig_power.set_mem_dslp(true);
253
254 self.lp_sys_sleep
255 .clk_power
256 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
257 self.lp_sys_sleep
258 .clk_power
259 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
260 self.lp_sys_sleep
261 .clk_power
262 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
263
264 self.lp_sys_sleep
265 .xtal
266 .set_xpd_xtal(pd_flags.pd_xtal().not());
267 }
268
269 fn apply(&self) {
270 PMU::regs()
274 .hp_sleep_dig_power()
275 .modify(|_, w| unsafe { w.bits(self.hp_sys.dig_power.0) });
276 PMU::regs()
277 .hp_sleep_hp_ck_power()
278 .modify(|_, w| unsafe { w.bits(self.hp_sys.clk.0) });
279 PMU::regs()
280 .hp_sleep_xtal()
281 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
282
283 PMU::regs()
285 .hp_sleep_lp_dig_power()
286 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
287 PMU::regs()
288 .hp_sleep_lp_ck_power()
289 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
290
291 PMU::regs()
293 .lp_sleep_lp_dig_power()
294 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
295 PMU::regs()
296 .lp_sleep_lp_ck_power()
297 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
298 PMU::regs()
299 .lp_sleep_xtal()
300 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
301 }
302}
303
304#[derive(Clone, Copy)]
306pub struct HpParam {
308 pub modem_wakeup_wait_cycle: u32,
310 pub analog_wait_target_cycle: u16,
312 pub digital_power_down_wait_cycle: u16,
314 pub digital_power_supply_wait_cycle: u16,
316 pub digital_power_up_wait_cycle: u16,
318 pub pll_stable_wait_cycle: u16,
320 pub modify_icg_cntl_wait_cycle: u8,
322 pub switch_icg_cntl_wait_cycle: u8,
324 pub min_slp_slow_clk_cycle: u8,
326 pub isolate_wait_cycle: u8,
328 pub reset_wait_cycle: u8,
330}
331
332#[derive(Clone, Copy)]
334pub struct LpParam {
336 pub digital_power_supply_wait_cycle: u16,
338 pub min_slp_slow_clk_cycle: u8,
340 pub analog_wait_target_cycle: u8,
342 pub digital_power_down_wait_cycle: u8,
344 pub digital_power_up_wait_cycle: u8,
346 pub isolate_wait_cycle: u8,
348 pub reset_wait_cycle: u8,
350}
351
352#[derive(Clone, Copy)]
355pub struct HpLpParam {
357 pub xtal_stable_wait_cycle: u16,
359}
360
361#[derive(Clone, Copy)]
363pub struct ParamSleepConfig {
365 pub hp_sys: HpParam,
367 pub lp_sys: LpParam,
369 pub hp_lp: HpLpParam,
371}
372impl ParamSleepConfig {
373 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
374 hp_sys: HpParam {
375 min_slp_slow_clk_cycle: 10,
376 analog_wait_target_cycle: 2419,
377 digital_power_supply_wait_cycle: 32,
378 digital_power_up_wait_cycle: 32,
379 modem_wakeup_wait_cycle: 20700,
380 pll_stable_wait_cycle: 2,
381
382 digital_power_down_wait_cycle: 0,
383 modify_icg_cntl_wait_cycle: 0,
384 switch_icg_cntl_wait_cycle: 0,
385 isolate_wait_cycle: 0,
386 reset_wait_cycle: 0,
387 },
388 lp_sys: LpParam {
389 min_slp_slow_clk_cycle: 10,
390 analog_wait_target_cycle: 23,
391 digital_power_supply_wait_cycle: 32,
392 digital_power_up_wait_cycle: 32,
393
394 digital_power_down_wait_cycle: 0,
395 isolate_wait_cycle: 0,
396 reset_wait_cycle: 0,
397 },
398 hp_lp: HpLpParam {
399 xtal_stable_wait_cycle: 30,
400 },
401 };
402
403 fn apply(&self) {
404 PMU::regs().slp_wakeup_cntl3().modify(|_, w| unsafe {
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| unsafe {
414 w.ana_wait_target()
416 .bits(self.hp_sys.analog_wait_target_cycle)
417 });
418
419 PMU::regs().power_wait_timer0().modify(|_, w| unsafe {
420 w.dg_hp_pd_wait_timer()
422 .bits(self.hp_sys.digital_power_supply_wait_cycle);
423 w.dg_hp_powerup_timer()
425 .bits(self.hp_sys.digital_power_up_wait_cycle)
426 });
427
428 PMU::regs().power_wait_timer1().modify(|_, w| unsafe {
429 w.dg_lp_pd_wait_timer()
431 .bits(self.lp_sys.digital_power_supply_wait_cycle);
432 w.dg_lp_powerup_timer()
434 .bits(self.lp_sys.digital_power_up_wait_cycle)
435 });
436
437 PMU::regs().power_wait_timer2().modify(|_, w| unsafe {
439 w.dg_hp_iso_wait_timer()
440 .bits(self.hp_sys.isolate_wait_cycle);
441 w.dg_hp_rst_wait_timer().bits(self.hp_sys.reset_wait_cycle);
442 w.dg_lp_iso_wait_timer()
443 .bits(self.lp_sys.isolate_wait_cycle);
444 w.dg_lp_rst_wait_timer().bits(self.lp_sys.reset_wait_cycle)
445 });
446
447 PMU::regs().slp_wakeup_cntl5().modify(|_, w| unsafe {
448 w.lp_ana_wait_target()
450 .bits(self.lp_sys.analog_wait_target_cycle);
451 w.modem_wait_target()
453 .bits(self.hp_sys.modem_wakeup_wait_cycle)
454 });
455 PMU::regs().power_ck_wait_cntl().modify(|_, w| unsafe {
456 w.wait_xtl_stable().bits(self.hp_lp.xtal_stable_wait_cycle);
458 w.wait_pll_stable().bits(self.hp_sys.pll_stable_wait_cycle)
460 });
461 }
462
463 fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, pd_xtal: bool) -> Self {
464 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
465
466 param.hp_sys.min_slp_slow_clk_cycle =
468 config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8;
469 param.hp_sys.analog_wait_target_cycle =
470 config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16;
471 param.hp_sys.digital_power_supply_wait_cycle =
472 config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
473 param.hp_sys.digital_power_up_wait_cycle =
474 config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16;
475 param.hp_sys.pll_stable_wait_cycle =
476 config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
477 param.hp_sys.isolate_wait_cycle =
478 config.us_to_fastclk(MachineConstants::HP_ISOLATE_WAIT_TIME_US) as u8;
479 param.hp_sys.reset_wait_cycle =
480 config.us_to_fastclk(MachineConstants::HP_RESET_WAIT_TIME_US) as u8;
481
482 let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags);
483
484 let modem_wakeup_wait_time_us = (config.sleep_time_adjustment
485 + MachineConstants::MODEM_STATE_SKIP_TIME_US
486 + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US)
487 .saturating_sub(hw_wait_time_us);
488 param.hp_sys.modem_wakeup_wait_cycle = config.us_to_fastclk(modem_wakeup_wait_time_us);
489
490 param.lp_sys.min_slp_slow_clk_cycle =
491 config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8;
492 param.lp_sys.analog_wait_target_cycle =
493 config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8;
494 param.lp_sys.digital_power_supply_wait_cycle =
495 config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
496 param.lp_sys.digital_power_up_wait_cycle =
497 config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8;
498 param.lp_sys.isolate_wait_cycle =
499 config.us_to_fastclk(MachineConstants::LP_ISOLATE_WAIT_TIME_US) as u8;
500 param.lp_sys.reset_wait_cycle =
501 config.us_to_fastclk(MachineConstants::LP_RESET_WAIT_TIME_US) as u8;
502
503 param.hp_lp.xtal_stable_wait_cycle = if pd_xtal {
507 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
508 } else {
509 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
510 };
511
512 param
513 }
514}
515
516impl SleepTimeConfig {
517 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160;
518 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 56;
519
520 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
521 let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE);
523 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
524 let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() {
525 MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US
526 } else {
527 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE)
528 };
529
530 let lp_control_wait_time_us =
532 MachineConstants::LP_ISOLATE_WAIT_TIME_US + MachineConstants::LP_RESET_WAIT_TIME_US;
533 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
534 + MachineConstants::LP_ANALOG_WAIT_TIME_US
535 + lp_clk_power_on_wait_time_us
536 + lp_wakeup_wait_time_us
537 + lp_clk_switch_time_us
538 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
539 + MachineConstants::LP_POWER_UP_WAIT_TIME_US
540 + lp_control_wait_time_us;
541
542 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
544 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
545 let hp_control_wait_time_us =
546 MachineConstants::HP_ISOLATE_WAIT_TIME_US + MachineConstants::HP_RESET_WAIT_TIME_US;
547 let hp_regdma_wait_time_us = u32::max(
548 MachineConstants::HP_REGDMA_S2M_WORK_TIME_US
549 + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US,
550 MachineConstants::HP_REGDMA_S2A_WORK_TIME_US,
551 );
552 let hp_clock_wait_time_us = MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
553 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US;
554
555 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
556 + u32::max(
557 hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us,
558 hp_clock_wait_time_us,
559 )
560 + hp_control_wait_time_us;
561
562 #[rustfmt::skip] const CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP: bool = true;
581
582 let (rf_on_protect_time_us, sync_time_us) = if CONFIG_ESP_RADIO_ENHANCED_LIGHT_SLEEP {
583 (
584 MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US,
585 MachineConstants::HP_CLOCK_DOMAIN_SYNC_TIME_US,
586 )
587 } else {
588 (0, 0)
589 };
590
591 lp_hw_wait_time_us + hp_hw_wait_time_us + sync_time_us + rf_on_protect_time_us
592 }
593}
594
595#[derive(Clone, Copy)]
597pub struct RtcSleepConfig {
599 pub deep: bool,
601 pub pd_flags: PowerDownFlags,
603}
604
605impl Default for RtcSleepConfig {
606 fn default() -> Self {
607 Self {
611 deep: false,
612 pd_flags: PowerDownFlags(0),
613 }
614 }
615}
616
617bitfield::bitfield! {
618 #[derive(Clone, Copy)]
619 pub struct PowerDownFlags(u32);
621
622 pub u32, pd_top , set_pd_top : 0;
624 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
626 pub u32, pd_modem , set_pd_modem : 2;
628 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
630 pub(crate) u32, pd_cpu, set_pd_cpu: 4;
635 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
637 pub u32, pd_mem_g0 , set_pd_mem_g0 : 6;
639 pub u32, pd_mem_g1 , set_pd_mem_g1 : 7;
641 pub u32, pd_mem_g2 , set_pd_mem_g2 : 8;
643 pub u32, pd_mem_g3 , set_pd_mem_g3 : 9;
645 pub u32, pd_xtal , set_pd_xtal : 10;
647 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
649 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
651 pub u32, pd_rc32k , set_pd_rc32k : 13;
653 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
655}
656
657impl PowerDownFlags {
658 pub fn pd_mem(self) -> bool {
660 self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3()
661 }
662
663 pub fn set_pd_mem(&mut self, value: bool) {
666 self.set_pd_mem_g0(value);
667 self.set_pd_mem_g1(value);
668 self.set_pd_mem_g2(value);
669 self.set_pd_mem_g3(value);
670 }
671}
672
673struct MachineConstants;
675impl MachineConstants {
676 const LP_MIN_SLP_TIME_US: u32 = 450;
677 const LP_WAKEUP_WAIT_CYCLE: u32 = 4;
678 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
679 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
680 const LP_CLK_SWITCH_CYCLE: u32 = 1;
681 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
682 const LP_ISOLATE_WAIT_TIME_US: u32 = 1;
683 const LP_RESET_WAIT_TIME_US: u32 = 1;
684 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
685 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
686
687 const HP_MIN_SLP_TIME_US: u32 = 450;
688 const HP_CLOCK_DOMAIN_SYNC_TIME_US: u32 = 2;
689 const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124;
690 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
691 const HP_ISOLATE_WAIT_TIME_US: u32 = 1;
692 const HP_RESET_WAIT_TIME_US: u32 = 1;
693 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
694 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
695 const HP_REGDMA_S2M_WORK_TIME_US: u32 = 287;
696 const HP_REGDMA_S2A_WORK_TIME_US: u32 = 720;
697 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 430;
698 const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 68;
701 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
704 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 50;
705
706 const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US
707 + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US
708 + Self::LP_MIN_SLP_TIME_US;
709}
710
711impl RtcSleepConfig {
712 pub fn deep_slp(&self) -> bool {
714 self.deep
715 }
716
717 pub fn deep() -> Self {
719 Self {
721 deep: true,
722 ..Self::default()
723 }
724 }
725
726 pub(crate) fn is_deep_sleep(&self) -> bool {
727 self.deep
728 }
729
730 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
731
732 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
737 self.deep = kind == SleepKind::Deep;
738
739 let lp_slow_uses_xtal32k = cfg_select! {
740 use_xtal32k => ClockTree::with(|clocks| {
741 matches!(
742 clocks::lp_slow_clk_config(clocks),
743 Some(clocks::LpSlowClkConfig::Xtal32k)
744 )
745 }),
746 _ => false,
747 };
748
749 if self.deep {
750 self.pd_flags.set_pd_top(true);
752 self.pd_flags.set_pd_vddsdio(true);
753 self.pd_flags.set_pd_modem(true);
754 self.pd_flags.set_pd_hp_periph(true);
755 self.pd_flags.set_pd_cpu(true);
756 self.pd_flags.set_pd_mem(true);
757 self.pd_flags.set_pd_xtal(true);
758 self.pd_flags.set_pd_hp_aon(true);
759 self.pd_flags.set_pd_lp_periph(true);
760 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
761 self.pd_flags.set_pd_rc32k(true);
762 self.pd_flags.set_pd_rc_fast(true);
763 } else {
764 self.pd_flags.set_pd_xtal(true);
772 self.pd_flags.set_pd_rc_fast(true);
773 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
774 }
775 }
776
777 #[crate::ram]
783 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
784 let restore_clock_config = ClockTree::with(|clocks| {
785 let old_root = clocks.hp_root_clk();
786
787 clocks::configure_hp_root_clk(clocks, HpRootClkConfig::Xtal);
788
789 DropGuard::new((), move |_| {
791 ClockTree::with(|clocks| {
792 crate::soc::clocks::reconfigure_pll(clocks);
793 if let Some(old_root) = old_root {
794 clocks::configure_hp_root_clk(clocks, old_root);
795 }
796 });
797 })
798 });
799
800 let power = PowerSleepConfig::defaults(self.pd_flags);
803 power.apply();
804
805 let config = if self.deep {
807 SleepTimeConfig::deep_sleep()
808 } else {
809 SleepTimeConfig::light_sleep(self.pd_flags)
810 };
811
812 let mut param =
813 ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal());
814
815 if self.deep {
816 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
817 param.lp_sys.analog_wait_target_cycle =
818 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
819
820 AnalogSleepConfig::defaults_deep_sleep().apply();
821 } else {
822 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
823 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
824 }
825
826 param.apply();
827
828 LP_AON::regs()
832 .store9()
833 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
834
835 PMU::regs()
837 .slp_wakeup_cntl2()
838 .write(|w| unsafe { w.bits(wakeup_mask) });
839
840 PMU::regs().slp_wakeup_cntl1().modify(|_, w| unsafe {
842 w.slp_reject_en().bit(reject_mask != 0);
843 w.sleep_reject_ena().bits(reject_mask)
844 });
845
846 PMU::regs()
848 .slp_wakeup_cntl4()
849 .write(|w| w.slp_reject_cause_clr().bit(true));
850
851 PMU::regs().int_clr().write(|w| {
852 w.sw().clear_bit_by_one();
854 w.soc_sleep_reject().clear_bit_by_one();
856 w.soc_wakeup().clear_bit_by_one()
858 });
859
860 restore_clock_config
865 }
866
867 #[inline(always)]
871 pub(crate) fn enter_sleep(&self) -> bool {
872 request_sleep()
873 }
874
875 #[inline(always)]
877 pub(crate) fn finish_sleep(&self) {
878 }
884}