Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions examples/deep_sleep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! Tests deep sleep
//!
//! Enables multiple deep sleep wakeup sources and then enter deep sleep.
//! There is no loop here, since the program will not continue after deep sleep,
//! it always starts from the beginning after a deep sleep wake-up.
//! For ESP32c3, only timer wakeup is supported.
//! The program starts by printing reset and wakeup reason, since the deep
//! sleep effectively ends the program, this is how we get information about
//! the previous run.

#![allow(unknown_lints)]
#![allow(unexpected_cfgs)]

use core::time::Duration;

use esp_idf_hal::gpio::{Level, PinDriver, Pull};
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::reset::{ResetReason, WakeupReason};
use esp_idf_hal::sleep::*;

fn main() -> anyhow::Result<()> {
esp_idf_hal::sys::link_patches();

let reset_reason = ResetReason::get();
let wakeup_reason = WakeupReason::get();
println!("Reset after {reset_reason:?}; wakeup due to {wakeup_reason:?}");

let peripherals = Peripherals::take()?;

// Sample GPIO pins
// GPIO pins can only be used in deep sleep on the esp32c2 and esp32c3 where there are no RTC pins
//
// Note also, that ONLY pins connected to the VDD3P3_RTC power domain can be used for deep-sleep wakeup,
// which is not enforced in the deep-sleep API.

#[cfg(any(esp32c2, esp32c3))]
let gpio0 = PinDriver::input(peripherals.pins.gpio5, Pull::Down)?;
#[cfg(any(esp32c2, esp32c3))]
let gpio1 = PinDriver::input(peripherals.pins.gpio6, Pull::Down)?;

// Sample RTC pins
// No RTC on esp32c2 and esp32c3

#[cfg(not(any(esp32c2, esp32c3)))]
let rtc0 = PinDriver::rtc_input(peripherals.pins.gpio2, Pull::Down)?;
#[cfg(not(any(esp32c2, esp32c3)))]
let rtc1 = PinDriver::rtc_input(peripherals.pins.gpio4, Pull::Down)?;

// Assemble the wakeup sources now

let wakeups: &[&dyn DeepSleepWakeup] = &[
// Add timer wakeup
&TimerWakeup::new(Duration::from_secs(5)),
#[cfg(any(esp32c2, esp32c3))]
&PinsWakeup::<_, Gpio>::new([(&gpio0, Level::High), (&gpio1, Level::High)]),
#[cfg(not(any(esp32c2, esp32c3)))]
&PinsWakeup::<_, Rtc>::new([(&rtc0, Level::High), (&rtc1, Level::High)]),
];

// println!("Deep sleep with wakeup: {wakeup:?}");

let e = deep_sleep(wakeups);

println!("Failed to enter deep sleep: {e:?}");

Ok(())
}
89 changes: 89 additions & 0 deletions examples/light_sleep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//! Light sleep example
//!
//! Enable multiple light sleep wakeup sources and do sleep in a loop.
//! Print wakeup reason and sleep time on wakeup.

#![allow(unknown_lints)]
#![allow(unexpected_cfgs)]

use core::time::Duration;

use std::thread;
use std::time::Instant;

use esp_idf_hal::gpio::{AnyIOPin, Level, PinDriver, Pull};
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::reset::WakeupReason;
use esp_idf_hal::sleep::*;
use esp_idf_hal::uart::config::Config;
use esp_idf_hal::uart::UartDriver;
use esp_idf_hal::units::Hertz;

fn main() -> anyhow::Result<()> {
esp_idf_hal::sys::link_patches();

let peripherals = Peripherals::take()?;

// Sample GPIO pins

let gpio0 = PinDriver::input(peripherals.pins.gpio5, Pull::Down)?;
let gpio1 = PinDriver::input(peripherals.pins.gpio6, Pull::Down)?;

// Sample RTC pins

#[cfg(not(any(esp32c2, esp32c3)))]
let rtc0 = PinDriver::rtc_input(peripherals.pins.gpio2, Pull::Down)?;
#[cfg(not(any(esp32c2, esp32c3)))]
let rtc1 = PinDriver::rtc_input(peripherals.pins.gpio4, Pull::Down)?;

// Sample UART driver

let uart = UartDriver::new(
peripherals.uart0,
peripherals.pins.gpio7,
peripherals.pins.gpio8,
None::<AnyIOPin>,
None::<AnyIOPin>,
&Config::new().baudrate(Hertz(115_200)),
)?;

// Assemble the wakeup sources now

let wakeups: &[&dyn LightSleepWakeup] = &[
// Add GPIO wakeup
&PinsWakeup::<_, Gpio>::new([(&gpio0, Level::High), (&gpio1, Level::High)]),
// Add UART wakeup
&UartWakeup::new(&uart, 3),
// Add timer wakeup
&TimerWakeup::new(Duration::from_secs(5)),
#[cfg(not(esp32c3))]
&PinsWakeup::<_, Rtc>::new([(&rtc0, Level::High), (&rtc1, Level::High)]),
];

loop {
// println!("Light sleep with wakeup: {wakeup:?}");

// short sleep to flush stdout
thread::sleep(Duration::from_millis(60));

let time_before = Instant::now();

match light_sleep(wakeups) {
Ok(_) => {
let time_after = Instant::now();

let wakeup_reason = WakeupReason::get();
println!(
"wake up from light sleep due to {wakeup_reason:?} which lasted for {:?}",
time_after - time_before
);
}
Err(e) => {
println!("failed to do sleep: {e:?}");
thread::sleep(Duration::from_secs(1));
}
}

println!("---");
}
}
2 changes: 1 addition & 1 deletion src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1539,7 +1539,7 @@ macro_rules! impl_dac {

macro_rules! impl_touch {
($pxi:ident: $pin:expr, TOUCH: $touch:expr) => {
#[cfg(any(esp32, esp32s2, esp32s3))]
#[cfg(any(esp32, esp32s2, esp32s3, esp32p4))]
impl TouchPin for $pxi<'_> {
type TouchChannel = TOUCHCH<$touch>;
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ pub mod rmt {
pub use crate::rmt_legacy::*;
}

#[cfg(not(feature = "riscv-ulp-hal"))]
pub mod sleep;

pub mod rom;
pub mod sd;
pub mod spi;
Expand Down
Loading