use super::{Armed, prepare_pad};
use crate::{
gpio::{Level, lp_io::low_level},
peripherals::PMU,
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.gpio;
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 {
if super::lp_number(gpio).is_none() {
return false;
}
cause.contains(WakeupSource::Ext1)
&& PMU::regs()
.ext_wakeup_st()
.read()
.ext_wakeup_status()
.bits()
& (1 << gpio)
!= 0
}
pub(super) fn wake_io_reset() {
let armed = PMU::regs().ext_wakeup_sel().read().ext_wakeup_sel().bits();
for (gpio, lp) in super::low_power_pads() {
if armed & (1 << gpio) != 0 {
low_level::pad_hold(lp, false);
}
}
PMU::regs().ext_wakeup_sel().reset();
}
fn write_ext1(pads: u32, levels: u32) {
PMU::regs()
.ext_wakeup_cntl()
.modify(|_, w| w.ext_wakeup_status_clr().set_bit());
PMU::regs()
.ext_wakeup_cntl()
.modify(|_, w| w.ext_wakeup_status_clr().clear_bit());
PMU::regs()
.ext_wakeup_sel()
.write(|w| unsafe { w.ext_wakeup_sel().bits(pads) });
PMU::regs()
.ext_wakeup_lv()
.write(|w| unsafe { w.ext_wakeup_lv().bits(levels) });
}