Add TimerWakeupSource for the esp32-c6 deepsleep. (#1201)

This commit is contained in:
Timo 2024-02-28 17:59:49 +01:00 committed by GitHub
parent 5b5770965e
commit 0c99d8bb60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 8 deletions

View File

@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- A way to push into I2S DMA buffer via a closure (#1189)
- Added basic `LP-I2C` driver for C6 (#1185)
- Ensuring that the random number generator is TRNG. (#1200)
- ESP32-C6: Add timer wakeup source for deepsleep (#1201)
### Fixed

View File

@ -73,8 +73,12 @@ bitflags::bitflags! {
const ExtEvent1Trig = 1 << 1;
/// GPIO wakeup (light sleep only)
const GpioTrigEn = 1 << 2;
#[cfg(not(any(esp32c6, esp32h2)))]
/// Timer wakeup
const TimerTrigEn = 1 << 3;
#[cfg(any(esp32c6, esp32h2))]
/// Timer wakeup
const TimerTrigEn = 1 << 4;
#[cfg(pm_support_wifi_wakeup)]
/// MAC wakeup (light sleep only)
const WifiTrigEn = 1 << 5;

View File

@ -1,6 +1,7 @@
use core::ops::Not;
use crate::{
clock::Clock,
efuse::Efuse,
gpio::{Pins, RtcFunction},
peripherals::Peripherals,
@ -15,12 +16,44 @@ use crate::{
RtcCalSel,
SavedClockConfig,
},
sleep::{Ext1WakeupSource, WakeSource, WakeTriggers, WakeupLevel},
sleep::{Ext1WakeupSource, TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel},
RtcClock,
},
Rtc,
};
impl WakeSource for TimerWakeupSource {
fn apply(&self, rtc: &Rtc, triggers: &mut WakeTriggers, _sleep_config: &mut RtcSleepConfig) {
triggers.set_timer(true);
let lp_timer = unsafe { &*esp32c6::LP_TIMER::ptr() };
let clock_freq = RtcClock::get_slow_freq();
// TODO: maybe add sleep time adjustlemnt like idf
// TODO: maybe add check to prevent overflow?
let clock_hz = clock_freq.frequency().to_Hz() as u64;
let ticks = self.duration.as_micros() as u64 * clock_hz / 1_000_000u64;
// "alarm" time in slow rtc ticks
let now = rtc.get_time_raw();
let time_in_ticks = now + ticks;
unsafe {
lp_timer.tar0_high().write(|w| {
w.main_timer_tar_high0()
.bits(((time_in_ticks >> 32) & 0xffff) as u16)
});
lp_timer.tar0_low().write(|w| {
w.main_timer_tar_low0()
.bits((time_in_ticks & 0xffffffff) as u32)
});
lp_timer
.int_clr()
.write(|w| w.soc_wakeup_int_clr().set_bit());
lp_timer
.tar0_high()
.modify(|_, w| w.main_timer_tar_en0().set_bit());
}
}
}
impl Ext1WakeupSource<'_, '_> {
/// Returns the currently configured wakeup pins.
fn wakeup_pins() -> u8 {

View File

@ -21,7 +21,7 @@
//! * `BT (Bluetooth) wake` - light sleep only
use core::cell::RefCell;
#[cfg(any(esp32, esp32c3, esp32s3))]
#[cfg(any(esp32, esp32c3, esp32s3, esp32c6))]
use core::time::Duration;
#[cfg(any(esp32, esp32s3))]
@ -46,12 +46,12 @@ pub enum WakeupLevel {
}
#[derive(Debug, Default, Clone, Copy)]
#[cfg(any(esp32, esp32c3, esp32s3))]
#[cfg(any(esp32, esp32c3, esp32s3, esp32c6))]
pub struct TimerWakeupSource {
duration: Duration,
}
#[cfg(any(esp32, esp32c3, esp32s3))]
#[cfg(any(esp32, esp32c3, esp32s3, esp32c6))]
impl TimerWakeupSource {
pub fn new(duration: Duration) -> Self {
Self { duration }

View File

@ -1,6 +1,6 @@
//! Demonstrates deep sleep with timer wakeup
//% CHIPS: esp32 esp32c3 esp32s3
//% CHIPS: esp32 esp32c3 esp32c6 esp32s3
#![no_std]
#![no_main]

View File

@ -1,10 +1,12 @@
//! Demonstrates deep sleep with gpio2 (low) and gpio3 (high) as wakeup sources.
//! Demonstrates deep sleep with timer, using gpio2 (low) and gpio3 (high) as wakeup sources.
//% CHIPS: esp32c6
#![no_std]
#![no_main]
use core::time::Duration;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
@ -15,7 +17,7 @@ use esp_hal::{
rtc_cntl::{
get_reset_reason,
get_wakeup_cause,
sleep::{Ext1WakeupSource, WakeupLevel},
sleep::{Ext1WakeupSource, TimerWakeupSource, WakeupLevel},
SocResetReason,
},
Cpu,
@ -44,6 +46,8 @@ fn main() -> ! {
println!("wake reason: {:?}", wake_reason);
let mut delay = Delay::new(&clocks);
let timer = TimerWakeupSource::new(Duration::from_secs(10));
let wakeup_pins: &mut [(&mut dyn RTCPinWithResistors, WakeupLevel)] = &mut [
(&mut pin2, WakeupLevel::Low),
(&mut pin3, WakeupLevel::High),
@ -52,5 +56,5 @@ fn main() -> ! {
let rtcio = Ext1WakeupSource::new(wakeup_pins);
println!("sleeping!");
delay.delay_ms(100u32);
rtc.sleep_deep(&[&rtcio], &mut delay);
rtc.sleep_deep(&[&timer, &rtcio], &mut delay);
}