esp_hal/rtc_cntl/sleep/
esp32.rs

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
8// Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,
9// RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
10// Valid if RTC_CNTL_DBG_ATTEN is 0.
11/// RTC digital bias setting corresponding to 0.90V.
12pub const RTC_CNTL_DBIAS_0V90: u8 = 0;
13/// RTC digital bias setting corresponding to 0.95V.
14pub const RTC_CNTL_DBIAS_0V95: u8 = 1;
15/// RTC digital bias setting corresponding to 1.00V.
16pub const RTC_CNTL_DBIAS_1V00: u8 = 2;
17/// RTC digital bias setting corresponding to 1.05V.
18pub const RTC_CNTL_DBIAS_1V05: u8 = 3;
19/// RTC digital bias setting corresponding to 1.10V.
20pub const RTC_CNTL_DBIAS_1V10: u8 = 4;
21/// RTC digital bias setting corresponding to 1.15V.
22pub const RTC_CNTL_DBIAS_1V15: u8 = 5;
23/// RTC digital bias setting corresponding to 1.20V.
24pub const RTC_CNTL_DBIAS_1V20: u8 = 6;
25/// RTC digital bias setting corresponding to 1.25V.
26pub const RTC_CNTL_DBIAS_1V25: u8 = 7;
27
28// Various delays to be programmed into power control state machines
29/// Time (in microseconds) for waiting the XTL buffer to stabilize during sleep.
30pub const RTC_CNTL_XTL_BUF_WAIT_SLP_US: u32 = 1000;
31/// Cycles to wait for PLL buffer stabilization.
32pub const RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES: u8 = 1;
33/// Cycles to wait for the 8MHz clock to stabilize.
34pub const RTC_CNTL_CK8M_WAIT_SLP_CYCLES: u8 = 4;
35/// Delay in cycles for wakeup signal to be applied.
36pub const RTC_CNTL_WAKEUP_DELAY_CYCLES: u8 = 7;
37/// Power-up cycles for other blocks.
38pub const RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES: u8 = 1;
39/// Wait cycles for other blocks.
40pub const RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES: u16 = 1;
41/// Minimum sleep value (in cycles).
42pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 128;
43/// Default debug attenuation value.
44pub const RTC_CNTL_DBG_ATTEN_DEFAULT: u8 = 3;
45
46/// Power-up cycles for RTC memory.
47pub const RTC_MEM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
48/// Wait cycles for RTC memory.
49pub const RTC_MEM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
50/// Power-up cycles for ROM and RAM.
51pub const ROM_RAM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
52/// Wait cycles for ROM and RAM.
53pub const ROM_RAM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
54/// Power-up cycles for Wi-Fi.
55pub const WIFI_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
56/// Wait cycles for Wi-Fi.
57pub const WIFI_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
58/// Power-up cycles for RTC components.
59pub const RTC_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
60/// Wait cycles for RTC components.
61pub const RTC_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
62/// Power-up cycles for the digital wrap components.
63pub const DG_WRAP_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
64/// Wait cycles for the digital wrap components.
65pub const DG_WRAP_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
66
67/// Default wait cycles for the 8MHz clock.
68pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
69/// Default wait cycles to enable the 8MHz clock.
70pub 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        // TODO: maybe add sleep time adjustlemnt like idf
81        // TODO: maybe add check to prevent overflow?
82        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        // "alarm" time in slow rtc ticks
85        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        // don't power down RTC peripherals
110        sleep_config.set_rtc_peri_pd_en(false);
111        triggers.set_ext0(true);
112
113        // set pin to RTC function
114        self.pin
115            .borrow_mut()
116            .rtc_set_config(true, true, RtcFunction::Rtc);
117
118        unsafe {
119            // set pin register field
120            RTC_IO::regs()
121                .ext_wakeup0()
122                .modify(|_, w| w.sel().bits(self.pin.borrow().rtc_number()));
123            // set level register field
124            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        // should we have saved the pin configuration first?
134        // set pin back to IO_MUX (input_enable and func have no effect when pin is sent
135        // to IO_MUX)
136        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        // don't power down RTC peripherals
150        sleep_config.set_rtc_peri_pd_en(false);
151        triggers.set_ext1(true);
152
153        // set pins to RTC function
154        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        // clear previous wakeup status
162        LPWR::regs()
163            .ext_wakeup1()
164            .modify(|_, w| w.status_clr().set_bit());
165        // set pin register field
166
167        LPWR::regs()
168            .ext_wakeup1()
169            .modify(|_, w| unsafe { w.sel().bits(bits) });
170
171        // set level register field
172        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        // should we have saved the pin configuration first?
181        // set pin back to IO_MUX (input_enable and func have no effect when pin is sent
182        // to IO_MUX)
183        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    /// Configuration for the RTC sleep behavior.
193    pub struct RtcSleepConfig(u32);
194    impl Debug;
195    /// force normal voltage in sleep mode (digital domain memory)
196    pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
197    /// force normal voltage in sleep mode (RTC memory)
198    pub rtc_mem_inf_fpu, set_rtc_mem_inf_fpu: 1;
199    /// keep low voltage in sleep mode (even if ULP/touch is used)
200    pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 2;
201    /// power down RTC fast memory
202    pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 3;
203    /// power down RTC slow memory
204    pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 4;
205    /// power down RTC peripherals
206    pub rtc_peri_pd_en, set_rtc_peri_pd_en: 5;
207    /// power down WiFi
208    pub wifi_pd_en, set_wifi_pd_en: 6;
209    /// Power down Internal 8M oscillator
210    pub int_8m_pd_en, set_int_8m_pd_en: 7;
211    /// power down main RAM and ROM
212    pub rom_mem_pd_en, set_rom_mem_pd_en: 8;
213    /// power down digital domain
214    pub deep_slp, set_deep_slp: 9;
215    /// enable WDT flashboot mode
216    pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
217    /// bias for digital domain, in active mode
218    pub u8, dig_dbias_wak, set_dig_dbias_wak: 13, 11;
219    /// bias for digital domain, in sleep mode
220    pub u8, dig_dbias_slp, set_dig_dbias_slp: 16, 14;
221    /// bias for RTC domain, in active mode
222    pub u8, rtc_dbias_wak, set_rtc_dbias_wak: 19, 17;
223    /// bias for RTC domain, in sleep mode
224    pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 22, 20;
225    /// remove all peripheral force power up flags
226    pub lslp_meminf_pd, set_lslp_meminf_pd: 23;
227    /// power down VDDSDIO regulator
228    pub vddsdio_pd_en, set_vddsdio_pd_en: 24;
229    /// keep main XTAL powered up in sleep
230    pub xtal_fpu, set_xtal_fpu: 25;
231    /// enable deep sleep reject
232    pub deep_slp_reject, set_deep_slp_reject: 26;
233    /// enable light sleep reject
234    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    /// Configures the RTC for deep sleep mode.
253    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_rtc_dbias_slp(RTC_CNTL_DBIAS_0V90);
258        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        // settings derived from esp-idf after basic boot
271        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        // like esp-idf rtc_sleep_init()
365        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                    // set rtc memory timer
372                    .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                    // set rom&ram timer
381                    .rom_ram_powerup_timer()
382                    .bits(ROM_RAM_POWERUP_CYCLES)
383                    .rom_ram_wait_timer()
384                    .bits(ROM_RAM_WAIT_CYCLES)
385                    // set wifi timer
386                    .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                    // set rtc peri timer
395                    .powerup_timer()
396                    .bits(RTC_POWERUP_CYCLES)
397                    .wait_timer()
398                    .bits(RTC_WAIT_CYCLES)
399                    // set digital wrap timer
400                    .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            // remove all peripheral force power up flags
411            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                // esp-idf also clears these:
424
425                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                // (&*esp32::FE::ptr()).gen_ctrl.modify(|_, w| w
446                //     .iq_est_force_pu().clear_bit()
447                // );
448                //
449                // (&*esp32::FE2::ptr()).tx_interp_ctrl.modify(|_, w| w
450                //     .inf_force_pu().clear_bit()
451                // );
452            }
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                    // TODO: does this need to be optional based on if there is something stored in
460                    // fastmem?
461                    //.fastmem_pd_en().bit(self.rtc_fastmem_pd_en())
462                    .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            // rtc_cntl.dig_pwc.modify(|_, w| w
481            //     .wifi_pd_en().bit(self.wifi_pd_en())
482            //     .rom0_pd_en().bit(self.rom_mem_pd_en())
483            // );
484
485            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            // enable VDDSDIO control by state machine
540
541            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        // set bits for what can wake us up
574        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        // In deep sleep mode, we never get here
585        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        // restore DBG_ATTEN to the default value
593
594        LPWR::regs()
595            .bias_conf()
596            .modify(|_, w| unsafe { w.dbg_atten().bits(RTC_CNTL_DBG_ATTEN_DEFAULT) });
597    }
598}