esp_hal/clock/clocks_ll/
esp32.rs1use crate::{
2 clock::{Clock, PllClock, XtalClock},
3 efuse::{Efuse, VOL_LEVEL_HP_INV},
4 peripherals::{APB_CTRL, DPORT, LPWR},
5 soc::regi2c,
6};
7
8const REF_CLK_FREQ: u32 = 1000000;
9
10const MHZ: u32 = 1000000;
11const UINT16_MAX: u32 = 0xffff;
12
13const RTC_CNTL_DBIAS_1V10: u8 = 4;
14const RTC_CNTL_DBIAS_1V25: u8 = 7;
15
16const DIG_DBIAS_80M_160M: u8 = RTC_CNTL_DBIAS_1V10;
17const DIG_DBIAS_XTAL: u8 = RTC_CNTL_DBIAS_1V10;
18
19const BBPLL_IR_CAL_DELAY_VAL: u8 = 0x18;
20const BBPLL_IR_CAL_EXT_CAP_VAL: u8 = 0x20;
21const BBPLL_OC_ENB_FCAL_VAL: u8 = 0x9a;
22const BBPLL_OC_ENB_VCON_VAL: u8 = 0x00;
23const BBPLL_BBADC_CAL_7_0_VAL: u8 = 0x00;
24
25const BBPLL_ENDIV5_VAL_320M: u8 = 0x43;
26const BBPLL_BBADC_DSMP_VAL_320M: u8 = 0x84;
27const BBPLL_ENDIV5_VAL_480M: u8 = 0xc3;
28const BBPLL_BBADC_DSMP_VAL_480M: u8 = 0x74;
29
30pub(crate) fn esp32_rtc_bbpll_configure(xtal_freq: XtalClock, pll_freq: PllClock) {
31 let rtc_cntl_dbias_hp_volt = RTC_CNTL_DBIAS_1V25 - Efuse::read_field_le::<u8>(VOL_LEVEL_HP_INV);
32 let dig_dbias_240_m = rtc_cntl_dbias_hp_volt;
33
34 let div_ref: u8;
35 let div7_0: u8;
36 let div10_8: u8;
37 let lref: u8;
38 let dcur: u8;
39 let bw: u8;
40
41 if matches!(pll_freq, PllClock::Pll320MHz) {
42 LPWR::regs()
44 .reg()
45 .modify(|_, w| unsafe { w.dig_dbias_wak().bits(DIG_DBIAS_80M_160M) });
46
47 match xtal_freq {
49 XtalClock::_40M => {
50 div_ref = 0;
51 div7_0 = 32;
52 div10_8 = 0;
53 lref = 0;
54 dcur = 6;
55 bw = 3;
56 }
57
58 XtalClock::_26M => {
59 div_ref = 12;
60 div7_0 = 224;
61 div10_8 = 4;
62 lref = 1;
63 dcur = 0;
64 bw = 1;
65 }
66
67 XtalClock::Other(_) => {
68 div_ref = 12;
69 div7_0 = 224;
70 div10_8 = 4;
71 lref = 0;
72 dcur = 0;
73 bw = 0;
74 }
75 }
76
77 regi2c::I2C_BBPLL_ENDIV5.write_reg(BBPLL_ENDIV5_VAL_320M);
78 regi2c::I2C_BBPLL_BBADC_DSMP.write_reg(BBPLL_BBADC_DSMP_VAL_320M);
79 } else {
80 LPWR::regs()
82 .reg()
83 .modify(|_, w| unsafe { w.dig_dbias_wak().bits(dig_dbias_240_m) });
84
85 match xtal_freq {
87 XtalClock::_40M => {
88 div_ref = 0;
89 div7_0 = 28;
90 div10_8 = 0;
91 lref = 0;
92 dcur = 6;
93 bw = 3;
94 }
95
96 XtalClock::_26M => {
97 div_ref = 12;
98 div7_0 = 144;
99 div10_8 = 4;
100 lref = 1;
101 dcur = 0;
102 bw = 1;
103 }
104
105 XtalClock::Other(_) => {
106 div_ref = 12;
107 div7_0 = 224;
108 div10_8 = 4;
109 lref = 0;
110 dcur = 0;
111 bw = 0;
112 }
113 }
114
115 regi2c::I2C_BBPLL_ENDIV5.write_reg(BBPLL_ENDIV5_VAL_480M);
116 regi2c::I2C_BBPLL_BBADC_DSMP.write_reg(BBPLL_BBADC_DSMP_VAL_480M);
117 }
118
119 let i2c_bbpll_lref = (lref << 7) | (div10_8 << 4) | (div_ref);
120 let i2c_bbpll_dcur = (bw << 6) | dcur;
121
122 regi2c::I2C_BBPLL_OC_LREF.write_reg(i2c_bbpll_lref);
123 regi2c::I2C_BBPLL_OC_DIV_REG.write_reg(div7_0);
124 regi2c::I2C_BBPLL_OC_DCUR.write_reg(i2c_bbpll_dcur);
125}
126
127pub(crate) fn esp32_rtc_bbpll_enable() {
128 LPWR::regs().options0().modify(|_, w| {
129 w.bias_i2c_force_pd().clear_bit();
130 w.bb_i2c_force_pd().clear_bit();
131 w.bbpll_force_pd().clear_bit();
132 w.bbpll_i2c_force_pd().clear_bit()
133 });
134
135 regi2c::I2C_BBPLL_IR_CAL_DELAY.write_reg(BBPLL_IR_CAL_DELAY_VAL);
137 regi2c::I2C_BBPLL_IR_CAL_EXT_CAP.write_reg(BBPLL_IR_CAL_EXT_CAP_VAL);
138 regi2c::I2C_BBPLL_OC_ENB_FCAL.write_reg(BBPLL_OC_ENB_FCAL_VAL);
139 regi2c::I2C_BBPLL_OC_ENB_VCON.write_reg(BBPLL_OC_ENB_VCON_VAL);
140 regi2c::I2C_BBPLL_BBADC_CAL_REG.write_reg(BBPLL_BBADC_CAL_7_0_VAL);
141}
142
143pub(crate) fn esp32_rtc_update_to_xtal(freq: XtalClock, _div: u32) {
144 let value = ((freq.hz() >> 12) & UINT16_MAX) | (((freq.hz() >> 12) & UINT16_MAX) << 16);
145 esp32_update_cpu_freq(freq.hz());
146
147 APB_CTRL::regs().sysclk_conf().modify(|_, w| unsafe {
149 w.pre_div_cnt()
150 .bits(((freq.hz()) / REF_CLK_FREQ - 1) as u16)
151 });
152
153 APB_CTRL::regs().xtal_tick_conf().modify(|_, w| unsafe {
155 w.xtal_tick_num()
156 .bits(((freq.hz()) / REF_CLK_FREQ - 1) as u8)
157 });
158
159 LPWR::regs()
161 .clk_conf()
162 .modify(|_, w| w.soc_clk_sel().xtal());
163 LPWR::regs()
164 .store5()
165 .modify(|_, w| unsafe { w.scratch5().bits(value) });
166
167 LPWR::regs()
169 .reg()
170 .modify(|_, w| unsafe { w.dig_dbias_wak().bits(DIG_DBIAS_XTAL) });
171}
172
173pub(crate) fn set_cpu_freq(cpu_freq_mhz: crate::clock::CpuClock) {
174 let rtc_cntl_dbias_hp_volt = RTC_CNTL_DBIAS_1V25 - Efuse::read_field_le::<u8>(VOL_LEVEL_HP_INV);
175
176 let dig_dbias_240_m = rtc_cntl_dbias_hp_volt;
177
178 const CPU_80M: u8 = 0;
179 const CPU_160M: u8 = 1;
180 const CPU_240M: u8 = 2;
181
182 let mut dbias = DIG_DBIAS_80M_160M;
183 let per_conf = match cpu_freq_mhz {
184 crate::clock::CpuClock::_160MHz => CPU_160M,
185 crate::clock::CpuClock::_240MHz => {
186 dbias = dig_dbias_240_m;
187 CPU_240M
188 }
189 crate::clock::CpuClock::_80MHz => CPU_80M,
190 };
191
192 let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16);
193 DPORT::regs()
194 .cpu_per_conf()
195 .write(|w| unsafe { w.cpuperiod_sel().bits(per_conf) });
196 LPWR::regs()
197 .reg()
198 .modify(|_, w| unsafe { w.dig_dbias_wak().bits(dbias) });
199 LPWR::regs().clk_conf().modify(|_, w| w.soc_clk_sel().pll());
200 LPWR::regs()
201 .store5()
202 .modify(|_, w| unsafe { w.scratch5().bits(value) });
203
204 esp32_update_cpu_freq(cpu_freq_mhz.mhz());
205}
206
207fn esp32_update_cpu_freq(mhz: u32) {
210 const G_TICKS_PER_US_PRO: u32 = 0x3ffe01e0;
211 unsafe {
212 (G_TICKS_PER_US_PRO as *mut u32).write_volatile(mhz);
214 }
215}
216
217const DPORT_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x000003c9;
218const DPORT_WIFI_CLK_WIFI_EN_M: u32 = 0x00000406;
219const DPORT_WIFI_CLK_BT_EN_M: u32 = 0x00030800;
220
221pub(super) fn enable_phy(enable: bool) {
222 DPORT::regs().wifi_clk_en().modify(|r, w| unsafe {
225 if enable {
226 w.bits(r.bits() | DPORT_WIFI_CLK_WIFI_BT_COMMON_M)
227 } else {
228 w.bits(r.bits() & !DPORT_WIFI_CLK_WIFI_BT_COMMON_M)
229 }
230 });
231}
232
233pub(super) fn enable_bt(enable: bool) {
234 DPORT::regs().wifi_clk_en().modify(|r, w| unsafe {
235 if enable {
236 w.bits(r.bits() | DPORT_WIFI_CLK_BT_EN_M)
237 } else {
238 w.bits(r.bits() & !DPORT_WIFI_CLK_BT_EN_M)
239 }
240 });
241}
242
243pub(super) fn enable_wifi(enable: bool) {
244 DPORT::regs().wifi_clk_en().modify(|r, w| unsafe {
247 if enable {
248 w.bits(r.bits() | DPORT_WIFI_CLK_WIFI_EN_M)
249 } else {
250 w.bits(r.bits() & !DPORT_WIFI_CLK_WIFI_EN_M)
251 }
252 });
253}
254
255pub(super) fn reset_mac() {
256 DPORT::regs()
257 .wifi_rst_en()
258 .modify(|_, w| w.mac_rst().set_bit());
259 DPORT::regs()
260 .wifi_rst_en()
261 .modify(|_, w| w.mac_rst().clear_bit());
262}
263
264pub(super) fn init_clocks() {
265 DPORT::regs()
289 .wifi_clk_en()
290 .write(|w| unsafe { w.bits(u32::MAX) });
291}
292
293pub(super) fn ble_rtc_clk_init() {
294 }
296
297pub(super) fn reset_rpa() {
298 }