1#![allow(dead_code, reason = "Some of this is bound to be unused")]
15#![allow(missing_docs, reason = "Experimental")]
16
17use crate::{
20 peripherals::{I2C_ANA_MST, LP_CLKRST, PCR, PMU, TIMG0, UART0, UART1},
21 soc::regi2c,
22};
23
24define_clock_tree_types!();
25
26#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29#[allow(
30 clippy::enum_variant_names,
31 reason = "MHz suffix indicates physical unit."
32)]
33#[non_exhaustive]
34pub enum CpuClock {
35 #[default]
37 _80MHz = 80,
38
39 _160MHz = 160,
41}
42
43impl CpuClock {
44 const PRESET_80: ClockConfig = ClockConfig {
45 xtal_clk: None,
46 soc_root_clk: Some(SocRootClkConfig::Pll),
47 cpu_hs_div: Some(CpuHsDivConfig::new(CpuHsDivDivisor::_1)),
48 cpu_ls_div: None, ahb_hs_div: Some(AhbHsDivConfig::new(AhbHsDivDivisor::_3)),
50 ahb_ls_div: None, mspi_fast_hs_clk: Some(MspiFastHsClkConfig::new(MspiFastHsClkDivisor::_5)),
53 mspi_fast_ls_clk: None, apb_clk: Some(ApbClkConfig::new(ApbClkDivisor::_0)),
55 ledc_sclk: Some(LedcSclkConfig::PllF80m),
56 lp_fast_clk: Some(LpFastClkConfig::RcFastClk),
57 lp_slow_clk: Some(LpSlowClkConfig::RcSlow),
58 timg_calibration_clock: None,
59 };
60 const PRESET_160: ClockConfig = ClockConfig {
61 xtal_clk: None,
62 soc_root_clk: Some(SocRootClkConfig::Pll),
63 cpu_hs_div: Some(CpuHsDivConfig::new(CpuHsDivDivisor::_0)),
64 cpu_ls_div: None, ahb_hs_div: Some(AhbHsDivConfig::new(AhbHsDivDivisor::_3)),
66 ahb_ls_div: None, mspi_fast_hs_clk: Some(MspiFastHsClkConfig::new(MspiFastHsClkDivisor::_5)),
69 mspi_fast_ls_clk: None, apb_clk: Some(ApbClkConfig::new(ApbClkDivisor::_0)),
71 ledc_sclk: Some(LedcSclkConfig::PllF80m),
72 lp_fast_clk: Some(LpFastClkConfig::RcFastClk),
73 lp_slow_clk: Some(LpSlowClkConfig::RcSlow),
74 timg_calibration_clock: None,
75 };
76}
77
78impl From<CpuClock> for ClockConfig {
79 fn from(value: CpuClock) -> ClockConfig {
80 match value {
81 CpuClock::_80MHz => CpuClock::PRESET_80,
82 CpuClock::_160MHz => CpuClock::PRESET_160,
83 }
84 }
85}
86
87impl Default for ClockConfig {
88 fn default() -> Self {
89 Self::from(CpuClock::default())
90 }
91}
92
93impl ClockConfig {
94 pub(crate) fn try_get_preset(self) -> Option<CpuClock> {
95 match self {
96 v if v == CpuClock::PRESET_80 => Some(CpuClock::_80MHz),
97 v if v == CpuClock::PRESET_160 => Some(CpuClock::_160MHz),
98 _ => None,
99 }
100 }
101
102 pub(crate) fn configure(mut self) {
103 if self.xtal_clk.is_none() {
104 self.xtal_clk = Some(XtalClkConfig::_40);
105 }
106
107 ClockTree::with(|clocks| {
112 configure_mspi_fast_hs_clk(clocks, MspiFastHsClkConfig::new(MspiFastHsClkDivisor::_5))
113 });
114
115 self.apply();
116 }
117}
118
119fn configure_xtal_clk_impl(
122 _clocks: &mut ClockTree,
123 _old_config: Option<XtalClkConfig>,
124 _config: XtalClkConfig,
125) {
126 }
128
129fn enable_pll_clk_impl(_clocks: &mut ClockTree, en: bool) {
132 if en {
133 PMU::regs().imm_hp_ck_power().modify(|_, w| {
135 w.tie_high_xpd_bb_i2c().set_bit();
136 w.tie_high_xpd_bbpll().set_bit();
137 w.tie_high_xpd_bbpll_i2c().set_bit()
138 });
139 PMU::regs()
140 .imm_hp_ck_power()
141 .modify(|_, w| w.tie_high_global_bbpll_icg().set_bit());
142 } else {
143 PMU::regs()
144 .imm_hp_ck_power()
145 .modify(|_, w| w.tie_low_global_bbpll_icg().set_bit());
146 PMU::regs().imm_hp_ck_power().modify(|_, w| {
147 w.tie_low_xpd_bb_i2c().set_bit();
148 w.tie_low_xpd_bbpll().set_bit();
149 w.tie_low_xpd_bbpll_i2c().set_bit()
150 });
151
152 return;
153 }
154
155 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
157 w.bbpll_stop_force_high().clear_bit();
158 w.bbpll_stop_force_low().set_bit()
159 });
160
161 const DIV_REF: u8 = 0; const DCHGP: u8 = 5;
163 const DCUR: u8 = 3;
164
165 const I2C_BBPLL_OC_DCHGP_LSB: u32 = 4;
166 const I2C_BBPLL_OC_DHREF_SEL_LSB: u32 = 4;
167 const I2C_BBPLL_OC_DLREF_SEL_LSB: u32 = 6;
168
169 const I2C_BBPLL_LREF: u8 = (DCHGP << I2C_BBPLL_OC_DCHGP_LSB) | DIV_REF;
170 const I2C_BBPLL_DCUR: u8 =
171 (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | DCUR;
172
173 regi2c::I2C_BBPLL_OC_REF.write_reg(I2C_BBPLL_LREF);
174 regi2c::I2C_BBPLL_OC_DIV_REG.write_reg(8); regi2c::I2C_BBPLL_OC_DR1.write_field(0);
176 regi2c::I2C_BBPLL_OC_DR3.write_field(0);
177 regi2c::I2C_BBPLL_REG6.write_reg(I2C_BBPLL_DCUR);
178 regi2c::I2C_BBPLL_OC_VCO_DBIAS.write_field(2);
179
180 while I2C_ANA_MST::regs()
182 .ana_conf0()
183 .read()
184 .cal_done()
185 .bit_is_clear()
186 {}
187
188 crate::rom::ets_delay_us(10);
190
191 I2C_ANA_MST::regs().ana_conf0().modify(|_, w| {
193 w.bbpll_stop_force_high().set_bit();
194 w.bbpll_stop_force_low().clear_bit()
195 });
196}
197
198fn enable_rc_fast_clk_impl(_clocks: &mut ClockTree, en: bool) {
201 PMU::regs()
202 .hp_sleep_lp_ck_power()
203 .modify(|_, w| w.hp_sleep_xpd_fosc_clk().bit(en));
204 LP_CLKRST::regs()
206 .clk_to_hp()
207 .modify(|_, w| w.icg_hp_fosc().bit(en));
208 crate::rom::ets_delay_us(5);
209}
210
211fn enable_xtal32k_clk_impl(_clocks: &mut ClockTree, en: bool) {
214 LP_CLKRST::regs().xtal32k().write(|w| unsafe {
215 w.dac_xtal32k().bits(3);
216 w.dres_xtal32k().bits(3);
217 w.dgm_xtal32k().bits(3);
218 w.dbuf_xtal32k().bit(true)
219 });
220
221 PMU::regs()
222 .hp_sleep_lp_ck_power()
223 .modify(|_, w| w.hp_sleep_xpd_xtal32k().bit(en));
224
225 LP_CLKRST::regs()
228 .clk_to_hp()
229 .modify(|_, w| w.icg_hp_xtal32k().bit(en));
230}
231
232fn enable_osc_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {
235 todo!();
239
240 }
242
243fn enable_rc_slow_clk_impl(_clocks: &mut ClockTree, en: bool) {
246 if en {
247 const RTC_CNTL_SCK_DCAP_DEFAULT: u8 = 128;
250 crate::soc::regi2c::I2C_DIG_REG_SCK_DCAP.write_reg(RTC_CNTL_SCK_DCAP_DEFAULT);
251 }
252
253 PMU::regs()
254 .hp_sleep_lp_ck_power()
255 .modify(|_, w| w.hp_sleep_xpd_rc32k().bit(en));
256
257 LP_CLKRST::regs()
259 .clk_to_hp()
260 .modify(|_, w| w.icg_hp_osc32k().bit(en));
261}
262
263fn enable_hp_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {
266 }
268
269fn configure_hp_root_clk_impl(
270 _clocks: &mut ClockTree,
271 _old_config: Option<HpRootClkConfig>,
272 _new_config: HpRootClkConfig,
273) {
274 }
276
277fn configure_cpu_clk_impl(
280 _clocks: &mut ClockTree,
281 _old_config: Option<CpuClkConfig>,
282 _new_config: CpuClkConfig,
283) {
284 }
286
287fn configure_ahb_clk_impl(
290 _clocks: &mut ClockTree,
291 _old_config: Option<AhbClkConfig>,
292 _new_config: AhbClkConfig,
293) {
294 }
296
297fn enable_mspi_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {
300 }
302
303fn configure_mspi_fast_clk_impl(
304 _clocks: &mut ClockTree,
305 _old_config: Option<MspiFastClkConfig>,
306 _new_config: MspiFastClkConfig,
307) {
308 }
310
311fn enable_soc_root_clk_impl(_clocks: &mut ClockTree, _en: bool) {
314 }
316
317fn configure_soc_root_clk_impl(
318 _clocks: &mut ClockTree,
319 _old_config: Option<SocRootClkConfig>,
320 new_config: SocRootClkConfig,
321) {
322 PCR::regs().sysclk_conf().modify(|_, w| unsafe {
323 w.soc_clk_sel().bits(match new_config {
324 SocRootClkConfig::Xtal => 0,
325 SocRootClkConfig::Pll => 1,
326 SocRootClkConfig::RcFast => 2,
327 })
328 });
329}
330
331fn enable_cpu_hs_div_impl(_clocks: &mut ClockTree, _en: bool) {
334 }
336
337fn configure_cpu_hs_div_impl(
338 _clocks: &mut ClockTree,
339 _old_config: Option<CpuHsDivConfig>,
340 new_config: CpuHsDivConfig,
341) {
342 PCR::regs()
343 .cpu_freq_conf()
344 .modify(|_, w| unsafe { w.cpu_hs_div_num().bits(new_config.divisor() as u8) });
345}
346
347fn enable_cpu_ls_div_impl(_clocks: &mut ClockTree, _en: bool) {
350 }
352
353fn configure_cpu_ls_div_impl(
354 _clocks: &mut ClockTree,
355 _old_config: Option<CpuLsDivConfig>,
356 new_config: CpuLsDivConfig,
357) {
358 PCR::regs()
359 .cpu_freq_conf()
360 .modify(|_, w| unsafe { w.cpu_ls_div_num().bits(new_config.divisor() as u8) });
361}
362
363fn enable_ahb_hs_div_impl(_clocks: &mut ClockTree, _en: bool) {
366 }
368
369fn configure_ahb_hs_div_impl(
370 _clocks: &mut ClockTree,
371 _old_config: Option<AhbHsDivConfig>,
372 new_config: AhbHsDivConfig,
373) {
374 PCR::regs()
375 .ahb_freq_conf()
376 .modify(|_, w| unsafe { w.ahb_hs_div_num().bits(new_config.divisor() as u8) });
377}
378
379fn enable_ahb_ls_div_impl(_clocks: &mut ClockTree, _en: bool) {
382 }
384
385fn configure_ahb_ls_div_impl(
386 _clocks: &mut ClockTree,
387 _old_config: Option<AhbLsDivConfig>,
388 new_config: AhbLsDivConfig,
389) {
390 PCR::regs()
391 .ahb_freq_conf()
392 .modify(|_, w| unsafe { w.ahb_ls_div_num().bits(new_config.divisor() as u8) });
393}
394
395fn enable_apb_clk_impl(_clocks: &mut ClockTree, _en: bool) {
398 }
400
401fn configure_apb_clk_impl(
402 _clocks: &mut ClockTree,
403 _old_config: Option<ApbClkConfig>,
404 new_config: ApbClkConfig,
405) {
406 PCR::regs()
407 .apb_freq_conf()
408 .modify(|_, w| unsafe { w.apb_div_num().bits(new_config.divisor() as u8) });
409}
410
411fn enable_mspi_fast_hs_clk_impl(_clocks: &mut ClockTree, _en: bool) {
414 }
416
417fn configure_mspi_fast_hs_clk_impl(
418 _clocks: &mut ClockTree,
419 _old_config: Option<MspiFastHsClkConfig>,
420 new_config: MspiFastHsClkConfig,
421) {
422 PCR::regs()
423 .mspi_clk_conf()
424 .modify(|_, w| unsafe { w.mspi_fast_hs_div_num().bits(new_config.divisor() as u8) });
425}
426
427fn enable_mspi_fast_ls_clk_impl(_clocks: &mut ClockTree, _en: bool) {
430 }
432
433fn configure_mspi_fast_ls_clk_impl(
434 _clocks: &mut ClockTree,
435 _old_config: Option<MspiFastLsClkConfig>,
436 new_config: MspiFastLsClkConfig,
437) {
438 PCR::regs()
439 .mspi_clk_conf()
440 .modify(|_, w| unsafe { w.mspi_fast_ls_div_num().bits(new_config.divisor() as u8) });
441}
442
443fn enable_pll_f48m_impl(_clocks: &mut ClockTree, _en: bool) {
446 }
448
449fn enable_pll_f80m_impl(_clocks: &mut ClockTree, _en: bool) {
452 }
454
455fn enable_pll_f160m_impl(_clocks: &mut ClockTree, _en: bool) {
458 }
460
461fn enable_pll_f240m_impl(_clocks: &mut ClockTree, _en: bool) {
464 }
466
467fn enable_ledc_sclk_impl(_clocks: &mut ClockTree, en: bool) {
470 PCR::regs()
471 .ledc_sclk_conf()
472 .modify(|_, w| w.ledc_sclk_en().bit(en));
473}
474
475fn configure_ledc_sclk_impl(
476 _clocks: &mut ClockTree,
477 _old_config: Option<LedcSclkConfig>,
478 new_config: LedcSclkConfig,
479) {
480 PCR::regs().ledc_sclk_conf().modify(|_, w| unsafe {
481 w.ledc_sclk_sel().bits(match new_config {
482 LedcSclkConfig::PllF80m => 1,
483 LedcSclkConfig::RcFastClk => 2,
484 LedcSclkConfig::XtalClk => 3,
485 })
486 });
487}
488
489fn enable_xtal_d2_clk_impl(_clocks: &mut ClockTree, _en: bool) {
492 }
494
495fn enable_lp_fast_clk_impl(_clocks: &mut ClockTree, _en: bool) {
498 }
500
501fn configure_lp_fast_clk_impl(
502 _clocks: &mut ClockTree,
503 _old_config: Option<LpFastClkConfig>,
504 new_config: LpFastClkConfig,
505) {
506 LP_CLKRST::regs().lp_clk_conf().modify(|_, w| {
507 w.fast_clk_sel().bit(match new_config {
508 LpFastClkConfig::RcFastClk => false,
509 LpFastClkConfig::XtalD2Clk => true,
510 })
511 });
512}
513
514fn enable_lp_slow_clk_impl(_clocks: &mut ClockTree, _en: bool) {
517 }
519
520fn configure_lp_slow_clk_impl(
521 _clocks: &mut ClockTree,
522 _old_config: Option<LpSlowClkConfig>,
523 new_config: LpSlowClkConfig,
524) {
525 LP_CLKRST::regs().lp_clk_conf().modify(|_, w| unsafe {
526 w.slow_clk_sel().bits(match new_config {
527 LpSlowClkConfig::Xtal32k => 1,
528 LpSlowClkConfig::RcSlow => 0,
529 LpSlowClkConfig::OscSlow => 2,
530 })
531 });
532}
533
534fn enable_timg_calibration_clock_impl(_clocks: &mut ClockTree, _en: bool) {
537 }
540
541fn configure_timg_calibration_clock_impl(
542 _clocks: &mut ClockTree,
543 _old_config: Option<TimgCalibrationClockConfig>,
544 new_config: TimgCalibrationClockConfig,
545) {
546 TIMG0::regs().rtccalicfg().modify(|_, w| unsafe {
547 w.rtc_cali_clk_sel().bits(match new_config {
548 TimgCalibrationClockConfig::RcSlowClk => 0,
549 TimgCalibrationClockConfig::RcFastDivClk => 1,
550 TimgCalibrationClockConfig::Xtal32kClk => 2,
551 })
552 });
553}
554
555impl McpwmInstance {
556 fn enable_function_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
559 PCR::regs()
560 .pwm_clk_conf()
561 .modify(|_, w| w.pwm_clkm_en().bit(en));
562 }
563
564 fn configure_function_clock_impl(
565 self,
566 _clocks: &mut ClockTree,
567 _old_config: Option<McpwmFunctionClockConfig>,
568 new_config: McpwmFunctionClockConfig,
569 ) {
570 PCR::regs().pwm_clk_conf().modify(|_, w| unsafe {
571 w.pwm_clkm_sel().bits(match new_config {
572 McpwmFunctionClockConfig::PllF160m => 1,
573 McpwmFunctionClockConfig::XtalClk => 2,
574 McpwmFunctionClockConfig::RcFastClk => 3,
575 })
576 });
577 }
578}
579
580impl ParlIoInstance {
581 fn enable_rx_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
584 PCR::regs()
585 .parl_clk_rx_conf()
586 .modify(|_, w| w.parl_clk_rx_en().bit(en));
587 }
588
589 fn configure_rx_clock_impl(
590 self,
591 _clocks: &mut ClockTree,
592 _old_config: Option<ParlIoRxClockConfig>,
593 new_config: ParlIoRxClockConfig,
594 ) {
595 PCR::regs().parl_clk_rx_conf().modify(|_, w| unsafe {
596 w.parl_clk_rx_sel().bits(match new_config {
597 ParlIoRxClockConfig::XtalClk => 0,
598 ParlIoRxClockConfig::RcFastClk => 2,
599 ParlIoRxClockConfig::PllF240m => 1,
600 })
601 });
602 }
603
604 fn enable_tx_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
607 PCR::regs()
608 .parl_clk_tx_conf()
609 .modify(|_, w| w.parl_clk_tx_en().bit(en));
610 }
611
612 fn configure_tx_clock_impl(
613 self,
614 _clocks: &mut ClockTree,
615 _old_config: Option<ParlIoTxClockConfig>,
616 new_config: ParlIoTxClockConfig,
617 ) {
618 PCR::regs().parl_clk_tx_conf().modify(|_, w| unsafe {
619 w.parl_clk_tx_sel().bits(match new_config {
620 ParlIoTxClockConfig::XtalClk => 0,
621 ParlIoTxClockConfig::RcFastClk => 2,
622 ParlIoTxClockConfig::PllF240m => 1,
623 })
624 });
625 }
626}
627
628impl RmtInstance {
629 fn enable_sclk_impl(self, _clocks: &mut ClockTree, en: bool) {
632 PCR::regs()
633 .rmt_sclk_conf()
634 .modify(|_, w| w.sclk_en().bit(en));
635 }
636
637 fn configure_sclk_impl(
638 self,
639 _clocks: &mut ClockTree,
640 _old_config: Option<RmtSclkConfig>,
641 new_config: RmtSclkConfig,
642 ) {
643 PCR::regs().rmt_sclk_conf().modify(|_, w| unsafe {
644 w.sclk_sel().bits(match new_config {
645 RmtSclkConfig::PllF80m => 1,
646 RmtSclkConfig::RcFastClk => 2,
647 RmtSclkConfig::XtalClk => 3,
648 })
649 });
650 }
651}
652
653impl TimgInstance {
654 fn enable_function_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
657 let timg = match self {
658 TimgInstance::Timg0 => 0,
659 TimgInstance::Timg1 => 1,
660 };
661 PCR::regs()
662 .timergroup(timg)
663 .timer_clk_conf()
664 .modify(|_, w| w.timer_clk_en().bit(en));
665 }
666
667 fn configure_function_clock_impl(
668 self,
669 _clocks: &mut ClockTree,
670 _old_config: Option<TimgFunctionClockConfig>,
671 new_config: TimgFunctionClockConfig,
672 ) {
673 let timg = match self {
674 TimgInstance::Timg0 => 0,
675 TimgInstance::Timg1 => 1,
676 };
677 PCR::regs()
678 .timergroup(timg)
679 .timer_clk_conf()
680 .modify(|_, w| unsafe {
681 w.timer_clk_sel().bits(match new_config {
683 TimgFunctionClockConfig::XtalClk => 0,
684 TimgFunctionClockConfig::RcFastClk => 2,
685 TimgFunctionClockConfig::PllF80m => 1,
686 })
687 });
688 }
689
690 fn enable_wdt_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
693 let timg = match self {
694 TimgInstance::Timg0 => 0,
695 TimgInstance::Timg1 => 1,
696 };
697 PCR::regs()
698 .timergroup(timg)
699 .wdt_clk_conf()
700 .modify(|_, w| w.wdt_clk_en().bit(en));
701 }
702
703 fn configure_wdt_clock_impl(
704 self,
705 _clocks: &mut ClockTree,
706 _old_config: Option<TimgWdtClockConfig>,
707 new_config: TimgWdtClockConfig,
708 ) {
709 let timg = match self {
710 TimgInstance::Timg0 => 0,
711 TimgInstance::Timg1 => 1,
712 };
713 PCR::regs()
714 .timergroup(timg)
715 .wdt_clk_conf()
716 .modify(|_, w| unsafe {
717 w.wdt_clk_sel().bits(match new_config {
718 TimgWdtClockConfig::XtalClk => 0,
719 TimgWdtClockConfig::PllF80m => 1,
720 TimgWdtClockConfig::RcFastClk => 2,
721 })
722 });
723 }
724}
725
726impl UartInstance {
727 fn enable_function_clock_impl(self, _clocks: &mut ClockTree, en: bool) {
730 let uart = match self {
731 UartInstance::Uart0 => 0,
732 UartInstance::Uart1 => 1,
733 };
734 PCR::regs()
735 .uart(uart)
736 .clk_conf()
737 .modify(|_, w| w.sclk_en().bit(en));
738 }
739
740 fn configure_function_clock_impl(
741 self,
742 _clocks: &mut ClockTree,
743 _old_config: Option<UartFunctionClockConfig>,
744 new_config: UartFunctionClockConfig,
745 ) {
746 let uart = match self {
747 UartInstance::Uart0 => 0,
748 UartInstance::Uart1 => 1,
749 };
750 PCR::regs().uart(uart).clk_conf().modify(|_, w| unsafe {
751 w.sclk_sel().bits(match new_config.sclk {
752 UartFunctionClockSclk::PllF80m => 1,
753 UartFunctionClockSclk::RcFast => 2,
754 UartFunctionClockSclk::Xtal => 3,
755 });
756 w.sclk_div_a().bits(0);
757 w.sclk_div_b().bits(0);
758 w.sclk_div_num().bits(new_config.div_num as _);
759 w
760 });
761 }
762
763 fn enable_baud_rate_generator_impl(self, _clocks: &mut ClockTree, _en: bool) {
766 }
768
769 fn configure_baud_rate_generator_impl(
770 self,
771 _clocks: &mut ClockTree,
772 _old_config: Option<UartBaudRateGeneratorConfig>,
773 new_config: UartBaudRateGeneratorConfig,
774 ) {
775 let regs = match self {
776 UartInstance::Uart0 => UART0::regs(),
777 UartInstance::Uart1 => UART1::regs(),
778 };
779 regs.clkdiv().write(|w| unsafe {
780 w.clkdiv().bits(new_config.integral as _);
781 w.frag().bits(new_config.fractional as _)
782 });
783 }
784}