esp_hal/rtc_cntl/sleep/
esp32.rs1use super::SleepKind;
2use crate::{
3 peripherals::{BB, DPORT, I2S0, LPWR, NRX},
4 rtc_cntl::{Rtc, WakeupSource},
5};
6
7pub const RTC_CNTL_DBIAS_0V90: u8 = 0;
12pub const RTC_CNTL_DBIAS_0V95: u8 = 1;
14pub const RTC_CNTL_DBIAS_1V00: u8 = 2;
16pub const RTC_CNTL_DBIAS_1V05: u8 = 3;
18pub const RTC_CNTL_DBIAS_1V10: u8 = 4;
20pub const RTC_CNTL_DBIAS_1V15: u8 = 5;
22pub const RTC_CNTL_DBIAS_1V20: u8 = 6;
24pub const RTC_CNTL_DBIAS_1V25: u8 = 7;
26
27pub const RTC_CNTL_XTL_BUF_WAIT_SLP_US: u32 = 1000;
30pub const RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES: u8 = 1;
32pub const RTC_CNTL_CK8M_WAIT_SLP_CYCLES: u8 = 4;
34pub const RTC_CNTL_WAKEUP_DELAY_CYCLES: u8 = 7;
36pub const RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES: u8 = 1;
38pub const RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES: u16 = 1;
40pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 128;
42pub const RTC_CNTL_DBG_ATTEN_DEFAULT: u8 = 3;
44
45pub const RTC_MEM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
47pub const RTC_MEM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
49pub const ROM_RAM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
51pub const ROM_RAM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
53pub const WIFI_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
55pub const WIFI_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
57pub const RTC_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
59pub const RTC_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
61pub const DG_WRAP_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES;
63pub const DG_WRAP_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES;
65
66pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20;
68pub const RTC_CK8M_ENABLE_WAIT_DEFAULT: u8 = 5;
70
71bitfield::bitfield! {
72 #[derive(Clone, Copy)]
73 pub struct RtcSleepConfig(u32);
75 impl Debug;
76 pub lslp_mem_inf_fpu, set_lslp_mem_inf_fpu: 0;
78 pub rtc_mem_inf_fpu, set_rtc_mem_inf_fpu: 1;
80 pub rtc_mem_inf_follow_cpu, set_rtc_mem_inf_follow_cpu: 2;
82 pub rtc_fastmem_pd_en, set_rtc_fastmem_pd_en: 3;
84 pub rtc_slowmem_pd_en, set_rtc_slowmem_pd_en: 4;
86 pub rtc_peri_pd_en, set_rtc_peri_pd_en: 5;
88 pub wifi_pd_en, set_wifi_pd_en: 6;
90 pub int_8m_pd_en, set_int_8m_pd_en: 7;
92 pub rom_mem_pd_en, set_rom_mem_pd_en: 8;
94 pub deep_slp, set_deep_slp: 9;
96 pub wdt_flashboot_mod_en, set_wdt_flashboot_mod_en: 10;
98 pub u8, dig_dbias_wak, set_dig_dbias_wak: 13, 11;
100 pub u8, dig_dbias_slp, set_dig_dbias_slp: 16, 14;
102 pub u8, rtc_dbias_wak, set_rtc_dbias_wak: 19, 17;
104 pub u8, rtc_dbias_slp, set_rtc_dbias_slp: 22, 20;
106 pub lslp_meminf_pd, set_lslp_meminf_pd: 23;
108 pub vddsdio_pd_en, set_vddsdio_pd_en: 24;
110 pub xtal_fpu, set_xtal_fpu: 25;
112 pub deep_slp_reject, set_deep_slp_reject: 26;
114 pub light_slp_reject, set_light_slp_reject: 27;
116}
117
118impl Default for RtcSleepConfig {
119 fn default() -> Self {
120 let mut cfg = Self(Default::default());
121 cfg.set_lslp_meminf_pd(true);
122 cfg.set_deep_slp_reject(true);
123 cfg.set_light_slp_reject(true);
124 cfg.set_dig_dbias_wak(RTC_CNTL_DBIAS_1V10);
125 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_1V10);
126 cfg.set_rtc_dbias_wak(RTC_CNTL_DBIAS_1V10);
127 cfg.set_rtc_dbias_slp(RTC_CNTL_DBIAS_1V10);
128 cfg
129 }
130}
131
132impl RtcSleepConfig {
133 pub fn deep() -> Self {
135 let mut cfg = Self::default();
136 cfg.set_deep_slp(true);
137 cfg.set_dig_dbias_slp(RTC_CNTL_DBIAS_0V90);
138 cfg.set_vddsdio_pd_en(true);
140 cfg.set_int_8m_pd_en(true);
141 cfg.set_xtal_fpu(false);
142 cfg.set_wifi_pd_en(true);
143 cfg.set_rom_mem_pd_en(true);
144 cfg.set_rtc_peri_pd_en(true);
145 cfg.set_rtc_fastmem_pd_en(true);
146 cfg.set_rtc_slowmem_pd_en(true);
147 cfg
148 }
149
150 pub(crate) fn is_deep_sleep(&self) -> bool {
151 self.deep_slp()
152 }
153
154 pub(crate) fn set_sleep_kind(&mut self, kind: SleepKind) {
155 self.set_deep_slp(kind == SleepKind::Deep);
156 }
157
158 pub(crate) fn base_settings(_rtc: &Rtc<'_>) {
159 let rtc_cntl = LPWR::regs();
161
162 rtc_cntl.options0().modify(|_, w| {
163 w.bias_core_force_pu()
164 .clear_bit()
165 .bias_core_folw_8m()
166 .set_bit()
167 .bias_i2c_force_pu()
168 .clear_bit()
169 .bias_i2c_folw_8m()
170 .set_bit()
171 .bias_force_nosleep()
172 .clear_bit()
173 .bias_sleep_folw_8m()
174 .set_bit()
175 .xtl_force_pu()
176 .clear_bit()
177 });
178
179 rtc_cntl.reg().modify(|_, w| {
180 w.force_pu()
181 .clear_bit()
182 .dboost_force_pu()
183 .clear_bit()
184 .dboost_force_pd()
185 .set_bit()
186 });
187
188 rtc_cntl.pwc().modify(|_, w| {
189 w.slowmem_force_pu()
190 .clear_bit()
191 .fastmem_force_pu()
192 .clear_bit()
193 .force_noiso()
194 .clear_bit()
195 .slowmem_force_noiso()
196 .clear_bit()
197 .fastmem_force_noiso()
198 .clear_bit()
199 });
200
201 rtc_cntl.dig_pwc().modify(|_, w| {
202 w.dg_wrap_force_pu()
203 .clear_bit()
204 .wifi_force_pu()
205 .clear_bit()
206 .wifi_force_pd()
207 .set_bit()
208 .inter_ram4_force_pu()
209 .clear_bit()
210 .inter_ram3_force_pu()
211 .clear_bit()
212 .inter_ram2_force_pu()
213 .clear_bit()
214 .inter_ram1_force_pu()
215 .clear_bit()
216 .inter_ram0_force_pu()
217 .clear_bit()
218 .rom0_force_pu()
219 .clear_bit()
220 .lslp_mem_force_pu()
221 .clear_bit()
222 });
223
224 rtc_cntl.dig_iso().modify(|_, w| {
225 w.dg_wrap_force_noiso()
226 .clear_bit()
227 .wifi_force_noiso()
228 .clear_bit()
229 .wifi_force_iso()
230 .set_bit()
231 .inter_ram4_force_noiso()
232 .clear_bit()
233 .inter_ram3_force_noiso()
234 .clear_bit()
235 .inter_ram2_force_noiso()
236 .clear_bit()
237 .inter_ram1_force_noiso()
238 .clear_bit()
239 .inter_ram0_force_noiso()
240 .clear_bit()
241 .rom0_force_noiso()
242 .clear_bit()
243 .dg_pad_force_unhold()
244 .clear_bit()
245 .dg_pad_force_noiso()
246 .clear_bit()
247 });
248
249 rtc_cntl.int_ena().modify(|_, w| w.brown_out().set_bit());
250 }
251
252 pub(crate) fn apply(&self) {
253 unsafe {
255 let rtc_cntl = LPWR::regs();
256
257 rtc_cntl.timer5().modify(|_, w| {
258 w.min_slp_val()
259 .bits(RTC_CNTL_MIN_SLP_VAL_MIN)
260 .rtcmem_powerup_timer()
262 .bits(RTC_MEM_POWERUP_CYCLES)
263 .rtcmem_wait_timer()
264 .bits(RTC_MEM_WAIT_CYCLES)
265 });
266
267 rtc_cntl.timer3().modify(|_, w| {
268 w
269 .rom_ram_powerup_timer()
271 .bits(ROM_RAM_POWERUP_CYCLES)
272 .rom_ram_wait_timer()
273 .bits(ROM_RAM_WAIT_CYCLES)
274 .wifi_powerup_timer()
276 .bits(WIFI_POWERUP_CYCLES)
277 .wifi_wait_timer()
278 .bits(WIFI_WAIT_CYCLES)
279 });
280
281 rtc_cntl.timer4().modify(|_, w| {
282 w
283 .powerup_timer()
285 .bits(RTC_POWERUP_CYCLES)
286 .wait_timer()
287 .bits(RTC_WAIT_CYCLES)
288 .dg_wrap_powerup_timer()
290 .bits(DG_WRAP_POWERUP_CYCLES)
291 .dg_wrap_wait_timer()
292 .bits(DG_WRAP_WAIT_CYCLES)
293 });
294
295 rtc_cntl
296 .dig_pwc()
297 .modify(|_, w| w.lslp_mem_force_pu().bit(self.lslp_mem_inf_fpu()));
298
299 if self.lslp_meminf_pd() {
301 rtc_cntl
302 .dig_pwc()
303 .modify(|_, w| w.lslp_mem_force_pu().clear_bit());
304
305 rtc_cntl.pwc().modify(|_, w| {
306 w.slowmem_force_pu()
307 .clear_bit()
308 .fastmem_force_pu()
309 .clear_bit()
310 });
311
312 DPORT::regs()
315 .mem_pd_mask()
316 .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
317
318 I2S0::regs()
319 .pd_conf()
320 .modify(|_, w| w.plc_mem_force_pu().clear_bit().fifo_force_pu().clear_bit());
321
322 BB::regs()
323 .bbpd_ctrl()
324 .modify(|_, w| w.fft_force_pu().clear_bit().dc_est_force_pu().clear_bit());
325
326 NRX::regs().nrxpd_ctrl().modify(|_, w| {
327 w.rx_rot_force_pu()
328 .clear_bit()
329 .vit_force_pu()
330 .clear_bit()
331 .demap_force_pu()
332 .clear_bit()
333 });
334 }
342
343 rtc_cntl.pwc().modify(|_, w| {
344 w.slowmem_folw_cpu().bit(self.rtc_mem_inf_follow_cpu());
345 w.fastmem_folw_cpu().bit(self.rtc_mem_inf_follow_cpu());
346
347 w.fastmem_force_pu().bit(!self.rtc_fastmem_pd_en());
352 w.fastmem_force_lpu().bit(!self.rtc_fastmem_pd_en());
353 w.fastmem_force_noiso().bit(!self.rtc_fastmem_pd_en());
354 w.slowmem_pd_en().bit(self.rtc_slowmem_pd_en());
355 w.slowmem_force_pu().bit(!self.rtc_slowmem_pd_en());
356 w.slowmem_force_noiso().bit(!self.rtc_slowmem_pd_en());
357 w.slowmem_force_lpu().bit(!self.rtc_slowmem_pd_en());
358 w.pd_en().bit(self.rtc_peri_pd_en())
359 });
360
361 if self.deep_slp() {
367 rtc_cntl.dig_iso().modify(|_, w| {
368 w.dg_wrap_force_noiso()
369 .clear_bit()
370 .wifi_force_noiso()
371 .clear_bit()
372 .dg_pad_force_iso()
373 .clear_bit()
374 .dg_pad_force_noiso()
375 .clear_bit()
376 });
377
378 rtc_cntl.dig_pwc().modify(|_, w| {
379 w.dg_wrap_pd_en()
380 .set_bit()
381 .dg_wrap_force_pu()
382 .clear_bit()
383 .dg_wrap_force_pd()
384 .clear_bit()
385 });
386
387 rtc_cntl.options0().modify(|_, w| {
388 w.bias_force_nosleep()
389 .clear_bit()
390 .bb_i2c_force_pu()
391 .clear_bit()
392 });
393
394 rtc_cntl.ana_conf().modify(|_, w| {
395 w.ckgen_i2c_pu()
396 .clear_bit()
397 .pll_i2c_pu()
398 .clear_bit()
399 .rfrx_pbus_pu()
400 .clear_bit()
401 .txrf_i2c_pu()
402 .clear_bit()
403 });
404 } else {
405 rtc_cntl
406 .dig_pwc()
407 .modify(|_, w| w.dg_wrap_pd_en().clear_bit());
408
409 rtc_cntl.bias_conf().modify(|_, w| w.dbg_atten().bits(0));
410 }
411
412 rtc_cntl
413 .options0()
414 .modify(|_, w| w.xtl_force_pu().bit(self.xtal_fpu()));
415
416 rtc_cntl
417 .clk_conf()
418 .modify(|_, w| w.ck8m_force_pu().bit(!self.int_8m_pd_en()));
419
420 rtc_cntl.sdio_conf().modify(|_, w| {
423 w.sdio_force()
424 .clear_bit()
425 .sdio_pd_en()
426 .bit(self.vddsdio_pd_en())
427 });
428
429 rtc_cntl.reg().modify(|_, w| {
430 w.dbias_slp()
431 .bits(self.rtc_dbias_slp())
432 .dbias_wak()
433 .bits(self.rtc_dbias_wak())
434 .dig_dbias_slp()
435 .bits(self.dig_dbias_slp())
436 .dig_dbias_wak()
437 .bits(self.dig_dbias_wak())
438 });
439
440 rtc_cntl.slp_reject_conf().modify(|_, w| {
441 w.deep_slp_reject_en()
442 .bit(self.deep_slp_reject())
443 .light_slp_reject_en()
444 .bit(self.light_slp_reject())
445 });
446 }
447 }
448
449 pub(crate) fn start_sleep(&self, wakeup_mask: u32, reject_mask: u32) {
453 LPWR::regs()
454 .reset_state()
455 .modify(|_, w| w.procpu_stat_vector_sel().set_bit());
456
457 LPWR::regs()
459 .wakeup_state()
460 .modify(|_, w| unsafe { w.wakeup_ena().bits(wakeup_mask as u16) });
461
462 let rejects = enumset::EnumSet::<WakeupSource>::from_u32_truncated(reject_mask);
465 LPWR::regs().slp_reject_conf().modify(|_, w| {
466 w.gpio_reject_en().bit(rejects.contains(WakeupSource::Gpio));
467 w.sdio_reject_en().bit(rejects.contains(WakeupSource::Sdio))
468 });
469
470 LPWR::regs().state0().modify(|_, w| w.sleep_en().set_bit());
471 }
472
473 pub(crate) fn finish_sleep(&self) {
474 LPWR::regs().int_clr().write(|w| {
476 w.slp_reject()
477 .clear_bit_by_one()
478 .slp_wakeup()
479 .clear_bit_by_one()
480 });
481
482 LPWR::regs()
485 .bias_conf()
486 .modify(|_, w| unsafe { w.dbg_atten().bits(RTC_CNTL_DBG_ATTEN_DEFAULT) });
487 }
488}