1use super::{Ext0WakeupSource, Ext1WakeupSource, TimerWakeupSource, WakeSource, WakeTriggers};
2use crate::{
3 gpio::{RtcFunction, RtcPin},
4 peripherals::{BB, DPORT, I2S0, LPWR, NRX, RTC_IO},
5 rtc_cntl::{Clock, Rtc, RtcClock, sleep::WakeupLevel},
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;
27
28pub const RTC_CNTL_XTL_BUF_WAIT_SLP_US: u32 = 1000;
31pub const RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES: u8 = 1;
33pub const RTC_CNTL_CK8M_WAIT_SLP_CYCLES: u8 = 4;
35pub const RTC_CNTL_WAKEUP_DELAY_CYCLES: u8 = 7;
37pub const RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES: u8 = 1;
39pub const RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES: u16 = 1;
41pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 128;
43pub const RTC_CNTL_DBG_ATTEN_DEFAULT: u8 = 3;
45
46pub const RTC_MEM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
48pub const RTC_MEM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
50pub const ROM_RAM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
52pub const ROM_RAM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
54pub const WIFI_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
56pub const WIFI_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
58pub const RTC_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
60pub const RTC_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
62pub const DG_WRAP_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
64pub const DG_WRAP_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
66
67pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
69pub const RTC_CK8M_ENABLE_WAIT_DEFAULT: u8 = 5;
71impl WakeSource for TimerWakeupSource {
72 fn apply(
73 &self,
74 rtc: &Rtc<'_>,
75 triggers: &mut WakeTriggers,
76 _sleep_config: &mut RtcSleepConfig,
77 ) {
78 triggers.set_timer(true);
79 let clock_freq = RtcClock::slow_freq();
80 let clock_hz = clock_freq.frequency().as_hz() as u64;
83 let ticks = self.duration.as_micros() as u64 * clock_hz / 1_000_000u64;
84 let now = rtc.time_since_boot_raw();
86 let time_in_ticks = now + ticks;
87 unsafe {
88 LPWR::regs()
89 .slp_timer0()
90 .write(|w| w.slp_val_lo().bits((time_in_ticks & 0xffffffff) as u32));
91
92 LPWR::regs().slp_timer1().write(|w| {
93 w.slp_val_hi()
94 .bits(((time_in_ticks >> 32) & 0xffff) as u16)
95 .main_timer_alarm_en()
96 .set_bit()
97 });
98 }
99 }
100}
101
102impl<P: RtcPin> WakeSource for Ext0WakeupSource<P> {
103 fn apply(
104 &self,
105 _rtc: &Rtc<'_>,
106 triggers: &mut WakeTriggers,
107 sleep_config: &mut RtcSleepConfig,
108 ) {
109 sleep_config.set_rtc_peri_pd_en(false);
111 triggers.set_ext0(true);
112
113 self.pin
115 .borrow_mut()
116 .rtc_set_config(true, true, RtcFunction::Rtc);
117
118 unsafe {
119 RTC_IO::regs()
121 .ext_wakeup0()
122 .modify(|_, w| w.sel().bits(self.pin.borrow().rtc_number()));
123 LPWR::regs()
125 .ext_wakeup_conf()
126 .modify(|_r, w| w.ext_wakeup0_lv().bit(self.level == WakeupLevel::High));
127 }
128 }
129}
130
131impl<P: RtcPin> Drop for Ext0WakeupSource<P> {
132 fn drop(&mut self) {
133 self.pin
137 .borrow_mut()
138 .rtc_set_config(true, false, RtcFunction::Rtc);
139 }
140}
141
142impl WakeSource for Ext1WakeupSource<'_, '_> {
143 fn apply(
144 &self,
145 _rtc: &Rtc<'_>,
146 triggers: &mut WakeTriggers,
147 sleep_config: &mut RtcSleepConfig,
148 ) {
149 sleep_config.set_rtc_peri_pd_en(false);
151 triggers.set_ext1(true);
152
153 let mut pins = self.pins.borrow_mut();
155 let mut bits = 0u32;
156 for pin in pins.iter_mut() {
157 pin.rtc_set_config(true, true, RtcFunction::Rtc);
158 bits |= 1 << pin.rtc_number();
159 }
160
161 LPWR::regs()
163 .ext_wakeup1()
164 .modify(|_, w| w.status_clr().set_bit());
165 LPWR::regs()
168 .ext_wakeup1()
169 .modify(|_, w| unsafe { w.sel().bits(bits) });
170
171 LPWR::regs()
173 .ext_wakeup_conf()
174 .modify(|_r, w| w.ext_wakeup1_lv().bit(self.level == WakeupLevel::High));
175 }
176}
177
178impl Drop for Ext1WakeupSource<'_, '_> {
179 fn drop(&mut self) {
180 let mut pins = self.pins.borrow_mut();
184 for pin in pins.iter_mut() {
185 pin.rtc_set_config(true, false, RtcFunction::Rtc);
186 }
187 }
188}
189
190bitfield::bitfield! {
191 #[derive(Clone, Copy)]
192 pub struct RtcSleepConfig(u32);
194 impl Debug;
195 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
197 pub rtc_mem_inf_fpu, set_rtc_mem_inf_fpu: 1;
199 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 2;
201 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 3;
203 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 4;
205 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 5;
207 pub wifi_pd_en, set_wifi_pd_en: 6;
209 pub int_8m_pd_en, set_int_8m_pd_en: 7;
211 pub rom_mem_pd_en, set_rom_mem_pd_en: 8;
213 pub deep_slp, set_deep_slp: 9;
215 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
217 pub u8, dig_dbias_wak, set_dig_dbias_wak: 13, 11;
219 pub u8, dig_dbias_slp, set_dig_dbias_slp: 16, 14;
221 pub u8, rtc_dbias_wak, set_rtc_dbias_wak: 19, 17;
223 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 22, 20;
225 pub lslp_meminf_pd, set_lslp_meminf_pd: 23;
227 pub vddsdio_pd_en, set_vddsdio_pd_en: 24;
229 pub xtal_fpu, set_xtal_fpu: 25;
231 pub deep_slp_reject, set_deep_slp_reject: 26;
233 pub light_slp_reject, set_light_slp_reject: 27;
235}
236
237impl Default for RtcSleepConfig {
238 fn default() -> Self {
239 let mut cfg = Self(Default::default());
240 cfg.set_lslp_meminf_pd(true);
241 cfg.set_deep_slp_reject(true);
242 cfg.set_light_slp_reject(true);
243 cfg.set_dig_dbias_wak(RTC_CNTL_DBIAS_1V10);
244 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
245 cfg.set_rtc_dbias_wak(RTC_CNTL_DBIAS_1V10);
246 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
247 cfg
248 }
249}
250
251impl RtcSleepConfig {
252 pub fn deep() -> Self {
254 let mut cfg = Self::default();
255 cfg.set_deep_slp(true);
256 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_0V90);
257 cfg.set_vddsdio_pd_en(true);
259 cfg.set_int_8m_pd_en(true);
260 cfg.set_xtal_fpu(false);
261 cfg.set_wifi_pd_en(true);
262 cfg.set_rom_mem_pd_en(true);
263 cfg.set_rtc_peri_pd_en(true);
264 cfg.set_rtc_fastmem_pd_en(true);
265 cfg.set_rtc_slowmem_pd_en(true);
266 cfg
267 }
268
269 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
270 let rtc_cntl = LPWR::regs();
272
273 rtc_cntl.options0().modify(|_, w| {
274 w.bias_core_force_pu()
275 .clear_bit()
276 .bias_core_folw_8m()
277 .set_bit()
278 .bias_i2c_force_pu()
279 .clear_bit()
280 .bias_i2c_folw_8m()
281 .set_bit()
282 .bias_force_nosleep()
283 .clear_bit()
284 .bias_sleep_folw_8m()
285 .set_bit()
286 .xtl_force_pu()
287 .clear_bit()
288 });
289
290 rtc_cntl.reg().modify(|_, w| {
291 w.force_pu()
292 .clear_bit()
293 .dboost_force_pu()
294 .clear_bit()
295 .dboost_force_pd()
296 .set_bit()
297 });
298
299 rtc_cntl.pwc().modify(|_, w| {
300 w.slowmem_force_pu()
301 .clear_bit()
302 .fastmem_force_pu()
303 .clear_bit()
304 .force_noiso()
305 .clear_bit()
306 .slowmem_force_noiso()
307 .clear_bit()
308 .fastmem_force_noiso()
309 .clear_bit()
310 });
311
312 rtc_cntl.dig_pwc().modify(|_, w| {
313 w.dg_wrap_force_pu()
314 .clear_bit()
315 .wifi_force_pu()
316 .clear_bit()
317 .wifi_force_pd()
318 .set_bit()
319 .inter_ram4_force_pu()
320 .clear_bit()
321 .inter_ram3_force_pu()
322 .clear_bit()
323 .inter_ram2_force_pu()
324 .clear_bit()
325 .inter_ram1_force_pu()
326 .clear_bit()
327 .inter_ram0_force_pu()
328 .clear_bit()
329 .rom0_force_pu()
330 .clear_bit()
331 .lslp_mem_force_pu()
332 .clear_bit()
333 });
334
335 rtc_cntl.dig_iso().modify(|_, w| {
336 w.dg_wrap_force_noiso()
337 .clear_bit()
338 .wifi_force_noiso()
339 .clear_bit()
340 .wifi_force_iso()
341 .set_bit()
342 .inter_ram4_force_noiso()
343 .clear_bit()
344 .inter_ram3_force_noiso()
345 .clear_bit()
346 .inter_ram2_force_noiso()
347 .clear_bit()
348 .inter_ram1_force_noiso()
349 .clear_bit()
350 .inter_ram0_force_noiso()
351 .clear_bit()
352 .rom0_force_noiso()
353 .clear_bit()
354 .dg_pad_force_unhold()
355 .clear_bit()
356 .dg_pad_force_noiso()
357 .clear_bit()
358 });
359
360 rtc_cntl.int_ena().modify(|_, w| w.brown_out().set_bit());
361 }
362
363 pub(crate) fn apply(&self) {
364 unsafe {
366 let rtc_cntl = LPWR::regs();
367
368 rtc_cntl.timer5().modify(|_, w| {
369 w.min_slp_val()
370 .bits(RTC_CNTL_MIN_SLP_VAL_MIN)
371 .rtcmem_powerup_timer()
373 .bits(RTC_MEM_POWERUP_CYCLES)
374 .rtcmem_wait_timer()
375 .bits(RTC_MEM_WAIT_CYCLES)
376 });
377
378 rtc_cntl.timer3().modify(|_, w| {
379 w
380 .rom_ram_powerup_timer()
382 .bits(ROM_RAM_POWERUP_CYCLES)
383 .rom_ram_wait_timer()
384 .bits(ROM_RAM_WAIT_CYCLES)
385 .wifi_powerup_timer()
387 .bits(WIFI_POWERUP_CYCLES)
388 .wifi_wait_timer()
389 .bits(WIFI_WAIT_CYCLES)
390 });
391
392 rtc_cntl.timer4().modify(|_, w| {
393 w
394 .powerup_timer()
396 .bits(RTC_POWERUP_CYCLES)
397 .wait_timer()
398 .bits(RTC_WAIT_CYCLES)
399 .dg_wrap_powerup_timer()
401 .bits(DG_WRAP_POWERUP_CYCLES)
402 .dg_wrap_wait_timer()
403 .bits(DG_WRAP_WAIT_CYCLES)
404 });
405
406 rtc_cntl
407 .dig_pwc()
408 .modify(|_, w| w.lslp_mem_force_pu().bit(self.lslp_mem_inf_fpu()));
409
410 if self.lslp_meminf_pd() {
412 rtc_cntl
413 .dig_pwc()
414 .modify(|_, w| w.lslp_mem_force_pu().clear_bit());
415
416 rtc_cntl.pwc().modify(|_, w| {
417 w.slowmem_force_pu()
418 .clear_bit()
419 .fastmem_force_pu()
420 .clear_bit()
421 });
422
423 DPORT::regs()
426 .mem_pd_mask()
427 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
428
429 I2S0::regs()
430 .pd_conf()
431 .modify(|_, w| w.plc_mem_force_pu().clear_bit().fifo_force_pu().clear_bit());
432
433 BB::regs()
434 .bbpd_ctrl()
435 .modify(|_, w| w.fft_force_pu().clear_bit().dc_est_force_pu().clear_bit());
436
437 NRX::regs().nrxpd_ctrl().modify(|_, w| {
438 w.rx_rot_force_pu()
439 .clear_bit()
440 .vit_force_pu()
441 .clear_bit()
442 .demap_force_pu()
443 .clear_bit()
444 });
445 }
453
454 rtc_cntl.pwc().modify(|_, w| {
455 w.slowmem_folw_cpu()
456 .bit(self.rtc_mem_inf_follow_cpu())
457 .fastmem_folw_cpu()
458 .bit(self.rtc_mem_inf_follow_cpu())
459 .fastmem_force_pu()
463 .bit(!self.rtc_fastmem_pd_en())
464 .fastmem_force_lpu()
465 .bit(!self.rtc_fastmem_pd_en())
466 .fastmem_force_noiso()
467 .bit(!self.rtc_fastmem_pd_en())
468 .slowmem_pd_en()
469 .bit(self.rtc_slowmem_pd_en())
470 .slowmem_force_pu()
471 .bit(!self.rtc_slowmem_pd_en())
472 .slowmem_force_noiso()
473 .bit(!self.rtc_slowmem_pd_en())
474 .slowmem_force_lpu()
475 .bit(!self.rtc_slowmem_pd_en())
476 .pd_en()
477 .bit(self.rtc_peri_pd_en())
478 });
479
480 if self.deep_slp() {
486 rtc_cntl.dig_iso().modify(|_, w| {
487 w.dg_wrap_force_noiso()
488 .clear_bit()
489 .wifi_force_noiso()
490 .clear_bit()
491 .dg_pad_force_iso()
492 .clear_bit()
493 .dg_pad_force_noiso()
494 .clear_bit()
495 });
496
497 rtc_cntl.dig_pwc().modify(|_, w| {
498 w.dg_wrap_pd_en()
499 .set_bit()
500 .dg_wrap_force_pu()
501 .clear_bit()
502 .dg_wrap_force_pd()
503 .clear_bit()
504 });
505
506 rtc_cntl.options0().modify(|_, w| {
507 w.bias_force_nosleep()
508 .clear_bit()
509 .bb_i2c_force_pu()
510 .clear_bit()
511 });
512
513 rtc_cntl.ana_conf().modify(|_, w| {
514 w.ckgen_i2c_pu()
515 .clear_bit()
516 .pll_i2c_pu()
517 .clear_bit()
518 .rfrx_pbus_pu()
519 .clear_bit()
520 .txrf_i2c_pu()
521 .clear_bit()
522 });
523 } else {
524 rtc_cntl
525 .dig_pwc()
526 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
527
528 rtc_cntl.bias_conf().modify(|_, w| w.dbg_atten().bits(0));
529 }
530
531 rtc_cntl
532 .options0()
533 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
534
535 rtc_cntl
536 .clk_conf()
537 .modify(|_, w| w.ck8m_force_pu().bit(!self.int_8m_pd_en()));
538
539 rtc_cntl.sdio_conf().modify(|_, w| {
542 w.sdio_force()
543 .clear_bit()
544 .sdio_pd_en()
545 .bit(self.vddsdio_pd_en())
546 });
547
548 rtc_cntl.reg().modify(|_, w| {
549 w.dbias_slp()
550 .bits(self.rtc_dbias_slp())
551 .dbias_wak()
552 .bits(self.rtc_dbias_wak())
553 .dig_dbias_slp()
554 .bits(self.dig_dbias_slp())
555 .dig_dbias_wak()
556 .bits(self.dig_dbias_wak())
557 });
558
559 rtc_cntl.slp_reject_conf().modify(|_, w| {
560 w.deep_slp_reject_en()
561 .bit(self.deep_slp_reject())
562 .light_slp_reject_en()
563 .bit(self.light_slp_reject())
564 });
565 }
566 }
567
568 pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) {
569 LPWR::regs()
570 .reset_state()
571 .modify(|_, w| w.procpu_stat_vector_sel().set_bit());
572
573 LPWR::regs()
575 .wakeup_state()
576 .modify(|_, w| unsafe { w.wakeup_ena().bits(wakeup_triggers.0) });
577
578 LPWR::regs()
579 .state0()
580 .write(|w| w.sleep_en().set_bit().slp_wakeup().set_bit());
581 }
582
583 pub(crate) fn finish_sleep(&self) {
584 LPWR::regs().int_clr().write(|w| {
586 w.slp_reject()
587 .clear_bit_by_one()
588 .slp_wakeup()
589 .clear_bit_by_one()
590 });
591
592 LPWR::regs()
595 .bias_conf()
596 .modify(|_, w| unsafe { w.dbg_atten().bits(RTC_CNTL_DBG_ATTEN_DEFAULT) });
597 }
598}