1use super::SleepKind;
2use crate::{
3 peripherals::{APB_CTRL, BB, 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;
29
30pub const RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT: u8 = 5;
32pub const RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP: u8 = 0;
34pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT: u8 = 15;
36pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: u8 = 0;
38
39pub const RTC_CNTL_BIASSLP_SLEEP_DEFAULT: u8 = 1;
41pub const RTC_CNTL_BIASSLP_SLEEP_ON: u8 = 0;
43
44pub const RTC_CNTL_PD_CUR_SLEEP_DEFAULT: u8 = 1;
46pub const RTC_CNTL_PD_CUR_SLEEP_ON: u8 = 0;
48
49pub const RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT: u8 = 254;
51
52pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0;
54pub const RTC_CNTL_BIASSLP_MONITOR_DEFAULT: bool = false;
56pub const RTC_CNTL_PD_CUR_MONITOR_DEFAULT: bool = false;
58
59pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20;
61pub const RTC_CNTL_XTL_BUF_WAIT_DEFAULT: u8 = 100;
63pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
65pub const RTC_CK8M_ENABLE_WAIT_DEFAULT: u8 = 5;
67
68pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2;
70
71pub const OTHER_BLOCKS_POWERUP: u8 = 1;
73pub const OTHER_BLOCKS_WAIT: u16 = 1;
75
76pub const GPIO_INTR_DISABLE: u8 = 0;
78pub const GPIO_INTR_LOW_LEVEL: u8 = 4;
80pub const GPIO_INTR_HIGH_LEVEL: u8 = 5;
82
83pub const PIN_FUNC_GPIO: u8 = 1;
85pub const SIG_GPIO_OUT_IDX: u32 = 128;
87pub const GPIO_NUM_MAX: usize = 22;
89
90bitfield::bitfield! {
91 #[derive(Clone, Copy)]
92 pub struct RtcConfig(u32);
94 impl Debug;
95 pub u8, ck8m_wait, set_ck8m_wait: 7, 0;
97 pub u8, xtal_wait, set_xtal_wait: 15, 8;
99 pub u8, pll_wait, set_pll_wait: 23, 16;
101 pub clkctl_init, set_clkctl_init: 24;
103 pub pwrctl_init, set_pwrctl_init: 25;
105 pub rtc_dboost_fpd, set_rtc_dboost_fpd: 26;
107 pub xtal_fpu, set_xtal_fpu: 27;
109 pub bbpll_fpu, set_bbpll_fpu: 28;
111 pub cpu_waiti_clk_gate, set_cpu_waiti_clk_gate: 29;
113 pub cali_ocode, set_cali_ocode: 30;
115}
116
117impl Default for RtcConfig {
118 fn default() -> Self {
119 let mut cfg = Self(Default::default());
120 cfg.set_ck8m_wait(RTC_CNTL_CK8M_WAIT_DEFAULT);
121 cfg.set_xtal_wait(RTC_CNTL_XTL_BUF_WAIT_DEFAULT);
122 cfg.set_pll_wait(RTC_CNTL_PLL_BUF_WAIT_DEFAULT);
123 cfg.set_clkctl_init(true);
124 cfg.set_pwrctl_init(true);
125 cfg.set_rtc_dboost_fpd(true);
126 cfg.set_cpu_waiti_clk_gate(true);
127 cfg.set_bbpll_fpu(true);
128 cfg
129 }
130}
131
132bitfield::bitfield! {
133 #[derive(Clone, Copy)]
134 pub struct RtcInitConfig(u128);
136 impl Debug;
137 pub u8, wifi_powerup_cycles, set_wifi_powerup_cycles: 6, 0;
139 pub u16, wifi_wait_cycles, set_wifi_wait_cycles: 15, 7;
141 pub u8, bt_powerup_cycles, set_bt_powerup_cycles: 22, 16;
143 pub u16, bt_wait_cycles, set_bt_wait_cycles: 31, 23;
145 pub u8, cpu_top_powerup_cycles, set_cpu_top_powerup_cycles: 38, 32;
147 pub u16, cpu_top_wait_cycles, set_cpu_top_wait_cycles: 47, 39;
149 pub u8, dg_wrap_powerup_cycles, set_dg_wrap_powerup_cycles: 54, 48;
151 pub u16, dg_wrap_wait_cycles, set_dg_wrap_wait_cycles: 63, 55;
153 pub u8, dg_peri_powerup_cycles, set_dg_peri_powerup_cycles: 70, 64;
155 pub u16, dg_peri_wait_cycles, set_dg_peri_wait_cycles: 79, 71;
157}
158
159impl Default for RtcInitConfig {
160 fn default() -> Self {
161 let mut cfg = Self(Default::default());
162 cfg.set_wifi_powerup_cycles(OTHER_BLOCKS_POWERUP);
163 cfg.set_bt_powerup_cycles(OTHER_BLOCKS_POWERUP);
164 cfg.set_cpu_top_powerup_cycles(OTHER_BLOCKS_POWERUP);
165 cfg.set_dg_wrap_powerup_cycles(OTHER_BLOCKS_POWERUP);
166 cfg.set_dg_peri_powerup_cycles(OTHER_BLOCKS_POWERUP);
167 cfg.set_wifi_wait_cycles(OTHER_BLOCKS_WAIT);
168 cfg.set_bt_wait_cycles(OTHER_BLOCKS_WAIT);
169 cfg.set_cpu_top_wait_cycles(OTHER_BLOCKS_WAIT);
170 cfg.set_dg_wrap_wait_cycles(OTHER_BLOCKS_WAIT);
171 cfg.set_dg_peri_wait_cycles(OTHER_BLOCKS_WAIT);
172 cfg
173 }
174}
175
176bitfield::bitfield! {
177 #[derive(Clone, Copy)]
178 pub struct RtcSleepConfig(u64);
180 impl Debug;
181 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
183 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 1;
185 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 2;
187 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 3;
189 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 4;
191 pub wifi_pd_en, set_wifi_pd_en: 5;
193 pub bt_pd_en, set_bt_pd_en: 6;
195 pub int_8m_pd_en, set_int_8m_pd_en: 8;
197 pub dig_peri_pd_en, set_dig_peri_pd_en: 9;
199 pub deep_slp, set_deep_slp: 10;
201 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 11;
203 pub u8, dig_dbias_slp, set_dig_dbias_slp: 16, 12;
205 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 21, 17;
207 pub u8, dbg_atten_slp, set_dbg_atten_slp: 25, 22;
209 pub bias_sleep_monitor, set_bias_sleep_monitor: 26;
211 pub bias_sleep_slp, set_bias_sleep_slp: 27;
213 pub pd_cur_slp, set_pd_cur_slp: 28;
215 pub vddsdio_pd_en, set_vddsdio_pd_en: 29;
217 pub xtal_fpu, set_xtal_fpu: 30;
219 pub rtc_regulator_fpu, set_rtc_regulator_fpu: 31;
221 pub deep_slp_reject, set_deep_slp_reject: 32;
223 pub light_slp_reject, set_light_slp_reject: 33;
225}
226
227impl Default for RtcSleepConfig {
228 fn default() -> Self {
229 let mut cfg = Self(Default::default());
230 cfg.set_deep_slp_reject(true);
231 cfg.set_light_slp_reject(true);
232 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
233 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
234
235 cfg.set_rtc_regulator_fpu(true);
239 cfg.set_bias_sleep_monitor(true);
240 cfg.set_bias_sleep_slp(true);
241 cfg.set_pd_cur_slp(true);
242 cfg
243 }
244}
245
246const DR_REG_NRX_BASE: u32 = 0x6001CC00;
247const DR_REG_FE_BASE: u32 = 0x60006000;
248const DR_REG_FE2_BASE: u32 = 0x60005000;
249
250const NRXPD_CTRL: u32 = DR_REG_NRX_BASE + 0x00d4;
251const FE_GEN_CTRL: u32 = DR_REG_FE_BASE + 0x0090;
252const FE2_TX_INTERP_CTRL: u32 = DR_REG_FE2_BASE + 0x00f0;
253
254const SYSCON_SRAM_POWER_UP: u8 = 0x0000000F;
255const SYSCON_ROM_POWER_UP: u8 = 0x00000003;
256
257const NRX_RX_ROT_FORCE_PU: u32 = 1 << 5;
258const NRX_VIT_FORCE_PU: u32 = 1 << 3;
259const NRX_DEMAP_FORCE_PU: u32 = 1 << 1;
260
261const FE_IQ_EST_FORCE_PU: u32 = 1 << 5;
262const FE2_TX_INF_FORCE_PU: u32 = 1 << 10;
263
264fn modify_register(reg: u32, mask: u32, value: u32) {
265 let reg = reg as *mut u32;
266
267 unsafe { reg.write_volatile((reg.read_volatile() & !mask) | value) };
268}
269
270fn register_modify_bits(reg: u32, bits: u32, set: bool) {
271 if set {
272 modify_register(reg, bits, bits);
273 } else {
274 modify_register(reg, bits, 0);
275 }
276}
277
278fn rtc_sleep_pu(val: bool) {
279 LPWR::regs()
280 .dig_pwc()
281 .modify(|_, w| w.lslp_mem_force_pu().bit(val));
282
283 APB_CTRL::regs().front_end_mem_pd().modify(|_r, w| {
284 w.dc_mem_force_pu().bit(val);
285 w.pbus_mem_force_pu().bit(val);
286 w.agc_mem_force_pu().bit(val)
287 });
288
289 BB::regs()
290 .bbpd_ctrl()
291 .modify(|_r, w| w.fft_force_pu().bit(val).dc_est_force_pu().bit(val));
292
293 register_modify_bits(
294 NRXPD_CTRL,
295 NRX_RX_ROT_FORCE_PU | NRX_VIT_FORCE_PU | NRX_DEMAP_FORCE_PU,
296 val,
297 );
298
299 register_modify_bits(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, val);
300
301 register_modify_bits(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, val);
302
303 APB_CTRL::regs().mem_power_up().modify(|_r, w| unsafe {
304 w.sram_power_up()
305 .bits(if val { SYSCON_SRAM_POWER_UP } else { 0 });
306 w.rom_power_up()
307 .bits(if val { SYSCON_ROM_POWER_UP } else { 0 })
308 });
309}
310
311impl RtcSleepConfig {
312 pub fn deep() -> Self {
314 let mut cfg = Self::default();
316
317 cfg.set_lslp_mem_inf_fpu(false);
318 cfg.set_rtc_mem_inf_follow_cpu(true); cfg.set_rtc_fastmem_pd_en(true);
320 cfg.set_rtc_slowmem_pd_en(true);
321 cfg.set_rtc_peri_pd_en(true);
322 cfg.set_wifi_pd_en(true);
323 cfg.set_bt_pd_en(true);
324 cfg.set_int_8m_pd_en(true);
325
326 cfg.set_dig_peri_pd_en(true);
327 cfg.set_dig_dbias_slp(0); cfg.set_deep_slp(true);
330 cfg.set_wdt_flashboot_mod_en(false);
331 cfg.set_vddsdio_pd_en(true);
332 cfg.set_xtal_fpu(false);
333 cfg.set_deep_slp_reject(true);
334 cfg.set_light_slp_reject(true);
335 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
336
337 cfg.set_rtc_regulator_fpu(false);
339 cfg.set_dbg_atten_slp(RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT);
340
341 cfg.set_bias_sleep_monitor(true);
343 cfg.set_bias_sleep_slp(true);
344 cfg.set_pd_cur_slp(true);
345
346 cfg
347 }
348
349 pub(crate) fn is_deep_sleep(&self) -> bool {
350 self.deep_slp()
351 }
352
353 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
354 self.set_deep_slp(kind == SleepKind::Deep);
355 }
356
357 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
358 let cfg = RtcConfig::default();
359
360 let rtc_cntl = LPWR::regs();
362 let extmem = EXTMEM::regs();
363 let system = SYSTEM::regs();
364
365 regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
366 regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
367
368 unsafe {
369 rtc_cntl.timer1().modify(|_, w| {
370 w.pll_buf_wait().bits(cfg.pll_wait());
371 w.ck8m_wait().bits(cfg.ck8m_wait())
372 });
373
374 rtc_cntl
378 .timer5()
379 .modify(|_, w| w.min_slp_val().bits(RTC_CNTL_MIN_SLP_VAL_MIN));
380
381 regi2c::I2C_DIG_REG_EXT_RTC_DREG_SLEEP.write_field(RTC_CNTL_DBIAS_1V10);
385
386 regi2c::I2C_DIG_REG_EXT_RTC_DREG.write_field(RTC_CNTL_DBIAS_1V25);
392 regi2c::I2C_DIG_REG_EXT_DIG_DREG.write_field(RTC_CNTL_DBIAS_1V25);
393
394 if cfg.clkctl_init() {
395 extmem
398 .cache_mmu_power_ctrl()
399 .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
400 extmem
403 .icache_tag_power_ctrl()
404 .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
405
406 SPI0::regs()
408 .clock_gate()
409 .modify(|_, w| w.clk_en().clear_bit());
410 SPI1::regs()
411 .clock_gate()
412 .modify(|_, w| w.clk_en().clear_bit());
413 }
414
415 if cfg.pwrctl_init() {
416 rtc_cntl
417 .clk_conf()
418 .modify(|_, w| w.ck8m_force_pu().clear_bit());
419
420 rtc_cntl
421 .options0()
422 .modify(|_, w| w.xtl_force_pu().bit(cfg.xtal_fpu() || cfg.bbpll_fpu()));
423
424 rtc_cntl.options0().modify(|_, w| {
427 w.bbpll_force_pu().bit(cfg.bbpll_fpu());
428 w.bbpll_i2c_force_pu().bit(cfg.bbpll_fpu());
429 w.bb_i2c_force_pu().bit(cfg.bbpll_fpu())
430 });
431
432 rtc_cntl
433 .rtc_cntl()
434 .modify(|_, w| w.regulator_force_pu().clear_bit());
435
436 system
441 .mem_pd_mask()
442 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
443
444 rtc_sleep_pu(false);
448
449 rtc_cntl
450 .dig_pwc()
451 .modify(|_, w| w.dg_wrap_force_pu().clear_bit());
452
453 rtc_cntl
454 .dig_iso()
455 .modify(|_, w| w.dg_wrap_force_noiso().clear_bit());
456
457 system
461 .cpu_per_conf()
462 .modify(|_, w| w.cpu_wait_mode_force_on().bit(!cfg.cpu_waiti_clk_gate()));
463
464 rtc_cntl.dig_iso().modify(|_, w| {
467 w.dg_pad_force_unhold().clear_bit();
468 w.dg_pad_force_noiso().clear_bit()
469 });
470 }
471
472 rtc_cntl.int_ena().write(|w| w.bits(0));
473 rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
474
475 regi2c::I2C_ULP_IR_FORCE_XPD_CK.write_field(1);
476 }
477 }
478
479 pub(crate) fn apply(&self) {
480 let rtc_cntl = LPWR::regs();
482
483 if self.lslp_mem_inf_fpu() {
484 rtc_sleep_pu(true);
485 }
486
487 unsafe {
488 let xtal_on = self.xtal_fpu() && !self.deep_slp();
491 let bias_sleep_slp = self.bias_sleep_slp() && !xtal_on;
492 let pd_cur_slp = self.pd_cur_slp() && !xtal_on;
493 let dbg_atten_slp = if xtal_on {
494 RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP
495 } else {
496 self.dbg_atten_slp()
497 };
498
499 assert!(!pd_cur_slp || bias_sleep_slp);
500
501 regi2c::I2C_DIG_REG_EXT_RTC_DREG_SLEEP.write_field(self.rtc_dbias_slp());
502 regi2c::I2C_DIG_REG_EXT_DIG_DREG_SLEEP.write_field(self.dig_dbias_slp());
503
504 rtc_cntl.bias_conf().modify(|_, w| {
505 w.dbg_atten_monitor()
506 .bits(RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
507 w.bias_sleep_monitor().bit(RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
510 w.pd_cur_monitor().bit(RTC_CNTL_PD_CUR_MONITOR_DEFAULT)
511 });
512
513 rtc_cntl.bias_conf().modify(|_, w| {
514 w.dbg_atten_deep_slp().bits(dbg_atten_slp);
515 w.bias_sleep_deep_slp().bit(bias_sleep_slp);
516 w.pd_cur_deep_slp().bit(pd_cur_slp)
517 });
518
519 if self.deep_slp() {
520 regi2c::I2C_ULP_IR_FORCE_XPD_CK.write_field(0);
521
522 rtc_cntl
523 .dig_pwc()
524 .modify(|_, w| w.dg_wrap_pd_en().set_bit());
525
526 rtc_cntl.ana_conf().modify(|_, w| {
527 w.ckgen_i2c_pu().clear_bit();
528 w.pll_i2c_pu().clear_bit();
529 w.rfrx_pbus_pu().clear_bit();
530 w.txrf_i2c_pu().clear_bit()
531 });
532
533 rtc_cntl
534 .options0()
535 .modify(|_, w| w.bb_i2c_force_pu().clear_bit());
536 } else {
537 rtc_cntl.bias_conf().modify(|_, w| {
538 w.dg_vdd_drv_b_slp_en().set_bit();
539 w.dg_vdd_drv_b_slp().bits(RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT)
540 });
541
542 rtc_cntl
543 .dig_pwc()
544 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
545 }
546
547 rtc_cntl
548 .rtc_cntl()
549 .modify(|_, w| w.regulator_force_pu().bit(self.rtc_regulator_fpu()));
550
551 rtc_cntl.clk_conf().modify(|_, w| {
552 w.ck8m_force_pu().bit(!self.int_8m_pd_en());
553 w.ck8m_force_nogating().bit(!self.int_8m_pd_en())
554 });
555
556 rtc_cntl.dig_pwc().modify(|_, w| {
559 w.vdd_spi_pwr_force().clear_bit();
560 w.vdd_spi_pd_en().bit(self.vddsdio_pd_en())
561 });
562
563 rtc_cntl.slp_reject_conf().modify(|_, w| {
564 w.deep_slp_reject_en().bit(self.deep_slp_reject());
565 w.light_slp_reject_en().bit(self.light_slp_reject())
566 });
567
568 rtc_cntl
569 .options0()
570 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
571
572 rtc_cntl
573 .clk_conf()
574 .modify(|_, w| w.xtal_global_force_nogating().bit(self.xtal_fpu()));
575 }
576 }
577
578 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) {
582 LPWR::regs()
584 .wakeup_state()
585 .modify(|_, w| unsafe { w.wakeup_ena().bits(wakeup_mask) });
586
587 LPWR::regs()
590 .slp_reject_conf()
591 .modify(|_, w| unsafe { w.sleep_reject_ena().bits(reject_mask) });
592 }
593
594 #[inline(always)]
598 pub(crate) fn enter_sleep(&self) -> bool {
599 LPWR::regs().state0().modify(|_, w| w.sleep_en().set_bit());
600 super::wait_for_sleep_result()
601 }
602
603 pub(crate) fn finish_sleep(&self) {
604 LPWR::regs().int_clr().write(|w| {
607 w.slp_reject().clear_bit_by_one();
608 w.slp_wakeup().clear_bit_by_one()
609 });
610
611 if self.lslp_mem_inf_fpu() {
613 rtc_sleep_pu(true);
614 }
615 }
616}