diff --git a/esp-hal-common/src/clock.rs b/esp-hal-common/src/clock.rs index c1a2b22d7..8fd55e712 100644 --- a/esp-hal-common/src/clock.rs +++ b/esp-hal-common/src/clock.rs @@ -188,6 +188,22 @@ impl ClockControl { }, } } + + /// Configure the CPU clock speed. + #[allow(unused)] + pub fn configure(clock_control: SystemClockControl, cpu_clock_speed: CpuClock) -> ClockControl { + clocks_ll::set_cpu_clock(cpu_clock_speed); + + ClockControl { + _private: (), + desired_rates: RawClocks { + cpu_clock: cpu_clock_speed.frequency(), + apb_clock: MegahertzU32::MHz(80), + xtal_clock: MegahertzU32::MHz(40), + i2c_clock: MegahertzU32::MHz(40), + }, + } + } } #[cfg(feature = "esp32s3")] @@ -205,4 +221,20 @@ impl ClockControl { }, } } + + /// Configure the CPU clock speed. + #[allow(unused)] + pub fn configure(clock_control: SystemClockControl, cpu_clock_speed: CpuClock) -> ClockControl { + clocks_ll::set_cpu_clock(cpu_clock_speed); + + ClockControl { + _private: (), + desired_rates: RawClocks { + cpu_clock: cpu_clock_speed.frequency(), + apb_clock: MegahertzU32::MHz(80), + xtal_clock: MegahertzU32::MHz(40), + i2c_clock: MegahertzU32::MHz(40), + }, + } + } } diff --git a/esp-hal-common/src/clocks_ll/esp32c3.rs b/esp-hal-common/src/clocks_ll/esp32c3.rs index 92a726566..e2ecc94a0 100644 --- a/esp-hal-common/src/clocks_ll/esp32c3.rs +++ b/esp-hal-common/src/clocks_ll/esp32c3.rs @@ -1,13 +1,13 @@ use crate::clock::CpuClock; pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) { - let system_control = crate::pac::SYSTEM::PTR; + let system_control = unsafe { &*crate::pac::SYSTEM::PTR }; unsafe { - (&*system_control) + system_control .sysclk_conf .modify(|_, w| w.soc_clk_sel().bits(1)); - (&*system_control).cpu_per_conf.modify(|_, w| { + system_control.cpu_per_conf.modify(|_, w| { w.pll_freq_sel() .set_bit() .cpuperiod_sel() diff --git a/esp-hal-common/src/clocks_ll/esp32s2.rs b/esp-hal-common/src/clocks_ll/esp32s2.rs index 7379961e6..284f898e8 100644 --- a/esp-hal-common/src/clocks_ll/esp32s2.rs +++ b/esp-hal-common/src/clocks_ll/esp32s2.rs @@ -1 +1,45 @@ -// unused for now +use crate::clock::CpuClock; + +const MHZ: u32 = 1000000; +const UINT16_MAX: u32 = 0xffff; + +const RTC_CNTL_DBIAS_1V25: u32 = 7; + +// when not running with 80MHz Flash frequency we could use RTC_CNTL_DBIAS_1V10 +// for DIG_DBIAS_80M_160M - but RTC_CNTL_DBIAS_1V25 shouldn't hurt +const DIG_DBIAS_80M_160M: u32 = RTC_CNTL_DBIAS_1V25; +const DIG_DBIAS_240M: u32 = RTC_CNTL_DBIAS_1V25; + +pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) { + let system_control = unsafe { &*crate::pac::SYSTEM::PTR }; + let rtc_cntl = unsafe { &*crate::pac::RTC_CNTL::ptr() }; + + unsafe { + system_control + .sysclk_conf + .modify(|_, w| w.soc_clk_sel().bits(1)); + system_control.cpu_per_conf.modify(|_, w| { + w.pll_freq_sel() + .set_bit() + .cpuperiod_sel() + .bits(match cpu_clock_speed { + CpuClock::Clock80MHz => 0, + CpuClock::Clock160MHz => 1, + CpuClock::Clock240MHz => 2, + }) + }); + + rtc_cntl.reg.modify(|_, w| { + w.dig_reg_dbias_wak().bits(match cpu_clock_speed { + CpuClock::Clock80MHz => DIG_DBIAS_80M_160M, + CpuClock::Clock160MHz => DIG_DBIAS_80M_160M, + CpuClock::Clock240MHz => DIG_DBIAS_240M, + } as u8) + }); + + let value = (((80 * MHZ) >> 12) & UINT16_MAX) | ((((80 * MHZ) >> 12) & UINT16_MAX) << 16); + rtc_cntl + .store5 + .modify(|_, w| w.scratch5().bits(value as u32)); + } +} diff --git a/esp-hal-common/src/clocks_ll/esp32s3.rs b/esp-hal-common/src/clocks_ll/esp32s3.rs index 7379961e6..45b33636e 100644 --- a/esp-hal-common/src/clocks_ll/esp32s3.rs +++ b/esp-hal-common/src/clocks_ll/esp32s3.rs @@ -1 +1,21 @@ -// unused for now +use crate::clock::CpuClock; + +pub(crate) fn set_cpu_clock(cpu_clock_speed: CpuClock) { + let system_control = unsafe { &*crate::pac::SYSTEM::PTR }; + + unsafe { + system_control + .sysclk_conf + .modify(|_, w| w.soc_clk_sel().bits(1)); + system_control.cpu_per_conf.modify(|_, w| { + w.pll_freq_sel() + .set_bit() + .cpuperiod_sel() + .bits(match cpu_clock_speed { + CpuClock::Clock80MHz => 0, + CpuClock::Clock160MHz => 1, + CpuClock::Clock240MHz => 2, + }) + }); + } +}