use super::{Armed, prepare_pad};
use crate::{
gpio::{Level, lp_io::low_level},
peripherals::LP_AON,
rtc_cntl::{WakeupReason, WakeupSource, sleep::WrappedSleepConfig},
};
pub(super) fn disable() {
WakeupSource::Ext1.disable();
}
pub(super) fn allocate(armed: &[Armed], config: &mut WrappedSleepConfig<'_>) {
if armed.is_empty() {
write_ext1(0, 0);
WakeupSource::Ext1.disable();
return;
}
let mut pads = 0;
let mut levels = 0;
for pin in armed {
let bit = 1 << pin.lp;
pads |= bit;
if pin.level == Level::High {
levels |= bit;
}
prepare_pad(pin, config.is_deep_sleep());
}
write_ext1(pads, levels);
WakeupSource::Ext1.enable();
}
pub(super) fn caused_wakeup(gpio: u8, cause: WakeupReason) -> bool {
let Some(lp) = super::lp_number(gpio) else {
return false;
};
cause.contains(WakeupSource::Ext1)
&& LP_AON::regs()
.ext_wakeup_cntl()
.read()
.ext_wakeup_status()
.bits()
& (1 << lp)
!= 0
}
pub(super) fn wake_io_reset() {
let armed = LP_AON::regs()
.ext_wakeup_cntl()
.read()
.ext_wakeup_sel()
.bits();
for lp in super::low_power_numbers() {
if armed & (1 << lp) != 0 {
low_level::pad_hold(lp, false);
}
}
}
fn write_ext1(pads: u8, levels: u8) {
LP_AON::regs()
.ext_wakeup_cntl()
.modify(|_, w| w.ext_wakeup_status_clr().set_bit());
LP_AON::regs().ext_wakeup_cntl().modify(|_, w| unsafe {
w.ext_wakeup_status_clr().clear_bit();
w.ext_wakeup_sel().bits(pads);
w.ext_wakeup_lv().bits(levels)
});
}