1use core::ops::Not;
2
3use crate::{
4 clock::RtcClock,
5 gpio::{AnyPin, Input, InputConfig, Pull, RtcPin},
6 peripherals::APB_SARADC,
7 rtc_cntl::{
8 Rtc,
9 rtc::{HpSysCntlReg, HpSysPower, LpSysPower},
10 sleep::{Ext1WakeupSource, TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel},
11 },
12 soc::clocks::{ClockTree, CpuClkConfig, HpRootClkConfig, TimgCalibrationClockConfig},
13};
14
15impl WakeSource for TimerWakeupSource {
16 fn apply(
17 &self,
18 rtc: &Rtc<'_>,
19 triggers: &mut WakeTriggers,
20 _sleep_config: &mut RtcSleepConfig,
21 ) {
22 triggers.set_timer(true);
23
24 let lp_timer = unsafe { &*esp32h2::LP_TIMER::ptr() };
25 let ticks = crate::clock::us_to_rtc_ticks(self.duration.as_micros() as u64);
27 let now = rtc.time_since_boot_raw();
29 let time_in_ticks = now + ticks;
30 unsafe {
31 lp_timer.tar0_high().write(|w| {
32 w.main_timer_tar_high0()
33 .bits(((time_in_ticks >> 32) & 0xffff) as u16)
34 });
35 lp_timer.tar0_low().write(|w| {
36 w.main_timer_tar_low0()
37 .bits((time_in_ticks & 0xffffffff) as u32)
38 });
39 lp_timer
40 .int_clr()
41 .write(|w| w.soc_wakeup_int_clr().set_bit());
42 lp_timer
43 .tar0_high()
44 .modify(|_, w| w.main_timer_tar_en0().set_bit());
45 }
46 }
47}
48
49impl Ext1WakeupSource<'_, '_> {
50 fn wakeup_pins() -> u8 {
52 unsafe { lp_aon().ext_wakeup_cntl().read().ext_wakeup_sel().bits() }
53 }
54
55 fn wake_io_reset() {
57 fn uninit_pin(pin: impl RtcPin, wakeup_pins: u8) {
58 if wakeup_pins & (1 << pin.rtc_number()) != 0 {
59 pin.rtcio_pad_hold(false);
60 pin.degrade().init_gpio();
61 }
62 }
63
64 let wakeup_pins = Ext1WakeupSource::wakeup_pins();
65 for_each_lp_function! {
66 (($_rtc:ident, LP_GPIOn, $n:literal), $gpio:ident) => {
67 uninit_pin(unsafe { $crate::peripherals::$gpio::steal() }, wakeup_pins);
68 };
69 }
70 }
71}
72
73impl WakeSource for Ext1WakeupSource<'_, '_> {
74 fn apply(
75 &self,
76 _rtc: &Rtc<'_>,
77 triggers: &mut WakeTriggers,
78 sleep_config: &mut RtcSleepConfig,
79 ) {
80 triggers.set_ext1(true);
81 sleep_config.need_pd_top = true;
82
83 let mut pins = self.pins.borrow_mut();
85 let mut pin_mask = 0u8;
86 let mut level_mask = 0u8;
87 for (pin, level) in pins.iter_mut() {
88 pin_mask |= 1 << pin.rtc_number();
89 level_mask |= match level {
90 WakeupLevel::High => 1 << pin.rtc_number(),
91 WakeupLevel::Low => 0,
92 };
93
94 pin.rtcio_pad_hold(true);
95 Input::new(
96 unsafe { AnyPin::steal(pin.number()) },
97 InputConfig::default().with_pull(match level {
98 WakeupLevel::High => Pull::Down,
99 WakeupLevel::Low => Pull::Up,
100 }),
101 );
102 }
103
104 unsafe {
105 lp_aon()
107 .ext_wakeup_cntl()
108 .modify(|_, w| w.ext_wakeup_status_clr().set_bit());
109
110 lp_aon().ext_wakeup_cntl().modify(|r, w| {
112 w.ext_wakeup_sel()
113 .bits(r.ext_wakeup_sel().bits() | pin_mask)
114 .ext_wakeup_lv()
115 .bits(r.ext_wakeup_lv().bits() & !pin_mask | level_mask)
116 });
117 }
118 }
119}
120
121impl Drop for Ext1WakeupSource<'_, '_> {
122 fn drop(&mut self) {
123 let mut pins = self.pins.borrow_mut();
125 for (pin, _level) in pins.iter_mut() {
126 pin.rtcio_pad_hold(false);
127 unsafe { AnyPin::steal(pin.number()) }.init_gpio();
128 }
129 }
130}
131
132#[derive(Clone, Copy)]
134pub struct AnalogSleepConfig {
139 pub regulator_xpd: bool,
141}
142
143impl AnalogSleepConfig {
144 fn defaults_deep_sleep() -> Self {
145 Self {
146 regulator_xpd: false,
148 }
149 }
150
151 fn defaults_light_sleep() -> Self {
152 Self {
153 regulator_xpd: true,
155 }
156 }
157
158 fn apply(&self) {
159 unsafe {
161 pmu().hp_sleep_hp_regulator0().modify(|_, w| {
162 w.hp_sleep_hp_regulator_xpd() .bit(self.regulator_xpd)
164 });
165 }
166 }
167}
168
169#[derive(Clone, Copy)]
172pub struct DigitalSleepConfig {
174 pub syscntl: HpSysCntlReg,
176 pub icg_func: u32,
178 pub deep_sleep: bool,
180}
181
182impl DigitalSleepConfig {
183 fn defaults_light_sleep(pd_flags: PowerDownFlags) -> Self {
184 Self {
185 syscntl: {
187 let mut cfg = HpSysCntlReg::default();
188
189 cfg.set_dig_pad_slp_sel(pd_flags.pd_top().not());
190
191 cfg
192 },
193 icg_func: 0xffff_ffff, deep_sleep: false,
195 }
196 }
197
198 fn defaults_deep_sleep() -> Self {
199 Self {
200 syscntl: HpSysCntlReg::default(),
202 icg_func: 0,
203 deep_sleep: true,
204 }
205 }
206
207 fn apply(&self) {
208 unsafe {
210 pmu().hp_sleep_sysclk().modify(|_, w| {
211 w.hp_sleep_icg_sys_clock_en().bit(self.icg_func != 0) });
213 pmu().hp_sleep_icg_hp_func().modify(|_, w| {
214 w.hp_sleep_dig_icg_func_en().bits(self.icg_func) });
216 if !self.deep_sleep {
217 pmu().hp_sleep_hp_sys_cntl().modify(|_, w| {
218 w.hp_sleep_dig_pad_slp_sel()
219 .bit(self.syscntl.dig_pad_slp_sel()) });
221 }
222 };
223 }
224}
225
226#[derive(Clone, Copy)]
229pub struct PowerSleepConfig {
231 pub hp_sys: HpSysPower,
233 pub lp_sys_active: LpSysPower,
235 pub lp_sys_sleep: LpSysPower,
237}
238
239impl PowerSleepConfig {
240 fn defaults(pd_flags: PowerDownFlags) -> Self {
241 let mut this = Self {
242 hp_sys: HpSysPower::default(),
243 lp_sys_active: LpSysPower::default(),
244 lp_sys_sleep: LpSysPower::default(),
245 };
246 this.apply_flags(pd_flags);
247 this
248 }
249
250 fn apply_flags(&mut self, pd_flags: PowerDownFlags) {
251 self.hp_sys
253 .dig_power
254 .set_vdd_spi_pd_en(pd_flags.pd_vddsdio());
255 self.hp_sys.dig_power.set_modem_pd_en(pd_flags.pd_modem());
256 self.hp_sys.dig_power.set_cpu_pd_en(pd_flags.pd_cpu());
257 self.hp_sys.dig_power.set_top_pd_en(pd_flags.pd_top());
258
259 self.hp_sys.clk.set_xpd_bbpll(false);
260
261 self.hp_sys.xtal.set_xpd_xtal(pd_flags.pd_xtal().not());
262
263 self.lp_sys_active.clk_power.set_xpd_xtal32k(true);
264 self.lp_sys_active.clk_power.set_xpd_fosc(true);
265
266 self.lp_sys_sleep.dig_power.set_mem_dslp(true);
267 self.lp_sys_sleep.dig_power.set_vddbat_mode(0);
268 self.lp_sys_sleep.dig_power.set_bod_source_sel(true);
269
270 self.lp_sys_sleep
271 .clk_power
272 .set_xpd_xtal32k(pd_flags.pd_xtal32k().not());
273 self.lp_sys_sleep
274 .clk_power
275 .set_xpd_fosc(pd_flags.pd_rc_fast().not());
276
277 self.lp_sys_sleep
278 .xtal
279 .set_xpd_xtal(pd_flags.pd_xtal().not());
280 }
281
282 fn apply(&self) {
283 unsafe {
285 pmu()
287 .hp_sleep_dig_power()
288 .modify(|_, w| w.bits(self.hp_sys.dig_power.0));
289 pmu()
290 .hp_sleep_hp_ck_power()
291 .modify(|_, w| w.bits(self.hp_sys.clk.0));
292 pmu()
293 .hp_sleep_xtal()
294 .modify(|_, w| w.hp_sleep_xpd_xtal().bit(self.hp_sys.xtal.xpd_xtal()));
295
296 pmu()
298 .hp_sleep_lp_dig_power()
299 .modify(|_, w| w.bits(self.lp_sys_active.dig_power.0));
300 pmu()
301 .hp_sleep_lp_ck_power()
302 .modify(|_, w| w.bits(self.lp_sys_active.clk_power.0));
303
304 pmu()
306 .lp_sleep_lp_dig_power()
307 .modify(|_, w| w.bits(self.lp_sys_sleep.dig_power.0));
308 pmu()
309 .lp_sleep_lp_ck_power()
310 .modify(|_, w| w.bits(self.lp_sys_sleep.clk_power.0));
311 pmu()
312 .lp_sleep_xtal()
313 .modify(|_, w| w.lp_sleep_xpd_xtal().bit(self.lp_sys_sleep.xtal.xpd_xtal()));
314 }
315 }
316}
317
318#[derive(Clone, Copy)]
320pub struct HpParam {
322 pub modem_wakeup_wait_cycle: u32,
324 pub analog_wait_target_cycle: u16,
326 pub digital_power_down_wait_cycle: u16,
328 pub digital_power_supply_wait_cycle: u16,
330 pub digital_power_up_wait_cycle: u16,
332 pub pll_stable_wait_cycle: u16,
334 pub modify_icg_cntl_wait_cycle: u8,
336 pub switch_icg_cntl_wait_cycle: u8,
338 pub min_slp_slow_clk_cycle: u8,
340}
341
342#[derive(Clone, Copy)]
344pub struct LpParam {
346 pub digital_power_supply_wait_cycle: u16,
348 pub min_slp_slow_clk_cycle: u8,
350 pub analog_wait_target_cycle: u8,
352 pub digital_power_down_wait_cycle: u8,
354 pub digital_power_up_wait_cycle: u8,
356}
357
358#[derive(Clone, Copy)]
361pub struct HpLpParam {
363 pub xtal_stable_wait_cycle: u16,
365}
366
367#[derive(Clone, Copy)]
369pub struct ParamSleepConfig {
371 pub hp_sys: HpParam,
373 pub lp_sys: LpParam,
375 pub hp_lp: HpLpParam,
377}
378impl ParamSleepConfig {
379 const PMU_SLEEP_PARAM_CONFIG_DEFAULT: Self = Self {
380 hp_sys: HpParam {
381 min_slp_slow_clk_cycle: 10,
382 analog_wait_target_cycle: 1700,
383 digital_power_supply_wait_cycle: 32,
384 digital_power_up_wait_cycle: 32,
385 modem_wakeup_wait_cycle: 0,
386 pll_stable_wait_cycle: 2,
387
388 digital_power_down_wait_cycle: 0,
389 modify_icg_cntl_wait_cycle: 0,
390 switch_icg_cntl_wait_cycle: 0,
391 },
392 lp_sys: LpParam {
393 min_slp_slow_clk_cycle: 10,
394 analog_wait_target_cycle: 15,
395 digital_power_supply_wait_cycle: 32,
396 digital_power_up_wait_cycle: 32,
397
398 digital_power_down_wait_cycle: 0,
399 },
400 hp_lp: HpLpParam {
401 xtal_stable_wait_cycle: 30,
402 },
403 };
404
405 fn apply(&self) {
406 unsafe {
408 pmu().slp_wakeup_cntl3().modify(|_, w| {
409 w.hp_min_slp_val() .bits(self.hp_sys.min_slp_slow_clk_cycle)
411 .lp_min_slp_val() .bits(self.lp_sys.min_slp_slow_clk_cycle)
413 });
414
415 pmu().slp_wakeup_cntl7().modify(|_, w| {
416 w.ana_wait_target() .bits(self.hp_sys.analog_wait_target_cycle)
418 });
419
420 pmu().slp_wakeup_cntl5().modify(|_, w| {
421 w.lp_ana_wait_target() .bits(self.lp_sys.analog_wait_target_cycle)
423 });
424
425 pmu().power_wait_timer0().modify(|_, w| {
426 w.dg_hp_wait_timer() .bits(self.hp_sys.digital_power_supply_wait_cycle)
428 .dg_hp_powerup_timer() .bits(self.hp_sys.digital_power_up_wait_cycle)
430 });
431
432 pmu().power_wait_timer1().modify(|_, w| {
433 w.dg_lp_wait_timer() .bits(self.lp_sys.digital_power_supply_wait_cycle)
435 .dg_lp_powerup_timer() .bits(self.lp_sys.digital_power_up_wait_cycle)
437 });
438
439 pmu().power_ck_wait_cntl().modify(|_, w| {
440 w.wait_xtl_stable() .bits(self.hp_lp.xtal_stable_wait_cycle)
442 .wait_pll_stable() .bits(self.hp_sys.pll_stable_wait_cycle)
444 });
445 }
446 }
447
448 fn defaults(config: SleepTimeConfig, pd_xtal: bool) -> Self {
449 let mut param = Self::PMU_SLEEP_PARAM_CONFIG_DEFAULT;
450
451 param.hp_sys.min_slp_slow_clk_cycle =
453 config.us_to_slowclk(machine_constants::HP_MIN_SLP_TIME_US) as u8;
454 param.hp_sys.analog_wait_target_cycle =
455 config.us_to_fastclk(machine_constants::HP_ANALOG_WAIT_TIME_US) as u16;
456 param.hp_sys.digital_power_supply_wait_cycle =
457 config.us_to_fastclk(machine_constants::HP_POWER_SUPPLY_WAIT_TIME_US) as u16;
458 param.hp_sys.digital_power_up_wait_cycle =
459 config.us_to_fastclk(machine_constants::HP_POWER_UP_WAIT_TIME_US) as u16;
460 param.hp_sys.pll_stable_wait_cycle =
461 config.us_to_fastclk(machine_constants::HP_PLL_WAIT_STABLE_TIME_US) as u16;
462
463 param.lp_sys.min_slp_slow_clk_cycle =
464 config.us_to_slowclk(machine_constants::LP_MIN_SLP_TIME_US) as u8;
465 param.lp_sys.analog_wait_target_cycle =
466 config.us_to_slowclk(machine_constants::LP_ANALOG_WAIT_TIME_US) as u8;
467 param.lp_sys.digital_power_supply_wait_cycle =
468 config.us_to_fastclk(machine_constants::LP_POWER_SUPPLY_WAIT_TIME_US) as u16;
469 param.lp_sys.digital_power_up_wait_cycle =
470 config.us_to_fastclk(machine_constants::LP_POWER_UP_WAIT_TIME_US) as u8;
471
472 param.hp_lp.xtal_stable_wait_cycle = if pd_xtal {
476 config.us_to_slowclk(machine_constants::LP_XTAL_WAIT_STABLE_TIME_US) as u16
477 } else {
478 config.us_to_fastclk(machine_constants::HP_XTAL_WAIT_STABLE_TIME_US) as u16
479 };
480
481 param
482 }
483}
484
485#[derive(Clone, Copy)]
486struct SleepTimeConfig {
487 sleep_time_adjustment: u32, slowclk_period: u32,
489 fastclk_period: u32,
490}
491
492const CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: u32 = 96;
493
494impl SleepTimeConfig {
495 const RTC_CLK_CAL_FRACT: u32 = 19;
496
497 fn rtc_clk_cal_fast(slowclk_cycles: u32) -> u32 {
498 RtcClock::calibrate(TimgCalibrationClockConfig::RcFastDivClk, slowclk_cycles)
499 }
500
501 fn new() -> Self {
502 let slowclk_period = unsafe { lp_aon().store1().read().data().bits() };
503
504 const FAST_CLK_SRC_CAL_CYCLES: u32 = 2048;
506 let fastclk_period = Self::rtc_clk_cal_fast(FAST_CLK_SRC_CAL_CYCLES);
507
508 Self {
509 sleep_time_adjustment: 0,
510 slowclk_period,
511 fastclk_period,
512 }
513 }
514
515 fn light_sleep(pd_flags: PowerDownFlags) -> Self {
516 const LIGHT_SLEEP_TIME_OVERHEAD_US: u32 = 9;
517
518 let mut this = Self::new();
519
520 let sw = LIGHT_SLEEP_TIME_OVERHEAD_US;
521 let hw = this.pmu_sleep_calculate_hw_wait_time(pd_flags);
522
523 this.sleep_time_adjustment = sw + hw;
524
525 this
526 }
527
528 fn deep_sleep() -> Self {
529 let mut this = Self::new();
530
531 this.sleep_time_adjustment = 250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ;
532
533 this
534 }
535
536 fn us_to_slowclk(&self, us: u32) -> u32 {
537 (us << Self::RTC_CLK_CAL_FRACT) / self.slowclk_period
538 }
539
540 fn slowclk_to_us(&self, rtc_cycles: u32) -> u32 {
541 (rtc_cycles * self.slowclk_period) >> Self::RTC_CLK_CAL_FRACT
542 }
543
544 fn us_to_fastclk(&self, us: u32) -> u32 {
545 (us << Self::RTC_CLK_CAL_FRACT) / self.fastclk_period
546 }
547
548 fn pmu_sleep_calculate_hw_wait_time(&self, pd_flags: PowerDownFlags) -> u32 {
549 let lp_clk_switch_time_us = self.slowclk_to_us(machine_constants::LP_CLK_SWITCH_CYCLE);
550 let lp_clk_power_on_wait_time_us = if pd_flags.pd_xtal() {
551 machine_constants::LP_XTAL_WAIT_STABLE_TIME_US
552 } else {
553 self.slowclk_to_us(machine_constants::LP_CLK_POWER_ON_WAIT_CYCLE)
554 };
555
556 let lp_hw_wait_time_us = machine_constants::LP_MIN_SLP_TIME_US
557 + machine_constants::LP_ANALOG_WAIT_TIME_US
558 + lp_clk_power_on_wait_time_us
559 + lp_clk_switch_time_us
560 + machine_constants::LP_POWER_SUPPLY_WAIT_TIME_US
561 + machine_constants::LP_POWER_UP_WAIT_TIME_US;
562
563 let hp_digital_power_up_wait_time_us = machine_constants::HP_POWER_SUPPLY_WAIT_TIME_US
564 + machine_constants::HP_POWER_UP_WAIT_TIME_US;
565 let hp_regdma_wait_time_us = if pd_flags.pd_top() {
566 machine_constants::HP_REGDMA_S2A_WORK_TIME_PD_TOP_US
567 } else {
568 machine_constants::HP_REGDMA_S2A_WORK_TIME_PU_TOP_US
569 };
570 let hp_clock_wait_time_us = machine_constants::HP_XTAL_WAIT_STABLE_TIME_US
571 + machine_constants::HP_PLL_WAIT_STABLE_TIME_US;
572
573 let hp_hw_wait_time_us = machine_constants::HP_ANALOG_WAIT_TIME_US
574 + hp_digital_power_up_wait_time_us
575 + hp_regdma_wait_time_us
576 + hp_clock_wait_time_us;
577
578 lp_hw_wait_time_us + hp_hw_wait_time_us
579 }
580}
581
582#[derive(Clone, Copy)]
584pub struct RtcSleepConfig {
585 pub deep: bool,
587 pub pd_flags: PowerDownFlags,
589 need_pd_top: bool,
591}
592
593impl Default for RtcSleepConfig {
594 fn default() -> Self {
595 Self {
599 deep: false,
600 pd_flags: PowerDownFlags(0),
601 need_pd_top: false,
602 }
603 }
604}
605
606unsafe fn pmu<'a>() -> &'a esp32h2::pmu::RegisterBlock {
607 unsafe { &*esp32h2::PMU::ptr() }
608}
609
610unsafe fn lp_aon<'a>() -> &'a esp32h2::lp_aon::RegisterBlock {
611 unsafe { &*esp32h2::LP_AON::ptr() }
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_cpu , set_pd_cpu : 3;
627 pub u32, pd_xtal , set_pd_xtal : 4;
629 pub u32, pd_rc_fast , set_pd_rc_fast : 5;
631 pub u32, pd_xtal32k , set_pd_xtal32k : 6;
633}
634
635mod machine_constants {
637 pub const LP_MIN_SLP_TIME_US: u32 = 450;
638 pub const LP_ANALOG_WAIT_TIME_US: u32 = 154;
639 pub const LP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
640 pub const LP_CLK_SWITCH_CYCLE: u32 = 1;
641 pub const LP_CLK_POWER_ON_WAIT_CYCLE: u32 = 1;
642 pub const LP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
643 pub const LP_POWER_UP_WAIT_TIME_US: u32 = 2;
644
645 pub const HP_MIN_SLP_TIME_US: u32 = 450;
646 pub const HP_ANALOG_WAIT_TIME_US: u32 = 154;
647 pub const HP_POWER_SUPPLY_WAIT_TIME_US: u32 = 2;
648 pub const HP_POWER_UP_WAIT_TIME_US: u32 = 2;
649 pub const HP_REGDMA_S2A_WORK_TIME_PD_TOP_US: u32 = 480;
650 pub const HP_REGDMA_S2A_WORK_TIME_PU_TOP_US: u32 = 390;
651 pub const HP_XTAL_WAIT_STABLE_TIME_US: u32 = 250;
652 pub const HP_PLL_WAIT_STABLE_TIME_US: u32 = 50;
653}
654
655impl RtcSleepConfig {
656 pub fn deep_slp(&self) -> bool {
658 self.deep
659 }
660
661 pub fn deep() -> Self {
663 Self {
665 deep: true,
666 ..Self::default()
667 }
668 }
669
670 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
671 Self::wake_io_reset();
672 }
673
674 fn wake_io_reset() {
675 Ext1WakeupSource::wake_io_reset();
676 }
677
678 pub(crate) fn apply(&mut self) {
680 if self.deep {
681 self.pd_flags.set_pd_top(self.need_pd_top.not());
683 self.pd_flags.set_pd_vddsdio(true);
684 self.pd_flags.set_pd_modem(true);
685 self.pd_flags.set_pd_cpu(true);
686 self.pd_flags.set_pd_xtal(true);
687 self.pd_flags.set_pd_rc_fast(true);
688 self.pd_flags.set_pd_xtal32k(true);
689 } else if self.need_pd_top {
690 self.pd_flags.set_pd_top(false);
691 }
692 }
693
694 pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) {
698 const PMU_EXT1_WAKEUP_EN: u32 = 1 << 1;
699 const PMU_GPIO_WAKEUP_EN: u32 = 1 << 2;
700 const PMU_LP_TIMER_WAKEUP_EN: u32 = 1 << 4;
701 const PMU_UART0_WAKEUP_EN: u32 = 1 << 6;
702 const PMU_UART1_WAKEUP_EN: u32 = 1 << 7;
703 const PMU_BLE_SOC_WAKEUP_EN: u32 = 1 << 10;
704
705 const RTC_SLEEP_REJECT_MASK: u32 = PMU_EXT1_WAKEUP_EN
706 | PMU_GPIO_WAKEUP_EN
707 | PMU_LP_TIMER_WAKEUP_EN
708 | PMU_UART0_WAKEUP_EN
709 | PMU_UART1_WAKEUP_EN
710 | PMU_BLE_SOC_WAKEUP_EN;
711
712 let wakeup_mask = wakeup_triggers.0 as u32;
713 let reject_mask = if self.deep {
714 0
715 } else {
716 let reject_mask = RTC_SLEEP_REJECT_MASK;
717 wakeup_mask & reject_mask
718 };
719
720 let cpu_freq_config = ClockTree::with(|clocks| {
721 let cpu_freq_config = SavedClockConfig::save(clocks);
722 crate::soc::clocks::configure_hp_root_clk(
723 clocks,
724 crate::soc::clocks::HpRootClkConfig::Xtal,
725 );
726 crate::soc::clocks::configure_cpu_clk(clocks, crate::soc::clocks::CpuClkConfig::new(0));
727 cpu_freq_config
728 });
729
730 APB_SARADC::regs()
734 .ctrl()
735 .modify(|_, w| w.saradc2_pwdet_drv().bit(false));
736
737 let power = PowerSleepConfig::defaults(self.pd_flags);
740 power.apply();
741
742 let config = if self.deep {
744 SleepTimeConfig::deep_sleep()
745 } else {
746 SleepTimeConfig::light_sleep(self.pd_flags)
747 };
748
749 let param = ParamSleepConfig::defaults(config, power.hp_sys.xtal.xpd_xtal());
750
751 if self.deep {
752 DigitalSleepConfig::defaults_deep_sleep().apply();
753 AnalogSleepConfig::defaults_deep_sleep().apply();
754 } else {
755 DigitalSleepConfig::defaults_light_sleep(self.pd_flags).apply();
756 AnalogSleepConfig::defaults_light_sleep().apply();
757 }
758
759 param.apply();
760
761 unsafe {
764 lp_aon()
766 .store9()
767 .modify(|r, w| w.bits(r.bits() & !0x01 | self.deep as u32));
768
769 pmu().slp_wakeup_cntl2().write(|w| w.bits(wakeup_mask));
771
772 pmu().slp_wakeup_cntl1().modify(|_, w| {
774 w.slp_reject_en()
775 .bit(true)
776 .sleep_reject_ena()
777 .bits(reject_mask)
778 });
779
780 pmu().int_clr().write(|w| {
781 w.soc_wakeup() .clear_bit_by_one()
783 .soc_sleep_reject() .clear_bit_by_one()
785 });
786
787 pmu()
789 .slp_wakeup_cntl4()
790 .write(|w| w.slp_reject_cause_clr().bit(true));
791
792 pmu().slp_wakeup_cntl0().write(|w| w.sleep_req().bit(true));
796
797 loop {
798 let int_raw = pmu().int_raw().read();
799 if int_raw.soc_wakeup().bit_is_set() || int_raw.soc_sleep_reject().bit_is_set() {
800 break;
801 }
802 }
803 }
804
805 ClockTree::with(|clocks| {
808 cpu_freq_config.restore(clocks);
809 });
810 }
811
812 pub(crate) fn finish_sleep(&self) {
814 Self::wake_io_reset();
815 }
816}
817
818#[derive(Clone, Copy)]
819pub(crate) struct SavedClockConfig {
820 old_hp_root_clk: Option<HpRootClkConfig>,
822
823 old_cpu_divider: Option<CpuClkConfig>,
825}
826
827impl SavedClockConfig {
828 pub(crate) fn save(clocks: &ClockTree) -> Self {
829 let old_hp_root_clk = clocks.hp_root_clk();
830 let old_cpu_divider = clocks.cpu_clk();
831
832 SavedClockConfig {
833 old_hp_root_clk,
834 old_cpu_divider,
835 }
836 }
837
838 pub(crate) fn restore(self, clocks: &mut ClockTree) {
840 if let Some(old_hp_root_clk) = self.old_hp_root_clk {
841 crate::soc::clocks::configure_hp_root_clk(clocks, old_hp_root_clk);
842 }
843 if let Some(old_cpu_divider) = self.old_cpu_divider {
844 crate::soc::clocks::configure_cpu_clk(clocks, old_cpu_divider);
845 }
846 }
847}