Skip to main content

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}