esp_hal/rtc_cntl/sleep/
esp32c3.rs

1use super::{TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel};
2use crate::{
3    gpio::{RtcFunction, RtcPinWithResistors},
4    peripherals::{APB_CTRL, BB, EXTMEM, FE, FE2, GPIO, IO_MUX, LPWR, NRX, SPI0, SPI1, SYSTEM},
5    rom::regi2c_write_mask,
6    rtc_cntl::{sleep::RtcioWakeupSource, Clock, Rtc, RtcClock},
7};
8
9const I2C_DIG_REG: u32 = 0x6D;
10const I2C_DIG_REG_HOSTID: u32 = 0;
11
12const I2C_DIG_REG_EXT_RTC_DREG: u32 = 4;
13const I2C_DIG_REG_EXT_RTC_DREG_MSB: u32 = 4;
14const I2C_DIG_REG_EXT_RTC_DREG_LSB: u32 = 0;
15
16const I2C_DIG_REG_EXT_RTC_DREG_SLEEP: u32 = 5;
17const I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB: u32 = 4;
18const I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB: u32 = 0;
19
20const I2C_DIG_REG_EXT_DIG_DREG: u32 = 6;
21const I2C_DIG_REG_EXT_DIG_DREG_MSB: u32 = 4;
22const I2C_DIG_REG_EXT_DIG_DREG_LSB: u32 = 0;
23
24const I2C_DIG_REG_EXT_DIG_DREG_SLEEP: u32 = 7;
25const I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB: u32 = 4;
26const I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB: u32 = 0;
27
28const I2C_DIG_REG_XPD_RTC_REG: u32 = 13;
29const I2C_DIG_REG_XPD_RTC_REG_MSB: u32 = 2;
30const I2C_DIG_REG_XPD_RTC_REG_LSB: u32 = 2;
31
32const I2C_DIG_REG_XPD_DIG_REG: u32 = 13;
33const I2C_DIG_REG_XPD_DIG_REG_MSB: u32 = 3;
34const I2C_DIG_REG_XPD_DIG_REG_LSB: u32 = 3;
35
36const I2C_ULP_IR_FORCE_XPD_CK: u8 = 0;
37const I2C_ULP_IR_FORCE_XPD_CK_MSB: u8 = 2;
38const I2C_ULP_IR_FORCE_XPD_CK_LSB: u8 = 2;
39
40const I2C_ULP: u8 = 0x61;
41const I2C_ULP_HOSTID: u8 = 0;
42
43// Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,
44// RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
45// Valid if RTC_CNTL_DBG_ATTEN is 0.
46/// Digital bias voltage level of 0.90V.
47pub const RTC_CNTL_DBIAS_0V90: u32 = 13;
48/// Digital bias voltage level of 0.95V.
49pub const RTC_CNTL_DBIAS_0V95: u32 = 16;
50/// Digital bias voltage level of 1.00V.
51pub const RTC_CNTL_DBIAS_1V00: u32 = 18;
52/// Digital bias voltage level of 1.05V.
53pub const RTC_CNTL_DBIAS_1V05: u32 = 20;
54/// Digital bias voltage level of 1.10V.
55pub const RTC_CNTL_DBIAS_1V10: u32 = 23;
56/// Digital bias voltage level of 1.15V.
57pub const RTC_CNTL_DBIAS_1V15: u32 = 25;
58/// Digital bias voltage level of 1.20V.
59pub const RTC_CNTL_DBIAS_1V20: u32 = 28;
60/// Digital bias voltage level of 1.25V.
61pub const RTC_CNTL_DBIAS_1V25: u32 = 30;
62/// Digital bias voltage level of approximately 1.34V.
63pub const RTC_CNTL_DBIAS_1V30: u32 = 31;
64
65/// Default attenuation setting during light sleep, with a voltage drop.
66pub const RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT: u8 = 5;
67/// No attenuation (no voltage drop) during light sleep.
68pub const RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP: u8 = 0;
69/// Default attenuation setting during deep sleep, with maximum voltage drop.
70pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT: u8 = 15;
71/// No attenuation (no voltage drop) during deep sleep.
72pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: u8 = 0;
73
74/// Default bias setting during sleep mode.
75pub const RTC_CNTL_BIASSLP_SLEEP_DEFAULT: u8 = 1;
76/// Keeps the bias for ultra-low power sleep mode always on.
77pub const RTC_CNTL_BIASSLP_SLEEP_ON: u8 = 0;
78
79/// Default power-down current setting during sleep mode.
80pub const RTC_CNTL_PD_CUR_SLEEP_DEFAULT: u8 = 1;
81/// Keeps the power-down current setting for sleep mode always on.
82pub const RTC_CNTL_PD_CUR_SLEEP_ON: u8 = 0;
83
84/// Default driver bias setting for the digital domain during sleep mode.
85pub const RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT: u8 = 254;
86
87/// Default debug attenuation setting for the monitor mode.
88pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0;
89/// Default bias setting for sleep mode in the monitor mode.
90pub const RTC_CNTL_BIASSLP_MONITOR_DEFAULT: bool = false;
91/// Default power-down current setting for the monitor mode.
92pub const RTC_CNTL_PD_CUR_MONITOR_DEFAULT: bool = false;
93
94/// Default number of cycles to wait for the PLL buffer to stabilize.
95pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20;
96/// Default number of cycles to wait for the XTL buffer to stabilize.
97pub const RTC_CNTL_XTL_BUF_WAIT_DEFAULT: u8 = 100;
98/// Default number of cycles to wait for the internal 8MHz clock to stabilize.
99pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
100/// Default number of cycles required to enable the internal 8MHz clock.
101pub const RTC_CK8M_ENABLE_WAIT_DEFAULT: u8 = 5;
102
103/// Minimum number of cycles for sleep duration.
104pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2;
105
106/// Power-up cycles for other hardware blocks.
107pub const OTHER_BLOCKS_POWERUP: u8 = 1;
108/// Wait cycles for other hardware blocks to stabilize.
109pub const OTHER_BLOCKS_WAIT: u16 = 1;
110
111/// Disables GPIO interrupt.
112pub const GPIO_INTR_DISABLE: u8 = 0;
113/// Sets GPIO interrupt to trigger on a low level signal.
114pub const GPIO_INTR_LOW_LEVEL: u8 = 4;
115/// Sets GPIO interrupt to trigger on a high level signal.
116pub const GPIO_INTR_HIGH_LEVEL: u8 = 5;
117
118/// Specifies the function configuration for GPIO pins.
119pub const PIN_FUNC_GPIO: u8 = 1;
120/// Index for signaling GPIO output.
121pub const SIG_GPIO_OUT_IDX: u32 = 128;
122/// Maximum number of GPIO pins supported.
123pub const GPIO_NUM_MAX: usize = 22;
124
125impl WakeSource for TimerWakeupSource {
126    fn apply(
127        &self,
128        rtc: &Rtc<'_>,
129        triggers: &mut WakeTriggers,
130        _sleep_config: &mut RtcSleepConfig,
131    ) {
132        triggers.set_timer(true);
133        let clock_freq = RtcClock::slow_freq();
134        // TODO: maybe add sleep time adjustlemnt like idf
135        // TODO: maybe add check to prevent overflow?
136        let clock_hz = clock_freq.frequency().as_hz() as u64;
137        let ticks = self.duration.as_micros() as u64 * clock_hz / 1_000_000u64;
138        // "alarm" time in slow rtc ticks
139        let now = rtc.time_since_boot_raw();
140        let time_in_ticks = now + ticks;
141        unsafe {
142            LPWR::regs()
143                .slp_timer0()
144                .write(|w| w.slp_val_lo().bits((time_in_ticks & 0xffffffff) as u32));
145
146            LPWR::regs()
147                .int_clr()
148                .write(|w| w.main_timer().clear_bit_by_one());
149
150            LPWR::regs().slp_timer1().write(|w| {
151                w.slp_val_hi()
152                    .bits(((time_in_ticks >> 32) & 0xffff) as u16)
153                    .main_timer_alarm_en()
154                    .set_bit()
155            });
156        }
157    }
158}
159
160impl RtcioWakeupSource<'_, '_> {
161    fn apply_pin(&self, pin: &mut dyn RtcPinWithResistors, level: WakeupLevel) {
162        // The pullup/pulldown part is like in gpio_deep_sleep_wakeup_prepare
163        let level = match level {
164            WakeupLevel::High => {
165                pin.rtcio_pullup(false);
166                pin.rtcio_pulldown(true);
167                GPIO_INTR_HIGH_LEVEL
168            }
169            WakeupLevel::Low => {
170                pin.rtcio_pullup(true);
171                pin.rtcio_pulldown(false);
172                GPIO_INTR_LOW_LEVEL
173            }
174        };
175        pin.rtcio_pad_hold(true);
176
177        // apply_wakeup does the same as idf's esp_deep_sleep_enable_gpio_wakeup
178        unsafe {
179            pin.apply_wakeup(true, level);
180        }
181    }
182}
183
184fn isolate_digital_gpio() {
185    // like esp_sleep_isolate_digital_gpio
186    let rtc_cntl = LPWR::regs();
187    let io_mux = IO_MUX::regs();
188    let gpio = GPIO::regs();
189
190    let dig_iso = &rtc_cntl.dig_iso().read();
191    let deep_sleep_hold_is_en =
192        !dig_iso.dg_pad_force_unhold().bit() && dig_iso.dg_pad_autohold_en().bit();
193    if !deep_sleep_hold_is_en {
194        return;
195    }
196
197    // TODO: assert that the task stack is not in external ram
198
199    for pin_num in 0..GPIO_NUM_MAX {
200        let pin_hold = rtc_cntl.dig_pad_hold().read().bits() & (1 << pin_num) != 0;
201        if !pin_hold {
202            // input disable, like gpio_ll_input_disable
203            io_mux.gpio(pin_num).modify(|_, w| w.fun_ie().clear_bit());
204            // output disable, like gpio_ll_output_disable
205            unsafe {
206                gpio.func_out_sel_cfg(pin_num)
207                    .modify(|_, w| w.bits(SIG_GPIO_OUT_IDX));
208            }
209
210            // disable pull-up and pull-down
211            io_mux.gpio(pin_num).modify(|_, w| w.fun_wpu().clear_bit());
212            io_mux.gpio(pin_num).modify(|_, w| w.fun_wpd().clear_bit());
213
214            // make pad work as gpio (otherwise, deep_sleep bottom current will rise)
215            io_mux
216                .gpio(pin_num)
217                .modify(|_, w| unsafe { w.mcu_sel().bits(RtcFunction::Digital as u8) });
218        }
219    }
220}
221
222impl WakeSource for RtcioWakeupSource<'_, '_> {
223    fn apply(
224        &self,
225        _rtc: &Rtc<'_>,
226        triggers: &mut WakeTriggers,
227        sleep_config: &mut RtcSleepConfig,
228    ) {
229        let mut pins = self.pins.borrow_mut();
230
231        if pins.is_empty() {
232            return;
233        }
234
235        triggers.set_gpio(true);
236
237        // If deep sleep is enabled, esp_start_sleep calls
238        // gpio_deep_sleep_wakeup_prepare which sets these pullup and
239        // pulldown values. But later in esp_start_sleep it calls
240        // esp_sleep_isolate_digital_gpio, which disables the pullup and pulldown (but
241        // only if it isn't held).
242        // But it looks like gpio_deep_sleep_wakeup_prepare enables hold for all pins
243        // in the wakeup mask.
244        //
245        // So: all pins in the wake mask should get this treatment here, and all pins
246        // not in the wake mask should get
247        // - pullup and pulldowns disabled
248        // - input and output disabled, and
249        // - their func should get set to GPIO.
250        // But this last block of things gets skipped if hold is disabled globally (see
251        // gpio_ll_deep_sleep_hold_is_en)
252
253        LPWR::regs()
254            .gpio_wakeup()
255            .modify(|_, w| w.gpio_pin_clk_gate().set_bit());
256
257        LPWR::regs()
258            .ext_wakeup_conf()
259            .modify(|_, w| w.gpio_wakeup_filter().set_bit());
260
261        if sleep_config.deep_slp() {
262            for (pin, level) in pins.iter_mut() {
263                self.apply_pin(*pin, *level);
264            }
265
266            isolate_digital_gpio();
267        }
268
269        // like rtc_cntl_ll_gpio_clear_wakeup_status, as called from
270        // gpio_deep_sleep_wakeup_prepare
271        LPWR::regs()
272            .gpio_wakeup()
273            .modify(|_, w| w.gpio_wakeup_status_clr().set_bit());
274        LPWR::regs()
275            .gpio_wakeup()
276            .modify(|_, w| w.gpio_wakeup_status_clr().clear_bit());
277    }
278}
279
280// impl Drop for RtcioWakeupSource<'_, '_> {
281// fn drop(&mut self) {
282// should we have saved the pin configuration first?
283// set pin back to IO_MUX (input_enable and func have no effect when pin is sent
284// to IO_MUX)
285// let mut pins = self.pins.borrow_mut();
286// for (pin, _level) in pins.iter_mut() {
287// pin.rtc_set_config(true, false, RtcFunction::Rtc);
288// }
289// }
290// }
291
292bitfield::bitfield! {
293    #[derive(Clone, Copy)]
294    /// RTC Configuration.
295    pub struct RtcConfig(u32);
296    impl Debug;
297    /// Number of rtc_fast_clk cycles to wait for 8M clock to be ready
298    pub u8, ck8m_wait, set_ck8m_wait: 7, 0;
299    /// Number of rtc_fast_clk cycles to wait for XTAL clock to be ready
300    pub u8, xtal_wait, set_xtal_wait: 15, 8;
301    /// Number of rtc_fast_clk cycles to wait for PLL clock to be ready
302    pub u8, pll_wait, set_pll_wait: 23, 16;
303    /// Perform clock control related initialization.
304    pub clkctl_init, set_clkctl_init: 24;
305    /// Perform power control related initialization.
306    pub pwrctl_init, set_pwrctl_init: 25;
307    /// Force power down `RTC_DBOOST`.
308    pub rtc_dboost_fpd, set_rtc_dboost_fpd: 26;
309    /// Keep the XTAL oscillator powered up in sleep.
310    pub xtal_fpu, set_xtal_fpu: 27;
311    /// Keep the BBPLL oscillator powered up in sleep.
312    pub bbpll_fpu, set_bbpll_fpu: 28;
313    /// Enable clock gating when the CPU is in wait-for-interrupt state.
314    pub cpu_waiti_clk_gate, set_cpu_waiti_clk_gate: 29;
315    /// Calibrate Ocode to make bandgap voltage more precise.
316    pub cali_ocode, set_cali_ocode: 30;
317}
318
319impl Default for RtcConfig {
320    fn default() -> Self {
321        let mut cfg = Self(Default::default());
322        cfg.set_ck8m_wait(RTC_CNTL_CK8M_WAIT_DEFAULT);
323        cfg.set_xtal_wait(RTC_CNTL_XTL_BUF_WAIT_DEFAULT);
324        cfg.set_pll_wait(RTC_CNTL_PLL_BUF_WAIT_DEFAULT);
325        cfg.set_clkctl_init(true);
326        cfg.set_pwrctl_init(true);
327        cfg.set_rtc_dboost_fpd(true);
328        cfg.set_cpu_waiti_clk_gate(true);
329        cfg
330    }
331}
332
333bitfield::bitfield! {
334    #[derive(Clone, Copy)]
335    /// Configuration for RTC initialization.
336    pub struct RtcInitConfig(u128);
337    impl Debug;
338    /// Number of cycles required to power up WiFi
339    pub u8, wifi_powerup_cycles, set_wifi_powerup_cycles: 6, 0;
340    /// Number of wait cycles for WiFi to stabilize
341    pub u16, wifi_wait_cycles, set_wifi_wait_cycles: 15, 7;
342    /// Number of cycles required to power up Bluetooth
343    pub u8, bt_powerup_cycles, set_bt_powerup_cycles: 22, 16;
344    /// Number of wait cycles for Bluetooth to stabilize
345    pub u16, bt_wait_cycles, set_bt_wait_cycles: 31, 23;
346    /// Number of cycles required to power up the top CPU
347    pub u8, cpu_top_powerup_cycles, set_cpu_top_powerup_cycles: 38, 32;
348    /// Number of wait cycles for the top CPU to stabilize
349    pub u16, cpu_top_wait_cycles, set_cpu_top_wait_cycles: 47, 39;
350    /// Number of cycles required to power up the digital wrapper
351    pub u8, dg_wrap_powerup_cycles, set_dg_wrap_powerup_cycles: 54, 48;
352    /// Number of wait cycles for the digital wrapper to stabilize
353    pub u16, dg_wrap_wait_cycles, set_dg_wrap_wait_cycles: 63, 55;
354    /// Number of cycles required to power up the digital peripherals
355    pub u8, dg_peri_powerup_cycles, set_dg_peri_powerup_cycles: 70, 64;
356    /// Number of wait cycles for the digital peripherals to stabilize
357    pub u16, dg_peri_wait_cycles, set_dg_peri_wait_cycles: 79, 71;
358}
359
360impl Default for RtcInitConfig {
361    fn default() -> Self {
362        let mut cfg = Self(Default::default());
363        cfg.set_wifi_powerup_cycles(OTHER_BLOCKS_POWERUP);
364        cfg.set_bt_powerup_cycles(OTHER_BLOCKS_POWERUP);
365        cfg.set_cpu_top_powerup_cycles(OTHER_BLOCKS_POWERUP);
366        cfg.set_dg_wrap_powerup_cycles(OTHER_BLOCKS_POWERUP);
367        cfg.set_dg_peri_powerup_cycles(OTHER_BLOCKS_POWERUP);
368        cfg.set_wifi_wait_cycles(OTHER_BLOCKS_WAIT);
369        cfg.set_bt_wait_cycles(OTHER_BLOCKS_WAIT);
370        cfg.set_cpu_top_wait_cycles(OTHER_BLOCKS_WAIT);
371        cfg.set_dg_wrap_wait_cycles(OTHER_BLOCKS_WAIT);
372        cfg.set_dg_peri_wait_cycles(OTHER_BLOCKS_WAIT);
373        cfg
374    }
375}
376
377bitfield::bitfield! {
378    #[derive(Clone, Copy)]
379    /// Configuration for RTC sleep mode.
380    pub struct RtcSleepConfig(u64);
381    impl Debug;
382    /// force normal voltage in sleep mode (digital domain memory)
383    pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
384    /// keep low voltage in sleep mode (even if ULP/touch is used)
385    pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 1;
386    /// power down RTC fast memory
387    pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 2;
388    /// power down RTC slow memory
389    pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 3;
390    /// power down RTC peripherals
391    pub rtc_peri_pd_en, set_rtc_peri_pd_en: 4;
392    /// power down WiFi
393    pub wifi_pd_en, set_wifi_pd_en: 5;
394    /// power down BT
395    pub bt_pd_en, set_bt_pd_en: 6;
396    /// power down CPU, but not restart when lightsleep.
397    pub cpu_pd_en, set_cpu_pd_en: 7;
398    /// Power down Internal 8M oscillator
399    pub int_8m_pd_en, set_int_8m_pd_en: 8;
400    /// power down digital peripherals
401    pub dig_peri_pd_en, set_dig_peri_pd_en: 9;
402    /// power down digital domain
403    pub deep_slp, set_deep_slp: 10;
404    /// enable WDT flashboot mode
405    pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 11;
406    /// set bias for digital domain, in sleep mode
407    pub u32, dig_dbias_slp, set_dig_dbias_slp: 16, 12;
408    /// set bias for RTC domain, in sleep mode
409    pub u32, rtc_dbias_slp, set_rtc_dbias_slp: 21, 17;
410    /// voltage parameter, in sleep mode
411    pub u8, dbg_atten_slp, set_dbg_atten_slp: 25, 22;
412    /// circuit control parameter, in monitor mode
413    pub bias_sleep_monitor, set_bias_sleep_monitor: 26;
414    /// circuit control parameter, in sleep mode
415    pub bias_sleep_slp, set_bias_sleep_slp: 27;
416    /// circuit control parameter, in monitor mode
417    pub pd_cur_slp, set_pd_cur_slp: 28;
418    /// power down VDDSDIO regulator
419    pub vddsdio_pd_en, set_vddsdio_pd_en: 29;
420    /// keep main XTAL powered up in sleep
421    pub xtal_fpu, set_xtal_fpu: 30;
422    /// keep rtc regulator powered up in sleep
423    pub rtc_regulator_fpu, set_rtc_regulator_fpu: 31;
424    /// enable deep sleep reject
425    pub deep_slp_reject, set_deep_slp_reject: 32;
426    /// enable light sleep reject
427    pub light_slp_reject, set_light_slp_reject: 33;
428}
429
430impl Default for RtcSleepConfig {
431    fn default() -> Self {
432        let mut cfg = Self(Default::default());
433        cfg.set_deep_slp_reject(true);
434        cfg.set_light_slp_reject(true);
435        cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
436        cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
437        cfg
438    }
439}
440
441const SYSCON_SRAM_POWER_UP: u8 = 0x0000000F;
442const SYSCON_ROM_POWER_UP: u8 = 0x00000003;
443
444fn rtc_sleep_pu(val: bool) {
445    LPWR::regs()
446        .dig_pwc()
447        .modify(|_, w| w.lslp_mem_force_pu().bit(val).fastmem_force_lpu().bit(val));
448
449    APB_CTRL::regs().front_end_mem_pd().modify(|_r, w| {
450        w.dc_mem_force_pu()
451            .bit(val)
452            .pbus_mem_force_pu()
453            .bit(val)
454            .agc_mem_force_pu()
455            .bit(val)
456    });
457
458    BB::regs()
459        .bbpd_ctrl()
460        .modify(|_r, w| w.fft_force_pu().bit(val).dc_est_force_pu().bit(val));
461
462    NRX::regs().nrxpd_ctrl().modify(|_, w| {
463        w.rx_rot_force_pu()
464            .bit(val)
465            .vit_force_pu()
466            .bit(val)
467            .demap_force_pu()
468            .bit(val)
469    });
470
471    FE::regs()
472        .gen_ctrl()
473        .modify(|_, w| w.iq_est_force_pu().bit(val));
474
475    FE2::regs()
476        .tx_interp_ctrl()
477        .modify(|_, w| w.tx_inf_force_pu().bit(val));
478
479    APB_CTRL::regs().mem_power_up().modify(|_r, w| unsafe {
480        w.sram_power_up()
481            .bits(if val { SYSCON_SRAM_POWER_UP } else { 0 })
482            .rom_power_up()
483            .bits(if val { SYSCON_ROM_POWER_UP } else { 0 })
484    });
485}
486
487impl RtcSleepConfig {
488    /// Configures the RTC for deep sleep mode.
489    pub fn deep() -> Self {
490        // Set up for ultra-low power sleep. Wakeup sources may modify these settings.
491        let mut cfg = Self::default();
492
493        cfg.set_lslp_mem_inf_fpu(false);
494        cfg.set_rtc_mem_inf_follow_cpu(true); // ?
495        cfg.set_rtc_fastmem_pd_en(true);
496        cfg.set_rtc_slowmem_pd_en(true);
497        cfg.set_rtc_peri_pd_en(true);
498        cfg.set_wifi_pd_en(true);
499        cfg.set_bt_pd_en(true);
500        cfg.set_cpu_pd_en(true);
501        cfg.set_int_8m_pd_en(true);
502
503        cfg.set_dig_peri_pd_en(true);
504        cfg.set_dig_dbias_slp(0); // because of dig_peri_pd_en
505
506        cfg.set_deep_slp(true);
507        cfg.set_wdt_flashboot_mod_en(false);
508        cfg.set_vddsdio_pd_en(true);
509        cfg.set_xtal_fpu(false);
510        cfg.set_deep_slp_reject(true);
511        cfg.set_light_slp_reject(true);
512        cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
513
514        // because of dig_peri_pd_en
515        cfg.set_rtc_regulator_fpu(false);
516        cfg.set_dbg_atten_slp(RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT);
517
518        // because of xtal_fpu
519        cfg.set_bias_sleep_monitor(true);
520        cfg.set_bias_sleep_slp(true);
521        cfg.set_pd_cur_slp(true);
522
523        cfg
524    }
525
526    pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
527        let cfg = RtcConfig::default();
528
529        // settings derived from esp_clk_init -> rtc_init
530        let rtc_cntl = LPWR::regs();
531        let extmem = EXTMEM::regs();
532        let system = SYSTEM::regs();
533
534        unsafe {
535            rtc_cntl
536                .dig_pwc()
537                .modify(|_, w| w.wifi_force_pd().clear_bit());
538
539            regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
540
541            regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
542
543            rtc_cntl.ana_conf().modify(|_, w| w.pvtmon_pu().clear_bit());
544
545            rtc_cntl.timer1().modify(|_, w| {
546                w.pll_buf_wait()
547                    .bits(cfg.pll_wait())
548                    .ck8m_wait()
549                    .bits(cfg.ck8m_wait())
550            });
551
552            // Moved from rtc sleep to rtc init to save sleep function running time
553            // set shortest possible sleep time limit
554
555            rtc_cntl
556                .timer5()
557                .modify(|_, w| w.min_slp_val().bits(RTC_CNTL_MIN_SLP_VAL_MIN));
558
559            let init_cfg = RtcInitConfig::default();
560
561            rtc_cntl.timer3().modify(|_, w| {
562                w
563                    // set wifi timer
564                    .wifi_powerup_timer()
565                    .bits(init_cfg.wifi_powerup_cycles())
566                    .wifi_wait_timer()
567                    .bits(init_cfg.wifi_wait_cycles())
568                    // set bt timer
569                    .bt_powerup_timer()
570                    .bits(init_cfg.bt_powerup_cycles())
571                    .bt_wait_timer()
572                    .bits(init_cfg.bt_wait_cycles())
573            });
574
575            rtc_cntl.timer4().modify(|_, w| {
576                w.cpu_top_powerup_timer()
577                    .bits(init_cfg.cpu_top_powerup_cycles())
578                    .cpu_top_wait_timer()
579                    .bits(init_cfg.cpu_top_wait_cycles())
580                    // set digital wrap timer
581                    .dg_wrap_powerup_timer()
582                    .bits(init_cfg.dg_wrap_powerup_cycles())
583                    .dg_wrap_wait_timer()
584                    .bits(init_cfg.dg_wrap_wait_cycles())
585            });
586
587            rtc_cntl.timer6().modify(|_, w| {
588                w.dg_peri_powerup_timer()
589                    .bits(init_cfg.dg_peri_powerup_cycles())
590                    .dg_peri_wait_timer()
591                    .bits(init_cfg.dg_peri_wait_cycles())
592            });
593
594            // TODO: something about cali_ocode
595
596            // Reset RTC bias to default value (needed if waking up from deep sleep)
597            regi2c_write_mask!(
598                I2C_DIG_REG,
599                I2C_DIG_REG_EXT_RTC_DREG_SLEEP,
600                RTC_CNTL_DBIAS_1V10
601            );
602
603            // LDO dbias initialization
604            // TODO: this modifies g_rtc_dbias_pvt_non_240m and g_dig_dbias_pvt_non_240m.
605            //       We're using a high enough default but we should read from the efuse.
606            // set_rtc_dig_dbias();
607
608            regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, RTC_CNTL_DBIAS_1V25);
609            regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, RTC_CNTL_DBIAS_1V25);
610
611            if cfg.clkctl_init() {
612                // clear CMMU clock force on
613
614                extmem
615                    .cache_mmu_power_ctrl()
616                    .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
617                // clear tag clock force on
618
619                extmem
620                    .icache_tag_power_ctrl()
621                    .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
622                // clear register clock force on
623                SPI0::regs()
624                    .clock_gate()
625                    .modify(|_, w| w.clk_en().clear_bit());
626                SPI1::regs()
627                    .clock_gate()
628                    .modify(|_, w| w.clk_en().clear_bit());
629            }
630
631            if cfg.pwrctl_init() {
632                rtc_cntl
633                    .clk_conf()
634                    .modify(|_, w| w.ck8m_force_pu().clear_bit());
635
636                rtc_cntl
637                    .options0()
638                    .modify(|_, w| w.xtl_force_pu().bit(cfg.xtal_fpu() || cfg.bbpll_fpu()));
639
640                // force pd APLL
641
642                rtc_cntl
643                    .ana_conf()
644                    .modify(|_, w| w.plla_force_pu().clear_bit().plla_force_pd().set_bit());
645
646                rtc_cntl.ana_conf().modify(|_, w| {
647                    w
648                        // open sar_i2c protect function to avoid sar_i2c reset when rtc_ldo is low.
649                        .reset_por_force_pd()
650                        .clear_bit()
651                });
652
653                // cancel bbpll force pu if setting no force power up
654
655                rtc_cntl.options0().modify(|_, w| {
656                    w.bbpll_force_pu()
657                        .bit(cfg.bbpll_fpu())
658                        .bbpll_i2c_force_pu()
659                        .bit(cfg.bbpll_fpu())
660                        .bb_i2c_force_pu()
661                        .bit(cfg.bbpll_fpu())
662                });
663
664                rtc_cntl.rtc_cntl().modify(|_, w| {
665                    w.regulator_force_pu()
666                        .clear_bit()
667                        .dboost_force_pu()
668                        .clear_bit()
669                        .dboost_force_pd()
670                        .bit(cfg.rtc_dboost_fpd())
671                });
672
673                // If this mask is enabled, all soc memories cannot enter power down mode
674                // We should control soc memory power down mode from RTC, so we will not touch
675                // this register any more
676
677                system
678                    .mem_pd_mask()
679                    .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
680
681                // If this pd_cfg is set to 1, all memory won't enter low power mode during
682                // light sleep If this pd_cfg is set to 0, all memory will enter low
683                // power mode during light sleep
684                rtc_sleep_pu(false);
685
686                rtc_cntl.dig_pwc().modify(|_, w| {
687                    w.dg_wrap_force_pu()
688                        .clear_bit()
689                        .wifi_force_pu()
690                        .clear_bit()
691                        .bt_force_pu()
692                        .clear_bit()
693                        .cpu_top_force_pu()
694                        .clear_bit()
695                        .dg_peri_force_pu()
696                        .clear_bit()
697                });
698
699                rtc_cntl.dig_iso().modify(|_, w| {
700                    w.dg_wrap_force_noiso()
701                        .clear_bit()
702                        .wifi_force_noiso()
703                        .clear_bit()
704                        .bt_force_noiso()
705                        .clear_bit()
706                        .cpu_top_force_noiso()
707                        .clear_bit()
708                        .dg_peri_force_noiso()
709                        .clear_bit()
710                });
711
712                // if SYSTEM_CPU_WAIT_MODE_FORCE_ON == 0 , the cpu clk will be closed when cpu
713                // enter WAITI mode
714
715                system
716                    .cpu_per_conf()
717                    .modify(|_, w| w.cpu_wait_mode_force_on().bit(!cfg.cpu_waiti_clk_gate()));
718
719                // cancel digital PADS force no iso
720
721                rtc_cntl.dig_iso().modify(|_, w| {
722                    w.dg_pad_force_unhold()
723                        .clear_bit()
724                        .dg_pad_force_noiso()
725                        .clear_bit()
726                });
727            }
728
729            // force power down modem(wifi and ble) power domain
730
731            rtc_cntl
732                .dig_iso()
733                .modify(|_, w| w.wifi_force_iso().set_bit().bt_force_iso().set_bit());
734
735            rtc_cntl
736                .dig_pwc()
737                .modify(|_, w| w.wifi_force_pd().set_bit().bt_force_pd().set_bit());
738
739            rtc_cntl.int_ena().write(|w| w.bits(0));
740            rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
741
742            regi2c_write_mask!(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 1);
743        }
744    }
745
746    pub(crate) fn apply(&self) {
747        // like esp-idf rtc_sleep_init()
748        let rtc_cntl = LPWR::regs();
749
750        if self.lslp_mem_inf_fpu() {
751            rtc_sleep_pu(true);
752        }
753
754        if self.wifi_pd_en() {
755            rtc_cntl.dig_iso().modify(|_, w| {
756                w.wifi_force_noiso()
757                    .clear_bit()
758                    .wifi_force_iso()
759                    .clear_bit()
760            });
761
762            rtc_cntl
763                .dig_pwc()
764                .modify(|_, w| w.wifi_force_pu().clear_bit().wifi_pd_en().set_bit());
765        } else {
766            rtc_cntl.dig_pwc().modify(|_, w| w.wifi_pd_en().clear_bit());
767        }
768        if self.bt_pd_en() {
769            rtc_cntl
770                .dig_iso()
771                .modify(|_, w| w.bt_force_noiso().clear_bit().bt_force_iso().clear_bit());
772
773            rtc_cntl
774                .dig_pwc()
775                .modify(|_, w| w.bt_force_pu().clear_bit().bt_pd_en().set_bit());
776        } else {
777            rtc_cntl.dig_pwc().modify(|_, w| w.bt_pd_en().clear_bit());
778        }
779
780        rtc_cntl
781            .dig_pwc()
782            .modify(|_, w| w.cpu_top_pd_en().bit(self.cpu_pd_en()));
783
784        rtc_cntl
785            .dig_pwc()
786            .modify(|_, w| w.dg_peri_pd_en().bit(self.dig_peri_pd_en()));
787
788        unsafe {
789            rtc_cntl.bias_conf().modify(|_, w| {
790                w.dbg_atten_monitor()
791                    .bits(RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT)
792                    // We have config values for this in self, so I don't know why we're setting
793                    // hardcoded defaults for these next two. It's what IDF does...
794                    .bias_sleep_monitor()
795                    .bit(RTC_CNTL_BIASSLP_MONITOR_DEFAULT)
796                    .pd_cur_monitor()
797                    .bit(RTC_CNTL_PD_CUR_MONITOR_DEFAULT)
798            });
799
800            assert!(!self.pd_cur_slp() || self.bias_sleep_slp());
801
802            regi2c_write_mask!(
803                I2C_DIG_REG,
804                I2C_DIG_REG_EXT_RTC_DREG_SLEEP,
805                self.rtc_dbias_slp()
806            );
807
808            regi2c_write_mask!(
809                I2C_DIG_REG,
810                I2C_DIG_REG_EXT_DIG_DREG_SLEEP,
811                self.dig_dbias_slp()
812            );
813
814            rtc_cntl.bias_conf().modify(|_, w| {
815                w.dbg_atten_deep_slp()
816                    .bits(self.dbg_atten_slp())
817                    .bias_sleep_deep_slp()
818                    .bit(self.bias_sleep_slp())
819                    .pd_cur_deep_slp()
820                    .bit(self.pd_cur_slp())
821            });
822
823            if self.deep_slp() {
824                regi2c_write_mask!(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
825
826                rtc_cntl
827                    .dig_pwc()
828                    .modify(|_, w| w.dg_wrap_pd_en().set_bit());
829
830                rtc_cntl.ana_conf().modify(|_, w| {
831                    w.ckgen_i2c_pu()
832                        .clear_bit()
833                        .pll_i2c_pu()
834                        .clear_bit()
835                        .rfrx_pbus_pu()
836                        .clear_bit()
837                        .txrf_i2c_pu()
838                        .clear_bit()
839                });
840
841                rtc_cntl
842                    .options0()
843                    .modify(|_, w| w.bb_i2c_force_pu().clear_bit());
844            } else {
845                rtc_cntl.bias_conf().modify(|_, w| {
846                    w.dg_vdd_drv_b_slp_en()
847                        .set_bit()
848                        .dg_vdd_drv_b_slp()
849                        .bits(RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT)
850                });
851
852                rtc_cntl
853                    .dig_pwc()
854                    .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
855            }
856
857            // mem force pu
858
859            rtc_cntl
860                .dig_pwc()
861                .modify(|_, w| w.lslp_mem_force_pu().set_bit());
862
863            rtc_cntl
864                .rtc_cntl()
865                .modify(|_, w| w.regulator_force_pu().bit(self.rtc_regulator_fpu()));
866
867            rtc_cntl.clk_conf().modify(|_, w| {
868                w.ck8m_force_pu()
869                    .bit(!self.int_8m_pd_en())
870                    .ck8m_force_nogating()
871                    .bit(!self.int_8m_pd_en())
872            });
873
874            // enable VDDSDIO control by state machine
875
876            rtc_cntl.sdio_conf().modify(|_, w| {
877                w.sdio_force()
878                    .clear_bit()
879                    .sdio_reg_pd_en()
880                    .bit(self.vddsdio_pd_en())
881            });
882
883            rtc_cntl.slp_reject_conf().modify(|_, w| {
884                w.deep_slp_reject_en()
885                    .bit(self.deep_slp_reject())
886                    .light_slp_reject_en()
887                    .bit(self.light_slp_reject())
888            });
889
890            rtc_cntl
891                .options0()
892                .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
893
894            rtc_cntl
895                .clk_conf()
896                .modify(|_, w| w.xtal_global_force_nogating().bit(self.xtal_fpu()));
897        }
898    }
899
900    pub(crate) fn start_sleep(&self, wakeup_triggers: WakeTriggers) {
901        // set bits for what can wake us up
902        LPWR::regs()
903            .wakeup_state()
904            .modify(|_, w| unsafe { w.wakeup_ena().bits(wakeup_triggers.0.into()) });
905
906        LPWR::regs()
907            .state0()
908            .write(|w| w.sleep_en().set_bit().slp_wakeup().set_bit());
909    }
910
911    pub(crate) fn finish_sleep(&self) {
912        // In deep sleep mode, we never get here
913        LPWR::regs().int_clr().write(|w| {
914            w.slp_reject().clear_bit_by_one();
915            w.slp_wakeup().clear_bit_by_one()
916        });
917
918        // restore config if it is a light sleep
919        if self.lslp_mem_inf_fpu() {
920            rtc_sleep_pu(true);
921        }
922    }
923}