1use core::ops::Not;
2
3use crate::{
4 peripherals::{EFUSE, HP_APM, LP_AON, PMU},
5 private::DropGuard,
6 rtc_cntl::{
7 Rtc,
8 rtc::{
9 HP_CALI_DRVB,
10 HpAnalog,
11 HpSysCntlReg,
12 HpSysPower,
13 LP_CALI_DBIAS,
14 LpAnalog,
15 LpSysPower,
16 },
17 sleep::{
18 SleepKind,
19 pmu_common::{SleepTimeConfig, request_sleep},
20 },
21 },
22 soc::clocks::{self, AhbClkConfig, ClockTree, CpuClkConfig, CpuClkDivisor, HpRootClkConfig},
23};
24
25#[derive(Clone, Copy)]
27pub struct AnalogSleepConfig {
29 pub hp_sys: HpAnalog,
31 pub lp_sys_sleep: LpAnalog,
33}
34
35impl AnalogSleepConfig {
36 fn defaults_deep_sleep() -> Self {
37 Self {
38 hp_sys: {
40 let mut cfg = HpAnalog::default();
41
42 cfg.bias.set_dcdc_ccm_enb(true);
43 cfg.bias.set_dig_reg_dpcur_bias(1);
44 cfg.bias.set_dig_reg_dsfmos(4);
45 cfg.bias.set_dcm_vset(20);
46 cfg.bias.set_dcm_mode(3);
47 cfg.bias.set_discnnt_dig_rtc(false);
48 cfg.bias.set_xpd_trx(false);
49 cfg.bias.set_pd_cur(false);
50 cfg.bias.set_bias_sleep(false);
51 cfg.regulator0.set_xpd(false);
52
53 cfg
54 },
55 lp_sys_sleep: {
56 let mut cfg = LpAnalog::default();
57
58 cfg.bias.set_dcdc_ccm_enb(true);
59 cfg.bias.set_dig_reg_dpcur_bias(1);
60 cfg.bias.set_dig_reg_dsfmos(4);
61 cfg.bias.set_dcm_vset(0);
62 cfg.bias.set_dcm_mode(3);
63 cfg.bias.set_discnnt_dig_rtc(true);
64 cfg.bias.set_pd_cur(true);
65 cfg.bias.set_bias_sleep(true);
66 cfg.regulator0.set_slp_xpd(false);
67 cfg.regulator0.set_slp_dbias(0);
68 cfg.regulator0.set_xpd(false);
69 cfg.regulator0.set_dbias(3); cfg.regulator1.set_drv_b(0);
71
72 cfg
73 },
74 }
75 }
76
77 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
78 let mut this = Self {
79 hp_sys: {
81 let mut cfg = HpAnalog::default();
82
83 cfg.bias.set_dcdc_ccm_enb(true);
84 cfg.bias.set_dig_reg_dpcur_bias(1);
85 cfg.bias.set_dig_reg_dsfmos(4);
86 cfg.bias.set_dcm_mode(3);
87 cfg.bias.set_discnnt_dig_rtc(false);
88 cfg.bias.set_xpd_trx(false);
89 cfg.bias.set_xpd_bias(false);
90 cfg.bias.set_pd_cur(true);
91 cfg.bias.set_bias_sleep(true);
92 cfg.regulator0.set_xpd(true);
93 cfg.regulator0.set_dbias(0); cfg.regulator1
96 .set_drv_b(if pd_flags.pd_top() { 23 } else { 25 });
97
98 cfg
99 },
100 lp_sys_sleep: {
101 let mut cfg = LpAnalog::default();
102
103 cfg.bias.set_dcdc_ccm_enb(true);
104 cfg.bias.set_dig_reg_dpcur_bias(1);
105 cfg.bias.set_dig_reg_dsfmos(4);
106 cfg.bias.set_dcm_vset(20);
107 cfg.bias.set_dcm_mode(3);
108 cfg.bias.set_discnnt_dig_rtc(false);
109 cfg.bias.set_pd_cur(true);
110 cfg.bias.set_bias_sleep(true);
111 cfg.regulator0.set_slp_xpd(false);
112 cfg.regulator0.set_slp_dbias(0);
113 cfg.regulator0.set_xpd(true);
114 cfg.regulator0.set_dbias(3); cfg.regulator1.set_drv_b(0);
116
117 cfg
118 },
119 };
120
121 if !pd_flags.pd_xtal() {
124 this.hp_sys.bias.set_xpd_trx(true);
125 this.hp_sys.regulator1.set_drv_b(HP_CALI_DRVB);
126 this.hp_sys.bias.set_pd_cur(false);
127 this.hp_sys.bias.set_bias_sleep(false);
128
129 this.lp_sys_sleep.bias.set_pd_cur(false);
130 this.lp_sys_sleep.bias.set_bias_sleep(false);
131 this.lp_sys_sleep.regulator0.set_dbias(LP_CALI_DBIAS);
132 this.lp_sys_sleep.bias.set_dcm_vset(20);
133 } else if !pd_flags.pd_rc_fast() {
134 this.hp_sys.regulator1.set_drv_b(HP_CALI_DRVB);
135 this.lp_sys_sleep.regulator0.set_dbias(LP_CALI_DBIAS);
136 }
137
138 this
139 }
140
141 fn apply(&self) {
142 PMU::regs().hp_sleep_bias().modify(|_, w| unsafe {
146 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
147 w.sleep().bit(self.hp_sys.bias.bias_sleep());
148 w.hp_sleep_xpd_trx().bit(self.hp_sys.bias.xpd_trx());
149 w.hp_sleep_discnnt_dig_rtc()
150 .bit(self.hp_sys.bias.discnnt_dig_rtc());
151 w.hp_sleep_dcm_mode().bits(self.hp_sys.bias.dcm_mode());
152 w.hp_sleep_dcm_vset().bits(self.hp_sys.bias.dcm_vset())
153 });
154 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| {
155 w.hp_sleep_hp_regulator_xpd()
156 .bit(self.hp_sys.regulator0.xpd())
157 });
158 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| unsafe {
159 w.hp_sleep_hp_regulator_drv_b()
160 .bits(self.hp_sys.regulator1.drv_b())
161 });
162
163 PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
165 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
166 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep());
167 w.lp_sleep_discnnt_dig_rtc()
168 .bit(self.lp_sys_sleep.bias.discnnt_dig_rtc());
169 w.lp_sleep_dcm_mode()
170 .bits(self.lp_sys_sleep.bias.dcm_mode());
171 w.lp_sleep_dcm_vset()
172 .bits(self.lp_sys_sleep.bias.dcm_vset())
173 });
174 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| unsafe {
175 w.lp_sleep_lp_regulator_slp_xpd()
176 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
177 w.lp_sleep_lp_regulator_xpd()
178 .bit(self.lp_sys_sleep.regulator0.xpd());
179 w.lp_sleep_lp_regulator_slp_dbias()
180 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
181 w.lp_sleep_lp_regulator_dbias()
182 .bits(self.lp_sys_sleep.regulator0.dbias())
183 });
184 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| unsafe {
185 w.lp_sleep_lp_regulator_drv_b()
186 .bits(self.lp_sys_sleep.regulator1.drv_b())
187 });
188 }
189}
190
191#[derive(Clone, Copy)]
194pub struct DigitalSleepConfig {
196 pub syscntl: HpSysCntlReg,
198 pub sleep_icg_func: u32,
200}
201
202impl DigitalSleepConfig {
203 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
204 let mut syscntl = HpSysCntlReg::default();
206 syscntl.set_dig_pad_slp_sel(pd_flags.pd_top().not());
207 syscntl.set_dig_pause_wdt(true);
208
209 Self {
210 syscntl,
211 sleep_icg_func: 0,
212 }
213 }
214
215 fn defaults_deep_sleep() -> Self {
216 let mut syscntl = HpSysCntlReg::default();
218 syscntl.set_dig_pad_slp_sel(true);
219 syscntl.set_dig_pause_wdt(true);
220
221 Self {
222 syscntl,
223 sleep_icg_func: 0,
224 }
225 }
226
227 fn apply(&self, deep: bool) {
228 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
230 w.hp_sleep_dig_pause_wdt().bit(self.syscntl.dig_pause_wdt());
231 if !deep {
232 w.hp_sleep_dig_pad_slp_sel()
233 .bit(self.syscntl.dig_pad_slp_sel());
234 }
235 w
236 });
237 PMU::regs()
238 .hp_sleep_sysclk()
239 .modify(|_, w| w.hp_sleep_icg_sys_clock_en().bit(self.sleep_icg_func != 0));
240 PMU::regs()
241 .hp_sleep_icg_hp_func()
242 .write(|w| unsafe { w.bits(self.sleep_icg_func) });
243 }
244}
245
246#[derive(Clone, Copy)]
249pub struct PowerSleepConfig {
251 pub hp_sys: HpSysPower,
253 pub lp_sys_active: LpSysPower,
255 pub lp_sys_sleep: LpSysPower,
257}
258
259impl PowerSleepConfig {
260 fn defaults(pd_flags: PowerDownFlags) -> Self {
261 let mut hp_sys = HpSysPower::default();
263 hp_sys
264 .dig_power
265 .set_vdd_flash_mode(if pd_flags.pd_vddsdio() { 1 } else { 3 });
266 hp_sys.dig_power.set_wifi_pd_en(pd_flags.pd_modem());
267 hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
268 hp_sys.dig_power.set_aon_pd_en(pd_flags.pd_hp_aon());
269 hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
270 hp_sys.clk.set_i2c_iso_en(true);
271 hp_sys.clk.set_i2c_retention(true);
272 hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
273
274 let mut lp_sys_active = LpSysPower::default();
275 lp_sys_active
276 .clk_power
277 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
278 lp_sys_active
279 .clk_power
280 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
281 lp_sys_active.clk_power.set_xpd_fosc(true);
282
283 let mut lp_sys_sleep = LpSysPower::default();
284 lp_sys_sleep.dig_power.set_vdd_io_mode(3);
285 lp_sys_sleep
286 .dig_power
287 .set_peri_pd_en(pd_flags.pd_lp_periph());
288 lp_sys_sleep
289 .clk_power
290 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
291 lp_sys_sleep
292 .clk_power
293 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
294 lp_sys_sleep
295 .clk_power
296 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
297 lp_sys_sleep.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
298
299 Self {
300 hp_sys,
301 lp_sys_active,
302 lp_sys_sleep,
303 }
304 }
305
306 fn apply(&self, deep: bool) {
307 PMU::regs()
311 .hp_sleep_dig_power()
312 .write(|w| unsafe { w.bits(self.hp_sys.dig_power.0) });
313 PMU::regs()
314 .hp_sleep_hp_ck_power()
315 .write(|w| unsafe { w.bits(self.hp_sys.clk.0) });
316 PMU::regs().hp_sleep_xtal().modify(|_, w| {
317 w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal());
318 w.hp_sleep_xpd_xtalx2().bit(self.hp_sys.xtal.xpd_xtalx2())
319 });
320
321 let mem_mask = if deep { 0 } else { 1 };
323 PMU::regs().power_pd_mem_mask().modify(|_, w| unsafe {
324 w.pd_hp_mem0_mask().bits(mem_mask);
325 w.pd_hp_mem1_mask().bits(mem_mask);
326 w.pd_hp_mem2_mask().bits(mem_mask)
327 });
328
329 PMU::regs()
331 .hp_sleep_lp_dig_power()
332 .write(|w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
333 PMU::regs()
334 .hp_sleep_lp_ck_power()
335 .write(|w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
336
337 PMU::regs()
339 .lp_sleep_lp_dig_power()
340 .write(|w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
341 PMU::regs()
342 .lp_sleep_lp_ck_power()
343 .write(|w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
344 PMU::regs().lp_sleep_xtal().modify(|_, w| {
345 w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal());
346 w.lp_sleep_xpd_xtalx2()
347 .bit(self.lp_sys_sleep.xtal.xpd_xtalx2())
348 });
349 }
350}
351
352#[derive(Clone, Copy)]
354pub struct HpParam {
356 pub modem_wakeup_wait_cycle: u32,
358 pub analog_wait_target_cycle: u16,
360 pub digital_power_supply_wait_cycle: u16,
362 pub digital_power_up_wait_cycle: u16,
364 pub pll_stable_wait_cycle: u16,
366 pub min_slp_slow_clk_cycle: u8,
368 pub isolate_wait_cycle: u8,
370 pub reset_wait_cycle: u8,
372}
373
374#[derive(Clone, Copy)]
376pub struct LpParam {
378 pub digital_power_supply_wait_cycle: u16,
380 pub min_slp_slow_clk_cycle: u8,
382 pub analog_wait_target_cycle: u8,
384 pub digital_power_up_wait_cycle: u8,
386 pub isolate_wait_cycle: u8,
388 pub reset_wait_cycle: u8,
390}
391
392#[derive(Clone, Copy)]
395pub struct HpLpParam {
397 pub xtal_stable_wait_cycle: u16,
401}
402
403#[derive(Clone, Copy)]
405pub struct ParamSleepConfig {
407 pub hp_sys: HpParam,
409 pub lp_sys: LpParam,
411 pub hp_lp: HpLpParam,
413}
414
415impl ParamSleepConfig {
416 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
417 hp_sys: HpParam {
418 min_slp_slow_clk_cycle: 10,
419 analog_wait_target_cycle: 2419,
420 digital_power_supply_wait_cycle: 32,
421 digital_power_up_wait_cycle: 32,
422 modem_wakeup_wait_cycle: 0,
423 pll_stable_wait_cycle: 2,
424 isolate_wait_cycle: 0,
425 reset_wait_cycle: 0,
426 },
427 lp_sys: LpParam {
428 min_slp_slow_clk_cycle: 10,
429 analog_wait_target_cycle: 23,
430 digital_power_supply_wait_cycle: 32,
431 digital_power_up_wait_cycle: 32,
432 isolate_wait_cycle: 0,
433 reset_wait_cycle: 0,
434 },
435 hp_lp: HpLpParam {
436 xtal_stable_wait_cycle: 30,
437 },
438 };
439
440 fn apply(&self) {
441 PMU::regs().slp_wakeup_cntl3().modify(|_, w| unsafe {
444 w.hp_min_slp_val().bits(self.hp_sys.min_slp_slow_clk_cycle);
445 w.lp_min_slp_val().bits(self.lp_sys.min_slp_slow_clk_cycle)
446 });
447
448 PMU::regs().slp_wakeup_cntl7().modify(|_, w| unsafe {
449 w.ana_wait_target()
450 .bits(self.hp_sys.analog_wait_target_cycle)
451 });
452
453 PMU::regs().power_wait_timer0().modify(|_, w| unsafe {
454 w.dg_hp_pd_wait_timer()
455 .bits(self.hp_sys.digital_power_supply_wait_cycle);
456 w.dg_hp_powerup_timer()
457 .bits(self.hp_sys.digital_power_up_wait_cycle)
458 });
459
460 PMU::regs().power_wait_timer1().modify(|_, w| unsafe {
461 w.dg_lp_pd_wait_timer()
462 .bits(self.lp_sys.digital_power_supply_wait_cycle);
463 w.dg_lp_powerup_timer()
464 .bits(self.lp_sys.digital_power_up_wait_cycle)
465 });
466
467 PMU::regs().power_wait_timer2().modify(|_, w| unsafe {
468 w.dg_hp_iso_wait_timer()
469 .bits(self.hp_sys.isolate_wait_cycle);
470 w.dg_hp_rst_wait_timer().bits(self.hp_sys.reset_wait_cycle);
471 w.dg_lp_iso_wait_timer()
472 .bits(self.lp_sys.isolate_wait_cycle);
473 w.dg_lp_rst_wait_timer().bits(self.lp_sys.reset_wait_cycle)
474 });
475
476 PMU::regs().slp_wakeup_cntl5().modify(|_, w| unsafe {
477 w.lp_ana_wait_target()
478 .bits(self.lp_sys.analog_wait_target_cycle);
479 w.modem_wait_target()
480 .bits(self.hp_sys.modem_wakeup_wait_cycle)
481 });
482
483 PMU::regs().power_ck_wait_cntl().modify(|_, w| unsafe {
484 w.wait_xtl_stable().bits(self.hp_lp.xtal_stable_wait_cycle);
485 w.wait_pll_stable().bits(self.hp_sys.pll_stable_wait_cycle)
486 });
487 }
488
489 fn defaults(config: SleepTimeConfig, xpd_xtal: bool) -> Self {
490 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
491
492 param.hp_sys.min_slp_slow_clk_cycle =
494 config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US) as u8;
495 param.hp_sys.analog_wait_target_cycle =
496 config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US) as u16;
497 param.hp_sys.digital_power_supply_wait_cycle =
498 config.us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
499 param.hp_sys.digital_power_up_wait_cycle =
500 config.us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US) as u16;
501 param.hp_sys.pll_stable_wait_cycle =
502 config.us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
503 param.hp_sys.isolate_wait_cycle =
504 config.us_to_fastclk(MachineConstants::HP_ISOLATE_WAIT_TIME_US) as u8;
505 param.hp_sys.reset_wait_cycle =
506 config.us_to_fastclk(MachineConstants::HP_RESET_WAIT_TIME_US) as u8;
507
508 param.lp_sys.min_slp_slow_clk_cycle =
509 config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US) as u8;
510 param.lp_sys.analog_wait_target_cycle =
511 config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US) as u8;
512 param.lp_sys.digital_power_supply_wait_cycle =
513 config.us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
514 param.lp_sys.digital_power_up_wait_cycle =
515 config.us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US) as u8;
516 param.lp_sys.isolate_wait_cycle =
517 config.us_to_fastclk(MachineConstants::LP_ISOLATE_WAIT_TIME_US) as u8;
518 param.lp_sys.reset_wait_cycle =
519 config.us_to_fastclk(MachineConstants::LP_RESET_WAIT_TIME_US) as u8;
520
521 param.hp_lp.xtal_stable_wait_cycle = if xpd_xtal {
522 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
523 } else {
524 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
525 };
526
527 param
528 }
529}
530
531impl SleepTimeConfig {
532 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 96;
533 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 9;
534
535 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
536 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
540 let lp_clk_power_on_wait_time_us =
541 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE);
542 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
543 + MachineConstants::LP_ANALOG_WAIT_TIME_US
544 + lp_clk_power_on_wait_time_us
545 + lp_clk_switch_time_us
546 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
547 + MachineConstants::LP_POWER_UP_WAIT_TIME_US;
548
549 let hp_regdma_s2a_work_time_us = if pd_flags.pd_top() {
551 MachineConstants::HP_REGDMA_S2A_WORK_TIME_PD_TOP_US
552 } else {
553 MachineConstants::HP_REGDMA_S2A_WORK_TIME_PU_TOP_US
554 };
555 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
556 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
557 let hp_control_wait_time_us =
558 MachineConstants::HP_ISOLATE_WAIT_TIME_US + MachineConstants::HP_RESET_WAIT_TIME_US;
559 let hp_regdma_wait_time_us = u32::max(
560 MachineConstants::HP_REGDMA_S2M_WORK_TIME_US
561 + MachineConstants::HP_REGDMA_M2A_WORK_TIME_US,
562 hp_regdma_s2a_work_time_us,
563 );
564 let hp_clock_wait_time_us = if pd_flags.pd_xtal() {
565 MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
566 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US
567 } else {
568 MachineConstants::HP_PLL_WAIT_STABLE_TIME_US
569 };
570 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
571 + hp_digital_power_up_wait_time_us
572 + hp_regdma_wait_time_us
573 + hp_clock_wait_time_us
574 + hp_control_wait_time_us;
575
576 lp_hw_wait_time_us + hp_hw_wait_time_us
577 }
578}
579
580#[derive(Clone, Copy)]
582pub struct RtcSleepConfig {
584 pub deep: bool,
586 pub pd_flags: PowerDownFlags,
588}
589
590impl Default for RtcSleepConfig {
591 fn default() -> Self {
592 Self {
593 deep: false,
594 pd_flags: PowerDownFlags(0),
595 }
596 }
597}
598
599bitfield::bitfield! {
600 #[derive(Clone, Copy)]
601 pub struct PowerDownFlags(u32);
603
604 pub u32, pd_top , set_pd_top : 0;
606 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
608 pub u32, pd_modem , set_pd_modem : 2;
610 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
612 pub(crate) u32, pd_cpu, set_pd_cpu: 4;
617 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
619 pub u32, pd_xtal , set_pd_xtal : 10;
621 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
623 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
625 pub u32, pd_rc32k , set_pd_rc32k : 13;
627 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
629}
630
631struct MachineConstants;
633impl MachineConstants {
634 const LP_MIN_SLP_TIME_US: u32 = 450;
635 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
636 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
637 const LP_CLK_SWITCH_CYCLE: u32 = 1;
638 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
639 const LP_ISOLATE_WAIT_TIME_US: u32 = 1;
640 const LP_RESET_WAIT_TIME_US: u32 = 1;
641 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
642 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
643
644 const HP_MIN_SLP_TIME_US: u32 = 450;
645 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
646 const HP_ISOLATE_WAIT_TIME_US: u32 = 1;
647 const HP_RESET_WAIT_TIME_US: u32 = 1;
648 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
649 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
650 const HP_REGDMA_S2M_WORK_TIME_US: u32 = 172;
651 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 278;
652 const HP_REGDMA_S2A_WORK_TIME_PD_TOP_US: u32 = 0;
653 const HP_REGDMA_S2A_WORK_TIME_PU_TOP_US: u32 = 390;
654 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
655 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 1;
656}
657
658impl RtcSleepConfig {
659 pub fn deep_slp(&self) -> bool {
661 self.deep
662 }
663
664 pub fn deep() -> Self {
666 Self {
667 deep: true,
668 ..Self::default()
669 }
670 }
671
672 pub(crate) fn is_deep_sleep(&self) -> bool {
673 self.deep
674 }
675
676 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
677
678 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
683 self.deep = kind == SleepKind::Deep;
684
685 let lp_slow_uses_xtal32k = cfg_select! {
686 use_xtal32k => ClockTree::with(|clocks| {
687 matches!(
688 clocks::lp_slow_clk_config(clocks),
689 Some(clocks::LpSlowClkConfig::Xtal32k)
690 )
691 }),
692 _ => false,
693 };
694
695 if self.deep {
696 self.pd_flags.set_pd_top(true);
699 self.pd_flags.set_pd_vddsdio(true);
700 self.pd_flags.set_pd_modem(true);
701 self.pd_flags.set_pd_hp_periph(true);
702 self.pd_flags.set_pd_cpu(true);
703 self.pd_flags.set_pd_hp_aon(true);
704 self.pd_flags.set_pd_xtal(true);
705 self.pd_flags.set_pd_lp_periph(true);
706 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
707 self.pd_flags.set_pd_rc32k(true);
708 self.pd_flags.set_pd_rc_fast(true);
709 } else {
710 self.pd_flags.set_pd_xtal(true);
715 self.pd_flags.set_pd_rc_fast(true);
716 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
717 }
718 }
719
720 #[crate::ram]
726 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
727 let restore_clock_config = ClockTree::with(|clocks| {
729 let old_root = clocks.hp_root_clk();
730 let old_cpu = clocks.cpu_clk();
731 let old_ahb = clocks.ahb_clk();
732
733 clocks::configure_hp_root_clk(clocks, HpRootClkConfig::Xtal);
734 clocks::configure_cpu_clk(clocks, CpuClkConfig::new(CpuClkDivisor::_0));
735 clocks::configure_ahb_clk(clocks, AhbClkConfig::new(0));
736
737 DropGuard::new((), move |_| {
738 ClockTree::with(|clocks| {
739 crate::soc::clocks::reconfigure_pll(clocks);
740 if let Some(old_ahb) = old_ahb {
743 clocks::configure_ahb_clk(clocks, old_ahb);
744 }
745 if let Some(old_cpu) = old_cpu {
746 clocks::configure_cpu_clk(clocks, old_cpu);
747 }
748 if let Some(old_root) = old_root {
749 clocks::configure_hp_root_clk(clocks, old_root);
750 }
751 });
752 })
753 });
754
755 let power = PowerSleepConfig::defaults(self.pd_flags);
758 power.apply(self.deep);
759
760 let config = if self.deep {
762 SleepTimeConfig::deep_sleep()
763 } else {
764 SleepTimeConfig::light_sleep(self.pd_flags)
765 };
766
767 let mut param = ParamSleepConfig::defaults(config, power.hp_sys.xtal.xpd_xtal());
768
769 if self.deep {
770 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
771 param.lp_sys.analog_wait_target_cycle =
772 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
773
774 DigitalSleepConfig::defaults_deep_sleep().apply(true);
775 AnalogSleepConfig::defaults_deep_sleep().apply();
776 } else {
777 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply(false);
778 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
779 }
780
781 param.apply();
782
783 LP_AON::regs()
787 .store8()
788 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
789
790 PMU::regs()
792 .slp_wakeup_cntl2()
793 .write(|w| unsafe { w.bits(wakeup_mask) });
794
795 PMU::regs().slp_wakeup_cntl1().modify(|_, w| unsafe {
797 w.slp_reject_en().bit(reject_mask != 0);
798 w.sleep_reject_ena().bits(reject_mask)
799 });
800
801 PMU::regs().int_clr().write(|w| {
802 w.soc_wakeup().clear_bit_by_one();
804 w.soc_sleep_reject().clear_bit_by_one()
806 });
807
808 PMU::regs()
810 .slp_wakeup_cntl4()
811 .write(|w| w.slp_reject_cause_clr().bit(true));
812
813 restore_clock_config
814 }
815
816 #[inline(always)]
820 pub(crate) fn enter_sleep(&self) -> bool {
821 request_sleep()
822 }
823
824 #[inline(always)]
826 pub(crate) fn finish_sleep(&self) {
827 while EFUSE::regs().status().read().state().bits() != 1 {}
831
832 HP_APM::regs().func_ctrl().write(|w| unsafe { w.bits(0) });
834
835 }
838}