1use core::ops::Not;
3
4use crate::{
5 peripherals::{LP_SYS as LP_AON, PMU},
6 private::DropGuard,
7 rtc_cntl::{
8 Rtc,
9 rtc::{HpAnalog, HpSysCntlReg, HpSysPower, LpAnalog, LpSysPower},
10 sleep::{
11 SleepKind,
12 pmu_common::{SleepTimeConfig, request_sleep},
13 },
14 },
15 soc::{
16 clocks::{self, ClockTree, CpuRootClkConfig},
17 xtal32k,
18 },
19};
20
21const HP_CALI_DBIAS: u8 = 26;
22const LP_CALI_DBIAS: u8 = 26;
23
24#[derive(Clone, Copy)]
26pub struct AnalogSleepConfig {
27 pub hp_sys: HpAnalog,
29 pub lp_sys_sleep: LpAnalog,
31}
32
33impl AnalogSleepConfig {
34 fn defaults_deep_sleep() -> Self {
35 Self {
37 hp_sys: {
38 let mut cfg = HpAnalog::default();
39 cfg.bias.set_pd_cur(true);
40 cfg.bias.set_bias_sleep(true);
41 cfg.regulator0.set_xpd(false);
42 cfg.bias.set_dbg_atten(0);
43 cfg
44 },
45 lp_sys_sleep: {
46 let mut cfg = LpAnalog::default();
47 cfg.regulator1.set_drv_b(0);
48 cfg.bias.set_pd_cur(true);
49 cfg.bias.set_bias_sleep(true);
50 cfg.regulator0.set_slp_xpd(false);
51 cfg.regulator0.set_slp_dbias(0);
52 cfg.regulator0.set_xpd(true);
53 cfg.bias.set_dbg_atten(12);
54 cfg.regulator0.set_dbias(23);
55 cfg
56 },
57 }
58 }
59
60 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
61 let mut this = Self {
62 hp_sys: {
63 let mut cfg = HpAnalog::default();
64 cfg.regulator1.set_drv_b(0);
65 cfg.bias.set_pd_cur(true);
66 cfg.bias.set_bias_sleep(true);
67 cfg.regulator0.set_xpd(true);
68 cfg.bias.set_dbg_atten(0);
69 cfg.regulator0.set_dbias(1);
70 cfg
71 },
72 lp_sys_sleep: {
73 let mut cfg = LpAnalog::default();
74 cfg.regulator1.set_drv_b(0);
75 cfg.bias.set_pd_cur(true);
76 cfg.bias.set_bias_sleep(true);
77 cfg.regulator0.set_slp_xpd(false);
78 cfg.regulator0.set_slp_dbias(0);
79 cfg.regulator0.set_xpd(true);
80 cfg.bias.set_dbg_atten(0);
81 cfg.regulator0.set_dbias(12);
82 cfg
83 },
84 };
85
86 if !pd_flags.pd_xtal() {
87 this.hp_sys.bias.set_pd_cur(false);
88 this.lp_sys_sleep.bias.set_pd_cur(false);
89 }
90
91 if !pd_flags.pd_xtal() || !pd_flags.pd_rc_fast() {
92 this.hp_sys.bias.set_dbg_atten(0);
93 this.hp_sys.regulator0.set_dbias(HP_CALI_DBIAS);
94 this.lp_sys_sleep.bias.set_dbg_atten(0);
95 this.lp_sys_sleep.regulator0.set_dbias(LP_CALI_DBIAS);
96 }
97
98 this
99 }
100
101 fn apply(&self) {
102 PMU::regs().hp_sleep_bias().modify(|_, w| unsafe {
104 w.hp_sleep_dbg_atten().bits(self.hp_sys.bias.dbg_atten());
105 w.hp_sleep_pd_cur().bit(self.hp_sys.bias.pd_cur());
106 w.sleep().bit(self.hp_sys.bias.bias_sleep())
107 });
108 PMU::regs().hp_sleep_hp_regulator0().modify(|_, w| unsafe {
109 w.hp_sleep_hp_regulator_slp_mem_xpd()
110 .bit(self.hp_sys.regulator0.slp_mem_xpd());
111 w.hp_sleep_hp_regulator_slp_logic_xpd()
112 .bit(self.hp_sys.regulator0.slp_logic_xpd());
113 w.hp_sleep_hp_regulator_xpd()
114 .bit(self.hp_sys.regulator0.xpd());
115 w.hp_sleep_hp_regulator_slp_logic_dbias()
116 .bits(self.hp_sys.regulator0.slp_logic_dbias());
117 w.hp_sleep_hp_regulator_dbias()
118 .bits(self.hp_sys.regulator0.dbias())
119 });
120 PMU::regs().hp_sleep_hp_regulator1().modify(|_, w| unsafe {
121 w.hp_sleep_hp_regulator_drv_b()
122 .bits(self.hp_sys.regulator1.drv_b())
123 });
124
125 PMU::regs().lp_sleep_bias().modify(|_, w| unsafe {
126 w.lp_sleep_dbg_atten()
127 .bits(self.lp_sys_sleep.bias.dbg_atten());
128 w.lp_sleep_pd_cur().bit(self.lp_sys_sleep.bias.pd_cur());
129 w.sleep().bit(self.lp_sys_sleep.bias.bias_sleep())
130 });
131 PMU::regs().lp_sleep_lp_regulator0().modify(|_, w| unsafe {
132 w.lp_sleep_lp_regulator_slp_xpd()
133 .bit(self.lp_sys_sleep.regulator0.slp_xpd());
134 w.lp_sleep_lp_regulator_xpd()
135 .bit(self.lp_sys_sleep.regulator0.xpd());
136 w.lp_sleep_lp_regulator_slp_dbias()
137 .bits(self.lp_sys_sleep.regulator0.slp_dbias());
138 w.lp_sleep_lp_regulator_dbias()
139 .bits(self.lp_sys_sleep.regulator0.dbias())
140 });
141 PMU::regs().lp_sleep_lp_regulator1().modify(|_, w| unsafe {
142 w.lp_sleep_lp_regulator_drv_b()
143 .bits(self.lp_sys_sleep.regulator1.drv_b())
144 });
145 }
146}
147
148#[derive(Clone, Copy)]
150pub struct DigitalSleepConfig {
151 pub syscntl: HpSysCntlReg,
153}
154
155impl DigitalSleepConfig {
156 fn defaults_deep_sleep(pd_flags: PowerDownFlags) -> Self {
157 let mut syscntl = HpSysCntlReg::default();
158 syscntl.set_dig_pad_slp_sel(false);
159 syscntl.set_lp_pad_hold_all(true);
160 syscntl.set_hp_pad_hold_all(true);
161 syscntl.set_dig_pause_wdt(true);
162 syscntl.set_c_channel(!pd_flags.pd_top());
163 Self { syscntl }
164 }
165
166 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
167 let mut syscntl = HpSysCntlReg::default();
168 syscntl.set_dig_pad_slp_sel(!pd_flags.pd_top());
169 syscntl.set_lp_pad_hold_all(pd_flags.pd_top());
170 syscntl.set_hp_pad_hold_all(pd_flags.pd_top());
171 syscntl.set_dig_pause_wdt(true);
172 syscntl.set_c_channel(!pd_flags.pd_top());
173 Self { syscntl }
174 }
175
176 fn apply(&self) {
177 PMU::regs().hp_sleep_hp_sys_cntl().modify(|_, w| {
178 w.hp_sleep_c_channel().bit(self.syscntl.c_channel());
179 w.hp_sleep_dig_pad_slp_sel()
180 .bit(self.syscntl.dig_pad_slp_sel());
181 w.hp_sleep_lp_pad_hold_all()
182 .bit(self.syscntl.lp_pad_hold_all());
183 w.hp_sleep_hp_pad_hold_all()
184 .bit(self.syscntl.hp_pad_hold_all());
185 w.hp_sleep_dig_pause_wdt().bit(self.syscntl.dig_pause_wdt());
186 w.hp_sleep_dig_cpu_stall().bit(true)
187 });
188 }
189}
190
191#[derive(Clone, Copy)]
193pub struct PowerSleepConfig {
194 pub hp_sys: HpSysPower,
196 pub lp_sys_active: LpSysPower,
198 pub lp_sys_sleep: LpSysPower,
200}
201
202impl PowerSleepConfig {
203 fn defaults(pd_flags: PowerDownFlags) -> Self {
204 let mut this = Self {
205 hp_sys: HpSysPower::default(),
206 lp_sys_active: LpSysPower::default(),
207 lp_sys_sleep: LpSysPower::default(),
208 };
209 this.apply_flags(pd_flags);
210 this
211 }
212
213 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
214 self.hp_sys
216 .dig_power
217 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
218 self.hp_sys
219 .dig_power
220 .set_hp_alive_pd_en(pd_flags.pd_mem() || pd_flags.pd_hp_aon());
221 self.hp_sys
222 .dig_power
223 .set_modem_top_pd_en(pd_flags.pd_modem());
224 self.hp_sys.dig_power.set_hp_cnnt_pd_en(pd_flags.pd_modem());
225 self.hp_sys.dig_power.set_hp_cpu_pd_en(pd_flags.pd_cpu());
226 self.hp_sys.dig_power.set_modem_pwr_pd_en(pd_flags.pd_mem());
227 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
228
229 self.hp_sys.clk.set_i2c_iso_en(true);
230 self.hp_sys.clk.set_i2c_retention(true);
231
232 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
233
234 self.lp_sys_active
235 .clk_power
236 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
237 self.lp_sys_active
238 .clk_power
239 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
240 self.lp_sys_active.clk_power.set_xpd_fosc(true);
241
242 self.lp_sys_sleep
243 .dig_power
244 .set_peri_pd_en(pd_flags.pd_lp_periph());
245
246 self.lp_sys_sleep
247 .clk_power
248 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
249 self.lp_sys_sleep
250 .clk_power
251 .set_xpd_rc32k(pd_flags.pd_rc32k().not());
252 self.lp_sys_sleep
253 .clk_power
254 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
255
256 self.lp_sys_sleep
257 .xtal
258 .set_xpd_xtal(pd_flags.pd_xtal().not());
259 }
260
261 fn apply(&self, dslp: bool) {
262 PMU::regs()
264 .hp_sleep_dig_power()
265 .modify(|_, w| unsafe { w.bits(self.hp_sys.dig_power.0) });
266 PMU::regs()
267 .hp_sleep_hp_ck_power()
268 .modify(|_, w| unsafe { w.bits(self.hp_sys.clk.0) });
269 PMU::regs()
270 .hp_sleep_xtal()
271 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
272
273 set_memory_power_on_mask(!dslp);
274
275 PMU::regs()
276 .hp_sleep_lp_dig_power()
277 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.dig_power.0) });
278 PMU::regs()
279 .hp_sleep_lp_ck_power()
280 .modify(|_, w| unsafe { w.bits(self.lp_sys_active.clk_power.0) });
281
282 PMU::regs()
283 .lp_sleep_lp_dig_power()
284 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.dig_power.0) });
285 PMU::regs()
286 .lp_sleep_lp_ck_power()
287 .modify(|_, w| unsafe { w.bits(self.lp_sys_sleep.clk_power.0) });
288 PMU::regs()
289 .lp_sleep_xtal()
290 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
291 }
292}
293
294fn set_memory_power_on_mask(keep_on: bool) {
295 let mask = if keep_on { 0x1f } else { 0 };
297 PMU::regs().power_pd_mem_mask().modify(|_, w| unsafe {
298 w.pd_hp_mem0_mask().bits(mask);
299 w.pd_hp_mem1_mask().bits(mask);
300 w.pd_hp_mem2_mask().bits(mask)
301 });
302 PMU::regs().power_pd_mem_cntl().modify(|r, w| unsafe {
303 let mut pu = r.force_hp_mem_pu().bits();
304 if keep_on {
305 pu |= 1 << 3;
306 } else {
307 pu &= !(1 << 3);
308 }
309 w.force_hp_mem_pu().bits(pu)
310 });
311}
312
313#[derive(Clone, Copy, Default)]
315pub struct HpParam {
316 analog_wait_target_cycle: u16,
317 digital_power_supply_wait_cycle: u16,
318 digital_power_up_wait_cycle: u16,
319 pll_stable_wait_cycle: u16,
320 modem_wakeup_wait_cycle: u32,
321 isolate_wait_cycle: u8,
322 reset_wait_cycle: u8,
323 min_slp_slow_clk_cycle: u8,
324}
325
326#[derive(Clone, Copy, Default)]
328pub struct LpParam {
329 digital_power_supply_wait_cycle: u16,
330 min_slp_slow_clk_cycle: u8,
331 analog_wait_target_cycle: u8,
332 digital_power_up_wait_cycle: u8,
333 isolate_wait_cycle: u8,
334 reset_wait_cycle: u8,
335}
336
337#[derive(Clone, Copy, Default)]
339pub struct HpLpParam {
340 xtal_stable_wait_cycle: u16,
341}
342
343#[derive(Clone, Copy)]
345pub struct ParamSleepConfig {
346 hp_sys: HpParam,
347 lp_sys: LpParam,
348 hp_lp: HpLpParam,
349}
350
351impl ParamSleepConfig {
352 fn apply(&self) {
353 PMU::regs().slp_wakeup_cntl3().modify(|_, w| unsafe {
355 w.hp_min_slp_val().bits(self.hp_sys.min_slp_slow_clk_cycle);
356 w.lp_min_slp_val().bits(self.lp_sys.min_slp_slow_clk_cycle)
357 });
358
359 PMU::regs().slp_wakeup_cntl7().modify(|_, w| unsafe {
360 w.ana_wait_target()
361 .bits(self.hp_sys.analog_wait_target_cycle)
362 });
363
364 PMU::regs().power_wait_timer0().modify(|_, w| unsafe {
365 w.dg_hp_pd_wait_timer()
366 .bits(self.hp_sys.digital_power_supply_wait_cycle);
367 w.dg_hp_powerup_timer()
368 .bits(self.hp_sys.digital_power_up_wait_cycle)
369 });
370
371 PMU::regs().power_wait_timer1().modify(|_, w| unsafe {
372 w.dg_lp_pd_wait_timer()
373 .bits(self.lp_sys.digital_power_supply_wait_cycle);
374 w.dg_lp_powerup_timer()
375 .bits(self.lp_sys.digital_power_up_wait_cycle)
376 });
377
378 PMU::regs().power_wait_timer2().modify(|_, w| unsafe {
379 w.dg_hp_iso_wait_timer()
380 .bits(self.hp_sys.isolate_wait_cycle);
381 w.dg_hp_rst_wait_timer().bits(self.hp_sys.reset_wait_cycle);
382 w.dg_lp_iso_wait_timer()
383 .bits(self.lp_sys.isolate_wait_cycle);
384 w.dg_lp_rst_wait_timer().bits(self.lp_sys.reset_wait_cycle)
385 });
386
387 PMU::regs().slp_wakeup_cntl5().modify(|_, w| unsafe {
388 w.lp_ana_wait_target()
389 .bits(self.lp_sys.analog_wait_target_cycle);
390 w.modem_wait_target()
391 .bits(self.hp_sys.modem_wakeup_wait_cycle)
392 });
393
394 PMU::regs().power_ck_wait_cntl().modify(|_, w| unsafe {
395 w.pmu_wait_xtl_stable()
396 .bits(self.hp_lp.xtal_stable_wait_cycle);
397 w.pmu_wait_pll_stable()
398 .bits(self.hp_sys.pll_stable_wait_cycle)
399 });
400 }
401
402 fn defaults(config: SleepTimeConfig, pd_flags: PowerDownFlags, xpd_xtal: bool) -> Self {
403 let hw_wait_time_us = config.pmu_sleep_calculate_hw_wait_time(pd_flags);
404 let modem_wakeup_wait_time_us = (config.sleep_time_adjustment
405 + MachineConstants::MODEM_STATE_SKIP_TIME_US
406 + MachineConstants::HP_REGDMA_RF_ON_WORK_TIME_US)
407 .saturating_sub(hw_wait_time_us);
408
409 let hp_sys = HpParam {
410 min_slp_slow_clk_cycle: config.us_to_slowclk(MachineConstants::HP_MIN_SLP_TIME_US)
411 as u8,
412 analog_wait_target_cycle: config.us_to_fastclk(MachineConstants::HP_ANALOG_WAIT_TIME_US)
413 as u16,
414 digital_power_supply_wait_cycle: config
415 .us_to_fastclk(MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US)
416 as u16,
417 digital_power_up_wait_cycle: config
418 .us_to_fastclk(MachineConstants::HP_POWER_UP_WAIT_TIME_US)
419 as u16,
420 pll_stable_wait_cycle: config
421 .us_to_fastclk(MachineConstants::HP_PLL_WAIT_STABLE_TIME_US)
422 as u16,
423 modem_wakeup_wait_cycle: config.us_to_fastclk(modem_wakeup_wait_time_us),
424 isolate_wait_cycle: config.us_to_fastclk(MachineConstants::HP_ISOLATE_WAIT_TIME_US)
425 as u8,
426 reset_wait_cycle: config.us_to_fastclk(MachineConstants::HP_RESET_WAIT_TIME_US) as u8,
427 };
428
429 let lp_sys = LpParam {
430 min_slp_slow_clk_cycle: config.us_to_slowclk(MachineConstants::LP_MIN_SLP_TIME_US)
431 as u8,
432 analog_wait_target_cycle: config.us_to_slowclk(MachineConstants::LP_ANALOG_WAIT_TIME_US)
433 as u8,
434 digital_power_supply_wait_cycle: config
435 .us_to_fastclk(MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US)
436 as u16,
437 digital_power_up_wait_cycle: config
438 .us_to_fastclk(MachineConstants::LP_POWER_UP_WAIT_TIME_US)
439 as u8,
440 isolate_wait_cycle: config.us_to_fastclk(MachineConstants::LP_ISOLATE_WAIT_TIME_US)
441 as u8,
442 reset_wait_cycle: config.us_to_fastclk(MachineConstants::LP_RESET_WAIT_TIME_US) as u8,
443 };
444
445 let xtal_stable_wait_cycle = if xpd_xtal {
446 config.us_to_slowclk(MachineConstants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
447 } else {
448 config.us_to_fastclk(MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
449 };
450
451 Self {
452 hp_sys,
453 lp_sys,
454 hp_lp: HpLpParam {
455 xtal_stable_wait_cycle,
456 },
457 }
458 }
459}
460
461impl SleepTimeConfig {
462 pub(crate) const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 160;
463 pub(crate) const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 780;
464
465 pub(crate) fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
466 let lp_wakeup_wait_time_us = self.slowclk_to_us(MachineConstants::LP_WAKEUP_WAIT_CYCLE);
467 let lp_clk_switch_time_us = self.slowclk_to_us(MachineConstants::LP_CLK_SWITCH_CYCLE);
468 let lp_clk_power_on_wait_time_us =
469 self.slowclk_to_us(MachineConstants::LP_CLK_POWER_ON_WAIT_CYCLE);
470 let lp_control_wait_time_us =
471 MachineConstants::LP_ISOLATE_WAIT_TIME_US + MachineConstants::LP_RESET_WAIT_TIME_US;
472
473 let lp_hw_wait_time_us = MachineConstants::LP_MIN_SLP_TIME_US
474 + MachineConstants::LP_ANALOG_WAIT_TIME_US
475 + lp_clk_power_on_wait_time_us
476 + lp_wakeup_wait_time_us
477 + lp_clk_switch_time_us
478 + MachineConstants::LP_POWER_SUPPLY_WAIT_TIME_US
479 + MachineConstants::LP_POWER_UP_WAIT_TIME_US
480 + lp_control_wait_time_us;
481
482 let hp_digital_power_up_wait_time_us = MachineConstants::HP_POWER_SUPPLY_WAIT_TIME_US
483 + MachineConstants::HP_POWER_UP_WAIT_TIME_US;
484 let hp_control_wait_time_us =
485 MachineConstants::HP_ISOLATE_WAIT_TIME_US + MachineConstants::HP_RESET_WAIT_TIME_US;
486 let hp_regdma_wait_time_us = 0;
488 let hp_clock_wait_time_us = if pd_flags.pd_xtal() {
489 MachineConstants::HP_XTAL_WAIT_STABLE_TIME_US
490 + MachineConstants::HP_PLL_WAIT_STABLE_TIME_US
491 } else {
492 MachineConstants::HP_PLL_WAIT_STABLE_TIME_US
493 };
494
495 let hp_hw_wait_time_us = MachineConstants::HP_ANALOG_WAIT_TIME_US
496 + hp_digital_power_up_wait_time_us
497 + hp_regdma_wait_time_us
498 + hp_clock_wait_time_us
499 + hp_control_wait_time_us;
500
501 lp_hw_wait_time_us + hp_hw_wait_time_us
502 }
503}
504
505#[derive(Clone, Copy)]
507pub struct RtcSleepConfig {
508 pub deep: bool,
510 pub pd_flags: PowerDownFlags,
512}
513
514impl Default for RtcSleepConfig {
515 fn default() -> Self {
516 Self {
517 deep: false,
518 pd_flags: PowerDownFlags(0),
519 }
520 }
521}
522
523bitfield::bitfield! {
524 #[derive(Clone, Copy)]
525 pub struct PowerDownFlags(u32);
527
528 pub u32, pd_top , set_pd_top : 0;
530 pub u32, pd_vddsdio , set_pd_vddsdio : 1;
532 pub u32, pd_modem , set_pd_modem : 2;
534 pub u32, pd_hp_periph, set_pd_hp_periph: 3;
536 pub(crate) u32, pd_cpu, set_pd_cpu: 4;
541 pub u32, pd_hp_aon , set_pd_hp_aon : 5;
543 pub u32, pd_mem_g0 , set_pd_mem_g0 : 6;
545 pub u32, pd_mem_g1 , set_pd_mem_g1 : 7;
547 pub u32, pd_mem_g2 , set_pd_mem_g2 : 8;
549 pub u32, pd_mem_g3 , set_pd_mem_g3 : 9;
551 pub u32, pd_xtal , set_pd_xtal : 10;
553 pub u32, pd_rc_fast , set_pd_rc_fast : 11;
555 pub u32, pd_xtal32k , set_pd_xtal32k : 12;
557 pub u32, pd_rc32k , set_pd_rc32k : 13;
559 pub u32, pd_lp_periph, set_pd_lp_periph: 14;
561}
562
563impl PowerDownFlags {
564 pub fn pd_mem(self) -> bool {
566 self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3()
567 }
568
569 pub fn set_pd_mem(&mut self, value: bool) {
571 self.set_pd_mem_g0(value);
572 self.set_pd_mem_g1(value);
573 self.set_pd_mem_g2(value);
574 self.set_pd_mem_g3(value);
575 }
576}
577
578struct MachineConstants;
580impl MachineConstants {
581 const LP_MIN_SLP_TIME_US: u32 = 450;
582 const LP_WAKEUP_WAIT_CYCLE: u32 = 4;
583 const LP_ANALOG_WAIT_TIME_US: u32 = 154;
584 const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
585 const LP_CLK_SWITCH_CYCLE: u32 = 1;
586 const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
587 const LP_ISOLATE_WAIT_TIME_US: u32 = 1;
588 const LP_RESET_WAIT_TIME_US: u32 = 1;
589 const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
590 const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
591
592 const HP_MIN_SLP_TIME_US: u32 = 450;
593 const HP_ANALOG_WAIT_TIME_US: u32 = 154;
594 const HP_ISOLATE_WAIT_TIME_US: u32 = 1;
595 const HP_RESET_WAIT_TIME_US: u32 = 1;
596 const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
597 const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
598 const HP_REGDMA_M2A_WORK_TIME_US: u32 = 278;
599 const HP_REGDMA_RF_ON_WORK_TIME_US: u32 = 70;
600 const HP_SYSTEM_DFS_UP_WORK_TIME_US: u32 = 124;
601 const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
602 const HP_PLL_WAIT_STABLE_TIME_US: u32 = 50;
603
604 const MODEM_STATE_SKIP_TIME_US: u32 = Self::HP_REGDMA_M2A_WORK_TIME_US
605 + Self::HP_SYSTEM_DFS_UP_WORK_TIME_US
606 + Self::LP_MIN_SLP_TIME_US;
607}
608
609impl RtcSleepConfig {
610 pub fn deep_slp(&self) -> bool {
612 self.deep
613 }
614
615 pub fn deep() -> Self {
617 Self {
618 deep: true,
619 ..Self::default()
620 }
621 }
622
623 pub(crate) fn is_deep_sleep(&self) -> bool {
624 self.deep
625 }
626
627 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {}
628
629 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
634 self.deep = kind == SleepKind::Deep;
635
636 let lp_slow_uses_xtal32k = cfg_select! {
637 use_xtal32k => ClockTree::with(|clocks| {
638 matches!(
639 clocks::lp_slow_clk_config(clocks),
640 Some(clocks::LpSlowClkConfig::Xtal32k)
641 )
642 }),
643 _ => false,
644 };
645
646 if self.deep {
647 self.pd_flags.set_pd_top(true);
648 self.pd_flags.set_pd_vddsdio(true);
649 self.pd_flags.set_pd_modem(true);
650 self.pd_flags.set_pd_hp_periph(true);
651 self.pd_flags.set_pd_cpu(true);
652 self.pd_flags.set_pd_mem(true);
653 self.pd_flags.set_pd_xtal(true);
654 self.pd_flags.set_pd_hp_aon(true);
655 self.pd_flags.set_pd_lp_periph(true);
656 self.pd_flags.set_pd_xtal32k(!lp_slow_uses_xtal32k);
657 self.pd_flags.set_pd_rc32k(true);
658 self.pd_flags.set_pd_rc_fast(true);
659 } else {
660 self.pd_flags.set_pd_xtal(true);
661 self.pd_flags.set_pd_rc_fast(true);
662 self.pd_flags
663 .set_pd_xtal32k(!lp_slow_uses_xtal32k && !xtal32k::use_xtal32k());
664 }
665 }
666
667 #[crate::ram]
673 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) -> impl Sized {
674 let restore_clock_config = ClockTree::with(|clocks| {
675 let old_cpu_root_clk = clocks.cpu_root_clk();
676
677 clocks::configure_cpu_root_clk(clocks, CpuRootClkConfig::Xtal);
678
679 DropGuard::new((), move |_| {
680 ClockTree::with(|clocks| {
681 if let Some(old) = old_cpu_root_clk {
682 clocks::configure_cpu_root_clk(clocks, old);
683 }
684 });
685 })
686 });
687
688 let power = PowerSleepConfig::defaults(self.pd_flags);
689 power.apply(self.deep);
690
691 let config = if self.deep {
692 SleepTimeConfig::deep_sleep()
693 } else {
694 SleepTimeConfig::light_sleep(self.pd_flags)
695 };
696
697 let mut param =
698 ParamSleepConfig::defaults(config, self.pd_flags, power.hp_sys.xtal.xpd_xtal());
699
700 if self.deep {
701 const PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US: u32 = 500;
702 param.lp_sys.analog_wait_target_cycle =
703 config.us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US) as u8;
704
705 DigitalSleepConfig::defaults_deep_sleep(self.pd_flags).apply();
706 AnalogSleepConfig::defaults_deep_sleep().apply();
707 } else {
708 AnalogSleepConfig::defaults_light_sleep(self.pd_flags).apply();
709 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
710 }
711
712 param.apply();
713
714 LP_AON::regs()
716 .lp_store(8)
717 .modify(|r, w| unsafe { w.bits(r.bits() & !0x01 | self.deep as u32) });
718
719 PMU::regs()
720 .slp_wakeup_cntl2()
721 .write(|w| unsafe { w.bits(wakeup_mask) });
722
723 PMU::regs()
724 .slp_wakeup_cntl1()
725 .write(|w| unsafe { w.sleep_reject_ena().bits(reject_mask) });
726
727 PMU::regs()
728 .slp_wakeup_cntl4()
729 .write(|w| w.slp_reject_cause_clr().bit(true));
730
731 PMU::regs().int_clr().write(|w| {
732 w.sw().clear_bit_by_one();
733 w.soc_sleep_reject().clear_bit_by_one();
734 w.soc_wakeup().clear_bit_by_one()
735 });
736
737 PMU::regs()
738 .slp_wakeup_cntl0()
739 .write(|w| w.slp_reject_en().bit(reject_mask != 0));
740
741 restore_clock_config
742 }
743
744 #[inline(always)]
748 pub(crate) fn enter_sleep(&self) -> bool {
749 request_sleep()
750 }
751
752 #[inline(always)]
754 pub(crate) fn finish_sleep(&self) {}
755}