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::{Rtc, 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 ticks = crate::clock::us_to_rtc_ticks(self.duration.as_micros() as u64);
81 let now = rtc.time_since_boot_raw();
83 let time_in_ticks = now + ticks;
84 unsafe {
85 LPWR::regs()
86 .slp_timer0()
87 .write(|w| w.slp_val_lo().bits((time_in_ticks & 0xffffffff) as u32));
88
89 LPWR::regs().slp_timer1().write(|w| {
90 w.slp_val_hi()
91 .bits(((time_in_ticks >> 32) & 0xffff) as u16)
92 .main_timer_alarm_en()
93 .set_bit()
94 });
95 }
96 }
97}
98
99impl<P: RtcPin> WakeSource for Ext0WakeupSource<P> {
100 fn apply(
101 &self,
102 _rtc: &Rtc<'_>,
103 triggers: &mut WakeTriggers,
104 sleep_config: &mut RtcSleepConfig,
105 ) {
106 sleep_config.set_rtc_peri_pd_en(false);
108 triggers.set_ext0(true);
109
110 self.pin
112 .borrow_mut()
113 .rtc_set_config(true, true, RtcFunction::Rtc);
114
115 unsafe {
116 RTC_IO::regs()
118 .ext_wakeup0()
119 .modify(|_, w| w.sel().bits(self.pin.borrow().rtc_number()));
120 LPWR::regs()
122 .ext_wakeup_conf()
123 .modify(|_r, w| w.ext_wakeup0_lv().bit(self.level == WakeupLevel::High));
124 }
125 }
126}
127
128impl<P: RtcPin> Drop for Ext0WakeupSource<P> {
129 fn drop(&mut self) {
130 self.pin
134 .borrow_mut()
135 .rtc_set_config(true, false, RtcFunction::Rtc);
136 }
137}
138
139impl WakeSource for Ext1WakeupSource<'_, '_> {
140 fn apply(
141 &self,
142 _rtc: &Rtc<'_>,
143 triggers: &mut WakeTriggers,
144 sleep_config: &mut RtcSleepConfig,
145 ) {
146 sleep_config.set_rtc_peri_pd_en(false);
148 triggers.set_ext1(true);
149
150 let mut pins = self.pins.borrow_mut();
152 let mut bits = 0u32;
153 for pin in pins.iter_mut() {
154 pin.rtc_set_config(true, true, RtcFunction::Rtc);
155 bits |= 1 << pin.rtc_number();
156 }
157
158 LPWR::regs()
160 .ext_wakeup1()
161 .modify(|_, w| w.status_clr().set_bit());
162 LPWR::regs()
165 .ext_wakeup1()
166 .modify(|_, w| unsafe { w.sel().bits(bits) });
167
168 LPWR::regs()
170 .ext_wakeup_conf()
171 .modify(|_r, w| w.ext_wakeup1_lv().bit(self.level == WakeupLevel::High));
172 }
173}
174
175impl Drop for Ext1WakeupSource<'_, '_> {
176 fn drop(&mut self) {
177 let mut pins = self.pins.borrow_mut();
181 for pin in pins.iter_mut() {
182 pin.rtc_set_config(true, false, RtcFunction::Rtc);
183 }
184 }
185}
186
187bitfield::bitfield! {
188 #[derive(Clone, Copy)]
189 pub struct RtcSleepConfig(u32);
191 impl Debug;
192 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
194 pub rtc_mem_inf_fpu, set_rtc_mem_inf_fpu: 1;
196 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 2;
198 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 3;
200 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 4;
202 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 5;
204 pub wifi_pd_en, set_wifi_pd_en: 6;
206 pub int_8m_pd_en, set_int_8m_pd_en: 7;
208 pub rom_mem_pd_en, set_rom_mem_pd_en: 8;
210 pub deep_slp, set_deep_slp: 9;
212 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
214 pub u8, dig_dbias_wak, set_dig_dbias_wak: 13, 11;
216 pub u8, dig_dbias_slp, set_dig_dbias_slp: 16, 14;
218 pub u8, rtc_dbias_wak, set_rtc_dbias_wak: 19, 17;
220 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 22, 20;
222 pub lslp_meminf_pd, set_lslp_meminf_pd: 23;
224 pub vddsdio_pd_en, set_vddsdio_pd_en: 24;
226 pub xtal_fpu, set_xtal_fpu: 25;
228 pub deep_slp_reject, set_deep_slp_reject: 26;
230 pub light_slp_reject, set_light_slp_reject: 27;
232}
233
234impl Default for RtcSleepConfig {
235 fn default() -> Self {
236 let mut cfg = Self(Default::default());
237 cfg.set_lslp_meminf_pd(true);
238 cfg.set_deep_slp_reject(true);
239 cfg.set_light_slp_reject(true);
240 cfg.set_dig_dbias_wak(RTC_CNTL_DBIAS_1V10);
241 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
242 cfg.set_rtc_dbias_wak(RTC_CNTL_DBIAS_1V10);
243 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
244 cfg
245 }
246}
247
248impl RtcSleepConfig {
249 pub fn deep() -> Self {
251 let mut cfg = Self::default();
252 cfg.set_deep_slp(true);
253 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_0V90);
254 cfg.set_vddsdio_pd_en(true);
256 cfg.set_int_8m_pd_en(true);
257 cfg.set_xtal_fpu(false);
258 cfg.set_wifi_pd_en(true);
259 cfg.set_rom_mem_pd_en(true);
260 cfg.set_rtc_peri_pd_en(true);
261 cfg.set_rtc_fastmem_pd_en(true);
262 cfg.set_rtc_slowmem_pd_en(true);
263 cfg
264 }
265
266 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
267 let rtc_cntl = LPWR::regs();
269
270 rtc_cntl.options0().modify(|_, w| {
271 w.bias_core_force_pu()
272 .clear_bit()
273 .bias_core_folw_8m()
274 .set_bit()
275 .bias_i2c_force_pu()
276 .clear_bit()
277 .bias_i2c_folw_8m()
278 .set_bit()
279 .bias_force_nosleep()
280 .clear_bit()
281 .bias_sleep_folw_8m()
282 .set_bit()
283 .xtl_force_pu()
284 .clear_bit()
285 });
286
287 rtc_cntl.reg().modify(|_, w| {
288 w.force_pu()
289 .clear_bit()
290 .dboost_force_pu()
291 .clear_bit()
292 .dboost_force_pd()
293 .set_bit()
294 });
295
296 rtc_cntl.pwc().modify(|_, w| {
297 w.slowmem_force_pu()
298 .clear_bit()
299 .fastmem_force_pu()
300 .clear_bit()
301 .force_noiso()
302 .clear_bit()
303 .slowmem_force_noiso()
304 .clear_bit()
305 .fastmem_force_noiso()
306 .clear_bit()
307 });
308
309 rtc_cntl.dig_pwc().modify(|_, w| {
310 w.dg_wrap_force_pu()
311 .clear_bit()
312 .wifi_force_pu()
313 .clear_bit()
314 .wifi_force_pd()
315 .set_bit()
316 .inter_ram4_force_pu()
317 .clear_bit()
318 .inter_ram3_force_pu()
319 .clear_bit()
320 .inter_ram2_force_pu()
321 .clear_bit()
322 .inter_ram1_force_pu()
323 .clear_bit()
324 .inter_ram0_force_pu()
325 .clear_bit()
326 .rom0_force_pu()
327 .clear_bit()
328 .lslp_mem_force_pu()
329 .clear_bit()
330 });
331
332 rtc_cntl.dig_iso().modify(|_, w| {
333 w.dg_wrap_force_noiso()
334 .clear_bit()
335 .wifi_force_noiso()
336 .clear_bit()
337 .wifi_force_iso()
338 .set_bit()
339 .inter_ram4_force_noiso()
340 .clear_bit()
341 .inter_ram3_force_noiso()
342 .clear_bit()
343 .inter_ram2_force_noiso()
344 .clear_bit()
345 .inter_ram1_force_noiso()
346 .clear_bit()
347 .inter_ram0_force_noiso()
348 .clear_bit()
349 .rom0_force_noiso()
350 .clear_bit()
351 .dg_pad_force_unhold()
352 .clear_bit()
353 .dg_pad_force_noiso()
354 .clear_bit()
355 });
356
357 rtc_cntl.int_ena().modify(|_, w| w.brown_out().set_bit());
358 }
359
360 pub(crate) fn apply(&self) {
361 unsafe {
363 let rtc_cntl = LPWR::regs();
364
365 rtc_cntl.timer5().modify(|_, w| {
366 w.min_slp_val()
367 .bits(RTC_CNTL_MIN_SLP_VAL_MIN)
368 .rtcmem_powerup_timer()
370 .bits(RTC_MEM_POWERUP_CYCLES)
371 .rtcmem_wait_timer()
372 .bits(RTC_MEM_WAIT_CYCLES)
373 });
374
375 rtc_cntl.timer3().modify(|_, w| {
376 w
377 .rom_ram_powerup_timer()
379 .bits(ROM_RAM_POWERUP_CYCLES)
380 .rom_ram_wait_timer()
381 .bits(ROM_RAM_WAIT_CYCLES)
382 .wifi_powerup_timer()
384 .bits(WIFI_POWERUP_CYCLES)
385 .wifi_wait_timer()
386 .bits(WIFI_WAIT_CYCLES)
387 });
388
389 rtc_cntl.timer4().modify(|_, w| {
390 w
391 .powerup_timer()
393 .bits(RTC_POWERUP_CYCLES)
394 .wait_timer()
395 .bits(RTC_WAIT_CYCLES)
396 .dg_wrap_powerup_timer()
398 .bits(DG_WRAP_POWERUP_CYCLES)
399 .dg_wrap_wait_timer()
400 .bits(DG_WRAP_WAIT_CYCLES)
401 });
402
403 rtc_cntl
404 .dig_pwc()
405 .modify(|_, w| w.lslp_mem_force_pu().bit(self.lslp_mem_inf_fpu()));
406
407 if self.lslp_meminf_pd() {
409 rtc_cntl
410 .dig_pwc()
411 .modify(|_, w| w.lslp_mem_force_pu().clear_bit());
412
413 rtc_cntl.pwc().modify(|_, w| {
414 w.slowmem_force_pu()
415 .clear_bit()
416 .fastmem_force_pu()
417 .clear_bit()
418 });
419
420 DPORT::regs()
423 .mem_pd_mask()
424 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
425
426 I2S0::regs()
427 .pd_conf()
428 .modify(|_, w| w.plc_mem_force_pu().clear_bit().fifo_force_pu().clear_bit());
429
430 BB::regs()
431 .bbpd_ctrl()
432 .modify(|_, w| w.fft_force_pu().clear_bit().dc_est_force_pu().clear_bit());
433
434 NRX::regs().nrxpd_ctrl().modify(|_, w| {
435 w.rx_rot_force_pu()
436 .clear_bit()
437 .vit_force_pu()
438 .clear_bit()
439 .demap_force_pu()
440 .clear_bit()
441 });
442 }
450
451 rtc_cntl.pwc().modify(|_, w| {
452 w.slowmem_folw_cpu()
453 .bit(self.rtc_mem_inf_follow_cpu())
454 .fastmem_folw_cpu()
455 .bit(self.rtc_mem_inf_follow_cpu())
456 .fastmem_force_pu()
460 .bit(!self.rtc_fastmem_pd_en())
461 .fastmem_force_lpu()
462 .bit(!self.rtc_fastmem_pd_en())
463 .fastmem_force_noiso()
464 .bit(!self.rtc_fastmem_pd_en())
465 .slowmem_pd_en()
466 .bit(self.rtc_slowmem_pd_en())
467 .slowmem_force_pu()
468 .bit(!self.rtc_slowmem_pd_en())
469 .slowmem_force_noiso()
470 .bit(!self.rtc_slowmem_pd_en())
471 .slowmem_force_lpu()
472 .bit(!self.rtc_slowmem_pd_en())
473 .pd_en()
474 .bit(self.rtc_peri_pd_en())
475 });
476
477 if self.deep_slp() {
483 rtc_cntl.dig_iso().modify(|_, w| {
484 w.dg_wrap_force_noiso()
485 .clear_bit()
486 .wifi_force_noiso()
487 .clear_bit()
488 .dg_pad_force_iso()
489 .clear_bit()
490 .dg_pad_force_noiso()
491 .clear_bit()
492 });
493
494 rtc_cntl.dig_pwc().modify(|_, w| {
495 w.dg_wrap_pd_en()
496 .set_bit()
497 .dg_wrap_force_pu()
498 .clear_bit()
499 .dg_wrap_force_pd()
500 .clear_bit()
501 });
502
503 rtc_cntl.options0().modify(|_, w| {
504 w.bias_force_nosleep()
505 .clear_bit()
506 .bb_i2c_force_pu()
507 .clear_bit()
508 });
509
510 rtc_cntl.ana_conf().modify(|_, w| {
511 w.ckgen_i2c_pu()
512 .clear_bit()
513 .pll_i2c_pu()
514 .clear_bit()
515 .rfrx_pbus_pu()
516 .clear_bit()
517 .txrf_i2c_pu()
518 .clear_bit()
519 });
520 } else {
521 rtc_cntl
522 .dig_pwc()
523 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
524
525 rtc_cntl.bias_conf().modify(|_, w| w.dbg_atten().bits(0));
526 }
527
528 rtc_cntl
529 .options0()
530 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
531
532 rtc_cntl
533 .clk_conf()
534 .modify(|_, w| w.ck8m_force_pu().bit(!self.int_8m_pd_en()));
535
536 rtc_cntl.sdio_conf().modify(|_, w| {
539 w.sdio_force()
540 .clear_bit()
541 .sdio_pd_en()
542 .bit(self.vddsdio_pd_en())
543 });
544
545 rtc_cntl.reg().modify(|_, w| {
546 w.dbias_slp()
547 .bits(self.rtc_dbias_slp())
548 .dbias_wak()
549 .bits(self.rtc_dbias_wak())
550 .dig_dbias_slp()
551 .bits(self.dig_dbias_slp())
552 .dig_dbias_wak()
553 .bits(self.dig_dbias_wak())
554 });
555
556 rtc_cntl.slp_reject_conf().modify(|_, w| {
557 w.deep_slp_reject_en()
558 .bit(self.deep_slp_reject())
559 .light_slp_reject_en()
560 .bit(self.light_slp_reject())
561 });
562 }
563 }
564
565 pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) {
566 LPWR::regs()
567 .reset_state()
568 .modify(|_, w| w.procpu_stat_vector_sel().set_bit());
569
570 LPWR::regs()
572 .wakeup_state()
573 .modify(|_, w| unsafe { w.wakeup_ena().bits(wakeup_triggers.0) });
574
575 LPWR::regs()
576 .state0()
577 .write(|w| w.sleep_en().set_bit().slp_wakeup().set_bit());
578 }
579
580 pub(crate) fn finish_sleep(&self) {
581 LPWR::regs().int_clr().write(|w| {
583 w.slp_reject()
584 .clear_bit_by_one()
585 .slp_wakeup()
586 .clear_bit_by_one()
587 });
588
589 LPWR::regs()
592 .bias_conf()
593 .modify(|_, w| unsafe { w.dbg_atten().bits(RTC_CNTL_DBG_ATTEN_DEFAULT) });
594 }
595}