Skip to content

Commit 757cb15

Browse files
committed
sleep: adds gpio deep sleep for esp32c* targets
1 parent 8ac288b commit 757cb15

File tree

2 files changed

+117
-12
lines changed

2 files changed

+117
-12
lines changed

examples/deep_sleep.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
//! the previous run.
1010
1111
use core::time::Duration;
12-
#[cfg(any(esp32, esp32s2, esp32s3))]
1312
use esp_idf_hal::gpio::PinDriver;
14-
#[cfg(any(esp32, esp32s2, esp32s3))]
13+
#[cfg(any(esp32c2, esp32c3))]
14+
use esp_idf_hal::gpio::Level;
1515
use esp_idf_hal::peripherals::Peripherals;
1616
use esp_idf_hal::reset::{ResetReason, WakeupReason};
1717
use esp_idf_hal::sleep::*;
@@ -30,7 +30,6 @@ fn main() -> anyhow::Result<()> {
3030

3131
print_wakeup_result();
3232

33-
#[cfg(any(esp32, esp32s2, esp32s3))]
3433
let peripherals = Peripherals::take().unwrap();
3534

3635
// RTC wakeup definitions
@@ -62,8 +61,30 @@ fn main() -> anyhow::Result<()> {
6261
None,
6362
);
6463

65-
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
66-
let dsleep = make_deep_sleep_no_pins(Some(TimerWakeup::new(Duration::from_secs(5))));
64+
// GPIO wakeup definitions
65+
#[cfg(any(esp32c2, esp32c3))]
66+
let gpio0 = PinDriver::input(peripherals.pins.gpio0)?;
67+
#[cfg(any(esp32c2, esp32c3))]
68+
let gpio1 = PinDriver::input(peripherals.pins.gpio1)?;
69+
70+
#[cfg(any(esp32c2, esp32c3))]
71+
let gpio_pin0 = GpioWakeupPin {
72+
pindriver: &gpio0,
73+
wake_level: Level::High,
74+
};
75+
#[cfg(any(esp32c2, esp32c3))]
76+
let gpio_pin1 = GpioWakeupPin {
77+
pindriver: &gpio1,
78+
wake_level: Level::Low,
79+
};
80+
#[cfg(any(esp32c2, esp32c3))]
81+
let gpio_wakeup = Some(GpioDeepWakeup {
82+
pins: EmptyGpioWakeupPins::chain(gpio_pin0).chain(gpio_pin1),
83+
});
84+
85+
#[cfg(any(esp32c2, esp32c3))]
86+
let dsleep =
87+
make_deep_sleep_gpio_pins(Some(TimerWakeup::new(Duration::from_secs(5))), gpio_wakeup);
6788

6889
println!("Deep sleep with: {:?}", dsleep);
6990
dsleep.prepare()?;

src/sleep.rs

+91-7
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use crate::gpio::{GPIOMode, InputPin, Level, PinDriver};
2727
#[cfg(any(esp32, esp32s2, esp32s3))]
2828
use crate::gpio::{RTCMode, RTCPin};
2929
use crate::uart::UartDriver;
30-
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
3130
use core::marker::PhantomData;
3231

3332
/// Will wake the CPU up after a given duration
@@ -274,6 +273,63 @@ where
274273
}
275274
}
276275

276+
#[cfg(any(esp32c2, esp32c3))]
277+
pub struct GpioDeepWakeup<P>
278+
where
279+
P: GpioWakeupPins,
280+
{
281+
pub pins: P,
282+
}
283+
284+
#[cfg(any(esp32c2, esp32c3))]
285+
impl<P> GpioDeepWakeup<P>
286+
where
287+
P: GpioWakeupPins,
288+
{
289+
fn mask(&self, level: Level) -> u64 {
290+
let mut m: u64 = 0;
291+
for pin in self.pins.iter() {
292+
if pin.1 == level {
293+
m |= 1 << pin.0;
294+
}
295+
}
296+
m
297+
}
298+
299+
fn apply(&self) -> Result<(), EspError> {
300+
esp!(unsafe {
301+
esp_deep_sleep_enable_gpio_wakeup(
302+
self.mask(Level::Low),
303+
esp_deepsleep_gpio_wake_up_mode_t_ESP_GPIO_WAKEUP_GPIO_LOW,
304+
)
305+
})?;
306+
307+
esp!(unsafe {
308+
esp_deep_sleep_enable_gpio_wakeup(
309+
self.mask(Level::High),
310+
esp_deepsleep_gpio_wake_up_mode_t_ESP_GPIO_WAKEUP_GPIO_HIGH,
311+
)
312+
})?;
313+
314+
Ok(())
315+
}
316+
}
317+
318+
#[cfg(any(esp32c2, esp32c3))]
319+
impl<P> fmt::Debug for GpioDeepWakeup<P>
320+
where
321+
P: GpioWakeupPins,
322+
{
323+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
324+
write!(f, "GpioDeepWakeup {{ pins: [")?;
325+
326+
for pin in self.pins.iter() {
327+
write!(f, "({} {:?}), ", pin.0, pin.1)?;
328+
}
329+
write!(f, "")
330+
}
331+
}
332+
277333
pub trait GpioWakeupPinTrait {
278334
fn pin(&self) -> i32;
279335
fn wake_level(&self) -> Level;
@@ -584,35 +640,41 @@ where
584640
}
585641

