mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 12:50:53 +00:00
Add TimerWakeupSource for the esp32-c6 deepsleep. (#1201)
This commit is contained in:
parent
5b5770965e
commit
0c99d8bb60
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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 }
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Demonstrates deep sleep with timer wakeup
|
||||
|
||||
//% CHIPS: esp32 esp32c3 esp32s3
|
||||
//% CHIPS: esp32 esp32c3 esp32c6 esp32s3
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user