Skip to content

Commit 1472428

Browse files
committed
sleep: Adds module for light and deep sleep with examples
1 parent b61a2b1 commit 1472428

File tree

4 files changed

+574
-0
lines changed

4 files changed

+574
-0
lines changed

examples/deep_sleep.rs

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//! Tests deep sleep
2+
//!
3+
//! Enables multiple deep sleep wakeup sources and then enter deep sleep.
4+
//! There is no loop here, since the program will not continue after deep sleep.
5+
//! For ESP32c3, only timer wakeup is supported.
6+
//! The program starts by printing reset and wakeup reason, since the deep
7+
//! sleep effectively ends the program, this is how we get information about
8+
//! the previous run.
9+
10+
use core::time::Duration;
11+
use esp_idf_hal::peripherals::Peripherals;
12+
use esp_idf_hal::reset::{ResetReason, WakeupReason};
13+
use esp_idf_hal::sleep::*;
14+
15+
fn print_wakeup_result() {
16+
let reset_reason = ResetReason::get();
17+
let wakeup_reason = WakeupReason::get();
18+
println!(
19+
"reset after {:?} wakeup due to {:?}",
20+
reset_reason, wakeup_reason
21+
);
22+
}
23+
24+
fn main() -> anyhow::Result<()> {
25+
esp_idf_sys::link_patches();
26+
27+
print_wakeup_result();
28+
29+
#[cfg(any(esp32, esp32s2, esp32s3))]
30+
let peripherals = Peripherals::take().unwrap();
31+
32+
// RTC wakeup definitions
33+
#[cfg(esp32)]
34+
let rtc_pins = [
35+
RtcWakeupPin::new(peripherals.pins.gpio4.into(), false, true),
36+
RtcWakeupPin::new(peripherals.pins.gpio27.into(), false, true),
37+
];
38+
#[cfg(any(esp32s2, esp32s3))]
39+
let rtc_pins = [
40+
RtcWakeupPin::new(peripherals.pins.gpio1.into(), false, true),
41+
RtcWakeupPin::new(peripherals.pins.gpio2.into(), false, true),
42+
];
43+
#[cfg(any(esp32, esp32s2, esp32s3))]
44+
let rtc_wakeup = Some(RtcWakeup::new(&rtc_pins, RtcWakeLevel::AnyHigh));
45+
46+
let dsleep = DeepSleep {
47+
timer: Some(TimerWakeup::new(Duration::from_secs(5))),
48+
#[cfg(any(esp32, esp32s2, esp32s3))]
49+
rtc: rtc_wakeup,
50+
..Default::default()
51+
};
52+
53+
println!("Deep sleep with: {:?}", dsleep);
54+
dsleep.prepare()?;
55+
dsleep.sleep();
56+
}

