esp_hal/rtc_cntl/rtc/
esp32h2.rs

1use strum::FromRepr;
2
3use crate::{
4    clock::{RtcClock, RtcFastClock, RtcSlowClock, clocks_ll::regi2c_write_mask},
5    peripherals::{LP_AON, PMU},
6    rtc_cntl::RtcCalSel,
7};
8
9const I2C_PMU: u8 = 0x6d;
10const I2C_PMU_HOSTID: u8 = 0;
11
12const I2C_PMU_EN_I2C_RTC_DREG: u8 = 8;
13const I2C_PMU_EN_I2C_RTC_DREG_MSB: u8 = 0;
14const I2C_PMU_EN_I2C_RTC_DREG_LSB: u8 = 0;
15
16const I2C_PMU_EN_I2C_DIG_DREG: u8 = 8;
17const I2C_PMU_EN_I2C_DIG_DREG_MSB: u8 = 1;
18const I2C_PMU_EN_I2C_DIG_DREG_LSB: u8 = 1;
19
20const I2C_PMU_EN_I2C_RTC_DREG_SLP: u8 = 8;
21const I2C_PMU_EN_I2C_RTC_DREG_SLP_MSB: u8 = 2;
22const I2C_PMU_EN_I2C_RTC_DREG_SLP_LSB: u8 = 2;
23
24const I2C_PMU_EN_I2C_DIG_DREG_SLP: u8 = 8;
25const I2C_PMU_EN_I2C_DIG_DREG_SLP_MSB: u8 = 3;
26const I2C_PMU_EN_I2C_DIG_DREG_SLP_LSB: u8 = 3;
27
28const I2C_PMU_OR_XPD_RTC_REG: u8 = 8;
29const I2C_PMU_OR_XPD_RTC_REG_MSB: u8 = 4;
30const I2C_PMU_OR_XPD_RTC_REG_LSB: u8 = 4;
31
32const I2C_PMU_OR_XPD_DIG_REG: u8 = 8;
33const I2C_PMU_OR_XPD_DIG_REG_MSB: u8 = 5;
34const I2C_PMU_OR_XPD_DIG_REG_LSB: u8 = 5;
35
36const I2C_PMU_OR_XPD_TRX: u8 = 15;
37const I2C_PMU_OR_XPD_TRX_MSB: u8 = 2;
38const I2C_PMU_OR_XPD_TRX_LSB: u8 = 2;
39
40pub(crate) fn init() {
41    // * No peripheral reg i2c power up required on the target */
42    regi2c_write_mask(
43        I2C_PMU,
44        I2C_PMU_HOSTID,
45        I2C_PMU_EN_I2C_RTC_DREG,
46        I2C_PMU_EN_I2C_RTC_DREG_MSB,
47        I2C_PMU_EN_I2C_RTC_DREG_LSB,
48        0,
49    );
50    regi2c_write_mask(
51        I2C_PMU,
52        I2C_PMU_HOSTID,
53        I2C_PMU_EN_I2C_DIG_DREG,
54        I2C_PMU_EN_I2C_DIG_DREG_MSB,
55        I2C_PMU_EN_I2C_DIG_DREG_LSB,
56        0,
57    );
58    regi2c_write_mask(
59        I2C_PMU,
60        I2C_PMU_HOSTID,
61        I2C_PMU_EN_I2C_RTC_DREG_SLP,
62        I2C_PMU_EN_I2C_RTC_DREG_SLP_MSB,
63        I2C_PMU_EN_I2C_RTC_DREG_SLP_LSB,
64        0,
65    );
66    regi2c_write_mask(
67        I2C_PMU,
68        I2C_PMU_HOSTID,
69        I2C_PMU_EN_I2C_DIG_DREG_SLP,
70        I2C_PMU_EN_I2C_DIG_DREG_SLP_MSB,
71        I2C_PMU_EN_I2C_DIG_DREG_SLP_LSB,
72        0,
73    );
74    regi2c_write_mask(
75        I2C_PMU,
76        I2C_PMU_HOSTID,
77        I2C_PMU_OR_XPD_RTC_REG,
78        I2C_PMU_OR_XPD_RTC_REG_MSB,
79        I2C_PMU_OR_XPD_RTC_REG_LSB,
80        0,
81    );
82    regi2c_write_mask(
83        I2C_PMU,
84        I2C_PMU_HOSTID,
85        I2C_PMU_OR_XPD_DIG_REG,
86        I2C_PMU_OR_XPD_DIG_REG_MSB,
87        I2C_PMU_OR_XPD_DIG_REG_LSB,
88        0,
89    );
90    regi2c_write_mask(
91        I2C_PMU,
92        I2C_PMU_HOSTID,
93        I2C_PMU_OR_XPD_TRX,
94        I2C_PMU_OR_XPD_TRX_MSB,
95        I2C_PMU_OR_XPD_TRX_LSB,
96        0,
97    );
98
99    let pmu = PMU::regs();
100    unsafe {
101        pmu.power_pd_top_cntl().write(|w| w.bits(0));
102        pmu.power_pd_hpaon_cntl().write(|w| w.bits(0));
103        pmu.power_pd_hpcpu_cntl().write(|w| w.bits(0));
104        pmu.power_pd_hpperi_reserve().write(|w| w.bits(0));
105        pmu.power_pd_hpwifi_cntl().write(|w| w.bits(0));
106        pmu.power_pd_lpperi_cntl().write(|w| w.bits(0));
107
108        pmu.hp_active_hp_regulator0()
109            .modify(|_, w| w.hp_active_hp_regulator_dbias().bits(25));
110        pmu.hp_sleep_lp_regulator0()
111            .modify(|_, w| w.hp_sleep_lp_regulator_dbias().bits(26));
112
113        pmu.slp_wakeup_cntl5()
114            .modify(|_, w| w.lp_ana_wait_target().bits(15));
115        pmu.slp_wakeup_cntl7()
116            .modify(|_, w| w.ana_wait_target().bits(1700));
117    }
118
119    RtcClock::set_fast_freq(RtcFastClock::RcFast);
120    RtcClock::set_slow_freq(RtcSlowClock::RcSlow);
121}
122
123pub(crate) fn configure_clock() {
124    let cal_val = loop {
125        let res = RtcClock::calibrate(RtcCalSel::RtcMux, 1024);
126        if res != 0 {
127            break res;
128        }
129    };
130
131    LP_AON::regs()
132        .store1()
133        .modify(|_, w| unsafe { w.bits(cal_val) });
134}
135
136// Terminology:
137//
138// CPU Reset:    Reset CPU core only, once reset done, CPU will execute from
139//               reset vector
140// Core Reset:   Reset the whole digital system except RTC sub-system
141// System Reset: Reset the whole digital system, including RTC sub-system
142// Chip Reset:   Reset the whole chip, including the analog part
143
144/// SOC Reset Reason.
145#[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)]
146pub enum SocResetReason {
147    /// Power on reset
148    ///
149    /// In ESP-IDF this value (0x01) can *also* be `ChipBrownOut` or
150    /// `ChipSuperWdt`, however that is not really compatible with Rust-style
151    /// enums.
152    ChipPowerOn   = 0x01,
153    /// Software resets the digital core by RTC_CNTL_SW_SYS_RST
154    CoreSw        = 0x03,
155    /// Deep sleep reset the digital core
156    CoreDeepSleep = 0x05,
157    /// Main watch dog 0 resets digital core
158    CoreMwdt0     = 0x07,
159    /// Main watch dog 1 resets digital core
160    CoreMwdt1     = 0x08,
161    /// RTC watch dog resets digital core
162    CoreRtcWdt    = 0x09,
163    /// Main watch dog 0 resets CPU 0
164    Cpu0Mwdt0     = 0x0B,
165    /// Software resets CPU 0 by RTC_CNTL_SW_PROCPU_RST
166    Cpu0Sw        = 0x0C,
167    /// RTC watch dog resets CPU 0
168    Cpu0RtcWdt    = 0x0D,
169    /// VDD voltage is not stable and resets the digital core
170    SysBrownOut   = 0x0F,
171    /// RTC watch dog resets digital core and rtc module
172    SysRtcWdt     = 0x10,
173    /// Main watch dog 1 resets CPU 0
174    Cpu0Mwdt1     = 0x11,
175    /// Super watch dog resets the digital core and rtc module
176    SysSuperWdt   = 0x12,
177    /// Glitch on clock resets the digital core and rtc module
178    SysClkGlitch  = 0x13,
179    /// eFuse CRC error resets the digital core
180    CoreEfuseCrc  = 0x14,
181    /// USB UART resets the digital core
182    CoreUsbUart   = 0x15,
183    /// USB JTAG resets the digital core
184    CoreUsbJtag   = 0x16,
185    /// Glitch on power resets the digital core
186    CorePwrGlitch = 0x17,
187}