1use super::SleepKind;
2use crate::{
3 peripherals::{EXTMEM, LPWR, SPI0, SPI1, SYSTEM},
4 rtc_cntl::Rtc,
5 soc::regi2c,
6};
7
8pub const RTC_CNTL_DBIAS_0V90: u8 = 0;
13pub const RTC_CNTL_DBIAS_0V95: u8 = 1;
15pub const RTC_CNTL_DBIAS_1V00: u8 = 2;
17pub const RTC_CNTL_DBIAS_1V05: u8 = 3;
19pub const RTC_CNTL_DBIAS_1V10: u8 = 4;
21pub const RTC_CNTL_DBIAS_1V15: u8 = 5;
23pub const RTC_CNTL_DBIAS_1V20: u8 = 6;
25pub const RTC_CNTL_DBIAS_1V25: u8 = 7;
27pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0;
29pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP: u16 = 0xFF;
31pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT: u16 = 0x10;
33pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20;
35pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
37pub const RTC_CNTL_XTL_BUF_WAIT_DEFAULT: u8 = 100;
39pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2;
41pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT: 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 RTC_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
53pub const RTC_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
55pub const DG_WRAP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
57pub const DG_WRAP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
59pub const DG_PERI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
61pub const DG_PERI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
63pub const RTC_MEM_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP;
65pub const RTC_MEM_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT;
67
68bitfield::bitfield! {
69 #[derive(Clone, Copy)]
71 pub struct RtcSleepConfig(u64);
72 impl Debug;
73 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
75 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 1;
77 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 2;
79 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 3;
81 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 4;
83 pub wifi_pd_en, set_wifi_pd_en: 5;
85 pub int_8m_pd_en, set_int_8m_pd_en: 6;
87 pub deep_slp, set_deep_slp: 8;
89 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 9;
91 pub u8, dig_dbias_slp, set_dig_dbias_slp: 12, 10;
93 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 16, 13;
95 pub bias_sleep_monitor, set_bias_sleep_monitor: 17;
97 pub u8, dbg_atten_slp, set_dbg_atten_slp: 22, 18;
99 pub bias_sleep_slp, set_bias_sleep_slp: 23;
101 pub pd_cur_monitor, set_pd_cur_monitor: 24;
103 pub pd_cur_slp, set_pd_cur_slp: 25;
105 pub vddsdio_pd_en, set_vddsdio_pd_en: 26;
107 pub xtal_fpu, set_xtal_fpu: 27;
109 pub rtc_regulator_fpu, set_rtc_regulator_fpu: 28;
111 pub deep_slp_reject, set_deep_slp_reject: 29;
113 pub light_slp_reject, set_light_slp_reject: 30;
115}
116
117impl Default for RtcSleepConfig {
118 fn default() -> Self {
119 let mut cfg = Self(Default::default());
120 cfg.set_deep_slp_reject(true);
121 cfg.set_light_slp_reject(true);
122 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
123 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
124
125 cfg.set_rtc_regulator_fpu(true);
129 cfg.set_bias_sleep_monitor(true);
130 cfg.set_pd_cur_monitor(true);
131 cfg.set_bias_sleep_slp(true);
132 cfg.set_pd_cur_slp(true);
133 cfg
134 }
135}
136
137fn rtc_sleep_pu(val: bool) {
138 let rtc_cntl = LPWR::regs();
141 let syscon = unsafe { &*esp32s2::SYSCON::ptr() };
142 let bb = unsafe { &*esp32s2::BB::ptr() };
143 let i2s = unsafe { &*esp32s2::I2S0::ptr() };
144 let nrx = unsafe { &*esp32s2::NRX::ptr() };
145 let fe = unsafe { &*esp32s2::FE::ptr() };
146 let fe2 = unsafe { &*esp32s2::FE2::ptr() };
147
148 rtc_cntl
149 .dig_pwc()
150 .modify(|_, w| w.lslp_mem_force_pu().bit(val));
151
152 rtc_cntl
153 .pwc()
154 .modify(|_, w| w.slowmem_force_lpu().bit(val).fastmem_force_lpu().bit(val));
155
156 i2s.pd_conf()
157 .write(|w| w.plc_mem_force_pu().bit(val).fifo_force_pu().bit(val));
158
159 syscon.front_end_mem_pd().modify(|_r, w| {
160 w.dc_mem_force_pu()
161 .bit(val)
162 .pbus_mem_force_pu()
163 .bit(val)
164 .agc_mem_force_pu()
165 .bit(val)
166 });
167
168 bb.bbpd_ctrl()
169 .modify(|_r, w| w.fft_force_pu().bit(val).dc_est_force_pu().bit(val));
170
171 nrx.nrxpd_ctrl().modify(|_, w| {
172 w.rx_rot_force_pu()
173 .bit(val)
174 .vit_force_pu()
175 .bit(val)
176 .demap_force_pu()
177 .bit(val)
178 });
179
180 fe.gen_ctrl().modify(|_, w| w.iq_est_force_pu().bit(val));
181
182 fe2.tx_interp_ctrl()
183 .modify(|_, w| w.tx_inf_force_pu().bit(val));
184}
185
186impl RtcSleepConfig {
187 pub fn deep() -> Self {
189 let mut cfg = Self::default();
191
192 cfg.set_lslp_mem_inf_fpu(false);
193 cfg.set_rtc_mem_inf_follow_cpu(true); cfg.set_rtc_fastmem_pd_en(true);
195 cfg.set_rtc_slowmem_pd_en(true);
196 cfg.set_rtc_peri_pd_en(true);
197 cfg.set_wifi_pd_en(true);
198 cfg.set_int_8m_pd_en(true);
199
200 cfg.set_vddsdio_pd_en(true);
202
203 cfg.set_dig_dbias_slp(0);
205
206 cfg.set_deep_slp(true);
207 cfg.set_wdt_flashboot_mod_en(false);
208 cfg.set_vddsdio_pd_en(true);
209 cfg.set_xtal_fpu(false);
210 cfg.set_deep_slp_reject(true);
211 cfg.set_light_slp_reject(true);
212
213 cfg.set_rtc_regulator_fpu(false);
217 cfg.set_dbg_atten_slp(RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT);
218 cfg.set_rtc_dbias_slp(0);
219
220 cfg.set_xtal_fpu(false);
222 cfg.set_bias_sleep_monitor(true);
223 cfg.set_pd_cur_monitor(true);
224 cfg.set_bias_sleep_slp(true);
225 cfg.set_pd_cur_slp(true);
226
227 cfg
228 }
229
230 pub(crate) fn is_deep_sleep(&self) -> bool {
231 self.deep_slp()
232 }
233
234 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
235 self.set_deep_slp(kind == SleepKind::Deep);
236 }
237
238 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
239 unsafe {
241 let rtc_cntl = LPWR::regs();
242 let extmem = EXTMEM::regs();
243 let system = SYSTEM::regs();
244
245 rtc_cntl
246 .dig_pwc()
247 .modify(|_, w| w.wifi_force_pd().clear_bit());
248 rtc_cntl
249 .dig_iso()
250 .modify(|_, w| w.wifi_force_iso().clear_bit());
251
252 rtc_cntl.ana_conf().modify(|_, w| w.pvtmon_pu().clear_bit());
253
254 rtc_cntl.timer1().modify(|_, w| {
255 w.pll_buf_wait().bits(RTC_CNTL_PLL_BUF_WAIT_DEFAULT);
256 w.ck8m_wait().bits(RTC_CNTL_CK8M_WAIT_DEFAULT)
257 });
258
259 rtc_cntl
263 .timer5()
264 .modify(|_, w| w.min_slp_val().bits(RTC_CNTL_MIN_SLP_VAL_MIN));
265
266 rtc_cntl.timer3().modify(|_, w| {
267 w.wifi_powerup_timer().bits(WIFI_POWERUP_CYCLES);
269 w.wifi_wait_timer().bits(WIFI_WAIT_CYCLES)
270 });
271
272 rtc_cntl.timer4().modify(|_, w| {
273 w.powerup_timer().bits(RTC_POWERUP_CYCLES);
275 w.wait_timer().bits(RTC_WAIT_CYCLES);
276 w.dg_wrap_powerup_timer().bits(DG_WRAP_POWERUP_CYCLES);
278 w.dg_wrap_wait_timer().bits(DG_WRAP_WAIT_CYCLES)
279 });
280
281 rtc_cntl.timer5().modify(|_, w| {
282 w.rtcmem_powerup_timer().bits(RTC_MEM_POWERUP_CYCLES);
283 w.rtcmem_wait_timer().bits(RTC_MEM_WAIT_CYCLES)
284 });
285
286 rtc_cntl.bias_conf().modify(|_, w| {
287 w.dec_heartbeat_width().set_bit();
288 w.inc_heartbeat_period().set_bit()
289 });
290
291 rtc_cntl.reg().modify(|_, w| {
293 w.dbias_wak().bits(RTC_CNTL_DBIAS_1V10);
294 w.dbias_slp().bits(RTC_CNTL_DBIAS_1V10)
295 });
296
297 rtc_cntl.timer2().modify(|_, w| {
299 w.ulpcp_touch_start_wait()
300 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
301 });
302
303 {
305 extmem
307 .pro_cache_mmu_power_ctrl()
308 .modify(|_, w| w.pro_cache_mmu_mem_force_on().clear_bit());
309
310 extmem
312 .pro_dcache_tag_power_ctrl()
313 .modify(|_, w| w.pro_dcache_tag_mem_force_on().clear_bit());
314
315 extmem
316 .pro_icache_tag_power_ctrl()
317 .modify(|_, w| w.pro_icache_tag_mem_force_on().clear_bit());
318
319 system.rom_ctrl_0().modify(|_, w| w.rom_fo().bits(0));
320 system.sram_ctrl_0().modify(|_, w| w.sram_fo().bits(0));
321
322 SPI0::regs()
324 .clock_gate()
325 .modify(|_, w| w.clk_en().clear_bit());
326 SPI1::regs()
327 .clock_gate()
328 .modify(|_, w| w.clk_en().clear_bit());
329 }
330
331 {
333 rtc_cntl
334 .clk_conf()
335 .modify(|_, w| w.ck8m_force_pu().clear_bit());
336
337 rtc_cntl
338 .options0()
339 .modify(|_, w| w.xtl_force_pu().clear_bit());
340
341 rtc_cntl.ana_conf().modify(|_, w| {
343 w.plla_force_pu().clear_bit();
344 w.plla_force_pd().set_bit()
345 });
346
347 rtc_cntl.options0().modify(|_, w| {
349 w.bbpll_force_pu().clear_bit();
350 w.bbpll_i2c_force_pu().clear_bit();
351 w.bb_i2c_force_pu().clear_bit()
352 });
353
354 rtc_cntl.pwc().modify(|_, w| w.force_pu().clear_bit());
357 rtc_cntl.reg().modify(|_, w| {
358 w.regulator_force_pu().clear_bit();
359 w.dboost_force_pu().clear_bit()
360 });
361
362 rtc_cntl.pwc().modify(|_, w| {
363 w.slowmem_force_pu().clear_bit();
364 w.fastmem_force_pu().clear_bit();
365 w.slowmem_force_noiso().clear_bit();
366 w.fastmem_force_noiso().clear_bit()
367 });
368
369 rtc_cntl.reg().modify(|_, w| w.dboost_force_pd().set_bit());
370
371 rtc_cntl
373 .ana_conf()
374 .modify(|_, w| w.sar_i2c_force_pd().clear_bit());
375 rtc_cntl.pwc().modify(|_, w| {
378 w.slowmem_force_pu().clear_bit();
379 w.fastmem_force_pu().clear_bit()
380 });
381
382 system
387 .mem_pd_mask()
388 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
389
390 rtc_sleep_pu(false);
394
395 rtc_cntl.dig_pwc().modify(|_, w| {
396 w.dg_wrap_force_pu().clear_bit();
397 w.wifi_force_pu().clear_bit()
398 });
399
400 rtc_cntl.dig_iso().modify(|_, w| {
401 w.dg_wrap_force_noiso().clear_bit();
402 w.dg_wrap_force_iso().clear_bit()
404 });
405
406 rtc_cntl.dig_iso().modify(|_, w| {
407 w.wifi_force_noiso().clear_bit();
408 w.wifi_force_iso().clear_bit()
410 });
411
412 rtc_cntl.pwc().modify(|_, w| w.force_noiso().clear_bit());
413
414 system
416 .cpu_per_conf()
417 .modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
418
419 rtc_cntl.dig_iso().modify(|_, w| {
422 w.dg_pad_force_unhold().clear_bit();
423 w.dg_pad_force_noiso().clear_bit()
424 });
425 }
426
427 rtc_cntl
429 .dig_iso()
430 .modify(|_, w| w.wifi_force_iso().set_bit());
431
432 rtc_cntl
433 .dig_pwc()
434 .modify(|_, w| w.wifi_force_pd().set_bit());
435
436 rtc_cntl.int_ena().write(|w| w.bits(0));
437 rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
438 }
439 }
440
441 pub(crate) fn apply(&self) {
442 let rtc_cntl = LPWR::regs();
444
445 if self.deep_slp() {
446 unsafe {
451 rtc_cntl.brown_out().modify(|_, w| {
453 w.int_wait().bits(2);
454 w.close_flash_ena().clear_bit();
455 w.pd_rf_ena().clear_bit();
456 w.cnt_clr().set_bit()
457 });
458 rtc_cntl.brown_out().modify(|_, w| {
459 w.cnt_clr().clear_bit();
461 w.rst_wait().bits(0x3fff);
462 w.rst_ena().clear_bit();
463 w.brown_out2_ena().set_bit();
464 w.rst_sel().set_bit()
465 });
466 regi2c::I2C_BOD_REG_THRESHOLD.write_field(0);
467 rtc_cntl.brown_out().modify(|_, w| w.ena().clear_bit());
468 rtc_cntl.int_ena().modify(|_, w| w.brown_out().clear_bit());
469 }
471 }
472
473 if self.lslp_mem_inf_fpu() {
474 rtc_sleep_pu(true);
475 }
476
477 let mem_folw_cpu = self.rtc_mem_inf_follow_cpu();
478 rtc_cntl.pwc().modify(|_, w| {
479 w.slowmem_folw_cpu().bit(mem_folw_cpu);
480 w.fastmem_folw_cpu().bit(mem_folw_cpu)
481 });
482
483 let rtc_fastmem_pd_en = self.rtc_fastmem_pd_en();
484 rtc_cntl.pwc().modify(|_, w| {
485 w.fastmem_pd_en().bit(rtc_fastmem_pd_en);
486 w.fastmem_force_pu().bit(!rtc_fastmem_pd_en);
487 w.fastmem_force_noiso().bit(!rtc_fastmem_pd_en)
488 });
489
490 let rtc_slowmem_pd_en = self.rtc_slowmem_pd_en();
491 rtc_cntl.pwc().modify(|_, w| {
492 w.slowmem_pd_en().bit(rtc_slowmem_pd_en);
493 w.slowmem_force_pu().bit(!rtc_slowmem_pd_en);
494 w.slowmem_force_noiso().bit(!rtc_slowmem_pd_en)
495 });
496
497 let rtc_peri_pd_en = self.rtc_peri_pd_en();
498 rtc_cntl.pwc().modify(|_, w| w.pd_en().bit(rtc_peri_pd_en));
499
500 if self.wifi_pd_en() {
501 rtc_cntl
502 .dig_iso()
503 .modify(|_, w| w.wifi_force_noiso().clear_bit());
504
505 rtc_cntl.dig_pwc().modify(|_, w| {
506 w.wifi_force_pu().clear_bit();
507 w.wifi_pd_en().set_bit()
508 });
509 } else {
510 rtc_cntl.dig_pwc().modify(|_, w| w.wifi_pd_en().clear_bit());
511 }
512
513 unsafe {
514 rtc_cntl.reg().modify(|_, w| {
515 w.dbias_slp().bits(self.rtc_dbias_slp());
516 w.dig_reg_dbias_slp().bits(self.dig_dbias_slp())
517 });
518
519 rtc_cntl.bias_conf().modify(|_, w| {
520 w.dbg_atten_monitor()
521 .bits(RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
522 w.bias_sleep_monitor().bit(self.bias_sleep_monitor());
523 w.bias_sleep_deep_slp().bit(self.bias_sleep_slp());
524 w.pd_cur_monitor().bit(self.pd_cur_monitor());
525 w.pd_cur_deep_slp().bit(self.pd_cur_slp());
526 w.dbg_atten_deep_slp().bits(self.dbg_atten_slp())
527 });
528
529 if self.deep_slp() {
530 rtc_cntl
531 .dig_pwc()
532 .modify(|_, w| w.dg_wrap_pd_en().set_bit());
533
534 rtc_cntl.ana_conf().modify(|_, w| {
535 w.ckgen_i2c_pu().clear_bit();
536 w.pll_i2c_pu().clear_bit();
537 w.rfrx_pbus_pu().clear_bit();
538 w.txrf_i2c_pu().clear_bit()
539 });
540
541 rtc_cntl
542 .options0()
543 .modify(|_, w| w.bb_i2c_force_pu().clear_bit());
544 } else {
545 rtc_cntl
546 .dig_pwc()
547 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
548 }
549
550 let rtc_regulator_fpu = self.rtc_regulator_fpu();
551 rtc_cntl
552 .reg()
553 .modify(|_, w| w.regulator_force_pu().bit(rtc_regulator_fpu));
554
555 let int_8m_pd_en = self.int_8m_pd_en();
556 rtc_cntl
557 .clk_conf()
558 .modify(|_, w| w.ck8m_force_pu().bit(!int_8m_pd_en));
559
560 rtc_cntl.sdio_conf().modify(|_, w| {
562 w.sdio_force().clear_bit();
563 w.sdio_reg_pd_en().bit(self.vddsdio_pd_en())
564 });
565
566 rtc_cntl.slp_reject_conf().modify(|_, w| {
567 w.deep_slp_reject_en().bit(self.deep_slp_reject());
568 w.light_slp_reject_en().bit(self.light_slp_reject())
569 });
570
571 rtc_cntl.timer2().modify(|_, w| {
575 w.ulpcp_touch_start_wait()
576 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP)
577 });
578
579 rtc_cntl
580 .options0()
581 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
582 }
583 }
584
585 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) {
589 unsafe {
590 LPWR::regs()
591 .reset_state()
592 .modify(|_, w| w.procpu_stat_vector_sel().set_bit());
593
594 LPWR::regs()
596 .wakeup_state()
597 .modify(|_, w| w.wakeup_ena().bits(wakeup_mask));
598
599 LPWR::regs()
602 .slp_reject_conf()
603 .modify(|_, w| w.sleep_reject_ena().bits(reject_mask));
604
605 LPWR::regs().state0().modify(|_, w| w.sleep_en().set_bit());
606 }
607 }
608
609 pub(crate) fn finish_sleep(&self) {
610 unsafe {
612 LPWR::regs().int_clr().write(|w| {
613 w.slp_reject()
614 .clear_bit_by_one()
615 .slp_wakeup()
616 .clear_bit_by_one()
617 });
618
619 if self.lslp_mem_inf_fpu() {
621 rtc_sleep_pu(true);
622 }
623
624 LPWR::regs().timer2().modify(|_, w| {
627 w.ulpcp_touch_start_wait()
628 .bits(RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT)
629 });
630 }
631 }
632}