esp_hal/clock/clocks_ll/
esp32c2.rs1use crate::{
2 clock::{ApbClock, Clock, CpuClock, PllClock, XtalClock},
3 peripherals::{APB_CTRL, I2C_ANA_MST, LPWR, MODEM_CLKRST, SYSTEM},
4 rom::{regi2c_write, regi2c_write_mask},
5};
6
7const I2C_BBPLL: u32 = 0x66;
8const I2C_BBPLL_HOSTID: u32 = 0;
9
10const I2C_BBPLL_MODE_HF: u32 = 4;
11
12const I2C_BBPLL_OC_REF_DIV: u32 = 2;
13const I2C_BBPLL_OC_DCHGP_LSB: u32 = 4;
14const I2C_BBPLL_OC_DIV_7_0: u32 = 3;
15
16const I2C_BBPLL_OC_DR1: u32 = 5;
17const I2C_BBPLL_OC_DR1_MSB: u32 = 2;
18const I2C_BBPLL_OC_DR1_LSB: u32 = 0;
19
20const I2C_BBPLL_OC_DR3: u32 = 5;
21const I2C_BBPLL_OC_DR3_MSB: u32 = 6;
22const I2C_BBPLL_OC_DR3_LSB: u32 = 4;
23
24const I2C_BBPLL_OC_DCUR: u32 = 6;
25
26const I2C_BBPLL_OC_VCO_DBIAS: u32 = 9;
27const I2C_BBPLL_OC_VCO_DBIAS_MSB: u32 = 1;
28const I2C_BBPLL_OC_VCO_DBIAS_LSB: u32 = 0;
29
30const I2C_BBPLL_OC_DHREF_SEL_LSB: u32 = 4;
31
32const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6;
33
34pub(crate) fn esp32c2_rtc_bbpll_configure(xtal_freq: XtalClock, _pll_freq: PllClock) {
35 let div_ref: u32;
36 let div7_0: u32;
37 let dr1: u32;
38 let dr3: u32;
39 let dchgp: u32;
40 let dcur: u32;
41 let dbias: u32;
42
43 SYSTEM::regs()
45 .cpu_per_conf()
46 .modify(|_, w| w.pll_freq_sel().set_bit());
47
48 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
49 w.bbpll_stop_force_high().clear_bit();
50 w.bbpll_stop_force_low().set_bit()
51 });
52
53 match xtal_freq {
55 XtalClock::_26M => {
56 div_ref = 12;
57 div7_0 = 236;
58 dr1 = 4;
59 dr3 = 4;
60 dchgp = 0;
61 dcur = 0;
62 dbias = 2;
63 }
64 XtalClock::_40M | XtalClock::Other(_) => {
65 div_ref = 0;
66 div7_0 = 8;
67 dr1 = 0;
68 dr3 = 0;
69 dchgp = 5;
70 dcur = 3;
71 dbias = 2;
72 }
73 }
74
75 regi2c_write!(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6b);
76
77 let i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | div_ref;
78 let i2c_bbpll_div_7_0 = div7_0;
79 let i2c_bbpll_dcur =
80 (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
81
82 regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
83
84 regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
85
86 regi2c_write_mask!(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
87
88 regi2c_write_mask!(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
89
90 regi2c_write!(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
91
92 regi2c_write_mask!(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
93
94 while I2C_ANA_MST::regs()
96 .ana_conf0()
97 .read()
98 .bbpll_cal_done()
99 .bit_is_clear()
100 {}
101
102 crate::rom::ets_delay_us(10);
104
105 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
107 w.bbpll_stop_force_high().set_bit();
108 w.bbpll_stop_force_low().clear_bit()
109 });
110}
111
112pub(crate) fn esp32c2_rtc_bbpll_enable() {
113 LPWR::regs().options0().modify(|_, w| {
114 w.bb_i2c_force_pd().clear_bit();
115 w.bbpll_force_pd().clear_bit();
116 w.bbpll_i2c_force_pd().clear_bit()
117 });
118}
119
120pub(crate) fn esp32c2_rtc_update_to_xtal(freq: XtalClock, div: u32) {
121 crate::rom::ets_update_cpu_frequency_rom(freq.mhz());
122
123 SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe {
126 w.pre_div_cnt().bits(0);
127 w.pre_div_cnt().bits((div - 1) as u16)
128 });
129
130 SYSTEM::regs()
134 .sysclk_conf()
135 .modify(|_, w| unsafe { w.soc_clk_sel().bits(0) });
136}
137
138pub(crate) fn esp32c2_rtc_freq_to_pll_mhz(cpu_clock_speed: CpuClock) {
139 SYSTEM::regs().sysclk_conf().modify(|_, w| unsafe {
140 w.pre_div_cnt().bits(0);
141 w.soc_clk_sel().bits(1)
142 });
143 SYSTEM::regs().cpu_per_conf().modify(|_, w| unsafe {
144 w.cpuperiod_sel().bits(match cpu_clock_speed {
145 CpuClock::_80MHz => 0,
146 CpuClock::_120MHz => 1,
147 })
148 });
149
150 crate::rom::ets_update_cpu_frequency_rom(cpu_clock_speed.mhz());
151}
152
153pub(crate) fn esp32c2_rtc_apb_freq_update(apb_freq: ApbClock) {
154 let value = ((apb_freq.hz() >> 12) & u16::MAX as u32)
155 | (((apb_freq.hz() >> 12) & u16::MAX as u32) << 16);
156
157 LPWR::regs()
158 .store5()
159 .modify(|_, w| unsafe { w.scratch5().bits(value) });
160}
161
162const SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x78078F;
165const SYSTEM_WIFI_CLK_EN: u32 = 0x00FB9FCF;
167
168pub(super) fn enable_phy(enable: bool) {
169 APB_CTRL::regs().wifi_clk_en().modify(|r, w| unsafe {
172 if enable {
173 w.bits(r.bits() | SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M)
174 } else {
175 w.bits(r.bits() & !SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M)
176 }
177 });
178}
179
180pub(super) fn enable_bt(_: bool) {
181 }
184
185pub(super) fn enable_wifi(_: bool) {
186 }
189
190pub(super) fn reset_mac() {
191 APB_CTRL::regs()
192 .wifi_rst_en()
193 .modify(|_, w| w.mac_rst().set_bit());
194 APB_CTRL::regs()
195 .wifi_rst_en()
196 .modify(|_, w| w.mac_rst().clear_bit());
197}
198
199pub(super) fn init_clocks() {
200 const SYSTEM_WIFI_CLK_UNUSED_BIT5: u32 = 1 << 5;
202 const SYSTEM_WIFI_CLK_UNUSED_BIT12: u32 = 1 << 12;
203 const WIFI_BT_SDIO_CLK: u32 = SYSTEM_WIFI_CLK_UNUSED_BIT5 | SYSTEM_WIFI_CLK_UNUSED_BIT12;
204
205 APB_CTRL::regs()
206 .wifi_clk_en()
207 .modify(|r, w| unsafe { w.bits(r.bits() & !WIFI_BT_SDIO_CLK | SYSTEM_WIFI_CLK_EN) });
208}
209
210pub(super) fn ble_rtc_clk_init() {
211 MODEM_CLKRST::regs().modem_lp_timer_conf().modify(|_, w| {
212 w.lp_timer_sel_xtal32k().clear_bit();
213 w.lp_timer_sel_xtal().set_bit();
214 w.lp_timer_sel_8m().clear_bit();
215 w.lp_timer_sel_rtc_slow().clear_bit()
216 });
217
218 MODEM_CLKRST::regs()
220 .modem_lp_timer_conf()
221 .modify(|_, w| unsafe { w.lp_timer_clk_div_num().bits(249) });
222
223 MODEM_CLKRST::regs().etm_clk_conf().modify(|_, w| {
224 w.etm_clk_active().set_bit();
225 w.etm_clk_sel().clear_bit()
226 });
227}
228
229pub(super) fn reset_rpa() {
230 APB_CTRL::regs()
231 .wifi_rst_en()
232 .modify(|_, w| w.ble_rpa_rst().set_bit());
233 APB_CTRL::regs()
234 .wifi_rst_en()
235 .modify(|_, w| w.ble_rpa_rst().clear_bit());
236}