|
1 | 1 | use crate::{ |
2 | | - clock::{ApbClock, Clock, CpuClock, PllClock, RtcClock, XtalClock}, |
3 | | - peripherals::{APB_CTRL, I2C_ANA_MST, LPWR, MODEM_CLKRST, SYSTEM}, |
4 | | - soc::regi2c, |
| 2 | + clock::{RtcClock, XtalClock}, |
| 3 | + peripherals::{APB_CTRL, MODEM_CLKRST}, |
5 | 4 | }; |
6 | 5 |
|
7 | | -const I2C_BBPLL_OC_DCHGP_LSB: u32 = 4; |
8 | | -const I2C_BBPLL_OC_DHREF_SEL_LSB: u32 = 4; |
9 | | -const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6; |
10 | | - |
11 | | -pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllClock) { |
12 | | - let div_ref: u8; |
13 | | - let div7_0: u8; |
14 | | - let dr1: u8; |
15 | | - let dr3: u8; |
16 | | - let dchgp: u8; |
17 | | - let dcur: u8; |
18 | | - let dbias: u8; |
19 | | - |
20 | | - // Set this register to let the digital part know 480M PLL is used |
21 | | - SYSTEM::regs() |
22 | | - .cpu_per_conf() |
23 | | - .modify(|_, w| w.pll_freq_sel().set_bit()); |
24 | | - |
25 | | - I2C_ANA_MST::regs().ana_conf0().modify(|_, w| { |
26 | | - w.bbpll_stop_force_high().clear_bit(); |
27 | | - w.bbpll_stop_force_low().set_bit() |
28 | | - }); |
29 | | - |
30 | | - // Configure 480M PLL |
31 | | - match xtal_freq { |
32 | | - XtalClock::_26M => { |
33 | | - div_ref = 12; |
34 | | - div7_0 = 236; |
35 | | - dr1 = 4; |
36 | | - dr3 = 4; |
37 | | - dchgp = 0; |
38 | | - dcur = 0; |
39 | | - dbias = 2; |
40 | | - } |
41 | | - XtalClock::_40M => { |
42 | | - div_ref = 0; |
43 | | - div7_0 = 8; |
44 | | - dr1 = 0; |
45 | | - dr3 = 0; |
46 | | - dchgp = 5; |
47 | | - dcur = 3; |
48 | | - dbias = 2; |
49 | | - } |
50 | | - } |
51 | | - |
52 | | - regi2c::I2C_BBPLL_REG4.write_reg(0x6b); |
53 | | - |
54 | | - let i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | div_ref; |
55 | | - let i2c_bbpll_dcur = |
56 | | - (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; |
57 | | - |
58 | | - regi2c::I2C_BBPLL_OC_REF.write_reg(i2c_bbpll_lref); |
59 | | - regi2c::I2C_BBPLL_OC_DIV_REG.write_reg(div7_0); |
60 | | - regi2c::I2C_BBPLL_OC_DR1.write_field(dr1); |
61 | | - regi2c::I2C_BBPLL_OC_DR3.write_field(dr3); |
62 | | - regi2c::I2C_BBPLL_REG6.write_reg(i2c_bbpll_dcur); |
63 | | - regi2c::I2C_BBPLL_OC_VCO_DBIAS.write_field(dbias); |
64 | | - |
65 | | - // WAIT CALIBRATION DONE |
66 | | - while I2C_ANA_MST::regs() |
67 | | - .ana_conf0() |
68 | | - .read() |
69 | | - .bbpll_cal_done() |
70 | | - .bit_is_clear() |
71 | | - {} |
72 | | - |
73 | | - // workaround bbpll calibration might stop early |
74 | | - crate::rom::ets_delay_us(10); |
75 | | - |
76 | | - // Stop BBPLL self-calibration |
77 | | - I2C_ANA_MST::regs().ana_conf0().modify(|_, w| { |
78 | | - w.bbpll_stop_force_high().set_bit(); |
79 | | - w.bbpll_stop_force_low().clear_bit() |
80 | | - }); |
81 | | -} |
82 | | - |
83 | | -pub(crate) fn esp32c2_rtc_bbpll_enable() { |
84 | | - LPWR::regs().options0().modify(|_, w| { |
85 | | - w.bb_i2c_force_pd().clear_bit(); |
86 | | - w.bbpll_force_pd().clear_bit(); |
87 | | - w.bbpll_i2c_force_pd().clear_bit() |
88 | | - }); |
89 | | -} |
90 | | - |
91 | | -pub(crate) fn esp32c2_rtc_update_to_xtal(freq: XtalClock, div: u32) { |
92 | | - crate::rom::ets_update_cpu_frequency_rom(freq.mhz()); |
93 | | - |
94 | | - // Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) |
95 | | - // first. |
96 | | - SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe { |
97 | | - w.pre_div_cnt().bits(0); |
98 | | - w.pre_div_cnt().bits((div - 1) as u16) |
99 | | - }); |
100 | | - |
101 | | - // No need to adjust the REF_TICK |
102 | | - |
103 | | - // Switch clock source |
104 | | - SYSTEM::regs() |
105 | | - .sysclk_conf() |
106 | | - .modify(|_, w| unsafe { w.soc_clk_sel().bits(0) }); |
107 | | -} |
108 | | - |
109 | | -pub(crate) fn esp32c2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) { |
110 | | - SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe { |
111 | | - w.pre_div_cnt().bits(0); |
112 | | - w.soc_clk_sel().bits(1) |
113 | | - }); |
114 | | - SYSTEM::regs().cpu_per_conf().modify(|_, w| unsafe { |
115 | | - w.cpuperiod_sel().bits(match cpu_clock_speed { |
116 | | - CpuClock::_80MHz => 0, |
117 | | - CpuClock::_120MHz => 1, |
118 | | - }) |
119 | | - }); |
120 | | - |
121 | | - crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz()); |
122 | | -} |
123 | | - |
124 | | -pub(crate) fn esp32c2_rtc_apb_freq_update(apb_freq: ApbClock) { |
125 | | - let value = ((apb_freq.hz() >> 12) & u16::MAX as u32) |
126 | | - | (((apb_freq.hz() >> 12) & u16::MAX as u32) << 16); |
127 | | - |
128 | | - LPWR::regs() |
129 | | - .store5() |
130 | | - .modify(|_, w| unsafe { w.data().bits(value) }); |
131 | | -} |
132 | | - |
133 | 6 | // Mask for clock bits used by both WIFI and Bluetooth, 0, 1, 2, 3, 7, 8, 9, 10, |
134 | 7 | // 19, 20, 21, 22, 23 |
135 | 8 | const SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x78078F; |
|
0 commit comments