esp_hal/rtc_cntl/rtc/
esp32c3.rs1use 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 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 let rtc_cntl = LPWR::regs();
94 rtc_cntl.clk_conf().modify(|_, w| w.enb_ck8m().clear_bit());
96 rtc_cntl.timer1().modify(|_, w| w.ck8m_wait().bits(5));
97 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
118fn clock_control_init() {
120 let extmem = EXTMEM::regs();
121 let spi_mem_0 = SPI0::regs();
122 let spi_mem_1 = SPI1::regs();
123
124 extmem
126 .cache_mmu_power_ctrl()
127 .modify(|_, w| w.cache_mmu_mem_force_on().clear_bit());
128
129 extmem
131 .icache_tag_power_ctrl()
132 .modify(|_, w| w.icache_tag_mem_force_on().clear_bit());
133
134 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
139fn 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 rtc_cntl
150 .options0()
151 .modify(|_, w| w.xtl_force_pu().clear_bit());
152
153 rtc_cntl.ana_conf().modify(|_, w| {
155 w.plla_force_pu()
156 .clear_bit()
157 .plla_force_pd()
158 .set_bit()
159 .reset_por_force_pd()
162 .clear_bit()
163 });
164
165 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 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 system
219 .cpu_per_conf()
220 .modify(|_, w| w.cpu_wait_mode_force_on().clear_bit());
221
222 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
232fn 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#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
267pub enum SocResetReason {
268 ChipPowerOn = 0x01,
274 CoreSw = 0x03,
276 CoreDeepSleep = 0x05,
278 CoreMwdt0 = 0x07,
280 CoreMwdt1 = 0x08,
282 CoreRtcWdt = 0x09,
284 Cpu0Mwdt0 = 0x0B,
286 Cpu0Sw = 0x0C,
288 Cpu0RtcWdt = 0x0D,
290 SysBrownOut = 0x0F,
292 SysRtcWdt = 0x10,
294 Cpu0Mwdt1 = 0x11,
296 SysSuperWdt = 0x12,
298 SysClkGlitch = 0x13,
300 CoreEfuseCrc = 0x14,
302 CoreUsbUart = 0x15,
304 CoreUsbJtag = 0x16,
306 CorePwrGlitch = 0x17,
308}