pub struct LowPower<'d> { /* private fields */ }unstable only.Expand description
Low-power management.
The sleep calls do not take the wakeup sources that end the sleep. Each driver enables the source that it owns, and the hardware wakeup-enable mask keeps that request until the driver clears it. The mask keeps it through a light sleep, and through a deep-sleep wake. A sleep call reads the mask back, and calculates the rest of the configuration from it.
§Stability
This API is marked as unstable and is only available when the unstable
crate feature is enabled. This comes with no stability guarantees, and could be changed
or removed at any time.
Implementations§
Source§impl<'d> LowPower<'d>
impl<'d> LowPower<'d>
Sourcepub fn set_wakeup_deadline(&mut self, deadline: Instant)
pub fn set_wakeup_deadline(&mut self, deadline: Instant)
Arms the sleep alarm for deadline, and enables the timer wakeup source.
The deadline is absolute, so the time between this call and the sleep does not make the
sleep shorter. The deadline is a standing request. The wake that it causes does not
disarm it, a later call replaces it, and Self::clear_wakeup_deadline removes it.
A deadline in the past ends a light sleep immediately, and makes Self::sleep_deep panic.
A wakeup source can limit one sleep to an earlier wake. The limit does not replace this deadline. The deadline stays armed for the next sleep.
Sourcepub fn clear_wakeup_deadline(&mut self)
pub fn clear_wakeup_deadline(&mut self)
Disarms the sleep alarm, and disables the timer wakeup source.
Sourcepub fn sleep_deep(&mut self, config: RtcSleepConfig) -> !
pub fn sleep_deep(&mut self, config: RtcSleepConfig) -> !
Enters deep sleep, and does not return.
In deep sleep the CPUs, most of the RAM, and all digital peripherals that are clocked from
APB_CLK are powered off. The wake resets the chip, so use the
#[esp_hal::ram(persistent)] attribute to keep a variable through the
sleep.
The hardware cannot reject this sleep, because the function cannot return to report the
rejection. Use Self::sleep_deep_with_rejection for that.
A wakeup source cannot refuse this sleep. The wake resets the chip, so the call cannot
return a refusal. Self::sleep_light reports a refusal.
§Panics
Panics if no wakeup source is enabled, because then nothing can end the sleep. Panics also if the armed wakeup deadline is too near for the sleep transition to catch it, or if a wakeup source limits the sleep to less time than the transition can catch. In these cases the chip never wakes again, and it gives no report of the cause.
Sourcepub fn sleep_deep_with_rejection(&mut self, config: RtcSleepConfig)
pub fn sleep_deep_with_rejection(&mut self, config: RtcSleepConfig)
Enters deep sleep, and returns only if the hardware rejects the request.
The hardware rejects a sleep if one of its wakeup sources is already asserted. Without the rejection, the chip sleeps through the event that the caller wants to wake on. The return of this function is the complete report, so it gives no other result.
A wakeup source cannot refuse this sleep. A wakeup source can limit it. The function also returns when that limit is too short for the sleep transition to catch. The chip stays awake. The return does not say which case it was.
A rejected request returns the wake pads to their drivers, but it cannot return every pad.
Sleep entry disconnects the pads that no hold keeps, on the chips that need that step to
reach the deep-sleep current, and it cannot know their earlier configuration. Configure
those pads again if this function returns. ESP-IDF has the same limit in
esp_deep_sleep_try_to_start.
§Panics
Panics if no wakeup source is enabled.
Sourcepub fn sleep_light(&mut self, config: RtcSleepConfig) -> LightSleep
pub fn sleep_light(&mut self, config: RtcSleepConfig) -> LightSleep
Enters light sleep, and returns when a wakeup source ends it.
Light sleep keeps the state of the digital domain, so the program continues at the same place.
A wakeup source can refuse the sleep, which keeps the chip awake. A direct call and automatic light sleep both honor a refusal. The return reports it, because the caller then has to wait for the event itself.
A wakeup source can also limit the length of the sleep. The chip wakes at the sooner of that
limit and the armed wakeup deadline. When the timer source is not enabled, the limit enables
it for this sleep and disables it again afterwards. The sleep does not start when that wake
is already due, or when the transition cannot catch it. The result is LightSleep::Ended,
not LightSleep::Refused.
The function also returns without a sleep if no wakeup source is enabled, or if the hardware rejects the request because a wakeup source is already asserted. It reports neither case. For the caller, a rejected sleep and a very short sleep have the same result.
Source§impl LowPower<'_>
impl LowPower<'_>
Sourcepub fn install_cpu_retention_memory(
&mut self,
memory: &'static mut CpuRetentionMemory,
) -> Result<(), CpuRetentionMemoryError>
pub fn install_cpu_retention_memory( &mut self, memory: &'static mut CpuRetentionMemory, ) -> Result<(), CpuRetentionMemoryError>
Gives light sleep the memory that it uses to retain the CPU domain.
Light sleep powers the CPU domain down only after it has this memory. The memory stays with the driver for the life of the program, and a second call is an error, because the sleep path can hold one buffer only.
§Errors
Returns CpuRetentionMemoryError if the driver holds a buffer already, or if the buffer
is not inside the range that retention needs. The
#[ram(reclaimed, unstable(zeroed))] attribute places a static inside that
range on DMA chips.
§Examples
use esp_hal::rtc_cntl::{CpuRetentionStorage, sleep::LowPower};
// #[esp_hal::ram(reclaimed, unstable(zeroed))]
static RETENTION: CpuRetentionStorage = CpuRetentionStorage::new();
let mut lpwr = LowPower::new(peripherals.LPWR);
lpwr.install_cpu_retention_memory(RETENTION.take())?;§Stability
This API is marked as unstable and is only available when the unstable
crate feature is enabled. This comes with no stability guarantees, and could be changed
or removed at any time.
Source§impl LowPower<'_>
impl LowPower<'_>
Sourcepub fn install_cache_tag_retention_memory(
&mut self,
memory: &'static mut CacheTagRetentionMemory,
) -> Result<(), CacheTagRetentionMemoryError>
pub fn install_cache_tag_retention_memory( &mut self, memory: &'static mut CacheTagRetentionMemory, ) -> Result<(), CacheTagRetentionMemoryError>
Gives light sleep the memory that it uses to retain the cache tag memory.
This is an optimisation, and it is separate from
install_cpu_retention_memory because it costs memory and buys wake latency
rather than correctness. Without it, a retained sleep invalidates both caches on the wake
path, which is correct but slower.
The memory stays with the driver for the life of the program, and a second call is an error, because the sleep path can hold one buffer only.
§Errors
Returns CacheTagRetentionMemoryError if the driver holds a buffer already, or if the
buffer is not inside the range that the retention DMA reaches. The
#[ram(reclaimed, unstable(zeroed))] attribute places a static inside that
range.
§Examples
use esp_hal::rtc_cntl::{CacheTagRetentionStorage, CpuRetentionStorage, sleep::LowPower};
// #[esp_hal::ram(reclaimed, unstable(zeroed))]
static RETENTION: CpuRetentionStorage = CpuRetentionStorage::new();
// #[esp_hal::ram(reclaimed, unstable(zeroed))]
static TAG_MEMORY: CacheTagRetentionStorage = CacheTagRetentionStorage::new();
let mut lpwr = LowPower::new(peripherals.LPWR);
lpwr.install_cpu_retention_memory(RETENTION.take())?;
lpwr.install_cache_tag_retention_memory(TAG_MEMORY.take())?;§Stability
This API is marked as unstable and is only available when the unstable
crate feature is enabled. This comes with no stability guarantees, and could be changed
or removed at any time.