esp_hal/rtc_cntl/sleep/mod.rs
1//! # RTC Control Sleep Module
2//!
3//! ## Overview
4//! The `sleep` module allows configuring various wakeup sources and setting up
5//! the sleep behavior based on those sources. The supported wakeup sources
6//! include:
7//! * `GPIO` pins - light sleep only
8//! * timers
9//! * `SDIO (Secure Digital Input/Output) - light sleep only`
10//! * `MAC (Media Access Control)` wake - light sleep only
11//! * `UART0` - light sleep only
12//! * `UART1` - light sleep only
13//! * `touch`
14//! * `ULP (Ultra-Low Power)` wake
15//! * `BT (Bluetooth) wake` - light sleep only
16
17use core::cell::RefCell;
18#[cfg(any(esp32, esp32c3, esp32s2, esp32s3, esp32c6, esp32c2, esp32h2))]
19use core::time::Duration;
20
21#[cfg(any(esp32, esp32s2, esp32s3))]
22use crate::gpio::RtcPin as RtcIoWakeupPinType;
23#[cfg(any(esp32c3, esp32c6, esp32c2, esp32h2))]
24use crate::gpio::RtcPinWithResistors as RtcIoWakeupPinType;
25use crate::rtc_cntl::Rtc;
26
27#[cfg_attr(esp32, path = "esp32.rs")]
28#[cfg_attr(esp32s2, path = "esp32s2.rs")]
29#[cfg_attr(esp32s3, path = "esp32s3.rs")]
30#[cfg_attr(esp32c3, path = "esp32c3.rs")]
31#[cfg_attr(esp32c6, path = "esp32c6.rs")]
32#[cfg_attr(esp32c2, path = "esp32c2.rs")]
33#[cfg_attr(esp32h2, path = "esp32h2.rs")]
34mod sleep_impl;
35
36pub use sleep_impl::*;
37
38#[derive(Debug, Default, Clone, Copy, PartialEq)]
39/// Level at which a wake-up event is triggered
40pub enum WakeupLevel {
41 /// The wake-up event is triggered when the pin is low.
42 Low,
43 #[default]
44 /// The wake-up event is triggered when the pin is high.
45 High,
46}
47
48#[procmacros::doc_replace]
49/// Represents a timer wake-up source, triggering an event after a specified
50/// duration.
51///
52/// ```rust, no_run
53/// # {before_snippet}
54/// # use core::time::Duration;
55/// # use esp_hal::delay::Delay;
56/// # use esp_hal::rtc_cntl::{reset_reason, sleep::TimerWakeupSource, wakeup_cause, Rtc, SocResetReason};
57/// # use esp_hal::system::Cpu;
58///
59/// let delay = Delay::new();
60/// let mut rtc = Rtc::new(peripherals.LPWR);
61///
62/// let reason = reset_reason(Cpu::ProCpu);
63/// let wake_reason = wakeup_cause();
64///
65/// println!("{:?} {?}", reason, wake_reason);
66///
67/// let timer = TimerWakeupSource::new(Duration::from_secs(5));
68/// delay.delay_millis(100);
69/// rtc.sleep_deep(&[&timer]);
70///
71/// # {after_snippet}
72/// ```
73#[derive(Debug, Default, Clone, Copy)]
74#[cfg(any(esp32, esp32c3, esp32s2, esp32s3, esp32c6, esp32c2, esp32h2))]
75pub struct TimerWakeupSource {
76 /// The duration after which the wake-up event is triggered.
77 duration: Duration,
78}
79
80#[cfg(any(esp32, esp32c3, esp32s2, esp32s3, esp32c6, esp32c2, esp32h2))]
81impl TimerWakeupSource {
82 /// Creates a new timer wake-up source with the specified duration.
83 pub fn new(duration: Duration) -> Self {
84 Self { duration }
85 }
86}
87
88/// Errors that can occur when configuring RTC wake-up sources.
89#[derive(Debug, Clone, Copy, PartialEq)]
90#[cfg_attr(feature = "defmt", derive(defmt::Format))]
91pub enum Error {
92 /// The selected pin is not a valid RTC pin.
93 NotRtcPin,
94 /// The maximum number of wake-up sources has been exceeded.
95 TooManyWakeupSources,
96}
97
98#[procmacros::doc_replace]
99/// External wake-up source (Ext0).
100///
101/// ```rust, no_run
102/// # {before_snippet}
103/// # use core::time::Duration;
104/// # use esp_hal::delay::Delay;
105/// # use esp_hal::rtc_cntl::{reset_reason, sleep::{Ext0WakeupSource, TimerWakeupSource, WakeupLevel}, wakeup_cause, Rtc, SocResetReason};
106/// # use esp_hal::system::Cpu;
107/// # use esp_hal::gpio::{Input, InputConfig, Pull};
108///
109/// let delay = Delay::new();
110/// let mut rtc = Rtc::new(peripherals.LPWR);
111///
112/// let config = InputConfig::default().with_pull(Pull::None);
113/// let mut pin_4 = peripherals.GPIO4;
114/// let pin_4_input = Input::new(pin_4.reborrow(), config);
115///
116/// let reason = reset_reason(Cpu::ProCpu);
117/// let wake_reason = wakeup_cause();
118///
119/// println!("{:?} {?}", reason, wake_reason);
120///
121/// let timer = TimerWakeupSource::new(Duration::from_secs(30));
122///
123/// core::mem::drop(pin_4_input);
124/// let ext0 = Ext0WakeupSource::new(pin_4, WakeupLevel::High);
125///
126/// delay.delay_millis(100);
127/// rtc.sleep_deep(&[&timer, &ext0]);
128///
129/// # }
130/// ```
131#[cfg(any(esp32, esp32s2, esp32s3))]
132pub struct Ext0WakeupSource<P: RtcIoWakeupPinType> {
133 /// The pin used as the wake-up source.
134 pin: RefCell<P>,
135 /// The level at which the wake-up event is triggered.
136 level: WakeupLevel,
137}
138
139#[cfg(any(esp32, esp32s2, esp32s3))]
140impl<P: RtcIoWakeupPinType> Ext0WakeupSource<P> {
141 /// Creates a new external wake-up source (Ext0``) with the specified pin
142 /// and wake-up level.
143 pub fn new(pin: P, level: WakeupLevel) -> Self {
144 Self {
145 pin: RefCell::new(pin),
146 level,
147 }
148 }
149}
150
151#[procmacros::doc_replace]
152/// External wake-up source (Ext1).
153///
154/// ```rust, no_run
155/// # {before_snippet}
156/// # use core::time::Duration;
157/// # use esp_hal::delay::Delay;
158/// # use esp_hal::rtc_cntl::{reset_reason, sleep::{Ext1WakeupSource, TimerWakeupSource, WakeupLevel}, wakeup_cause, Rtc, SocResetReason};
159/// # use esp_hal::system::Cpu;
160/// # use esp_hal::gpio::{Input, InputConfig, Pull, RtcPin};
161///
162/// let delay = Delay::new();
163/// let mut rtc = Rtc::new(peripherals.LPWR);
164///
165/// let config = InputConfig::default().with_pull(Pull::None);
166/// let mut pin_2 = peripherals.GPIO2;
167/// let mut pin_4 = peripherals.GPIO4;
168/// let pin_4_driver = Input::new(pin_4.reborrow(), config);
169///
170/// let reason = reset_reason(Cpu::ProCpu);
171/// let wake_reason = wakeup_cause();
172///
173/// println!("{:?} {?}", reason, wake_reason);
174///
175/// let timer = TimerWakeupSource::new(Duration::from_secs(30));
176///
177/// // Drop the driver to access `pin_4`
178/// core::mem::drop(pin_4_driver);
179///
180/// let mut wakeup_pins: [&mut dyn RtcPin; 2] = [&mut pin_4, &mut pin_2];
181///
182/// let ext1 = Ext1WakeupSource::new(&mut wakeup_pins, WakeupLevel::High);
183///
184/// delay.delay_millis(100);
185/// rtc.sleep_deep(&[&timer, &ext1]);
186///
187/// # }
188/// ```
189#[cfg(any(esp32, esp32s2, esp32s3))]
190pub struct Ext1WakeupSource<'a, 'b> {
191 /// A collection of pins used as wake-up sources.
192 pins: RefCell<&'a mut [&'b mut dyn RtcIoWakeupPinType]>,
193 /// The level at which the wake-up event is triggered across all pins.
194 level: WakeupLevel,
195}
196
197#[cfg(any(esp32, esp32s2, esp32s3))]
198impl<'a, 'b> Ext1WakeupSource<'a, 'b> {
199 /// Creates a new external wake-up source (Ext1) with the specified pins and
200 /// wake-up level.
201 pub fn new(pins: &'a mut [&'b mut dyn RtcIoWakeupPinType], level: WakeupLevel) -> Self {
202 Self {
203 pins: RefCell::new(pins),
204 level,
205 }
206 }
207}
208
209#[procmacros::doc_replace(
210 "pin_low" => {
211 cfg(esp32c6) => "GPIO2",
212 cfg(esp32h2) => "GPIO9",
213 },
214 "pin_high" => {
215 cfg(esp32c6) => "GPIO3",
216 cfg(esp32h2) => "GPIO10"
217 },
218)]
219/// External wake-up source (Ext1).
220/// ```rust, no_run
221/// # {before_snippet}
222/// # use core::time::Duration;
223/// # use esp_hal::delay::Delay;
224/// # use esp_hal::rtc_cntl::{reset_reason, sleep::{Ext1WakeupSource, TimerWakeupSource, WakeupLevel}, wakeup_cause, Rtc, SocResetReason};
225/// # use esp_hal::system::Cpu;
226/// # use esp_hal::gpio::{Input, InputConfig, Pull, RtcPinWithResistors};
227/// #
228/// let delay = Delay::new();
229/// let mut rtc = Rtc::new(peripherals.LPWR);
230///
231/// let config = InputConfig::default().with_pull(Pull::None);
232/// let mut pin_low_input = Input::new(peripherals.__pin_low__.reborrow(), config);
233///
234/// let reason = reset_reason(Cpu::ProCpu);
235/// let wake_reason = wakeup_cause();
236///
237/// println!("{:?} {?}", reason, wake_reason);
238///
239/// let timer = TimerWakeupSource::new(Duration::from_secs(30));
240///
241/// core::mem::drop(pin_low_input);
242///
243/// let wakeup_pins: &mut [(&mut dyn RtcPinWithResistors, WakeupLevel)] =
244/// &mut [
245/// (&mut peripherals.__pin_low__, WakeupLevel::Low),
246/// (&mut peripherals.__pin_high__, WakeupLevel::High),
247/// ];
248///
249/// let ext1 = Ext1WakeupSource::new(wakeup_pins);
250///
251/// delay.delay_millis(100);
252/// rtc.sleep_deep(&[&timer, &ext1]);
253///
254/// # }
255/// ```
256#[cfg(any(esp32c6, esp32h2))]
257pub struct Ext1WakeupSource<'a, 'b> {
258 pins: RefCell<&'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]>,
259}
260
261#[cfg(any(esp32c6, esp32h2))]
262impl<'a, 'b> Ext1WakeupSource<'a, 'b> {
263 /// Creates a new external wake-up source (Ext1) with the specified pins and
264 /// wake-up level.
265 pub fn new(pins: &'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]) -> Self {
266 Self {
267 pins: RefCell::new(pins),
268 }
269 }
270}
271
272#[procmacros::doc_replace(
273 "pin0" => {
274 cfg(any(esp32c3, esp32c2)) => "GPIO2",
275 cfg(any(esp32s2, esp32s3)) => "GPIO17"
276 },
277 "pin1" => {
278 cfg(any(esp32c3, esp32c2)) => "GPIO3",
279 cfg(any(esp32s2, esp32s3)) => "GPIO18"
280 },
281 "rtc_pin_trait" => {
282 cfg(any(esp32c3, esp32c2)) => "gpio::RtcPinWithResistors",
283 cfg(any(esp32s2, esp32s3)) => "gpio::RtcPin"
284 },
285)]
286/// RTC_IO wakeup source
287///
288/// RTC_IO wakeup allows configuring any combination of RTC_IO pins with
289/// arbitrary wakeup levels to wake up the chip from sleep. This wakeup source
290/// can be used to wake up from both light and deep sleep.
291///
292/// ```rust, no_run
293/// # {before_snippet}
294/// # use core::time::Duration;
295/// # use esp_hal::delay::Delay;
296/// # use esp_hal::gpio::{self, Input, InputConfig, Pull};
297/// # use esp_hal::rtc_cntl::{reset_reason,
298/// # sleep::{RtcioWakeupSource, TimerWakeupSource, WakeupLevel},
299/// # wakeup_cause, Rtc, SocResetReason
300/// # };
301/// # use esp_hal::system::Cpu;
302///
303/// let mut rtc = Rtc::new(peripherals.LPWR);
304///
305/// let reason = reset_reason(Cpu::ProCpu);
306/// let wake_reason = wakeup_cause();
307///
308/// println!("{:?} {?}", reason, wake_reason);
309///
310/// let delay = Delay::new();
311/// let timer = TimerWakeupSource::new(Duration::from_secs(10));
312/// let wakeup_pins: &mut [(&mut dyn __rtc_pin_trait__, WakeupLevel)] = &mut [
313/// (&mut peripherals.__pin0__, WakeupLevel::Low),
314/// (&mut peripherals.__pin1__, WakeupLevel::High),
315/// ];
316///
317/// let rtcio = RtcioWakeupSource::new(wakeup_pins);
318/// delay.delay_millis(100);
319/// rtc.sleep_deep(&[&timer, &rtcio]);
320///
321/// # {after_snippet}
322/// ```
323#[cfg(any(esp32c3, esp32s2, esp32s3, esp32c2))]
324pub struct RtcioWakeupSource<'a, 'b> {
325 pins: RefCell<&'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]>,
326}
327
328#[cfg(any(esp32c3, esp32s2, esp32s3, esp32c2))]
329impl<'a, 'b> RtcioWakeupSource<'a, 'b> {
330 /// Creates a new external GPIO wake-up source.
331 pub fn new(pins: &'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]) -> Self {
332 Self {
333 pins: RefCell::new(pins),
334 }
335 }
336}
337
338/// LP Core wakeup source
339///
340/// Wake up from LP core. This wakeup source
341/// can be used to wake up from both light and deep sleep.
342#[cfg(esp32c6)]
343pub struct WakeFromLpCoreWakeupSource {}
344
345#[cfg(esp32c6)]
346impl WakeFromLpCoreWakeupSource {
347 /// Create a new instance of `WakeFromLpCoreWakeupSource`
348 pub fn new() -> Self {
349 Self {}
350 }
351}
352
353#[cfg(esp32c6)]
354impl Default for WakeFromLpCoreWakeupSource {
355 fn default() -> Self {
356 Self::new()
357 }
358}
359
360/// ULP wakeup source
361///
362/// Wake up from ULP software interrupt, and/or ULP-RISCV Trap condition.
363/// Both of these triggers are enabled by default.
364/// This source will clear any outstanding software interrupts prior to entering sleep, by default.
365///
366/// S2 supports the following triggers (Refer to ESP32-S2 Technical Reference Manual, Table 9.4-3.
367/// Wakeup Source)
368/// - ULP-FSM software interrupt (unsure if this ALSO supports ULP-RISCV software interrupt)
369/// - ULP-RISCV Trap
370///
371/// S3 supports the following triggers (Refer to ESP32-S3 Technical Reference Manual, Table 10.4-3.
372/// Wakeup Source)
373/// - ULP-FSM software interrupt and ULP-RISCV software interrupt
374/// - ULP-RISCV Trap
375///
376/// This wakeup source can be used to wake up from both light and deep sleep.
377#[cfg(any(esp32s2, esp32s3))]
378pub struct UlpWakeupSource {
379 wake_on_interrupt: bool,
380 wake_on_trap: bool,
381 clear_interrupts_on_sleep: bool,
382}
383
384#[cfg(any(esp32s2, esp32s3))]
385impl UlpWakeupSource {
386 /// Create a new instance of `WakeFromUlpWakeupSource`
387 pub const fn new() -> Self {
388 Self {
389 wake_on_interrupt: true,
390 wake_on_trap: true,
391 clear_interrupts_on_sleep: true,
392 }
393 }
394
395 /// Enable wakeup triggered by software interrupt from ULP-FSM or ULP-RISCV
396 pub fn set_wake_on_interrupt(mut self, value: bool) -> Self {
397 self.wake_on_interrupt = value;
398 self
399 }
400
401 /// Enable wakeup triggered by ULP-RISCV Trap
402 pub fn set_wake_on_trap(mut self, value: bool) -> Self {
403 self.wake_on_trap = value;
404 self
405 }
406
407 /// Enable clearing of latched wake-up interrupts prior to entering sleep
408 pub fn set_clear_interrupts_on_sleep(mut self, value: bool) -> Self {
409 self.clear_interrupts_on_sleep = value;
410 self
411 }
412
413 /// Clears the wake-up interrupts
414 pub fn clear_interrupts(&self) {
415 crate::peripherals::LPWR::regs().int_clr().write(|w| {
416 w.cocpu_trap().clear_bit_by_one();
417 w.cocpu().clear_bit_by_one();
418 w.ulp_cp().clear_bit_by_one()
419 });
420 }
421}
422
423#[cfg(any(esp32s2, esp32s3))]
424impl Default for UlpWakeupSource {
425 fn default() -> Self {
426 Self::new()
427 }
428}
429
430/// GPIO wakeup source
431///
432/// Wake up from GPIO high or low level. Any pin can be used with this wake up
433/// source. Configure the pin for wake up via
434/// [crate::gpio::Input::wakeup_enable].
435///
436/// This wakeup source can be used to wake up from light sleep only.
437pub struct GpioWakeupSource {}
438
439impl GpioWakeupSource {
440 /// Create a new instance of [GpioWakeupSource]
441 pub fn new() -> Self {
442 Self {}
443 }
444}
445
446impl Default for GpioWakeupSource {
447 fn default() -> Self {
448 Self::new()
449 }
450}
451
452impl WakeSource for GpioWakeupSource {
453 fn apply(
454 &self,
455 _rtc: &Rtc<'_>,
456 triggers: &mut WakeTriggers,
457 _sleep_config: &mut RtcSleepConfig,
458 ) {
459 triggers.set_gpio(true);
460 }
461}
462
463macro_rules! uart_wakeup_impl {
464 ($num:literal) => {
465 paste::paste! {
466 #[doc = concat!("UART", $num, " wakeup source")]
467 ///
468 /// The chip can be woken up by reverting RXD for multiple cycles until the
469 /// number of rising edges is equal to or greater than the given value.
470 ///
471 /// Note that the character which triggers wakeup (and any characters before
472 /// it) will not be received by the UART after wakeup. This means that the
473 /// external device typically needs to send an extra character to trigger
474 /// wakeup before sending the data.
475 ///
476 /// After waking-up from UART, you should send some extra data through the UART
477 /// port in Active mode, so that the internal wakeup indication signal can be
478 /// cleared. Otherwise, the next UART wake-up would trigger with two less
479 /// rising edges than the configured threshold value.
480 ///
481 /// Wakeup from light sleep takes some time, so not every character sent to the
482 /// UART can be received by the application.
483 ///
484 /// This wakeup source can be used to wake up from light sleep only.
485 pub struct [< Uart $num WakeupSource >] {
486 threshold: u16,
487 }
488
489 impl [< Uart $num WakeupSource >] {
490 #[doc = concat!("Create a new instance of UART", $num, " wakeup source>") ]
491 ///
492 /// # Panics
493 ///
494 /// Panics if `threshold` is out of bounds.
495 pub fn new(threshold: u16) -> Self {
496 if threshold > 1023 {
497 panic!("Invalid threshold");
498 }
499 Self { threshold }
500 }
501 }
502
503 impl WakeSource for [< Uart $num WakeupSource >] {
504 fn apply(&self, _rtc: &Rtc<'_>, triggers: &mut WakeTriggers, _sleep_config: &mut RtcSleepConfig) {
505 triggers.[< set_uart $num >](true);
506 let uart = crate::peripherals::[< UART $num >]::regs();
507
508 #[cfg(any(esp32, esp32s2, esp32s3, esp32c2, esp32c3))]
509 uart.sleep_conf()
510 .modify(|_, w| unsafe { w.active_threshold().bits(self.threshold) });
511
512 #[cfg(not(any(esp32, esp32s2, esp32s3, esp32c2, esp32c3)))]
513 uart.sleep_conf2().modify(|_, w| unsafe {
514 w.wk_mode_sel()
515 .bits(0)
516 .active_threshold()
517 .bits(self.threshold)
518 });
519 }
520 }
521 }
522 };
523}
524
525uart_wakeup_impl!(0);
526uart_wakeup_impl!(1);
527
528#[cfg(esp32s2)]
529bitfield::bitfield! {
530 /// Represents the wakeup triggers.
531 #[derive(Default, Clone, Copy)]
532 pub struct WakeTriggers(u16);
533 impl Debug;
534 /// EXT0 GPIO wakeup
535 pub ext0, set_ext0: 0;
536 /// EXT1 GPIO wakeup
537 pub ext1, set_ext1: 1;
538 /// GPIO wakeup (l5ght sleep only)
539 pub gpio, set_gpio: 2;
540 /// Timer wakeup
541 pub timer, set_timer: 3;
542 /// WiFi SoC wakeup
543 pub wifi_soc, set_wifi_soc: 5;
544 /// UART0 wakeup (light sleep only)
545 pub uart0, set_uart0: 6;
546 /// UART1 wakeup (light sleep only)
547 pub uart1, set_uart1: 7;
548 /// Touch wakeup
549 pub touch, set_touch: 8;
550 /// ULP-FSM or ULP-RISCV wakeup
551 pub ulp, set_ulp: 11;
552 /// ULP-RISCV trap wakeup
553 pub ulp_riscv_trap, set_ulp_riscv_trap: 13;
554 /// USB wakeup
555 pub usb, set_usb: 15;
556}
557
558#[cfg(esp32s3)]
559bitfield::bitfield! {
560 /// Represents the wakeup triggers.
561 #[derive(Default, Clone, Copy)]
562 pub struct WakeTriggers(u16);
563 impl Debug;
564 /// EXT0 GPIO wakeup
565 pub ext0, set_ext0: 0;
566 /// EXT1 GPIO wakeup
567 pub ext1, set_ext1: 1;
568 /// GPIO wakeup (light sleep only)
569 pub gpio, set_gpio: 2;
570 /// Timer wakeup
571 pub timer, set_timer: 3;
572 /// SDIO wakeup (light sleep only)
573 pub sdio, set_sdio: 4;
574 /// MAC wakeup (light sleep only)
575 pub mac, set_mac: 5;
576 /// UART0 wakeup (light sleep only)
577 pub uart0, set_uart0: 6;
578 /// UART1 wakeup (light sleep only)
579 pub uart1, set_uart1: 7;
580 /// Touch wakeup
581 pub touch, set_touch: 8;
582 /// ULP-FSM wakeup
583 pub ulp_fsm, set_ulp_fsm: 9;
584 /// BT wakeup (light sleep only)
585 pub bt, set_bt: 10;
586 /// ULP-RISCV wakeup
587 pub ulp_riscv, set_ulp_riscv: 11;
588 /// ULP-RISCV trap wakeup
589 pub ulp_riscv_trap, set_ulp_riscv_trap: 13;
590}
591
592#[cfg(any(esp32, esp32c2, esp32c3))]
593bitfield::bitfield! {
594 /// Represents the wakeup triggers.
595 #[derive(Default, Clone, Copy)]
596 pub struct WakeTriggers(u16);
597 impl Debug;
598 /// EXT0 GPIO wakeup
599 pub ext0, set_ext0: 0;
600 /// EXT1 GPIO wakeup
601 pub ext1, set_ext1: 1;
602 /// GPIO wakeup (light sleep only)
603 pub gpio, set_gpio: 2;
604 /// Timer wakeup
605 pub timer, set_timer: 3;
606 /// SDIO wakeup (light sleep only)
607 pub sdio, set_sdio: 4;
608 /// MAC wakeup (light sleep only)
609 pub mac, set_mac: 5;
610 /// UART0 wakeup (light sleep only)
611 pub uart0, set_uart0: 6;
612 /// UART1 wakeup (light sleep only)
613 pub uart1, set_uart1: 7;
614 /// Touch wakeup
615 pub touch, set_touch: 8;
616 /// ULP-FSM wakeup
617 pub ulp, set_ulp: 9;
618 /// BT wakeup (light sleep only)
619 pub bt, set_bt: 10;
620}
621
622#[cfg(soc_has_pmu)]
623bitfield::bitfield! {
624 /// Represents the wakeup triggers.
625 #[derive(Default, Clone, Copy)]
626 pub struct WakeTriggers(u16);
627 impl Debug;
628
629 /// EXT0 GPIO wakeup
630 pub ext0, set_ext0: 0;
631 /// EXT1 GPIO wakeup
632 pub ext1, set_ext1: 1;
633 /// GPIO wakeup
634 pub gpio, set_gpio: 2;
635 /// WiFi beacon wakeup
636 pub wifi_beacon, set_wifi_beacon: 3;
637 /// Timer wakeup
638 pub timer, set_timer: 4;
639 /// WiFi SoC wakeup
640 pub wifi_soc, set_wifi_soc: 5;
641 /// UART0 wakeup
642 pub uart0, set_uart0: 6;
643 /// UART1 wakeup
644 pub uart1, set_uart1: 7;
645 /// SDIO wakeup
646 pub sdio, set_sdio: 8;
647 /// BT wakeup
648 pub bt, set_bt: 10;
649 /// LP core wakeup
650 pub lp_core, set_lp_core: 11;
651 /// USB wakeup
652 pub usb, set_usb: 14;
653}
654
655/// Trait representing a wakeup source.
656pub trait WakeSource {
657 /// Configures the RTC and applies the wakeup triggers.
658 fn apply(&self, rtc: &Rtc<'_>, triggers: &mut WakeTriggers, sleep_config: &mut RtcSleepConfig);
659}