examples/light_sleep.rs

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//! Tests light sleep
2+
//!
3+
//! Enables multiple light sleep wakeup sources and do sleeps in a loop.
4+
//! Prints wakeup reason and sleep time on wakeup.
5+
6+
use core::time::Duration;
7+
use esp_idf_hal::gpio::{self, AnyInputPin, PinDriver};
8+
use esp_idf_hal::peripherals::Peripherals;
9+
use esp_idf_hal::prelude::*;
10+
use esp_idf_hal::reset::WakeupReason;
11+
use esp_idf_hal::sleep::*;
12+
use esp_idf_hal::uart::config::Config;
13+
use esp_idf_hal::uart::UartDriver;
14+
use std::thread;
15+
use std::time::Instant;
16+
17+
use crate::gpio::Level;
18+
19+
fn print_wakeup_result(time_before: Instant) {
20+
let time_after = Instant::now();
21+
22+
let wakeup_reason = WakeupReason::get();
23+
println!(
24+
"wake up from light sleep due to {:?} which lasted for {:?}",
25+
wakeup_reason,
26+
time_after - time_before
27+
);
28+
}
29+
30+
fn main() -> anyhow::Result<()> {
31+
esp_idf_sys::link_patches();
32+
33+
// run in a thread with increased stack size to prevent overflow
34+
let builder = std::thread::Builder::new().stack_size(8 * 1024);
35+
let th = builder.spawn(move || -> anyhow::Result<()> {
36+
let peripherals = Peripherals::take().unwrap();
37+
38+
// RTC wakeup definitions
39+
#[cfg(esp32)]
40+
let rtc_pins = [
41+
RtcWakeupPin::new(peripherals.pins.gpio26.into(), false, true),
42+
RtcWakeupPin::new(peripherals.pins.gpio27.into(), false, true),
43+
];
44+
#[cfg(any(esp32s2, esp32s3))]
45+
let rtc_pins = [
46+
RtcWakeupPin::new(peripherals.pins.gpio1.into(), false, true),
47+
RtcWakeupPin::new(peripherals.pins.gpio2.into(), false, true),
48+
];
49+
#[cfg(any(esp32, esp32s2, esp32s3))]
50+
let rtc_wakeup = Some(RtcWakeup::new(&rtc_pins, RtcWakeLevel::AnyHigh));
51+
52+
// GPIO wakeup definitions
53+
#[cfg(esp32)]
54+
let gpio_pin1 = PinDriver::input(AnyInputPin::from(peripherals.pins.gpio16))?;
55+
#[cfg(esp32)]
56+
let gpio_pin2 = PinDriver::input(AnyInputPin::from(peripherals.pins.gpio17))?;
57+
58+
#[cfg(any(esp32s2, esp32s3))]
59+
let gpio_pin1 = PinDriver::input(AnyInputPin::from(peripherals.pins.gpio37))?;
60+
#[cfg(any(esp32s2, esp32s3))]
61+
let gpio_pin2 = PinDriver::input(AnyInputPin::from(peripherals.pins.gpio38))?;
62+
63+
#[cfg(esp32c3)]
64+
let gpio_pin1 = PinDriver::input(AnyInputPin::from(peripherals.pins.gpio6))?;
65+
#[cfg(esp32c3)]
66+
let gpio_pin2 = PinDriver::input(AnyInputPin::from(peripherals.pins.gpio7))?;
67+
68+
let gpio_pins = [
69+
GpioWakeupPin::new(gpio_pin1, Level::High)?,
70+
GpioWakeupPin::new(gpio_pin2, Level::High)?,
71+
];
72+
#[cfg(any(esp32, esp32c3, esp32s2, esp32s3))]
73+
let gpio_wakeup = Some(GpioWakeup::new(&gpio_pins));
74+
#[cfg(not(any(esp32, esp32c3, esp32s2, esp32s3)))]
75+
let gpio_wakeup: Option<GpioWakeup> = None;
76+
77+
// UART definitions
78+
let config = Config::new().baudrate(Hertz(115_200));
79+
#[cfg(any(esp32))]
80+
let uart = UartDriver::new(
81+
peripherals.uart0,
82+
peripherals.pins.gpio4,
83+
peripherals.pins.gpio3,
84+
Option::<gpio::Gpio0>::None,
85+
Option::<gpio::Gpio1>::None,
86+
&config,
87+
)?;
88+
#[cfg(any(esp32s2, esp32s3))]
89+
let uart = UartDriver::new(
90+
peripherals.uart0,
91+
peripherals.pins.gpio43,
92+
peripherals.pins.gpio44,
93+
Option::<gpio::Gpio0>::None,
94+
Option::<gpio::Gpio1>::None,
95+
&config,
96+
)?;
97+
#[cfg(esp32c3)]
98+
let uart = UartDriver::new(
99+
peripherals.uart0,
100+
peripherals.pins.gpio21,
101+
peripherals.pins.gpio20,
102+
Option::<gpio::Gpio0>::None,
103+
Option::<gpio::Gpio1>::None,
104+
&config,
105+
)?;
106+
#[cfg(any(esp32, esp32s2, esp32s3, esp32c3))]
107+
let uart_wakeup = Some(UartWakeup::new(&uart, 3));
108+
#[cfg(not(any(esp32, esp32s2, esp32s3, esp32c3)))]
109+
let uart_wakeup: Option<UartWakeup> = None;
110+
111+
let lsleep = LightSleep {
112+
timer: Some(TimerWakeup::new(Duration::from_secs(5))),
113+
#[cfg(any(esp32, esp32s2, esp32s3))]
114+
rtc: rtc_wakeup,
115+
gpio: gpio_wakeup,
116+
uart: uart_wakeup,
117+
..Default::default()
118+
};
119+
120+
loop {
121+
println!("Light sleep with: {:?}", lsleep);
122+
// short sleep to flush stdout
123+
thread::sleep(Duration::from_millis(60));
124+
125+
let time_before = Instant::now();
126+
let err = lsleep.sleep();
127+
match err {
128+
Ok(_) => print_wakeup_result(time_before),
129+
Err(e) => {
130+
println!("failed to do sleep: {:?}", e);
131+
thread::sleep(Duration::from_secs(1));
132+
}
133+
}
134+
println!("---");
135+
}
136+
})?;
137+
138+
let _err = th.join();
139+
Ok(())
140+
}

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ pub mod rmt;
7070
#[cfg(not(feature = "riscv-ulp-hal"))]
7171
pub mod rom;
7272
#[cfg(not(feature = "riscv-ulp-hal"))]
73+
pub mod sleep;
74+
#[cfg(not(feature = "riscv-ulp-hal"))]
7375
pub mod spi;
7476
pub mod sys;
7577
#[cfg(not(feature = "riscv-ulp-hal"))]

0 commit comments

Comments
 (0)