esp_hal/rtc_cntl/rtc/
esp32c2.rs

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