esp_hal/rtc_cntl/rtc/
esp32c3.rs

1use strum::FromRepr;
2
3use crate::{
4    clock::XtalClock,
5    peripherals::{APB_CTRL, EXTMEM, LPWR, SPI0, SPI1, SYSTEM},
6    rom::regi2c_write_mask,
7    rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
8};
9
10const I2C_DIG_REG: u32 = 0x6d;
11const I2C_DIG_REG_HOSTID: u32 = 0;
12
13const I2C_ULP: u32 = 0x61;
14const I2C_ULP_HOSTID: u32 = 0;
15
16const I2C_DIG_REG_XPD_RTC_REG: u32 = 13;
17const I2C_DIG_REG_XPD_RTC_REG_MSB: u32 = 2;
18const I2C_DIG_REG_XPD_RTC_REG_LSB: u32 = 2;
19
20const I2C_DIG_REG_XPD_DIG_REG: u32 = 13;
21const I2C_DIG_REG_XPD_DIG_REG_MSB: u32 = 3;
22const I2C_DIG_REG_XPD_DIG_REG_LSB: u32 = 3;
23
24const I2C_ULP_IR_FORCE_XPD_CK: u32 = 0;
25const I2C_ULP_IR_FORCE_XPD_CK_MSB: u32 = 2;
26const I2C_ULP_IR_FORCE_XPD_CK_LSB: u32 = 2;
27
28pub(crate) fn init() {
29    let rtc_cntl = LPWR::regs();
30
31    regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
32
33    regi2c_write_mask!(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
34
35    rtc_cntl.ana_conf().modify(|_, w| w.pvtmon_pu().clear_bit());
36
37    unsafe {
38        rtc_cntl
39            .timer1()
40            .modify(|_, w| w.pll_buf_wait().bits(20u8).ck8m_wait().bits(20u8));
41        rtc_cntl.timer5().modify(|_, w| w.min_slp_val().bits(2u8));
42
43        // Set default powerup & wait time
44        rtc_cntl.timer3().modify(|_, w| {
45            w.wifi_powerup_timer()
46                .bits(1u8)
47                .wifi_wait_timer()
48                .bits(1u16)
49                .bt_powerup_timer()
50                .bits(1u8)
51                .bt_wait_timer()
52                .bits(1u16)
53        });
54        rtc_cntl.timer4().modify(|_, w| {
55            w.cpu_top_powerup_timer()
56                .bits(1u8)
57                .cpu_top_wait_timer()
58                .bits(1u16)
59                .dg_wrap_powerup_timer()
60                .bits(1u8)
61                .dg_wrap_wait_timer()
62                .bits(1u16)
63        });
64        rtc_cntl.timer6().modify(|_, w| {
65            w.dg_peri_powerup_timer()
66                .bits(1u8)
67                .dg_peri_wait_timer()
68                .bits(1u16)
69        });
70    }
71
72    calibrate_ocode();
73
74    set_rtc_dig_dbias();
75
76    clock_control_init();
77
78    power_control_init();
79
80    unsafe {
81        rtc_cntl.int_ena().write(|w| w.bits(0));
82        rtc_cntl.int_clr().write(|w| w.bits(u32::MAX));
83    }
84
85    regi2c_write_mask!(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
86}
87
88pub(crate) fn configure_clock() {
89    assert!(matches!(RtcClock::xtal_freq(), XtalClock::_40M));
90
91    unsafe {
92        // from esp_clk_init:
93        let rtc_cntl = LPWR::regs();
94        // clk_ll_rc_fast_enable();
95        rtc_cntl.clk_conf().modify(|_, w| w.enb_ck8m().clear_bit());
96        rtc_cntl.timer1().modify(|_, w| w.ck8m_wait().bits(5));
97        // esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
98        crate::rom::ets_delay_us(50);
99    }
100    RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
101
102    let cal_val = loop {
103        RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
104
105        let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
106        if res != 0 {
107            break res;
108        }
109    };
110
111    LPWR::regs().store1().write(|w| unsafe { w.bits(cal_val) });
112}
113
114fn calibrate_ocode() {}
115
116fn set_rtc_dig_dbias() {}
117
118/// Perform clock control related initialization
119fn clock_control_init() {
120    let extmem = EXTMEM::regs();
121    let spi_mem_0 = SPI0::regs();
122    let spi_mem_1 = SPI1::regs();
123
124    // Clear CMMU clock force on
125    extmem
126        .cache_mmu_power_ctrl()
127        .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
128
129    // Clear tag clock force on
130    extmem
131        .icache_tag_power_ctrl()
132        .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
133
134    // Clear register clock force on
135    spi_mem_0.clock_gate().modify(|_, w| w.clk_en().clear_bit());
136    spi_mem_1.clock_gate().modify(|_, w| w.clk_en().clear_bit());
137}
138
139/// Perform power control related initialization
140fn power_control_init() {
141    let rtc_cntl = LPWR::regs();
142    let system = SYSTEM::regs();
143    rtc_cntl
144        .clk_conf()
145        .modify(|_, w| w.ck8m_force_pu().clear_bit());
146
147    // Cancel XTAL force PU if no need to force power up
148    // Cannot cancel XTAL force PU if PLL is force power on
149    rtc_cntl
150        .options0()
151        .modify(|_, w| w.xtl_force_pu().clear_bit());
152
153    // Force PD APLL
154    rtc_cntl.ana_conf().modify(|_, w| {
155        w.plla_force_pu()
156            .clear_bit()
157            .plla_force_pd()
158            .set_bit()
159            // Open SAR_I2C protect function to avoid SAR_I2C
160            // Reset when rtc_ldo is low.
161            .reset_por_force_pd()
162            .clear_bit()
163    });
164
165    // Cancel BBPLL force PU if setting no force power up
166    rtc_cntl.options0().modify(|_, w| {
167        w.bbpll_force_pu()
168            .clear_bit()
169            .bbpll_i2c_force_pu()
170            .clear_bit()
171            .bb_i2c_force_pu()
172            .clear_bit()
173    });
174    rtc_cntl.rtc_cntl().modify(|_, w| {
175        w.regulator_force_pu()
176            .clear_bit()
177            .dboost_force_pu()
178            .clear_bit()
179            .dboost_force_pd()
180            .set_bit()
181    });
182
183    // If this mask is enabled, all soc memories cannot enter power down mode.
184    // We should control soc memory power down mode from RTC,
185    // so we will not touch this register any more.
186    system
187        .mem_pd_mask()
188        .modify(|_, w| w.lslp_mem_pd_mask().clear_bit());
189
190    rtc_sleep_pu();
191
192    rtc_cntl.dig_pwc().modify(|_, w| {
193        w.dg_wrap_force_pu()
194            .clear_bit()
195            .wifi_force_pu()
196            .clear_bit()
197            .bt_force_pu()
198            .clear_bit()
199            .cpu_top_force_pu()
200            .clear_bit()
201            .dg_peri_force_pu()
202            .clear_bit()
203    });
204    rtc_cntl.dig_iso().modify(|_, w| {
205        w.dg_wrap_force_noiso()
206            .clear_bit()
207            .wifi_force_noiso()
208            .clear_bit()
209            .bt_force_noiso()
210            .clear_bit()
211            .cpu_top_force_noiso()
212            .clear_bit()
213            .dg_peri_force_noiso()
214            .clear_bit()
215    });
216
217    // Cancel digital PADS force no iso
218    system
219        .cpu_per_conf()
220        .modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
221
222    // If SYSTEM_CPU_WAIT_MODE_FORCE_ON == 0,
223    // the CPU clock will be closed when CPU enter WAITI mode.
224    rtc_cntl.dig_iso().modify(|_, w| {
225        w.dg_pad_force_unhold()
226            .clear_bit()
227            .dg_pad_force_noiso()
228            .clear_bit()
229    });
230}
231
232/// Configure whether certain peripherals are powered down in deep sleep
233fn rtc_sleep_pu() {
234    let rtc_cntl = LPWR::regs();
235    let apb_ctrl = APB_CTRL::regs();
236
237    rtc_cntl.dig_pwc().modify(|_, w| {
238        w.lslp_mem_force_pu()
239            .clear_bit()
240            .fastmem_force_lpu()
241            .clear_bit()
242    });
243
244    apb_ctrl.front_end_mem_pd().modify(|_, w| {
245        w.dc_mem_force_pu()
246            .clear_bit()
247            .pbus_mem_force_pu()
248            .clear_bit()
249            .agc_mem_force_pu()
250            .clear_bit()
251    });
252    apb_ctrl
253        .mem_power_up()
254        .modify(|_, w| unsafe { w.sram_power_up().bits(0u8).rom_power_up().bits(0u8) });
255}
256
257// Terminology:
258//
259// CPU Reset:    Reset CPU core only, once reset done, CPU will execute from
260//               reset vector
261// Core Reset:   Reset the whole digital system except RTC sub-system
262// System Reset: Reset the whole digital system, including RTC sub-system
263// Chip Reset:   Reset the whole chip, including the analog part
264
265/// SOC Reset Reason.
266#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
267pub enum SocResetReason {
268    /// Power on reset
269    ///
270    /// In ESP-IDF this value (0x01) can *also* be `ChipBrownOut` or
271    /// `ChipSuperWdt`, however that is not really compatible with Rust-style
272    /// enums.
273    ChipPowerOn   = 0x01,
274    /// Software resets the digital core by RTC_CNTL_SW_SYS_RST
275    CoreSw        = 0x03,
276    /// Deep sleep reset the digital core
277    CoreDeepSleep = 0x05,
278    /// Main watch dog 0 resets digital core
279    CoreMwdt0     = 0x07,
280    /// Main watch dog 1 resets digital core
281    CoreMwdt1     = 0x08,
282    /// RTC watch dog resets digital core
283    CoreRtcWdt    = 0x09,
284    /// Main watch dog 0 resets CPU 0
285    Cpu0Mwdt0     = 0x0B,
286    /// Software resets CPU 0 by RTC_CNTL_SW_PROCPU_RST
287    Cpu0Sw        = 0x0C,
288    /// RTC watch dog resets CPU 0
289    Cpu0RtcWdt    = 0x0D,
290    /// VDD voltage is not stable and resets the digital core
291    SysBrownOut   = 0x0F,
292    /// RTC watch dog resets digital core and rtc module
293    SysRtcWdt     = 0x10,
294    /// Main watch dog 1 resets CPU 0
295    Cpu0Mwdt1     = 0x11,
296    /// Super watch dog resets the digital core and rtc module
297    SysSuperWdt   = 0x12,
298    /// Glitch on clock resets the digital core and rtc module
299    SysClkGlitch  = 0x13,
300    /// eFuse CRC error resets the digital core
301    CoreEfuseCrc  = 0x14,
302    /// USB UART resets the digital core
303    CoreUsbUart   = 0x15,
304    /// USB JTAG resets the digital core
305    CoreUsbJtag   = 0x16,
306    /// Glitch on power resets the digital core
307    CorePwrGlitch = 0x17,
308}