1use super::SleepKind;
2use crate::{
3 peripherals::{APB_CTRL, EXTMEM, LPWR, SPI0, SPI1, SYSTEM},
4 rtc_cntl::Rtc,
5 soc::regi2c,
6};
7
8pub const RTC_CNTL_DBIAS_0V90: u8 = 13;
13pub const RTC_CNTL_DBIAS_0V95: u8 = 16;
15pub const RTC_CNTL_DBIAS_1V00: u8 = 18;
17pub const RTC_CNTL_DBIAS_1V05: u8 = 20;
19pub const RTC_CNTL_DBIAS_1V10: u8 = 23;
21pub const RTC_CNTL_DBIAS_1V15: u8 = 25;
23pub const RTC_CNTL_DBIAS_1V20: u8 = 28;
25pub const RTC_CNTL_DBIAS_1V25: u8 = 30;
27pub const RTC_CNTL_DBIAS_1V30: u8 = 31;
29pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0;
31pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP: u16 = 0xFF;
33pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT: u16 = 0x10;
35pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20;
37pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
39pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2;
41pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW: u8 = 15;
43pub const OTHER_BLOCKS_POWERUP: u8 = 1;
45pub const OTHER_BLOCKS_WAIT: u16 = 1;
47pub const WIFI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
49pub const WIFI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
51pub const BT_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
53pub const BT_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
55pub const RTC_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
57pub const RTC_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
59pub const CPU_TOP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
61pub const CPU_TOP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
63pub const DG_WRAP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
65pub const DG_WRAP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
67pub const DG_PERI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
69pub const DG_PERI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
71pub const RTC_MEM_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
73pub const RTC_MEM_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
75
76bitfield::bitfield! {
77 #[derive(Clone, Copy)]
79 pub struct RtcSleepConfig(u64);
80 impl Debug;
81 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
83 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 1;
85 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 2;
87 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 3;
89 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 4;
91 pub modem_pd_en, set_modem_pd_en: 5;
93 pub cpu_pd_en, set_cpu_pd_en: 6;
95 pub int_8m_pd_en, set_int_8m_pd_en: 7;
97 pub dig_peri_pd_en, set_dig_peri_pd_en: 8;
99 pub deep_slp, set_deep_slp: 9;
101 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
103 pub u8, dig_dbias_slp, set_dig_dbias_slp: 15, 11;
105 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 20, 16;
107 pub bias_sleep_monitor, set_bias_sleep_monitor: 21;
109 pub u8, dbg_atten_slp, set_dbg_atten_slp: 25, 22;
111 pub bias_sleep_slp, set_bias_sleep_slp: 26;
113 pub pd_cur_monitor, set_pd_cur_monitor: 27;
115 pub pd_cur_slp, set_pd_cur_slp: 28;
117 pub vddsdio_pd_en, set_vddsdio_pd_en: 29;
119 pub xtal_fpu, set_xtal_fpu: 30;
121 pub rtc_regulator_fpu, set_rtc_regulator_fpu: 31;
123 pub deep_slp_reject, set_deep_slp_reject: 32;
125 pub light_slp_reject, set_light_slp_reject: 33;
127}
128
129impl Default for RtcSleepConfig {
130 fn default() -> Self {
131 let mut cfg = Self(Default::default());
132 cfg.set_deep_slp_reject(true);
133 cfg.set_light_slp_reject(true);
134 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
135 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
136
137 cfg.set_rtc_regulator_fpu(true);
141 cfg.set_bias_sleep_monitor(true);
142 cfg.set_pd_cur_monitor(true);
143 cfg.set_bias_sleep_slp(true);
144 cfg.set_pd_cur_slp(true);
145 cfg
146 }
147}
148
149const SYSCON_SRAM_POWER_UP: u16 = 0x7FF;
150const SYSCON_ROM_POWER_UP: u8 = 0x7;
151
152fn rtc_sleep_pu(val: bool) {
153 let rtc_cntl = LPWR::regs();
154 let syscon = unsafe { &*esp32s3::APB_CTRL::ptr() };
155 let bb = unsafe { &*esp32s3::BB::ptr() };
156 let nrx = unsafe { &*esp32s3::NRX::ptr() };
157 let fe = unsafe { &*esp32s3::FE::ptr() };
158 let fe2 = unsafe { &*esp32s3::FE2::ptr() };
159
160 rtc_cntl
161 .dig_pwc()
162 .modify(|_, w| w.lslp_mem_force_pu().bit(val));
163
164 rtc_cntl
165 .pwc()
166 .modify(|_, w| w.slowmem_force_lpu().bit(val).fastmem_force_lpu().bit(val));
167
168 syscon.front_end_mem_pd().modify(|_r, w| {
169 w.dc_mem_force_pu().bit(val);
170 w.pbus_mem_force_pu().bit(val);
171 w.agc_mem_force_pu().bit(val)
172 });
173
174 bb.bbpd_ctrl()
175 .modify(|_r, w| w.fft_force_pu().bit(val).dc_est_force_pu().bit(val));
176
177 nrx.nrxpd_ctrl().modify(|_, w| {
178 w.rx_rot_force_pu().bit(val);
179 w.vit_force_pu().bit(val);
180 w.demap_force_pu().bit(val)
181 });
182
183 fe.gen_ctrl().modify(|_, w| w.iq_est_force_pu().bit(val));
184
185 fe2.tx_interp_ctrl()
186 .modify(|_, w| w.tx_inf_force_pu().bit(val));
187
188 syscon.mem_power_up().modify(|_r, w| unsafe {
189 w.sram_power_up()
190 .bits(if val { SYSCON_SRAM_POWER_UP } else { 0 });
191 w.rom_power_up()
192 .bits(if val { SYSCON_ROM_POWER_UP } else { 0 })
193 });
194}
195
196impl RtcSleepConfig {
197 pub fn deep() -> Self {
199 let mut cfg = Self::default();
201
202 cfg.set_lslp_mem_inf_fpu(false);
203 cfg.set_rtc_mem_inf_follow_cpu(true); cfg.set_rtc_fastmem_pd_en(true);
205 cfg.set_rtc_slowmem_pd_en(true);
206 cfg.set_rtc_peri_pd_en(true);
207 cfg.set_modem_pd_en(true);
208 cfg.set_cpu_pd_en(true);
209 cfg.set_int_8m_pd_en(true);
210
211 cfg.set_dig_peri_pd_en(true);
212 cfg.set_dig_dbias_slp(0); cfg.set_deep_slp(true);
215 cfg.set_wdt_flashboot_mod_en(false);
216 cfg.set_vddsdio_pd_en(true);
217 cfg.set_xtal_fpu(false);
218 cfg.set_deep_slp_reject(true);
219 cfg.set_light_slp_reject(true);
220 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
221
222 cfg.set_rtc_regulator_fpu(false);
224 cfg.set_dbg_atten_slp(RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW);
225
226 cfg.set_bias_sleep_monitor(true);
228 cfg.set_pd_cur_monitor(true);
229 cfg.set_bias_sleep_slp(true);
230 cfg.set_pd_cur_slp(true);
231
232 cfg
233 }
234
235 pub(crate) fn is_deep_sleep(&self) -> bool {
236 self.deep_slp()
237 }
238
239 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
240 self.set_deep_slp(kind == SleepKind::Deep);
241 }
242
243 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
244 unsafe {
246 let rtc_cntl = LPWR::regs();
247 let syscon = APB_CTRL::regs();
248 let extmem = EXTMEM::regs();
249 let system = SYSTEM::regs();
250
251 rtc_cntl
252 .dig_pwc()
253 .modify(|_, w| w.wifi_force_pd().clear_bit());
254
255 regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
256 regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
257
258 rtc_cntl.ana_conf().modify(|_, w| w.pvtmon_pu().clear_bit());
259
260 rtc_cntl.timer1().modify(|_, w| {
261 w.pll_buf_wait()
262 .bits(RTC_CNTL_PLL_BUF_WAIT_DEFAULT)
263 .ck8m_wait()
264 .bits(RTC_CNTL_CK8M_WAIT_DEFAULT)
265 });
266
267 rtc_cntl
271 .timer5()
272 .modify(|_, w| w.min_slp_val().bits(RTC_CNTL_MIN_SLP_VAL_MIN));
273
274 rtc_cntl.timer3().modify(|_, w| {
275 w.wifi_powerup_timer().bits(WIFI_POWERUP_CYCLES);
277 w.wifi_wait_timer().bits(WIFI_WAIT_CYCLES);
279 w.bt_powerup_timer().bits(BT_POWERUP_CYCLES);
280 w.bt_wait_timer().bits(BT_WAIT_CYCLES)
281 });
282
283 rtc_cntl.timer6().modify(|_, w| {
284 w.cpu_top_powerup_timer().bits(CPU_TOP_POWERUP_CYCLES);
285 w.cpu_top_wait_timer().bits(CPU_TOP_WAIT_CYCLES)
286 });
287
288 rtc_cntl.timer4().modify(|_, w| {
289 w.powerup_timer().bits(RTC_POWERUP_CYCLES);
291 w.wait_timer().bits(RTC_WAIT_CYCLES);
293 w.dg_wrap_powerup_timer().bits(DG_WRAP_POWERUP_CYCLES);
294 w.dg_wrap_wait_timer().bits(DG_WRAP_WAIT_CYCLES)
295 });
296
297 rtc_cntl.timer6().modify(|_, w| {
298 w.dg_peri_powerup_timer().bits(DG_PERI_POWERUP_CYCLES);
299 w.dg_peri_wait_timer().bits(DG_PERI_WAIT_CYCLES)
300 });
301
302 regi2c::I2C_DIG_REG_EXT_RTC_DREG_SLEEP.write_field(RTC_CNTL_DBIAS_1V10);
304 regi2c::I2C_DIG_REG_EXT_RTC_DREG.write_field(RTC_CNTL_DBIAS_1V10);
305
306 rtc_cntl.timer2().modify(|_, w| {
309 w.ulpcp_touch_start_wait()
310 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
311 });
312
313 regi2c::I2C_DIG_REG_EXT_RTC_DREG.write_field(RTC_CNTL_DBIAS_1V25);
319 regi2c::I2C_DIG_REG_EXT_DIG_DREG.write_field(RTC_CNTL_DBIAS_1V25);
320
321 extmem
324 .cache_mmu_power_ctrl()
325 .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
326
327 syscon.clkgate_force_on().write(|w| w.bits(0));
329
330 extmem
333 .dcache_tag_power_ctrl()
334 .modify(|_, w| w.dcache_tag_mem_force_on().clear_bit());
335
336 extmem
337 .icache_tag_power_ctrl()
338 .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
339
340 SPI0::regs()
342 .clock_gate()
343 .modify(|_, w| w.clk_en().clear_bit());
344 SPI1::regs()
345 .clock_gate()
346 .modify(|_, w| w.clk_en().clear_bit());
347
348 rtc_cntl
349 .clk_conf()
350 .modify(|_, w| w.ck8m_force_pu().clear_bit());
351
352 rtc_cntl
353 .options0()
354 .modify(|_, w| w.xtl_force_pu().clear_bit());
355
356 rtc_cntl.ana_conf().modify(|_, w| {
357 w
358 .i2c_reset_por_force_pd()
362 .clear_bit()
363 });
364
365 rtc_cntl.options0().modify(|_, w| {
368 w.bbpll_force_pu().clear_bit();
369 w.bbpll_i2c_force_pu().clear_bit();
370 w.bb_i2c_force_pu().clear_bit()
371 });
372
373 rtc_cntl.pwc().modify(|_, w| w.force_pu().clear_bit());
376
377 rtc_cntl.rtc().modify(|_, w| {
378 w.regulator_force_pu().clear_bit();
379 w.dboost_force_pu().clear_bit()
380 });
381
382 rtc_cntl.pwc().modify(|_, w| {
383 w.slowmem_force_noiso().clear_bit();
384 w.fastmem_force_noiso().clear_bit()
385 });
386
387 rtc_cntl.rtc().modify(|_, w| w.dboost_force_pd().set_bit());
388
389 system
394 .mem_pd_mask()
395 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
396
397 rtc_sleep_pu(false);
401
402 rtc_cntl
403 .dig_pwc()
404 .modify(|_, w| w.dg_wrap_force_pu().clear_bit());
405
406 rtc_cntl.dig_iso().modify(|_, w| {
407 w.dg_wrap_force_noiso().clear_bit();
408 w.dg_wrap_force_iso().clear_bit()
409 });
410
411 rtc_cntl.dig_iso().modify(|_, w| {
412 w.wifi_force_noiso().clear_bit();
413 w.wifi_force_iso().clear_bit()
414 });
415
416 rtc_cntl
417 .dig_pwc()
418 .modify(|_, w| w.wifi_force_pu().clear_bit());
419
420 rtc_cntl
421 .dig_iso()
422 .modify(|_, w| w.bt_force_noiso().clear_bit().bt_force_iso().clear_bit());
423
424 rtc_cntl
425 .dig_pwc()
426 .modify(|_, w| w.bt_force_pu().clear_bit());
427
428 rtc_cntl.dig_iso().modify(|_, w| {
429 w.cpu_top_force_noiso().clear_bit();
430 w.cpu_top_force_iso().clear_bit()
431 });
432
433 rtc_cntl
434 .dig_pwc()
435 .modify(|_, w| w.cpu_top_force_pu().clear_bit());
436
437 rtc_cntl.dig_iso().modify(|_, w| {
438 w.dg_peri_force_noiso().clear_bit();
439 w.dg_peri_force_iso().clear_bit()
440 });
441
442 rtc_cntl
443 .dig_pwc()
444 .modify(|_, w| w.dg_peri_force_pu().clear_bit());
445
446 rtc_cntl.pwc().modify(|_, w| {
447 w.force_noiso().clear_bit();
448 w.force_iso().clear_bit();
449 w.force_pu().clear_bit()
450 });
451
452 system
456 .cpu_per_conf()
457 .modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
458
459 rtc_cntl.dig_iso().modify(|_, w| {
462 w.dg_pad_force_unhold().clear_bit();
463 w.dg_pad_force_noiso().clear_bit()
464 });
465
466 rtc_cntl
469 .dig_iso()
470 .modify(|_, w| w.wifi_force_iso().set_bit());
471
472 rtc_cntl
473 .dig_pwc()
474 .modify(|_, w| w.wifi_force_pd().set_bit());
475
476 rtc_cntl.int_ena().write(|w| w.bits(0));
477 rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
478 }
479 }
480
481 pub(crate) fn apply(&self) {
482 let rtc_cntl = LPWR::regs();
484
485 if self.lslp_mem_inf_fpu() {
486 rtc_sleep_pu(true);
487 }
488
489 if self.modem_pd_en() {
490 rtc_cntl.dig_iso().modify(|_, w| {
491 w.wifi_force_noiso().clear_bit();
492 w.wifi_force_iso().clear_bit()
493 });
494
495 rtc_cntl
496 .dig_pwc()
497 .modify(|_, w| w.wifi_force_pu().clear_bit().wifi_pd_en().set_bit());
498 } else {
499 rtc_cntl.options0().modify(|_, w| {
500 w.bbpll_force_pu().set_bit();
501 w.bbpll_i2c_force_pu().set_bit();
502 w.bb_i2c_force_pu().set_bit()
503 });
504
505 rtc_cntl
506 .dig_pwc()
507 .modify(|_, w| w.wifi_force_pu().set_bit().wifi_pd_en().clear_bit());
508 }
509
510 if self.cpu_pd_en() {
511 rtc_cntl.dig_iso().modify(|_, w| {
512 w.cpu_top_force_noiso().clear_bit();
513 w.cpu_top_force_iso().clear_bit()
514 });
515
516 rtc_cntl
517 .dig_pwc()
518 .modify(|_, w| w.cpu_top_force_pu().clear_bit().cpu_top_pd_en().set_bit());
519 } else {
520 rtc_cntl
521 .dig_pwc()
522 .modify(|_, w| w.cpu_top_pd_en().clear_bit());
523 }
524
525 if self.dig_peri_pd_en() {
526 rtc_cntl.dig_iso().modify(|_, w| {
527 w.dg_peri_force_noiso().clear_bit();
528 w.dg_peri_force_iso().clear_bit()
529 });
530
531 rtc_cntl
532 .dig_pwc()
533 .modify(|_, w| w.dg_peri_force_pu().clear_bit().dg_peri_pd_en().set_bit());
534 } else {
535 rtc_cntl
536 .dig_pwc()
537 .modify(|_, w| w.dg_peri_pd_en().clear_bit());
538 }
539
540 if self.rtc_peri_pd_en() {
541 rtc_cntl.pwc().modify(|_, w| {
542 w.force_noiso().clear_bit();
543 w.force_iso().clear_bit();
544 w.force_pu().clear_bit();
545 w.pd_en().set_bit()
546 });
547 } else {
548 rtc_cntl.pwc().modify(|_, w| w.pd_en().clear_bit());
549 }
550
551 unsafe {
552 regi2c::I2C_DIG_REG_EXT_RTC_DREG_SLEEP.write_field(self.rtc_dbias_slp());
553 regi2c::I2C_DIG_REG_EXT_DIG_DREG_SLEEP.write_field(self.dig_dbias_slp());
554
555 rtc_cntl.bias_conf().modify(|_, w| {
556 w.dbg_atten_deep_slp().bits(self.dbg_atten_slp());
557 w.bias_sleep_deep_slp().bit(self.bias_sleep_slp());
558 w.pd_cur_deep_slp().bit(self.pd_cur_slp());
559 w.dbg_atten_monitor()
560 .bits(RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
561 w.bias_sleep_monitor().bit(self.bias_sleep_monitor());
562 w.pd_cur_monitor().bit(self.pd_cur_monitor())
563 });
564
565 if self.deep_slp() {
566 rtc_cntl
567 .dig_pwc()
568 .modify(|_, w| w.dg_wrap_pd_en().set_bit());
569
570 rtc_cntl.ana_conf().modify(|_, w| {
571 w.ckgen_i2c_pu().clear_bit();
572 w.pll_i2c_pu().clear_bit();
573 w.rfrx_pbus_pu().clear_bit();
574 w.txrf_i2c_pu().clear_bit()
575 });
576
577 rtc_cntl
578 .options0()
579 .modify(|_, w| w.bb_i2c_force_pu().clear_bit());
580 } else {
581 rtc_cntl
582 .regulator_drv_ctrl()
583 .modify(|_, w| w.dg_vdd_drv_b_slp().bits(0xF));
584
585 rtc_cntl
586 .dig_pwc()
587 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
588 }
589
590 rtc_cntl
593 .dig_pwc()
594 .modify(|_, w| w.lslp_mem_force_pu().set_bit());
595
596 rtc_cntl
597 .rtc()
598 .modify(|_, w| w.regulator_force_pu().bit(self.rtc_regulator_fpu()));
599
600 rtc_cntl
601 .clk_conf()
602 .modify(|_, w| w.ck8m_force_pu().bit(!self.int_8m_pd_en()));
603
604 rtc_cntl.sdio_conf().modify(|_, w| {
607 w.sdio_force().clear_bit();
608 w.sdio_reg_pd_en().bit(self.vddsdio_pd_en())
609 });
610
611 rtc_cntl.slp_reject_conf().modify(|_, w| {
612 w.deep_slp_reject_en().bit(self.deep_slp_reject());
613 w.light_slp_reject_en().bit(self.light_slp_reject())
614 });
615
616 rtc_cntl.timer2().modify(|_, w| {
620 w.ulpcp_touch_start_wait()
621 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP)
622 });
623
624 rtc_cntl
625 .options0()
626 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
627
628 rtc_cntl
629 .clk_conf()
630 .modify(|_, w| w.xtal_global_force_nogating().bit(self.xtal_fpu()));
631 }
632 }
633
634 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) {
638 unsafe {
639 LPWR::regs()
640 .reset_state()
641 .modify(|_, w| w.procpu_stat_vector_sel().set_bit());
642
643 LPWR::regs()
645 .wakeup_state()
646 .modify(|_, w| w.wakeup_ena().bits(wakeup_mask));
647
648 LPWR::regs()
651 .slp_reject_conf()
652 .modify(|_, w| w.sleep_reject_ena().bits(reject_mask));
653
654 LPWR::regs().state0().modify(|_, w| w.sleep_en().set_bit());
655 }
656 }
657
658 pub(crate) fn finish_sleep(&self) {
659 unsafe {
661 LPWR::regs().int_clr().write(|w| {
662 w.slp_reject().clear_bit_by_one();
663 w.slp_wakeup().clear_bit_by_one()
664 });
665
666 if self.lslp_mem_inf_fpu() {
668 rtc_sleep_pu(true);
669 }
670
671 LPWR::regs().timer2().modify(|_, w| {
674 w.ulpcp_touch_start_wait()
675 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
676 });
677 }
678 }
679}