esp_hal/rtc_cntl/rtc/
esp32c2.rs

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