586642
/// Struct for deep sleep. Add wakeup sources to this struct, and then call sleep().
587-
pub struct DeepSleep<R>
643+
pub struct DeepSleep<R, P>
588644
where
589645
R: RtcWakeupPins,
646+
P: GpioWakeupPins,
590647
{
591648
pub timer: Option<TimerWakeup>,
592649
#[cfg(any(esp32, esp32s2, esp32s3))]
593650
pub rtc: Option<RtcWakeup<R>>,
651+
#[cfg(any(esp32c2, esp32c3))]
652+
pub gpio: Option<GpioDeepWakeup<P>>,
594653
#[cfg(any(esp32, esp32s2, esp32s3))]
595654
pub touch: Option<TouchWakeup>,
596655
#[cfg(any(esp32, esp32s2, esp32s3))]
597656
pub ulp: Option<UlpWakeup>,
598657
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
599658
pub _p: PhantomData<R>,
659+
#[cfg(not(any(esp32c2, esp32c3)))]
660+
pub _p: PhantomData<P>,
600661
}
601662

602663
pub fn make_deep_sleep_no_pins(
603664
timer: Option<TimerWakeup>,
604665
#[cfg(any(esp32, esp32s2, esp32s3))] touch: Option<TouchWakeup>,
605666
#[cfg(any(esp32, esp32s2, esp32s3))] ulp: Option<UlpWakeup>,
606-
) -> DeepSleep<EmptyRtcWakeupPins> {
667+
) -> DeepSleep<EmptyRtcWakeupPins, EmptyGpioWakeupPins> {
607668
DeepSleep {
608669
timer,
609670
#[cfg(any(esp32, esp32s2, esp32s3))]
610671
rtc: None,
672+
#[cfg(any(esp32c2, esp32c3))]
673+
gpio: None,
611674
#[cfg(any(esp32, esp32s2, esp32s3))]
612675
touch,
613676
#[cfg(any(esp32, esp32s2, esp32s3))]
614677
ulp,
615-
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
616678
_p: PhantomData,
617679
}
618680
}
@@ -623,18 +685,32 @@ pub fn make_deep_sleep_rtc_pins<R: RtcWakeupPins>(
623685
rtc: Option<RtcWakeup<R>>,
624686
touch: Option<TouchWakeup>,
625687
ulp: Option<UlpWakeup>,
626-
) -> DeepSleep<R> {
688+
) -> DeepSleep<R, EmptyGpioWakeupPins> {
627689
DeepSleep {
628690
timer,
629691
rtc,
630692
touch,
631693
ulp,
694+
_p: PhantomData,
632695
}
633696
}
634697

635-
impl<R> DeepSleep<R>
698+
#[cfg(any(esp32c2, esp32c3))]
699+
pub fn make_deep_sleep_gpio_pins<P: GpioWakeupPins>(
700+
timer: Option<TimerWakeup>,
701+
gpio: Option<GpioDeepWakeup<P>>,
702+
) -> DeepSleep<EmptyRtcWakeupPins, P> {
703+
DeepSleep {
704+
timer,
705+
gpio,
706+
_p: PhantomData,
707+
}
708+
}
709+
710+
impl<R, P> DeepSleep<R, P>
636711
where
637712
R: RtcWakeupPins,
713+
P: GpioWakeupPins,
638714
{
639715
pub fn prepare(&self) -> Result<(), EspError> {
640716
esp!(unsafe { esp_sleep_disable_wakeup_source(esp_sleep_source_t_ESP_SLEEP_WAKEUP_ALL) })?;
@@ -648,6 +724,11 @@ where
648724
rtc.apply()?;
649725
}
650726

727+
#[cfg(any(esp32c2, esp32c3))]
728+
if let Some(gpio) = &self.gpio {
729+
gpio.apply()?;
730+
}
731+
651732
#[cfg(any(esp32, esp32s2, esp32s3))]
652733
if let Some(touch) = &self.touch {
653734
touch.apply()?;
@@ -679,14 +760,17 @@ where
679760
}
680761
}
681762

682-
impl<R> fmt::Debug for DeepSleep<R>
763+
impl<R, P> fmt::Debug for DeepSleep<R, P>
683764
where
684765
R: RtcWakeupPins,
766+
P: GpioWakeupPins,
685767
{
686768
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
687769
write!(f, "DeepSleep: {{timer: {:?}, ", self.timer)?;
688770
#[cfg(any(esp32, esp32s2, esp32s3))]
689771
write!(f, "rtc: {:?}, ", self.rtc)?;
772+
#[cfg(any(esp32c2, esp32c3))]
773+
write!(f, "gpio: {:?}, ", self.gpio)?;
690774
#[cfg(any(esp32, esp32s2, esp32s3))]
691775
write!(f, "touch: {:?}, ", self.touch)?;
692776
#[cfg(any(esp32, esp32s2, esp32s3))]

0 commit comments

Comments
 (0)