use super::{Armed, LP_NUMBERS, NO_LP_NUMBER};
use crate::{
gpio::{Level, lp_io::low_level},
peripherals::LPWR,
rtc_cntl::{WakeupReason, WakeupSource, sleep::WrappedSleepConfig},
};
pub(super) fn disable() {}
pub(super) fn allocate(armed: &[Armed], config: &mut WrappedSleepConfig<'_>) {
for &lp in LP_NUMBERS.iter().filter(|&&lp| lp != NO_LP_NUMBER) {
low_level::apply_wakeup(lp, false, Level::Low);
}
for pin in armed {
if config.is_deep_sleep() {
low_level::pad_hold(pin.lp, true);
super::hold_taken(pin.gpio);
}
low_level::apply_wakeup(pin.lp, true, pin.level);
}
prepare_gpio_wakeup();
}
pub(super) fn caused_wakeup(gpio: u8, cause: WakeupReason) -> bool {
let Some(lp) = super::lp_number(gpio) else {
return false;
};
let status = cfg_select! {
esp32c2 => LPWR::regs()
.cntl_gpio_wakeup()
.read()
.gpio_wakeup_status()
.bits(),
esp32c3 => LPWR::regs()
.gpio_wakeup()
.read()
.gpio_wakeup_status()
.bits(),
};
cause.contains(WakeupSource::Gpio) && status & (1 << lp) != 0
}
pub(super) fn wake_io_reset() {
let armed = low_level::wakeup_enabled_mask();
for lp in super::low_power_numbers() {
if armed & (1 << lp) != 0 {
low_level::pad_hold(lp, false);
}
}
}
fn prepare_gpio_wakeup() {
let gpio_wakeup = cfg_select! {
esp32c2 => LPWR::regs().cntl_gpio_wakeup(),
esp32c3 => LPWR::regs().gpio_wakeup(),
};
gpio_wakeup.modify(|_, w| w.gpio_pin_clk_gate().set_bit());
LPWR::regs()
.ext_wakeup_conf()
.modify(|_, w| w.gpio_wakeup_filter().set_bit());
gpio_wakeup.modify(|_, w| w.gpio_wakeup_status_clr().set_bit());
gpio_wakeup.modify(|_, w| w.gpio_wakeup_status_clr().clear_bit());
}