esp_hal/rtc_cntl/rtc/
esp32c2.rs

1use strum::FromRepr;
2
3use crate::{
4    peripherals::{APB_CTRL, EXTMEM, LPWR, SPI0, SPI1, SYSTEM},
5    rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
6    soc::regi2c,
7};
8
9pub(crate) fn init() {
10    let rtc_cntl = LPWR::regs();
11
12    regi2c::I2C_DIG_REG_XPD_DIG_REG.write_field(0);
13    regi2c::I2C_DIG_REG_XPD_RTC_REG.write_field(0);
14
15    unsafe {
16        rtc_cntl
17            .timer1()
18            .modify(|_, w| w.pll_buf_wait().bits(20u8).ck8m_wait().bits(20u8));
19
20        rtc_cntl.timer5().modify(|_, w| w.min_slp_val().bits(2u8));
21    }
22
23    calibrate_ocode();
24
25    set_rtc_dig_dbias();
26
27    clock_control_init();
28
29    power_control_init();
30
31    unsafe {
32        rtc_cntl.int_ena().write(|w| w.bits(0));
33        rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
34    }
35
36    regi2c::I2C_ULP_IR_FORCE_XPD_CK.write_field(0);
37}
38
39pub(crate) fn configure_clock() {
40    unsafe {
41        // from esp_clk_init:
42        // clk_ll_rc_fast_enable();
43        LPWR::regs()
44            .clk_conf()
45            .modify(|_, w| w.enb_ck8m().clear_bit());
46        LPWR::regs().timer1().modify(|_, w| w.ck8m_wait().bits(5));
47        // esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
48        crate::rom::ets_delay_us(50);
49    }
50    RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
51
52    let cal_val = loop {
53        RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
54
55        let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
56        if res != 0 {
57            break res;
58        }
59    };
60
61    unsafe { LPWR::regs().store1().write(|w| w.bits(cal_val)) };
62}
63
64fn calibrate_ocode() {}
65
66fn set_rtc_dig_dbias() {}
67
68/// Perform clock control related initialization
69fn clock_control_init() {
70    let extmem = EXTMEM::regs();
71    let spi_mem_0 = SPI0::regs();
72    let spi_mem_1 = SPI1::regs();
73
74    // Clear CMMU clock force on
75    extmem
76        .cache_mmu_power_ctrl()
77        .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
78
79    // Clear tag clock force on
80    extmem
81        .icache_tag_power_ctrl()
82        .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
83
84    // Clear register clock force on
85    spi_mem_0.clock_gate().modify(|_, w| w.clk_en().clear_bit());
86    spi_mem_1.clock_gate().modify(|_, w| w.clk_en().clear_bit());
87}
88
89/// Perform power control related initialization
90fn power_control_init() {
91    let rtc_cntl = LPWR::regs();
92    let system = SYSTEM::regs();
93
94    rtc_cntl
95        .clk_conf()
96        .modify(|_, w| w.ck8m_force_pu().clear_bit());
97
98    // Cancel XTAL force PU if no need to force power up
99    // Cannot cancel XTAL force PU if PLL is force power on
100    rtc_cntl
101        .options0()
102        .modify(|_, w| w.xtl_force_pu().clear_bit());
103
104    // Force PD APLL
105    rtc_cntl.ana_conf().modify(|_, w| {
106        w.plla_force_pu().clear_bit();
107        w.plla_force_pd().set_bit();
108        // Open SAR_I2C protect function to avoid SAR_I2C
109        // Reset when rtc_ldo is low.
110        w.i2c_reset_por_force_pd().clear_bit()
111    });
112
113    // Cancel BBPLL force PU if setting no force power up
114    rtc_cntl.options0().modify(|_, w| {
115        w.bbpll_force_pu().clear_bit();
116        w.bbpll_i2c_force_pu().clear_bit();
117        w.bb_i2c_force_pu().clear_bit()
118    });
119
120    rtc_cntl
121        .rtc_cntl()
122        .modify(|_, w| w.regulator_force_pu().clear_bit());
123
124    // If this mask is enabled, all soc memories cannot enter power down mode.
125    // We should control soc memory power down mode from RTC,
126    // so we will not touch this register any more.
127    system
128        .mem_pd_mask()
129        .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
130
131    rtc_sleep_pu();
132
133    rtc_cntl
134        .dig_pwc()
135        .modify(|_, w| w.dg_wrap_force_pu().clear_bit());
136
137    rtc_cntl
138        .dig_iso()
139        .modify(|_, w| w.dg_wrap_force_noiso().clear_bit());
140
141    // Cancel digital PADS force no iso
142    system
143        .cpu_per_conf()
144        .modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
145
146    // If SYSTEM_CPU_WAIT_MODE_FORCE_ON == 0,
147    // the CPU clock will be closed when CPU enter WAITI mode.
148    rtc_cntl.dig_iso().modify(|_, w| {
149        w.dg_pad_force_unhold().clear_bit();
150        w.dg_pad_force_noiso().clear_bit()
151    });
152}
153
154/// Configure whether certain peripherals are powered down in deep sleep
155fn rtc_sleep_pu() {
156    LPWR::regs()
157        .dig_pwc()
158        .modify(|_, w| w.lslp_mem_force_pu().clear_bit());
159
160    APB_CTRL::regs().front_end_mem_pd().modify(|_, w| {
161        w.dc_mem_force_pu().clear_bit();
162        w.pbus_mem_force_pu().clear_bit();
163        w.agc_mem_force_pu().clear_bit()
164    });
165    APB_CTRL::regs().mem_power_up().modify(|_, w| unsafe {
166        w.sram_power_up().bits(0u8);
167        w.rom_power_up().bits(0u8)
168    });
169}
170
171// Terminology:
172//
173// CPU Reset:    Reset CPU core only, once reset done, CPU will execute from
174//               reset vector
175// Core Reset:   Reset the whole digital system except RTC sub-system
176// System Reset: Reset the whole digital system, including RTC sub-system
177// Chip Reset:   Reset the whole chip, including the analog part
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
180/// SOC Reset Reason.
181pub enum SocResetReason {
182    /// Power on reset
183    ChipPowerOn   = 0x01,
184    /// Software resets the digital core by RTC_CNTL_SW_SYS_RST
185    CoreSw        = 0x03,
186    /// Deep sleep reset the digital core
187    CoreDeepSleep = 0x05,
188    /// Main watch dog 0 resets digital core
189    CoreMwdt0     = 0x07,
190    /// RTC watch dog resets digital core
191    CoreRtcWdt    = 0x09,
192    /// Main watch dog 0 resets CPU 0
193    Cpu0Mwdt0     = 0x0B,
194    /// Software resets CPU 0 by RTC_CNTL_SW_PROCPU_RST
195    Cpu0Sw        = 0x0C,
196    /// RTC watch dog resets CPU 0
197    Cpu0RtcWdt    = 0x0D,
198    /// VDD voltage is not stable and resets the digital core
199    SysBrownOut   = 0x0F,
200    /// RTC watch dog resets digital core and rtc module
201    SysRtcWdt     = 0x10,
202    /// Super watch dog resets the digital core and rtc module
203    SysSuperWdt   = 0x12,
204    /// Glitch on clock resets the digital core and rtc module
205    SysClkGlitch  = 0x13,
206    /// eFuse CRC error resets the digital core
207    CoreEfuseCrc  = 0x14,
208    /// JTAG resets the CPU 0
209    Cpu0Jtag      = 0x18,
210}