1use super::{
2 Ext0WakeupSource,
3 Ext1WakeupSource,
4 TimerWakeupSource,
5 UlpWakeupSource,
6 WakeSource,
7 WakeTriggers,
8 WakeupLevel,
9};
10use crate::{
11 gpio::{RtcFunction, RtcPin},
12 peripherals::{APB_CTRL, EXTMEM, LPWR, RTC_IO, SPI0, SPI1, SYSTEM},
13 rtc_cntl::{Rtc, sleep::RtcioWakeupSource},
14 soc::regi2c,
15};
16
17pub const RTC_CNTL_DBIAS_0V90: u8 = 13;
22pub const RTC_CNTL_DBIAS_0V95: u8 = 16;
24pub const RTC_CNTL_DBIAS_1V00: u8 = 18;
26pub const RTC_CNTL_DBIAS_1V05: u8 = 20;
28pub const RTC_CNTL_DBIAS_1V10: u8 = 23;
30pub const RTC_CNTL_DBIAS_1V15: u8 = 25;
32pub const RTC_CNTL_DBIAS_1V20: u8 = 28;
34pub const RTC_CNTL_DBIAS_1V25: u8 = 30;
36pub const RTC_CNTL_DBIAS_1V30: u8 = 31;
38pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0;
40pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP: u16 = 0xFF;
42pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT: u16 = 0x10;
44pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20;
46pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
48pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2;
50pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW: u8 = 15;
52pub const OTHER_BLOCKS_POWERUP: u8 = 1;
54pub const OTHER_BLOCKS_WAIT: u16 = 1;
56pub const WIFI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
58pub const WIFI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
60pub const BT_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
62pub const BT_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
64pub const RTC_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
66pub const RTC_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
68pub const CPU_TOP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
70pub const CPU_TOP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
72pub const DG_WRAP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
74pub const DG_WRAP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
76pub const DG_PERI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
78pub const DG_PERI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
80pub const RTC_MEM_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
82pub const RTC_MEM_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
84
85impl WakeSource for UlpWakeupSource {
86 fn apply(
87 &self,
88 _rtc: &Rtc<'_>,
89 triggers: &mut WakeTriggers,
90 sleep_config: &mut RtcSleepConfig,
91 ) {
92 triggers.set_ulp_fsm(self.wake_on_interrupt);
93 triggers.set_ulp_riscv(self.wake_on_interrupt);
94 triggers.set_ulp_riscv_trap(self.wake_on_trap);
95
96 if self.clear_interrupts_on_sleep {
97 self.clear_interrupts();
98 }
99
100 sleep_config.set_rtc_peri_pd_en(false);
103 }
104}
105
106impl WakeSource for TimerWakeupSource {
107 fn apply(
108 &self,
109 rtc: &Rtc<'_>,
110 triggers: &mut WakeTriggers,
111 _sleep_config: &mut RtcSleepConfig,
112 ) {
113 triggers.set_timer(true);
114 let rtc_cntl = LPWR::regs();
115 let ticks = crate::clock::us_to_rtc_ticks(self.duration.as_micros() as u64);
117 let now = rtc.time_since_boot_raw();
119 let time_in_ticks = now + ticks;
120 unsafe {
121 rtc_cntl
122 .slp_timer0()
123 .write(|w| w.slp_val_lo().bits((time_in_ticks & 0xffffffff) as u32));
124
125 rtc_cntl
126 .int_clr()
127 .write(|w| w.main_timer().clear_bit_by_one());
128
129 rtc_cntl.slp_timer1().write(|w| {
130 w.slp_val_hi().bits(((time_in_ticks >> 32) & 0xffff) as u16);
131 w.main_timer_alarm_en().set_bit()
132 });
133 }
134 }
135}
136
137impl<P: RtcPin> WakeSource for Ext0WakeupSource<P> {
138 fn apply(
139 &self,
140 _rtc: &Rtc<'_>,
141 triggers: &mut WakeTriggers,
142 sleep_config: &mut RtcSleepConfig,
143 ) {
144 sleep_config.set_rtc_peri_pd_en(false);
146 triggers.set_ext0(true);
147
148 self.pin
150 .borrow_mut()
151 .rtc_set_config(true, true, RtcFunction::Rtc);
152
153 unsafe {
154 let rtc_io = RTC_IO::regs();
155 rtc_io
157 .ext_wakeup0()
158 .modify(|_, w| w.sel().bits(self.pin.borrow().rtc_number()));
159 let rtc_cntl = LPWR::regs();
161 rtc_cntl
162 .ext_wakeup_conf()
163 .modify(|_r, w| w.ext_wakeup0_lv().bit(self.level == WakeupLevel::High));
164 }
165 }
166}
167
168impl<P: RtcPin> Drop for Ext0WakeupSource<P> {
169 fn drop(&mut self) {
170 self.pin
174 .borrow_mut()
175 .rtc_set_config(true, false, RtcFunction::Rtc);
176 }
177}
178
179impl WakeSource for Ext1WakeupSource<'_, '_> {
180 fn apply(
181 &self,
182 _rtc: &Rtc<'_>,
183 triggers: &mut WakeTriggers,
184 sleep_config: &mut RtcSleepConfig,
185 ) {
186 sleep_config.set_rtc_peri_pd_en(false);
188 triggers.set_ext1(true);
189
190 let mut pins = self.pins.borrow_mut();
192 let mut bits = 0u32;
193 for pin in pins.iter_mut() {
194 pin.rtc_set_config(true, true, RtcFunction::Rtc);
195 bits |= 1 << pin.rtc_number();
196 }
197
198 unsafe {
199 let rtc_cntl = LPWR::regs();
200 rtc_cntl
202 .ext_wakeup1()
203 .modify(|_, w| w.ext_wakeup1_status_clr().set_bit());
204 rtc_cntl
206 .ext_wakeup1()
207 .modify(|_, w| w.ext_wakeup1_sel().bits(bits));
208 rtc_cntl
210 .ext_wakeup_conf()
211 .modify(|_r, w| w.ext_wakeup1_lv().bit(self.level == WakeupLevel::High));
212 }
213 }
214}
215
216impl Drop for Ext1WakeupSource<'_, '_> {
217 fn drop(&mut self) {
218 let mut pins = self.pins.borrow_mut();
222 for pin in pins.iter_mut() {
223 pin.rtc_set_config(true, false, RtcFunction::Rtc);
224 }
225 }
226}
227
228impl RtcioWakeupSource<'_, '_> {
229 fn apply_pin(&self, pin: &mut dyn RtcPin, level: WakeupLevel) {
230 let rtcio = RTC_IO::regs();
231
232 pin.rtc_set_config(true, true, RtcFunction::Rtc);
233
234 rtcio.pin(pin.number() as usize).modify(|_, w| unsafe {
235 w.wakeup_enable().set_bit().int_type().bits(match level {
236 WakeupLevel::Low => 4,
237 WakeupLevel::High => 5,
238 })
239 });
240 }
241}
242
243impl WakeSource for RtcioWakeupSource<'_, '_> {
244 fn apply(
245 &self,
246 _rtc: &Rtc<'_>,
247 triggers: &mut WakeTriggers,
248 sleep_config: &mut RtcSleepConfig,
249 ) {
250 let mut pins = self.pins.borrow_mut();
251
252 if pins.is_empty() {
253 return;
254 }
255
256 sleep_config.set_rtc_peri_pd_en(false);
258 triggers.set_gpio(true);
259
260 let sens = crate::peripherals::SENS::regs();
262
263 sens.sar_peri_clk_gate_conf()
265 .modify(|_, w| w.iomux_clk_en().set_bit());
266
267 for (pin, level) in pins.iter_mut() {
268 self.apply_pin(*pin, *level);
269 }
270 }
271}
272
273impl Drop for RtcioWakeupSource<'_, '_> {
274 fn drop(&mut self) {
275 let mut pins = self.pins.borrow_mut();
279 for (pin, _level) in pins.iter_mut() {
280 pin.rtc_set_config(true, false, RtcFunction::Rtc);
281 }
282 }
283}
284
285bitfield::bitfield! {
286 #[derive(Clone, Copy)]
288 pub struct RtcSleepConfig(u64);
289 impl Debug;
290 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
292 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 1;
294 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 2;
296 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 3;
298 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 4;
300 pub modem_pd_en, set_modem_pd_en: 5;
302 pub cpu_pd_en, set_cpu_pd_en: 6;
304 pub int_8m_pd_en, set_int_8m_pd_en: 7;
306 pub dig_peri_pd_en, set_dig_peri_pd_en: 8;
308 pub deep_slp, set_deep_slp: 9;
310 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
312 pub u8, dig_dbias_slp, set_dig_dbias_slp: 15, 11;
314 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 20, 16;
316 pub bias_sleep_monitor, set_bias_sleep_monitor: 21;
318 pub u8, dbg_atten_slp, set_dbg_atten_slp: 25, 22;
320 pub bias_sleep_slp, set_bias_sleep_slp: 26;
322 pub pd_cur_monitor, set_pd_cur_monitor: 27;
324 pub pd_cur_slp, set_pd_cur_slp: 28;
326 pub vddsdio_pd_en, set_vddsdio_pd_en: 29;
328 pub xtal_fpu, set_xtal_fpu: 30;
330 pub rtc_regulator_fpu, set_rtc_regulator_fpu: 31;
332 pub deep_slp_reject, set_deep_slp_reject: 32;
334 pub light_slp_reject, set_light_slp_reject: 33;
336}
337
338impl Default for RtcSleepConfig {
339 fn default() -> Self {
340 let mut cfg = Self(Default::default());
341 cfg.set_deep_slp_reject(true);
342 cfg.set_light_slp_reject(true);
343 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
344 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
345 cfg
346 }
347}
348
349const SYSCON_SRAM_POWER_UP: u16 = 0x7FF;
350const SYSCON_ROM_POWER_UP: u8 = 0x7;
351
352fn rtc_sleep_pu(val: bool) {
353 let rtc_cntl = LPWR::regs();
354 let syscon = unsafe { &*esp32s3::APB_CTRL::ptr() };
355 let bb = unsafe { &*esp32s3::BB::ptr() };
356 let nrx = unsafe { &*esp32s3::NRX::ptr() };
357 let fe = unsafe { &*esp32s3::FE::ptr() };
358 let fe2 = unsafe { &*esp32s3::FE2::ptr() };
359
360 rtc_cntl
361 .dig_pwc()
362 .modify(|_, w| w.lslp_mem_force_pu().bit(val));
363
364 rtc_cntl
365 .pwc()
366 .modify(|_, w| w.slowmem_force_lpu().bit(val).fastmem_force_lpu().bit(val));
367
368 syscon.front_end_mem_pd().modify(|_r, w| {
369 w.dc_mem_force_pu()
370 .bit(val)
371 .pbus_mem_force_pu()
372 .bit(val)
373 .agc_mem_force_pu()
374 .bit(val)
375 });
376
377 bb.bbpd_ctrl()
378 .modify(|_r, w| w.fft_force_pu().bit(val).dc_est_force_pu().bit(val));
379
380 nrx.nrxpd_ctrl().modify(|_, w| {
381 w.rx_rot_force_pu()
382 .bit(val)
383 .vit_force_pu()
384 .bit(val)
385 .demap_force_pu()
386 .bit(val)
387 });
388
389 fe.gen_ctrl().modify(|_, w| w.iq_est_force_pu().bit(val));
390
391 fe2.tx_interp_ctrl()
392 .modify(|_, w| w.tx_inf_force_pu().bit(val));
393
394 syscon.mem_power_up().modify(|_r, w| unsafe {
395 w.sram_power_up()
396 .bits(if val { SYSCON_SRAM_POWER_UP } else { 0 })
397 .rom_power_up()
398 .bits(if val { SYSCON_ROM_POWER_UP } else { 0 })
399 });
400}
401
402impl RtcSleepConfig {
403 pub fn deep() -> Self {
405 let mut cfg = Self::default();
407
408 cfg.set_lslp_mem_inf_fpu(false);
409 cfg.set_rtc_mem_inf_follow_cpu(true); cfg.set_rtc_fastmem_pd_en(true);
411 cfg.set_rtc_slowmem_pd_en(true);
412 cfg.set_rtc_peri_pd_en(true);
413 cfg.set_modem_pd_en(true);
414 cfg.set_cpu_pd_en(true);
415 cfg.set_int_8m_pd_en(true);
416
417 cfg.set_dig_peri_pd_en(true);
418 cfg.set_dig_dbias_slp(0); cfg.set_deep_slp(true);
421 cfg.set_wdt_flashboot_mod_en(false);
422 cfg.set_vddsdio_pd_en(true);
423 cfg.set_xtal_fpu(false);
424 cfg.set_deep_slp_reject(true);
425 cfg.set_light_slp_reject(true);
426 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
427
428 cfg.set_rtc_regulator_fpu(false);
430 cfg.set_dbg_atten_slp(RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW);
431
432 cfg.set_bias_sleep_monitor(true);
434 cfg.set_pd_cur_monitor(true);
435 cfg.set_bias_sleep_slp(true);
436 cfg.set_pd_cur_slp(true);
437
438 cfg
439 }
440
441 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
442 unsafe {
444 let rtc_cntl = LPWR::regs();
445 let syscon = APB_CTRL::regs();
446 let extmem = EXTMEM::regs();
447 let system = SYSTEM::regs();
448
449 rtc_cntl
450 .dig_pwc()
451 .modify(|_, w| w.wifi_force_pd().clear_bit());
452
453 regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
454 regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
455
456 rtc_cntl.ana_conf().modify(|_, w| w.pvtmon_pu().clear_bit());
457
458 rtc_cntl.timer1().modify(|_, w| {
459 w.pll_buf_wait()
460 .bits(RTC_CNTL_PLL_BUF_WAIT_DEFAULT)
461 .ck8m_wait()
462 .bits(RTC_CNTL_CK8M_WAIT_DEFAULT)
463 });
464
465 rtc_cntl
469 .timer5()
470 .modify(|_, w| w.min_slp_val().bits(RTC_CNTL_MIN_SLP_VAL_MIN));
471
472 rtc_cntl.timer3().modify(|_, w| {
473 w.wifi_powerup_timer().bits(WIFI_POWERUP_CYCLES);
475 w.wifi_wait_timer().bits(WIFI_WAIT_CYCLES);
477 w.bt_powerup_timer().bits(BT_POWERUP_CYCLES);
478 w.bt_wait_timer().bits(BT_WAIT_CYCLES)
479 });
480
481 rtc_cntl.timer6().modify(|_, w| {
482 w.cpu_top_powerup_timer().bits(CPU_TOP_POWERUP_CYCLES);
483 w.cpu_top_wait_timer().bits(CPU_TOP_WAIT_CYCLES)
484 });
485
486 rtc_cntl.timer4().modify(|_, w| {
487 w.powerup_timer().bits(RTC_POWERUP_CYCLES);
489 w.wait_timer().bits(RTC_WAIT_CYCLES);
491 w.dg_wrap_powerup_timer().bits(DG_WRAP_POWERUP_CYCLES);
492 w.dg_wrap_wait_timer().bits(DG_WRAP_WAIT_CYCLES)
493 });
494
495 rtc_cntl.timer6().modify(|_, w| {
496 w.dg_peri_powerup_timer().bits(DG_PERI_POWERUP_CYCLES);
497 w.dg_peri_wait_timer().bits(DG_PERI_WAIT_CYCLES)
498 });
499
500 regi2c::I2C_DIG_REG_EXT_RTC_DREG_SLEEP.write_field(RTC_CNTL_DBIAS_1V10);
502 regi2c::I2C_DIG_REG_EXT_RTC_DREG.write_field(RTC_CNTL_DBIAS_1V10);
503
504 rtc_cntl.timer2().modify(|_, w| {
507 w.ulpcp_touch_start_wait()
508 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
509 });
510
511 regi2c::I2C_DIG_REG_EXT_RTC_DREG.write_field(RTC_CNTL_DBIAS_1V25);
517 regi2c::I2C_DIG_REG_EXT_DIG_DREG.write_field(RTC_CNTL_DBIAS_1V25);
518
519 extmem
522 .cache_mmu_power_ctrl()
523 .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
524
525 syscon.clkgate_force_on().write(|w| w.bits(0));
527
528 extmem
531 .dcache_tag_power_ctrl()
532 .modify(|_, w| w.dcache_tag_mem_force_on().clear_bit());
533
534 extmem
535 .icache_tag_power_ctrl()
536 .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
537
538 SPI0::regs()
540 .clock_gate()
541 .modify(|_, w| w.clk_en().clear_bit());
542 SPI1::regs()
543 .clock_gate()
544 .modify(|_, w| w.clk_en().clear_bit());
545
546 rtc_cntl
547 .clk_conf()
548 .modify(|_, w| w.ck8m_force_pu().clear_bit());
549
550 rtc_cntl
551 .options0()
552 .modify(|_, w| w.xtl_force_pu().clear_bit());
553
554 rtc_cntl.ana_conf().modify(|_, w| {
555 w
556 .i2c_reset_por_force_pd()
560 .clear_bit()
561 });
562
563 rtc_cntl.options0().modify(|_, w| {
566 w.bbpll_force_pu().clear_bit();
567 w.bbpll_i2c_force_pu().clear_bit();
568 w.bb_i2c_force_pu().clear_bit()
569 });
570
571 rtc_cntl.pwc().modify(|_, w| w.force_pu().clear_bit());
574
575 rtc_cntl.rtc().modify(|_, w| {
576 w.regulator_force_pu().clear_bit();
577 w.dboost_force_pu().clear_bit()
578 });
579
580 rtc_cntl.pwc().modify(|_, w| {
581 w.slowmem_force_noiso().clear_bit();
582 w.fastmem_force_noiso().clear_bit()
583 });
584
585 rtc_cntl.rtc().modify(|_, w| w.dboost_force_pd().set_bit());
586
587 system
592 .mem_pd_mask()
593 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
594
595 rtc_sleep_pu(false);
599
600 rtc_cntl
601 .dig_pwc()
602 .modify(|_, w| w.dg_wrap_force_pu().clear_bit());
603
604 rtc_cntl.dig_iso().modify(|_, w| {
605 w.dg_wrap_force_noiso().clear_bit();
606 w.dg_wrap_force_iso().clear_bit()
607 });
608
609 rtc_cntl.dig_iso().modify(|_, w| {
610 w.wifi_force_noiso().clear_bit();
611 w.wifi_force_iso().clear_bit()
612 });
613
614 rtc_cntl
615 .dig_pwc()
616 .modify(|_, w| w.wifi_force_pu().clear_bit());
617
618 rtc_cntl
619 .dig_iso()
620 .modify(|_, w| w.bt_force_noiso().clear_bit().bt_force_iso().clear_bit());
621
622 rtc_cntl
623 .dig_pwc()
624 .modify(|_, w| w.bt_force_pu().clear_bit());
625
626 rtc_cntl.dig_iso().modify(|_, w| {
627 w.cpu_top_force_noiso().clear_bit();
628 w.cpu_top_force_iso().clear_bit()
629 });
630
631 rtc_cntl
632 .dig_pwc()
633 .modify(|_, w| w.cpu_top_force_pu().clear_bit());
634
635 rtc_cntl.dig_iso().modify(|_, w| {
636 w.dg_peri_force_noiso().clear_bit();
637 w.dg_peri_force_iso().clear_bit()
638 });
639
640 rtc_cntl
641 .dig_pwc()
642 .modify(|_, w| w.dg_peri_force_pu().clear_bit());
643
644 rtc_cntl.pwc().modify(|_, w| {
645 w.force_noiso().clear_bit();
646 w.force_iso().clear_bit();
647 w.force_pu().clear_bit()
648 });
649
650 system
654 .cpu_per_conf()
655 .modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
656
657 rtc_cntl.dig_iso().modify(|_, w| {
660 w.dg_pad_force_unhold().clear_bit();
661 w.dg_pad_force_noiso().clear_bit()
662 });
663
664 rtc_cntl
667 .dig_iso()
668 .modify(|_, w| w.wifi_force_iso().set_bit());
669
670 rtc_cntl
671 .dig_pwc()
672 .modify(|_, w| w.wifi_force_pd().set_bit());
673
674 rtc_cntl.int_ena().write(|w| w.bits(0));
675 rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
676 }
677 }
678
679 pub(crate) fn apply(&self) {
680 let rtc_cntl = LPWR::regs();
682
683 if self.lslp_mem_inf_fpu() {
684 rtc_sleep_pu(true);
685 }
686
687 if self.modem_pd_en() {
688 rtc_cntl.dig_iso().modify(|_, w| {
689 w.wifi_force_noiso().clear_bit();
690 w.wifi_force_iso().clear_bit()
691 });
692
693 rtc_cntl
694 .dig_pwc()
695 .modify(|_, w| w.wifi_force_pu().clear_bit().wifi_pd_en().set_bit());
696 } else {
697 rtc_cntl.options0().modify(|_, w| {
698 w.bbpll_force_pu().set_bit();
699 w.bbpll_i2c_force_pu().set_bit();
700 w.bb_i2c_force_pu().set_bit()
701 });
702
703 rtc_cntl
704 .dig_pwc()
705 .modify(|_, w| w.wifi_force_pu().set_bit().wifi_pd_en().clear_bit());
706 }
707
708 if self.cpu_pd_en() {
709 rtc_cntl.dig_iso().modify(|_, w| {
710 w.cpu_top_force_noiso().clear_bit();
711 w.cpu_top_force_iso().clear_bit()
712 });
713
714 rtc_cntl
715 .dig_pwc()
716 .modify(|_, w| w.cpu_top_force_pu().clear_bit().cpu_top_pd_en().set_bit());
717 } else {
718 rtc_cntl
719 .dig_pwc()
720 .modify(|_, w| w.cpu_top_pd_en().clear_bit());
721 }
722
723 if self.dig_peri_pd_en() {
724 rtc_cntl.dig_iso().modify(|_, w| {
725 w.dg_peri_force_noiso().clear_bit();
726 w.dg_peri_force_iso().clear_bit()
727 });
728
729 rtc_cntl
730 .dig_pwc()
731 .modify(|_, w| w.dg_peri_force_pu().clear_bit().dg_peri_pd_en().set_bit());
732 } else {
733 rtc_cntl
734 .dig_pwc()
735 .modify(|_, w| w.dg_peri_pd_en().clear_bit());
736 }
737
738 if self.rtc_peri_pd_en() {
739 rtc_cntl.pwc().modify(|_, w| {
740 w.force_noiso().clear_bit();
741 w.force_iso().clear_bit();
742 w.force_pu().clear_bit();
743 w.pd_en().set_bit()
744 });
745 } else {
746 rtc_cntl.pwc().modify(|_, w| w.pd_en().clear_bit());
747 }
748
749 unsafe {
750 regi2c::I2C_DIG_REG_EXT_RTC_DREG_SLEEP.write_field(self.rtc_dbias_slp());
751 regi2c::I2C_DIG_REG_EXT_DIG_DREG_SLEEP.write_field(self.dig_dbias_slp());
752
753 rtc_cntl.bias_conf().modify(|_, w| {
754 w.dbg_atten_deep_slp().bits(self.dbg_atten_slp());
755 w.bias_sleep_deep_slp().bit(self.bias_sleep_slp());
756 w.pd_cur_deep_slp().bit(self.pd_cur_slp());
757 w.dbg_atten_monitor()
758 .bits(RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
759 w.bias_sleep_monitor().bit(self.bias_sleep_monitor());
760 w.pd_cur_monitor().bit(self.pd_cur_monitor())
761 });
762
763 if self.deep_slp() {
764 rtc_cntl
765 .dig_pwc()
766 .modify(|_, w| w.dg_wrap_pd_en().set_bit());
767
768 rtc_cntl.ana_conf().modify(|_, w| {
769 w.ckgen_i2c_pu().clear_bit();
770 w.pll_i2c_pu().clear_bit();
771 w.rfrx_pbus_pu().clear_bit();
772 w.txrf_i2c_pu().clear_bit()
773 });
774
775 rtc_cntl
776 .options0()
777 .modify(|_, w| w.bb_i2c_force_pu().clear_bit());
778 } else {
779 rtc_cntl
780 .regulator_drv_ctrl()
781 .modify(|_, w| w.dg_vdd_drv_b_slp().bits(0xF));
782
783 rtc_cntl
784 .dig_pwc()
785 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
786 }
787
788 rtc_cntl
791 .dig_pwc()
792 .modify(|_, w| w.lslp_mem_force_pu().set_bit());
793
794 rtc_cntl
795 .rtc()
796 .modify(|_, w| w.regulator_force_pu().bit(self.rtc_regulator_fpu()));
797
798 rtc_cntl
799 .clk_conf()
800 .modify(|_, w| w.ck8m_force_pu().bit(!self.int_8m_pd_en()));
801
802 rtc_cntl.sdio_conf().modify(|_, w| {
805 w.sdio_force().clear_bit();
806 w.sdio_reg_pd_en().bit(self.vddsdio_pd_en())
807 });
808
809 rtc_cntl.slp_reject_conf().modify(|_, w| {
810 w.deep_slp_reject_en().bit(self.deep_slp_reject());
811 w.light_slp_reject_en().bit(self.light_slp_reject())
812 });
813
814 rtc_cntl.timer2().modify(|_, w| {
818 w.ulpcp_touch_start_wait()
819 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP)
820 });
821
822 rtc_cntl
823 .options0()
824 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
825
826 rtc_cntl
827 .clk_conf()
828 .modify(|_, w| w.xtal_global_force_nogating().bit(self.xtal_fpu()));
829 }
830 }
831
832 pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) {
833 unsafe {
834 LPWR::regs()
835 .reset_state()
836 .modify(|_, w| w.procpu_stat_vector_sel().set_bit());
837
838 LPWR::regs()
840 .wakeup_state()
841 .modify(|_, w| w.wakeup_ena().bits(wakeup_triggers.0.into()));
842
843 LPWR::regs()
844 .state0()
845 .write(|w| w.sleep_en().set_bit().slp_wakeup().set_bit());
846 }
847 }
848
849 pub(crate) fn finish_sleep(&self) {
850 unsafe {
852 LPWR::regs().int_clr().write(|w| {
853 w.slp_reject()
854 .clear_bit_by_one()
855 .slp_wakeup()
856 .clear_bit_by_one()
857 });
858
859 if self.lslp_mem_inf_fpu() {
861 rtc_sleep_pu(true);
862 }
863
864 LPWR::regs().timer2().modify(|_, w| {
867 w.ulpcp_touch_start_wait()
868 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
869 });
870 }
871 }
872}