use strum::FromRepr;
use crate::{
peripherals::{APB_CTRL, EXTMEM, RTC_CNTL, SPI0, SPI1, SYSTEM},
regi2c_write_mask,
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
};
const I2C_DIG_REG: u32 = 0x6d;
const I2C_DIG_REG_HOSTID: u32 = 0;
const I2C_ULP: u32 = 0x61;
const I2C_ULP_HOSTID: u32 = 0;
const I2C_DIG_REG_XPD_RTC_REG: u32 = 13;
const I2C_DIG_REG_XPD_RTC_REG_MSB: u32 = 2;
const I2C_DIG_REG_XPD_RTC_REG_LSB: u32 = 2;
const I2C_DIG_REG_XPD_DIG_REG: u32 = 13;
const I2C_DIG_REG_XPD_DIG_REG_MSB: u32 = 3;
const I2C_DIG_REG_XPD_DIG_REG_LSB: u32 = 3;
const I2C_ULP_IR_FORCE_XPD_CK: u32 = 0;
const I2C_ULP_IR_FORCE_XPD_CK_MSB: u32 = 2;
const I2C_ULP_IR_FORCE_XPD_CK_LSB: u32 = 2;
pub(crate) fn init() {
let rtc_cntl = unsafe { &*RTC_CNTL::ptr() };
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
unsafe {
rtc_cntl
.timer1()
.modify(|_, w| w.pll_buf_wait().bits(20u8).ck8m_wait().bits(20u8));
rtc_cntl.timer5().modify(|_, w| w.min_slp_val().bits(2u8));
}
calibrate_ocode();
set_rtc_dig_dbias();
clock_control_init();
power_control_init();
unsafe {
rtc_cntl.int_ena_rtc().write(|w| w.bits(0));
rtc_cntl.int_clr_rtc().write(|w| w.bits(u32::MAX));
}
regi2c_write_mask!(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
}
pub(crate) fn configure_clock() {
RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
let cal_val = loop {
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
if res != 0 {
break res;
}
};
unsafe {
let rtc_cntl = &*RTC_CNTL::ptr();
rtc_cntl.store1().write(|w| w.bits(cal_val));
}
}
fn calibrate_ocode() {}
fn set_rtc_dig_dbias() {}
fn clock_control_init() {
let extmem = unsafe { &*EXTMEM::ptr() };
let spi_mem_0 = unsafe { &*SPI0::ptr() };
let spi_mem_1 = unsafe { &*SPI1::ptr() };
extmem
.cache_mmu_power_ctrl()
.modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
extmem
.icache_tag_power_ctrl()
.modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
spi_mem_0.clock_gate().modify(|_, w| w.clk_en().clear_bit());
spi_mem_1.clock_gate().modify(|_, w| w.clk_en().clear_bit());
}
fn power_control_init() {
let rtc_cntl = unsafe { &*RTC_CNTL::ptr() };
let system = unsafe { &*SYSTEM::ptr() };
rtc_cntl
.clk_conf()
.modify(|_, w| w.ck8m_force_pu().clear_bit());
rtc_cntl
.options0()
.modify(|_, w| w.xtl_force_pu().clear_bit());
rtc_cntl.ana_conf().modify(|_, w| {
w.plla_force_pu()
.clear_bit()
.plla_force_pd()
.set_bit()
.i2c_reset_por_force_pd()
.clear_bit()
});
rtc_cntl.options0().modify(|_, w| {
w.bbpll_force_pu()
.clear_bit()
.bbpll_i2c_force_pu()
.clear_bit()
.bb_i2c_force_pu()
.clear_bit()
});
rtc_cntl
.rtc_cntl()
.modify(|_, w| w.regulator_force_pu().clear_bit());
system
.mem_pd_mask()
.modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
rtc_sleep_pu();
rtc_cntl
.dig_pwc()
.modify(|_, w| w.dg_wrap_force_pu().clear_bit());
rtc_cntl
.dig_iso()
.modify(|_, w| w.dg_wrap_force_noiso().clear_bit());
system
.cpu_per_conf()
.modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
rtc_cntl.dig_iso().modify(|_, w| {
w.dg_pad_force_unhold()
.clear_bit()
.dg_pad_force_noiso()
.clear_bit()
});
}
fn rtc_sleep_pu() {
let rtc_cntl = unsafe { &*RTC_CNTL::ptr() };
let apb_ctrl = unsafe { &*APB_CTRL::ptr() };
rtc_cntl
.dig_pwc()
.modify(|_, w| w.lslp_mem_force_pu().clear_bit());
apb_ctrl.front_end_mem_pd().modify(|_, w| {
w.dc_mem_force_pu()
.clear_bit()
.pbus_mem_force_pu()
.clear_bit()
.agc_mem_force_pu()
.clear_bit()
});
apb_ctrl
.mem_power_up()
.modify(|_, w| unsafe { w.sram_power_up().bits(0u8).rom_power_up().bits(0u8) });
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
pub enum SocResetReason {
ChipPowerOn = 0x01,
CoreSw = 0x03,
CoreDeepSleep = 0x05,
CoreMwdt0 = 0x07,
CoreRtcWdt = 0x09,
Cpu0Mwdt0 = 0x0B,
Cpu0Sw = 0x0C,
Cpu0RtcWdt = 0x0D,
SysBrownOut = 0x0F,
SysRtcWdt = 0x10,
SysSuperWdt = 0x12,
SysClkGlitch = 0x13,
CoreEfuseCrc = 0x14,
Cpu0Jtag = 0x18,
}