mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 04:10:28 +00:00
More clock refactor (#3993)
* Remove duplicate constants * Metadata-ify some clock frequencies * Changelog
This commit is contained in:
parent
e6cdd8eb3c
commit
e42f7d2e06
@ -47,6 +47,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- `ShaDigest::finish` has been reimplemented to be properly non-blocking (#3948)
|
||||
- Replace Timer's `pub fn enable_interrupt(&mut self, enable: bool)` with `pub fn listen(&mut self)` and `pub fn unlisten(&mut self)` (#3933)
|
||||
- ESP32-S3: `PsramConfig::core_clock` is now an `Option` (#3974)
|
||||
- `RtcSlowClock::RtcFastClock8m` has been renamed to `RtcFastClock::RtcFastClockRcFast` (#3993)
|
||||
- `RtcSlowClock::RtcSlowClockRtc` has been renamed to `RtcSlowClock::RtcSlowClockRcSlow` (#3993)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -120,12 +120,10 @@ use crate::rtc_cntl::sleep::{RtcSleepConfig, WakeSource, WakeTriggers};
|
||||
use crate::{
|
||||
clock::{Clock, XtalClock},
|
||||
interrupt::{self, InterruptHandler},
|
||||
peripherals::{Interrupt, TIMG0},
|
||||
peripherals::{Interrupt, LPWR, TIMG0},
|
||||
system::{Cpu, SleepSource},
|
||||
time::Duration,
|
||||
time::{Duration, Rate},
|
||||
};
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
use crate::{peripherals::LPWR, time::Rate};
|
||||
// only include sleep where it's been implemented
|
||||
#[cfg(any(esp32, esp32s2, esp32s3, esp32c3, esp32c6, esp32c2))]
|
||||
pub mod sleep;
|
||||
@ -144,8 +142,6 @@ cfg_if::cfg_if! {
|
||||
use crate::peripherals::LP_WDT;
|
||||
use crate::peripherals::LP_TIMER;
|
||||
use crate::peripherals::LP_AON;
|
||||
|
||||
use rtc::{RtcSlowClock, RtcCalSel}; // TODO: bring the types into this module
|
||||
} else {
|
||||
use crate::peripherals::LPWR as LP_WDT;
|
||||
use crate::peripherals::LPWR as LP_TIMER;
|
||||
@ -194,28 +190,35 @@ bitflags::bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[allow(clippy::enum_variant_names)] // FIXME: resolve this
|
||||
/// RTC SLOW_CLK frequency values
|
||||
/// RTC FAST_CLK frequency values
|
||||
pub(crate) enum RtcFastClock {
|
||||
/// Main XTAL, divided by 4
|
||||
RtcFastClockXtalD4 = 0,
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
#[expect(unused)]
|
||||
RtcFastClockXtalD4,
|
||||
|
||||
/// Select XTAL_D2_CLK as RTC_FAST_CLK source
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
#[expect(unused)]
|
||||
RtcFastClockXtalD2,
|
||||
|
||||
/// Internal fast RC oscillator
|
||||
RtcFastClock8m = 1,
|
||||
RtcFastClockRcFast,
|
||||
}
|
||||
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
impl Clock for RtcFastClock {
|
||||
fn frequency(&self) -> Rate {
|
||||
match self {
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
RtcFastClock::RtcFastClockXtalD4 => Rate::from_hz(40_000_000 / 4),
|
||||
#[cfg(any(esp32, esp32s2))]
|
||||
RtcFastClock::RtcFastClock8m => Rate::from_hz(8_500_000),
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
RtcFastClock::RtcFastClock8m => Rate::from_hz(17_500_000),
|
||||
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
RtcFastClock::RtcFastClockXtalD2 => Rate::from_hz(property!("soc.xtal_frequency") / 2),
|
||||
|
||||
RtcFastClock::RtcFastClockRcFast => Rate::from_hz(property!("soc.rc_fast_clk_default")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,28 +231,44 @@ impl Clock for RtcFastClock {
|
||||
/// RTC SLOW_CLK frequency values
|
||||
pub enum RtcSlowClock {
|
||||
/// Internal slow RC oscillator
|
||||
RtcSlowClockRtc = 0,
|
||||
RtcSlowClockRcSlow = 0,
|
||||
/// External 32 KHz XTAL
|
||||
RtcSlowClock32kXtal = 1,
|
||||
/// Internal fast RC oscillator, divided by 256
|
||||
RtcSlowClock8mD256 = 2,
|
||||
}
|
||||
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
/// RTC SLOW_CLK frequency values
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
pub enum RtcSlowClock {
|
||||
/// Select RC_SLOW_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClockRcSlow = 0,
|
||||
/// Select XTAL32K_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClock32kXtal = 1,
|
||||
/// Select RC32K_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClock32kRc = 2,
|
||||
/// Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source
|
||||
RtcSlowOscSlow = 3,
|
||||
}
|
||||
|
||||
impl Clock for RtcSlowClock {
|
||||
fn frequency(&self) -> Rate {
|
||||
match self {
|
||||
#[cfg(esp32)]
|
||||
RtcSlowClock::RtcSlowClockRtc => Rate::from_hz(150_000),
|
||||
#[cfg(esp32s2)]
|
||||
RtcSlowClock::RtcSlowClockRtc => Rate::from_hz(90_000),
|
||||
#[cfg(any(esp32c2, esp32c3, esp32s3))]
|
||||
RtcSlowClock::RtcSlowClockRtc => Rate::from_hz(136_000),
|
||||
RtcSlowClock::RtcSlowClockRcSlow => Rate::from_hz(property!("soc.rc_slow_clock")),
|
||||
|
||||
RtcSlowClock::RtcSlowClock32kXtal => Rate::from_hz(32_768),
|
||||
#[cfg(any(esp32, esp32s2))]
|
||||
RtcSlowClock::RtcSlowClock8mD256 => Rate::from_hz(8_500_000 / 256),
|
||||
#[cfg(any(esp32c2, esp32c3, esp32s3))]
|
||||
RtcSlowClock::RtcSlowClock8mD256 => Rate::from_hz(17_500_000 / 256),
|
||||
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
RtcSlowClock::RtcSlowClock8mD256 => RtcFastClock::RtcFastClockRcFast.frequency() / 256,
|
||||
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
RtcSlowClock::RtcSlowClock32kRc => Rate::from_hz(32_768),
|
||||
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
RtcSlowClock::RtcSlowOscSlow => Rate::from_hz(32_768),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -272,6 +291,25 @@ pub(crate) enum RtcCalSel {
|
||||
RtcCalInternalOsc = 3,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
/// Clock source to be calibrated using rtc_clk_cal function
|
||||
pub(crate) enum RtcCalSel {
|
||||
/// Currently selected RTC SLOW_CLK
|
||||
RtcCalRtcMux = -1,
|
||||
/// Internal 150kHz RC oscillator
|
||||
RtcCalRcSlow = 0,
|
||||
/// External 32kHz XTAL, as one type of 32k clock
|
||||
RtcCal32kXtal = 1,
|
||||
/// Internal 32kHz RC oscillator, as one type of 32k clock
|
||||
RtcCal32kRc = 2,
|
||||
/// External slow clock signal input by lp_pad_gpio0, as one type of 32k
|
||||
/// clock
|
||||
RtcCal32kOscSlow = 3,
|
||||
/// Internal MHz-range RC oscillator
|
||||
RtcCalRcFast,
|
||||
}
|
||||
|
||||
/// Low-power Management
|
||||
pub struct Rtc<'d> {
|
||||
_inner: crate::peripherals::LPWR<'d>,
|
||||
@ -537,7 +575,8 @@ impl crate::interrupt::InterruptConfigurable for Rtc<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// RTC Watchdog Timer.
|
||||
/// Clocks.
|
||||
// TODO: this type belongs in `esp_hal::clock`.
|
||||
pub struct RtcClock;
|
||||
|
||||
/// RTC Watchdog Timer driver.
|
||||
@ -588,7 +627,7 @@ impl RtcClock {
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
pub fn slow_freq() -> RtcSlowClock {
|
||||
match LPWR::regs().clk_conf().read().ana_clk_rtc_sel().bits() {
|
||||
0 => RtcSlowClock::RtcSlowClockRtc,
|
||||
0 => RtcSlowClock::RtcSlowClockRcSlow,
|
||||
1 => RtcSlowClock::RtcSlowClock32kXtal,
|
||||
2 => RtcSlowClock::RtcSlowClock8mD256,
|
||||
_ => unreachable!(),
|
||||
@ -623,7 +662,7 @@ impl RtcClock {
|
||||
fn set_fast_freq(fast_freq: RtcFastClock) {
|
||||
LPWR::regs().clk_conf().modify(|_, w| {
|
||||
w.fast_clk_rtc_sel().bit(match fast_freq {
|
||||
RtcFastClock::RtcFastClock8m => true,
|
||||
RtcFastClock::RtcFastClockRcFast => true,
|
||||
RtcFastClock::RtcFastClockXtalD4 => false,
|
||||
})
|
||||
});
|
||||
@ -631,6 +670,56 @@ impl RtcClock {
|
||||
crate::rom::ets_delay_us(3u32);
|
||||
}
|
||||
|
||||
// TODO: IDF-5781 Some of esp32c6 SOC_RTC_FAST_CLK_SRC_XTAL_D2 rtc_fast clock
|
||||
// has timing issue. Force to use SOC_RTC_FAST_CLK_SRC_RC_FAST since 2nd
|
||||
// stage bootloader https://github.com/espressif/esp-idf/blob/master/components/bootloader_support/src/bootloader_clock_init.c#L65-L67
|
||||
#[cfg(any(esp32h2, esp32c6))]
|
||||
fn set_fast_freq(fast_freq: RtcFastClock) {
|
||||
#[cfg(esp32h2)]
|
||||
LPWR::regs().lp_clk_conf().modify(|_, w| unsafe {
|
||||
w.fast_clk_sel().bits(match fast_freq {
|
||||
RtcFastClock::RtcFastClockRcFast => 0b00,
|
||||
RtcFastClock::RtcFastClockXtalD2 => 0b01,
|
||||
})
|
||||
});
|
||||
|
||||
#[cfg(esp32c6)]
|
||||
LPWR::regs().lp_clk_conf().modify(|_, w| {
|
||||
w.fast_clk_sel().bit(match fast_freq {
|
||||
RtcFastClock::RtcFastClockRcFast => false,
|
||||
RtcFastClock::RtcFastClockXtalD2 => true,
|
||||
})
|
||||
});
|
||||
|
||||
crate::rom::ets_delay_us(3);
|
||||
}
|
||||
|
||||
#[cfg(any(esp32h2, esp32c6))]
|
||||
fn set_slow_freq(slow_freq: RtcSlowClock) {
|
||||
LPWR::regs()
|
||||
.lp_clk_conf()
|
||||
.modify(|_, w| unsafe { w.slow_clk_sel().bits(slow_freq as u8) });
|
||||
|
||||
LPWR::regs().clk_to_hp().modify(|_, w| {
|
||||
w.icg_hp_xtal32k()
|
||||
.bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kXtal));
|
||||
w.icg_hp_osc32k()
|
||||
.bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kRc))
|
||||
});
|
||||
}
|
||||
|
||||
/// Get the RTC_SLOW_CLK source
|
||||
#[cfg(any(esp32h2, esp32c6))]
|
||||
pub fn slow_freq() -> RtcSlowClock {
|
||||
match LPWR::regs().lp_clk_conf().read().slow_clk_sel().bits() {
|
||||
0 => RtcSlowClock::RtcSlowClockRcSlow,
|
||||
1 => RtcSlowClock::RtcSlowClock32kXtal,
|
||||
2 => RtcSlowClock::RtcSlowClock32kRc,
|
||||
3 => RtcSlowClock::RtcSlowOscSlow,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Calibration of RTC_SLOW_CLK is performed using a special feature of
|
||||
/// TIMG0. This feature counts the number of XTAL clock cycles within a
|
||||
/// given number of RTC_SLOW_CLK cycles.
|
||||
@ -719,7 +808,7 @@ impl RtcClock {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 10)
|
||||
});
|
||||
RtcSlowClock::RtcSlowClockRtc
|
||||
RtcSlowClock::RtcSlowClockRcSlow
|
||||
}
|
||||
};
|
||||
|
||||
@ -768,6 +857,290 @@ impl RtcClock {
|
||||
cal_val
|
||||
}
|
||||
|
||||
/// Calibration of RTC_SLOW_CLK is performed using a special feature of
|
||||
/// TIMG0. This feature counts the number of XTAL clock cycles within a
|
||||
/// given number of RTC_SLOW_CLK cycles.
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
pub(crate) fn calibrate_internal(mut cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
|
||||
use crate::peripherals::{LP_CLKRST, PCR, PMU};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum RtcCaliClkSel {
|
||||
CaliClkRcSlow = 0,
|
||||
CaliClkRcFast = 1,
|
||||
CaliClk32k = 2,
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match cal_clk {
|
||||
RtcCalSel::RtcCalRtcMux => match RtcClock::slow_freq() {
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
_ => cal_clk,
|
||||
},
|
||||
RtcCalSel::RtcCal32kOscSlow => RtcCalSel::RtcCalRtcMux,
|
||||
_ => cal_clk,
|
||||
};
|
||||
}
|
||||
|
||||
let clk_src = RtcClock::slow_freq();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match clk_src {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCal32kOscSlow,
|
||||
};
|
||||
}
|
||||
|
||||
let cali_clk_sel;
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match clk_src {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCalRcSlow,
|
||||
}
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClkRcFast;
|
||||
} else if cal_clk == RtcCalSel::RtcCalRcSlow {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClkRcSlow;
|
||||
} else {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClk32k;
|
||||
|
||||
match cal_clk {
|
||||
RtcCalSel::RtcCalRtcMux | RtcCalSel::RtcCalRcSlow | RtcCalSel::RtcCalRcFast => {}
|
||||
RtcCalSel::RtcCal32kRc => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(0) });
|
||||
}
|
||||
RtcCalSel::RtcCal32kXtal => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(1) });
|
||||
}
|
||||
RtcCalSel::RtcCal32kOscSlow => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(2) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable requested clock (150k is always on)
|
||||
// Some delay is required before the time is stable
|
||||
// Only enable if originaly was disabled
|
||||
// If clock is already on, do nothing
|
||||
|
||||
let dig_32k_xtal_enabled = LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_xtal32k()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().set_bit());
|
||||
}
|
||||
|
||||
// TODO: very hacky - icg_hp_xtal32k is already set in the above condition?
|
||||
// in ESP-IDF these are not called in this function but the fields are set
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().set_bit());
|
||||
PMU::regs().hp_sleep_lp_ck_power().modify(|_, w| {
|
||||
w.hp_sleep_xpd_xtal32k().set_bit();
|
||||
w.hp_sleep_xpd_rc32k().set_bit()
|
||||
});
|
||||
|
||||
let rc_fast_enabled = PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.read()
|
||||
.hp_sleep_xpd_fosc_clk()
|
||||
.bit_is_set();
|
||||
let dig_rc_fast_enabled = LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_fosc()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
if !rc_fast_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
|
||||
if !dig_rc_fast_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_fosc().set_bit());
|
||||
crate::rom::ets_delay_us(5);
|
||||
}
|
||||
}
|
||||
|
||||
let rc32k_enabled = PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.read()
|
||||
.hp_sleep_xpd_rc32k()
|
||||
.bit_is_set();
|
||||
let dig_rc32k_enabled = LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_osc32k()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kRc {
|
||||
if !rc32k_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
|
||||
crate::rom::ets_delay_us(300);
|
||||
}
|
||||
|
||||
if !dig_rc32k_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_osc32k().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there is already running calibration process
|
||||
// TODO: &mut TIMG0 for calibration
|
||||
let timg0 = TIMG0::regs();
|
||||
|
||||
if timg0
|
||||
.rtccalicfg()
|
||||
.read()
|
||||
.rtc_cali_start_cycling()
|
||||
.bit_is_set()
|
||||
{
|
||||
timg0
|
||||
.rtccalicfg2()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(1) });
|
||||
|
||||
// Set small timeout threshold to accelerate the generation of timeot
|
||||
// Internal circuit will be reset when timeout occurs and will not affect the
|
||||
// next calibration
|
||||
while !timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set()
|
||||
&& !timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set()
|
||||
{}
|
||||
}
|
||||
|
||||
// Prepare calibration
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_clk_sel().bits(cali_clk_sel as u8) });
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start_cycling().clear_bit());
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_max().bits(slowclk_cycles as u16) });
|
||||
|
||||
let expected_frequency = match cali_clk_sel {
|
||||
RtcCaliClkSel::CaliClk32k => {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 12)
|
||||
});
|
||||
RtcSlowClock::RtcSlowClock32kXtal.frequency()
|
||||
}
|
||||
RtcCaliClkSel::CaliClkRcFast => {
|
||||
timg0
|
||||
.rtccalicfg2()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(0x01FFFFFF) });
|
||||
RtcFastClock::RtcFastClockRcFast.frequency()
|
||||
}
|
||||
RtcCaliClkSel::CaliClkRcSlow => {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 10)
|
||||
});
|
||||
RtcSlowClock::RtcSlowClockRcSlow.frequency()
|
||||
}
|
||||
};
|
||||
|
||||
let us_time_estimate = Rate::from_mhz(slowclk_cycles) / expected_frequency;
|
||||
|
||||
// Start calibration
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().clear_bit());
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().set_bit());
|
||||
|
||||
// Wait for calibration to finish up to another us_time_estimate
|
||||
crate::rom::ets_delay_us(us_time_estimate);
|
||||
|
||||
let cal_val = loop {
|
||||
if timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set() {
|
||||
// The Fosc CLK of calibration circuit is divided by 32 for ECO1.
|
||||
// So we need to multiply the frequency of the Fosc for ECO1 and above chips by
|
||||
// 32 times. And ensure that this modification will not affect
|
||||
// ECO0.
|
||||
// https://github.com/espressif/esp-idf/commit/e3148369f32fdc6de62c35a67f7adb6f4faef4e3
|
||||
#[cfg(esp32c6)]
|
||||
if Efuse::chip_revision() > 0 && cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
break timg0.rtccalicfg1().read().rtc_cali_value().bits() >> 5;
|
||||
}
|
||||
break timg0.rtccalicfg1().read().rtc_cali_value().bits();
|
||||
}
|
||||
|
||||
if timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set() {
|
||||
// Timed out waiting for calibration
|
||||
break 0;
|
||||
}
|
||||
};
|
||||
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().clear_bit());
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().clear_bit());
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
if rc_fast_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
|
||||
if dig_rc_fast_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_fosc().set_bit());
|
||||
crate::rom::ets_delay_us(5);
|
||||
}
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kRc {
|
||||
if rc32k_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
|
||||
crate::rom::ets_delay_us(300);
|
||||
}
|
||||
if dig_rc32k_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_osc32k().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
cal_val
|
||||
}
|
||||
|
||||
/// Measure RTC slow clock's period, based on main XTAL frequency
|
||||
///
|
||||
/// This function will time out and return 0 if the time for the given
|
||||
@ -808,7 +1181,7 @@ impl RtcClock {
|
||||
};
|
||||
} else {
|
||||
let calibration_clock = match RtcClock::slow_freq() {
|
||||
RtcSlowClock::RtcSlowClockRtc => RtcCalSel::RtcCalRtcMux,
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRtcMux,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock8mD256 => RtcCalSel::RtcCal8mD256,
|
||||
};
|
||||
@ -829,13 +1202,7 @@ impl RtcClock {
|
||||
// TODO: this could reuse Self::calibrate_internal
|
||||
const SLOW_CLOCK_CYCLES: u32 = 100;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(esp32h2, esp32c6))] {
|
||||
let calibration_clock = rtc::RtcSlowClock::RtcSlowClockRcSlow;
|
||||
} else {
|
||||
let calibration_clock = RtcSlowClock::RtcSlowClockRtc;
|
||||
}
|
||||
}
|
||||
let calibration_clock = RtcSlowClock::RtcSlowClockRcSlow;
|
||||
|
||||
// Make sure the process doesn't time out due to some spooky configuration.
|
||||
#[cfg(not(esp32))]
|
||||
|
@ -8,10 +8,10 @@ use crate::{
|
||||
pub(crate) fn init() {}
|
||||
|
||||
pub(crate) fn configure_clock() {
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClockRcFast);
|
||||
|
||||
let cal_val = loop {
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRcSlow);
|
||||
|
||||
let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
|
||||
if res != 0 {
|
||||
|
@ -47,10 +47,10 @@ pub(crate) fn configure_clock() {
|
||||
// esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClockRcFast);
|
||||
|
||||
let cal_val = loop {
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRcSlow);
|
||||
|
||||
let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
|
||||
if res != 0 {
|
||||
|
@ -65,10 +65,10 @@ pub(crate) fn configure_clock() {
|
||||
// esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClockRcFast);
|
||||
|
||||
let cal_val = loop {
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRcSlow);
|
||||
|
||||
let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
|
||||
if res != 0 {
|
||||
|
@ -17,11 +17,9 @@ use crate::{
|
||||
esp32c6_rtc_update_to_xtal_raw,
|
||||
},
|
||||
},
|
||||
efuse::Efuse,
|
||||
peripherals::{LP_AON, LP_CLKRST, MODEM_LPCON, MODEM_SYSCON, PCR, PMU, TIMG0},
|
||||
rtc_cntl::RtcClock,
|
||||
peripherals::{LP_AON, LP_CLKRST, MODEM_LPCON, MODEM_SYSCON, PCR, PMU},
|
||||
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
|
||||
soc::regi2c,
|
||||
time::Rate,
|
||||
};
|
||||
|
||||
fn pmu_power_domain_force_default() {
|
||||
@ -1186,398 +1184,6 @@ pub enum SocResetReason {
|
||||
Cpu0JtagCpu = 0x18,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
/// RTC SLOW_CLK frequency values
|
||||
pub(crate) enum RtcFastClock {
|
||||
/// Select RC_FAST_CLK as RTC_FAST_CLK source
|
||||
RtcFastClockRcFast = 0,
|
||||
/// Select XTAL_D2_CLK as RTC_FAST_CLK source
|
||||
RtcFastClockXtalD2 = 1,
|
||||
}
|
||||
|
||||
impl Clock for RtcFastClock {
|
||||
fn frequency(&self) -> Rate {
|
||||
match self {
|
||||
RtcFastClock::RtcFastClockXtalD2 => {
|
||||
// TODO: Is the value correct?
|
||||
Rate::from_hz(40_000_000 / 2)
|
||||
}
|
||||
RtcFastClock::RtcFastClockRcFast => Rate::from_hz(property!("soc.rc_fast_clk_default")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
/// RTC SLOW_CLK frequency values
|
||||
pub enum RtcSlowClock {
|
||||
/// Select RC_SLOW_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClockRcSlow = 0,
|
||||
/// Select XTAL32K_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClock32kXtal = 1,
|
||||
/// Select RC32K_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClock32kRc = 2,
|
||||
/// Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source
|
||||
RtcSlowOscSlow = 3,
|
||||
}
|
||||
|
||||
impl Clock for RtcSlowClock {
|
||||
fn frequency(&self) -> Rate {
|
||||
match self {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => Rate::from_hz(136_000),
|
||||
RtcSlowClock::RtcSlowClock32kXtal => Rate::from_hz(32_768),
|
||||
RtcSlowClock::RtcSlowClock32kRc => Rate::from_hz(32_768),
|
||||
RtcSlowClock::RtcSlowOscSlow => Rate::from_hz(32_768),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
/// Clock source to be calibrated using rtc_clk_cal function
|
||||
pub(crate) enum RtcCalSel {
|
||||
/// Currently selected RTC SLOW_CLK
|
||||
RtcCalRtcMux = -1,
|
||||
/// Internal 150kHz RC oscillator
|
||||
RtcCalRcSlow = 0,
|
||||
/// External 32kHz XTAL, as one type of 32k clock
|
||||
RtcCal32kXtal = 1,
|
||||
/// Internal 32kHz RC oscillator, as one type of 32k clock
|
||||
RtcCal32kRc = 2,
|
||||
/// External slow clock signal input by lp_pad_gpio0, as one type of 32k
|
||||
/// clock
|
||||
RtcCal32kOscSlow = 3,
|
||||
/// Internal 20MHz RC oscillator
|
||||
RtcCalRcFast,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum RtcCaliClkSel {
|
||||
CaliClkRcSlow = 0,
|
||||
CaliClkRcFast = 1,
|
||||
CaliClk32k = 2,
|
||||
}
|
||||
|
||||
/// RTC Watchdog Timer driver
|
||||
impl RtcClock {
|
||||
/// Get the RTC_SLOW_CLK source
|
||||
pub fn slow_freq() -> RtcSlowClock {
|
||||
match LP_CLKRST::regs().lp_clk_conf().read().slow_clk_sel().bits() {
|
||||
0 => RtcSlowClock::RtcSlowClockRcSlow,
|
||||
1 => RtcSlowClock::RtcSlowClock32kXtal,
|
||||
2 => RtcSlowClock::RtcSlowClock32kRc,
|
||||
3 => RtcSlowClock::RtcSlowOscSlow,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_slow_freq(slow_freq: RtcSlowClock) {
|
||||
unsafe {
|
||||
LP_CLKRST::regs()
|
||||
.lp_clk_conf()
|
||||
.modify(|_, w| w.slow_clk_sel().bits(slow_freq as u8));
|
||||
}
|
||||
|
||||
LP_CLKRST::regs().clk_to_hp().modify(|_, w| {
|
||||
w.icg_hp_xtal32k()
|
||||
.bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kXtal));
|
||||
w.icg_hp_osc32k()
|
||||
.bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kRc))
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: IDF-5781 Some of esp32c6 SOC_RTC_FAST_CLK_SRC_XTAL_D2 rtc_fast clock
|
||||
// has timing issue Force to use SOC_RTC_FAST_CLK_SRC_RC_FAST since 2nd
|
||||
// stage bootloader https://github.com/espressif/esp-idf/blob/master/components/bootloader_support/src/bootloader_clock_init.c#L65-L67
|
||||
fn set_fast_freq(fast_freq: RtcFastClock) {
|
||||
LP_CLKRST::regs().lp_clk_conf().modify(|_, w| {
|
||||
w.fast_clk_sel().bit(match fast_freq {
|
||||
RtcFastClock::RtcFastClockRcFast => false,
|
||||
RtcFastClock::RtcFastClockXtalD2 => true,
|
||||
})
|
||||
});
|
||||
|
||||
crate::rom::ets_delay_us(3);
|
||||
}
|
||||
|
||||
/// Calibration of RTC_SLOW_CLK is performed using a special feature of
|
||||
/// TIMG0. This feature counts the number of XTAL clock cycles within a
|
||||
/// given number of RTC_SLOW_CLK cycles.
|
||||
pub(crate) fn calibrate_internal(mut cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
|
||||
const SOC_CLK_RC_FAST_FREQ_APPROX: u32 = 17_500_000;
|
||||
const SOC_CLK_RC_SLOW_FREQ_APPROX: u32 = 136_000;
|
||||
const SOC_CLK_XTAL32K_FREQ_APPROX: u32 = 32768;
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match cal_clk {
|
||||
RtcCalSel::RtcCalRtcMux => match RtcClock::slow_freq() {
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
_ => cal_clk,
|
||||
},
|
||||
RtcCalSel::RtcCal32kOscSlow => RtcCalSel::RtcCalRtcMux,
|
||||
_ => cal_clk,
|
||||
};
|
||||
}
|
||||
|
||||
let clk_src = RtcClock::slow_freq();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match clk_src {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCal32kOscSlow,
|
||||
};
|
||||
}
|
||||
|
||||
let cali_clk_sel;
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match clk_src {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCalRcSlow,
|
||||
}
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClkRcFast;
|
||||
} else if cal_clk == RtcCalSel::RtcCalRcSlow {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClkRcSlow;
|
||||
} else {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClk32k;
|
||||
|
||||
match cal_clk {
|
||||
RtcCalSel::RtcCalRtcMux | RtcCalSel::RtcCalRcSlow | RtcCalSel::RtcCalRcFast => {}
|
||||
RtcCalSel::RtcCal32kRc => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(0) });
|
||||
}
|
||||
RtcCalSel::RtcCal32kXtal => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(1) });
|
||||
}
|
||||
RtcCalSel::RtcCal32kOscSlow => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(2) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable requested clock (150k is always on)
|
||||
// Some delay is required before the time is stable
|
||||
// Only enable if originaly was disabled
|
||||
// If clock is already on, do nothing
|
||||
|
||||
let dig_32k_xtal_enabled = LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_xtal32k()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().set_bit());
|
||||
}
|
||||
|
||||
// TODO: very hacky - icg_hp_xtal32k is already set in the above condition?
|
||||
// in ESP-IDF these are not called in this function but the fields are set
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().set_bit());
|
||||
PMU::regs().hp_sleep_lp_ck_power().modify(|_, w| {
|
||||
w.hp_sleep_xpd_xtal32k().set_bit();
|
||||
w.hp_sleep_xpd_rc32k().set_bit()
|
||||
});
|
||||
|
||||
let rc_fast_enabled = PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.read()
|
||||
.hp_sleep_xpd_fosc_clk()
|
||||
.bit_is_set();
|
||||
let dig_rc_fast_enabled = LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_fosc()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
if !rc_fast_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
|
||||
if !dig_rc_fast_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_fosc().set_bit());
|
||||
crate::rom::ets_delay_us(5);
|
||||
}
|
||||
}
|
||||
|
||||
let rc32k_enabled = PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.read()
|
||||
.hp_sleep_xpd_rc32k()
|
||||
.bit_is_set();
|
||||
let dig_rc32k_enabled = LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_osc32k()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kRc {
|
||||
if !rc32k_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
|
||||
crate::rom::ets_delay_us(300);
|
||||
}
|
||||
|
||||
if !dig_rc32k_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_osc32k().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there is already running calibration process
|
||||
// TODO: &mut TIMG0 for calibration
|
||||
let timg0 = TIMG0::regs();
|
||||
|
||||
if timg0
|
||||
.rtccalicfg()
|
||||
.read()
|
||||
.rtc_cali_start_cycling()
|
||||
.bit_is_set()
|
||||
{
|
||||
timg0
|
||||
.rtccalicfg2()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(1) });
|
||||
|
||||
// Set small timeout threshold to accelerate the generation of timeot
|
||||
// Internal circuit will be reset when timeout occurs and will not affect the
|
||||
// next calibration
|
||||
while !timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set()
|
||||
&& !timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set()
|
||||
{}
|
||||
}
|
||||
|
||||
// Prepare calibration
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_clk_sel().bits(cali_clk_sel.clone() as u8) });
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start_cycling().clear_bit());
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_max().bits(slowclk_cycles as u16) });
|
||||
|
||||
let expected_freq = match cali_clk_sel {
|
||||
RtcCaliClkSel::CaliClk32k => {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 12)
|
||||
});
|
||||
SOC_CLK_XTAL32K_FREQ_APPROX
|
||||
}
|
||||
RtcCaliClkSel::CaliClkRcFast => {
|
||||
timg0
|
||||
.rtccalicfg2()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(0x01FFFFFF) });
|
||||
SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
}
|
||||
_ => {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 10)
|
||||
});
|
||||
SOC_CLK_RC_SLOW_FREQ_APPROX
|
||||
}
|
||||
};
|
||||
|
||||
let us_time_estimate = (Rate::from_mhz(slowclk_cycles) / expected_freq).as_hz();
|
||||
|
||||
// Start calibration
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().clear_bit());
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().set_bit());
|
||||
|
||||
// Wait for calibration to finish up to another us_time_estimate
|
||||
crate::rom::ets_delay_us(us_time_estimate);
|
||||
|
||||
let cal_val = loop {
|
||||
if timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set() {
|
||||
// The Fosc CLK of calibration circuit is divided by 32 for ECO1.
|
||||
// So we need to multiply the frequency of the Fosc for ECO1 and above chips by
|
||||
// 32 times. And ensure that this modification will not affect
|
||||
// ECO0.
|
||||
// https://github.com/espressif/esp-idf/commit/e3148369f32fdc6de62c35a67f7adb6f4faef4e3
|
||||
if Efuse::chip_revision() > 0 && cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
break timg0.rtccalicfg1().read().rtc_cali_value().bits() >> 5;
|
||||
}
|
||||
break timg0.rtccalicfg1().read().rtc_cali_value().bits();
|
||||
}
|
||||
|
||||
if timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set() {
|
||||
// Timed out waiting for calibration
|
||||
break 0;
|
||||
}
|
||||
};
|
||||
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().clear_bit());
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().clear_bit());
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
if rc_fast_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
|
||||
if dig_rc_fast_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_fosc().set_bit());
|
||||
crate::rom::ets_delay_us(5);
|
||||
}
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kRc {
|
||||
if rc32k_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
|
||||
crate::rom::ets_delay_us(300);
|
||||
}
|
||||
if dig_rc32k_enabled {
|
||||
LP_CLKRST::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_osc32k().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
cal_val
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn rtc_clk_cpu_freq_set_xtal() {
|
||||
// rtc_clk_cpu_set_to_default_config
|
||||
let freq = RtcClock::xtal_freq().mhz();
|
||||
|
@ -1,10 +1,9 @@
|
||||
use strum::FromRepr;
|
||||
|
||||
use crate::{
|
||||
clock::{Clock, clocks_ll::regi2c_write_mask},
|
||||
peripherals::{LP_AON, LPWR, PCR, PMU, TIMG0},
|
||||
rtc_cntl::RtcClock,
|
||||
time::Rate,
|
||||
clock::clocks_ll::regi2c_write_mask,
|
||||
peripherals::{LP_AON, PMU},
|
||||
rtc_cntl::{RtcCalSel, RtcClock, RtcFastClock, RtcSlowClock},
|
||||
};
|
||||
|
||||
const I2C_PMU: u8 = 0x6d;
|
||||
@ -188,372 +187,3 @@ pub enum SocResetReason {
|
||||
/// Glitch on power resets the digital core
|
||||
CorePwrGlitch = 0x17,
|
||||
}
|
||||
|
||||
/// RTC SLOW_CLK frequency values
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) enum RtcFastClock {
|
||||
/// Select RC_FAST_CLK as RTC_FAST_CLK source
|
||||
RtcFastClockRcFast = 0,
|
||||
#[allow(dead_code)]
|
||||
/// Select XTAL_D2_CLK as RTC_FAST_CLK source
|
||||
RtcFastClockXtalD2 = 1,
|
||||
}
|
||||
|
||||
impl Clock for RtcFastClock {
|
||||
fn frequency(&self) -> Rate {
|
||||
match self {
|
||||
RtcFastClock::RtcFastClockXtalD2 => Rate::from_hz(16_000_000),
|
||||
RtcFastClock::RtcFastClockRcFast => Rate::from_hz(property!("soc.rc_fast_clk_default")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// RTC SLOW_CLK frequency values
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
pub enum RtcSlowClock {
|
||||
/// Select RC_SLOW_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClockRcSlow = 0,
|
||||
/// Select XTAL32K_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClock32kXtal = 1,
|
||||
/// Select RC32K_CLK as RTC_SLOW_CLK source
|
||||
RtcSlowClock32kRc = 2,
|
||||
/// Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source
|
||||
RtcSlowOscSlow = 3,
|
||||
}
|
||||
|
||||
impl Clock for RtcSlowClock {
|
||||
fn frequency(&self) -> Rate {
|
||||
match self {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => Rate::from_hz(150_000),
|
||||
RtcSlowClock::RtcSlowClock32kXtal => Rate::from_hz(32_768),
|
||||
RtcSlowClock::RtcSlowClock32kRc => Rate::from_hz(32_768),
|
||||
RtcSlowClock::RtcSlowOscSlow => Rate::from_hz(32_768),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
/// Clock source to be calibrated using rtc_clk_cal function
|
||||
pub(crate) enum RtcCalSel {
|
||||
/// Currently selected RTC SLOW_CLK
|
||||
RtcCalRtcMux = -1,
|
||||
/// Internal 150kHz RC oscillator
|
||||
RtcCalRcSlow = 0,
|
||||
/// External 32kHz XTAL, as one type of 32k clock
|
||||
RtcCal32kXtal = 1,
|
||||
/// Internal 32kHz RC oscillator, as one type of 32k clock
|
||||
RtcCal32kRc = 2,
|
||||
/// External slow clock signal input by lp_pad_gpio0, as one type of 32k
|
||||
/// clock
|
||||
RtcCal32kOscSlow = 3,
|
||||
/// Internal 20MHz RC oscillator
|
||||
RtcCalRcFast,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum RtcCaliClkSel {
|
||||
CaliClkRcSlow = 0,
|
||||
CaliClkRcFast = 1,
|
||||
CaliClk32k = 2,
|
||||
}
|
||||
|
||||
/// RTC Watchdog Timer driver
|
||||
impl RtcClock {
|
||||
fn set_fast_freq(fast_freq: RtcFastClock) {
|
||||
// components/hal/esp32s2/include/hal/clk_tree_ll.h
|
||||
LPWR::regs().lp_clk_conf().modify(|_, w| unsafe {
|
||||
w.fast_clk_sel().bits(match fast_freq {
|
||||
RtcFastClock::RtcFastClockRcFast => 0b00,
|
||||
RtcFastClock::RtcFastClockXtalD2 => 0b01,
|
||||
})
|
||||
});
|
||||
|
||||
crate::rom::ets_delay_us(3);
|
||||
}
|
||||
|
||||
fn set_slow_freq(slow_freq: RtcSlowClock) {
|
||||
LPWR::regs()
|
||||
.lp_clk_conf()
|
||||
.modify(|_, w| unsafe { w.slow_clk_sel().bits(slow_freq as u8) });
|
||||
|
||||
LPWR::regs().clk_to_hp().modify(|_, w| {
|
||||
w.icg_hp_xtal32k()
|
||||
.bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kXtal));
|
||||
w.icg_hp_osc32k()
|
||||
.bit(matches!(slow_freq, RtcSlowClock::RtcSlowClock32kRc))
|
||||
});
|
||||
}
|
||||
|
||||
/// Get the RTC_SLOW_CLK source
|
||||
pub fn slow_freq() -> RtcSlowClock {
|
||||
match LPWR::regs().lp_clk_conf().read().slow_clk_sel().bits() {
|
||||
0 => RtcSlowClock::RtcSlowClockRcSlow,
|
||||
1 => RtcSlowClock::RtcSlowClock32kXtal,
|
||||
2 => RtcSlowClock::RtcSlowClock32kRc,
|
||||
3 => RtcSlowClock::RtcSlowOscSlow,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Calibration of RTC_SLOW_CLK is performed using a special feature of
|
||||
/// TIMG0. This feature counts the number of XTAL clock cycles within a
|
||||
/// given number of RTC_SLOW_CLK cycles.
|
||||
pub(crate) fn calibrate_internal(mut cal_clk: RtcCalSel, slowclk_cycles: u32) -> u32 {
|
||||
const SOC_CLK_RC_FAST_FREQ_APPROX: u32 = 17_500_000;
|
||||
const SOC_CLK_RC_SLOW_FREQ_APPROX: u32 = 136_000;
|
||||
const SOC_CLK_XTAL32K_FREQ_APPROX: u32 = 32768;
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match cal_clk {
|
||||
RtcCalSel::RtcCalRtcMux => match RtcClock::slow_freq() {
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
_ => cal_clk,
|
||||
},
|
||||
RtcCalSel::RtcCal32kOscSlow => RtcCalSel::RtcCalRtcMux,
|
||||
_ => cal_clk,
|
||||
};
|
||||
}
|
||||
|
||||
let clk_src = RtcClock::slow_freq();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match clk_src {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCal32kOscSlow,
|
||||
};
|
||||
}
|
||||
|
||||
let cali_clk_sel;
|
||||
if cal_clk == RtcCalSel::RtcCalRtcMux {
|
||||
cal_clk = match clk_src {
|
||||
RtcSlowClock::RtcSlowClockRcSlow => RtcCalSel::RtcCalRcSlow,
|
||||
RtcSlowClock::RtcSlowClock32kXtal => RtcCalSel::RtcCal32kXtal,
|
||||
RtcSlowClock::RtcSlowClock32kRc => RtcCalSel::RtcCal32kRc,
|
||||
RtcSlowClock::RtcSlowOscSlow => RtcCalSel::RtcCalRcSlow,
|
||||
}
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClkRcFast;
|
||||
} else if cal_clk == RtcCalSel::RtcCalRcSlow {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClkRcSlow;
|
||||
} else {
|
||||
cali_clk_sel = RtcCaliClkSel::CaliClk32k;
|
||||
match cal_clk {
|
||||
RtcCalSel::RtcCalRtcMux | RtcCalSel::RtcCalRcSlow | RtcCalSel::RtcCalRcFast => {}
|
||||
RtcCalSel::RtcCal32kRc => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(0) });
|
||||
}
|
||||
RtcCalSel::RtcCal32kXtal => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(1) });
|
||||
}
|
||||
RtcCalSel::RtcCal32kOscSlow => {
|
||||
PCR::regs()
|
||||
.ctrl_32k_conf()
|
||||
.modify(|_, w| unsafe { w.clk_32k_sel().bits(2) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable requested clock (150k is always on)
|
||||
// Some delay is required before the time is stable
|
||||
// Only enable if originaly was disabled
|
||||
// If clock is already on, do nothing
|
||||
|
||||
let dig_32k_xtal_enabled = LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.read()
|
||||
.icg_hp_xtal32k()
|
||||
.bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().set_bit());
|
||||
}
|
||||
|
||||
// TODO: very hacky - icg_hp_xtal32k is already set in the above condition?
|
||||
// in ESP-IDF these are not called in this function but the fields are set
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().set_bit());
|
||||
PMU::regs().hp_sleep_lp_ck_power().modify(|_, w| {
|
||||
w.hp_sleep_xpd_xtal32k().set_bit();
|
||||
w.hp_sleep_xpd_rc32k().set_bit()
|
||||
});
|
||||
|
||||
let rc_fast_enabled = PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.read()
|
||||
.hp_sleep_xpd_fosc_clk()
|
||||
.bit_is_set();
|
||||
let dig_rc_fast_enabled = LPWR::regs().clk_to_hp().read().icg_hp_fosc().bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
if !rc_fast_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
|
||||
if !dig_rc_fast_enabled {
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_fosc().set_bit());
|
||||
crate::rom::ets_delay_us(5);
|
||||
}
|
||||
}
|
||||
|
||||
let rc32k_enabled = PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.read()
|
||||
.hp_sleep_xpd_rc32k()
|
||||
.bit_is_set();
|
||||
let dig_rc32k_enabled = LPWR::regs().clk_to_hp().read().icg_hp_osc32k().bit_is_set();
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kRc {
|
||||
if !rc32k_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
|
||||
crate::rom::ets_delay_us(300);
|
||||
}
|
||||
|
||||
if !dig_rc32k_enabled {
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_osc32k().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there is already running calibration process
|
||||
// TODO: &mut TIMG0 for calibration
|
||||
let timg0 = TIMG0::regs();
|
||||
|
||||
if timg0
|
||||
.rtccalicfg()
|
||||
.read()
|
||||
.rtc_cali_start_cycling()
|
||||
.bit_is_set()
|
||||
{
|
||||
timg0
|
||||
.rtccalicfg2()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(1) });
|
||||
|
||||
// Set small timeout threshold to accelerate the generation of timeot
|
||||
// Internal circuit will be reset when timeout occurs and will not affect the
|
||||
// next calibration
|
||||
while !timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set()
|
||||
&& !timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set()
|
||||
{}
|
||||
}
|
||||
|
||||
// Prepare calibration
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_clk_sel().bits(cali_clk_sel.clone() as u8) });
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start_cycling().clear_bit());
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_max().bits(slowclk_cycles as u16) });
|
||||
|
||||
let expected_freq = match cali_clk_sel {
|
||||
RtcCaliClkSel::CaliClk32k => {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 12)
|
||||
});
|
||||
SOC_CLK_XTAL32K_FREQ_APPROX
|
||||
}
|
||||
RtcCaliClkSel::CaliClkRcFast => {
|
||||
timg0
|
||||
.rtccalicfg2()
|
||||
.modify(|_, w| unsafe { w.rtc_cali_timeout_thres().bits(0x01FFFFFF) });
|
||||
SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
}
|
||||
_ => {
|
||||
timg0.rtccalicfg2().modify(|_, w| unsafe {
|
||||
w.rtc_cali_timeout_thres().bits(slowclk_cycles << 10)
|
||||
});
|
||||
SOC_CLK_RC_SLOW_FREQ_APPROX
|
||||
}
|
||||
};
|
||||
|
||||
let us_time_estimate = (Rate::from_mhz(slowclk_cycles) / expected_freq).as_hz();
|
||||
|
||||
// Start calibration
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().clear_bit());
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().set_bit());
|
||||
|
||||
// Wait for calibration to finish up to another us_time_estimate
|
||||
crate::rom::ets_delay_us(us_time_estimate);
|
||||
|
||||
let cal_val = loop {
|
||||
if timg0.rtccalicfg().read().rtc_cali_rdy().bit_is_set() {
|
||||
break timg0.rtccalicfg1().read().rtc_cali_value().bits();
|
||||
}
|
||||
|
||||
if timg0.rtccalicfg2().read().rtc_cali_timeout().bit_is_set() {
|
||||
// Timed out waiting for calibration
|
||||
break 0;
|
||||
}
|
||||
};
|
||||
|
||||
timg0
|
||||
.rtccalicfg()
|
||||
.modify(|_, w| w.rtc_cali_start().clear_bit());
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kXtal && !dig_32k_xtal_enabled {
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_xtal32k().clear_bit());
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCalRcFast {
|
||||
if rc_fast_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_fosc_clk().set_bit());
|
||||
crate::rom::ets_delay_us(50);
|
||||
}
|
||||
|
||||
if dig_rc_fast_enabled {
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_fosc().set_bit());
|
||||
crate::rom::ets_delay_us(5);
|
||||
}
|
||||
}
|
||||
|
||||
if cal_clk == RtcCalSel::RtcCal32kRc {
|
||||
if rc32k_enabled {
|
||||
PMU::regs()
|
||||
.hp_sleep_lp_ck_power()
|
||||
.modify(|_, w| w.hp_sleep_xpd_rc32k().set_bit());
|
||||
crate::rom::ets_delay_us(300);
|
||||
}
|
||||
if dig_rc32k_enabled {
|
||||
LPWR::regs()
|
||||
.clk_to_hp()
|
||||
.modify(|_, w| w.icg_hp_osc32k().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
cal_val
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ use crate::{
|
||||
pub(crate) fn init() {}
|
||||
|
||||
pub(crate) fn configure_clock() {
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClockRcFast);
|
||||
|
||||
let cal_val = loop {
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRcSlow);
|
||||
|
||||
let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
|
||||
if res != 0 {
|
||||
|
@ -8,10 +8,10 @@ use crate::{
|
||||
pub(crate) fn init() {}
|
||||
|
||||
pub(crate) fn configure_clock() {
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClock8m);
|
||||
RtcClock::set_fast_freq(RtcFastClock::RtcFastClockRcFast);
|
||||
|
||||
let cal_val = loop {
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRtc);
|
||||
RtcClock::set_slow_freq(RtcSlowClock::RtcSlowClockRcSlow);
|
||||
|
||||
let res = RtcClock::calibrate(RtcCalSel::RtcCalRtcMux, 1024);
|
||||
if res != 0 {
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
gpio::RtcFunction,
|
||||
rtc_cntl::{
|
||||
Rtc,
|
||||
RtcCalSel,
|
||||
RtcClock,
|
||||
rtc::{
|
||||
HpAnalog,
|
||||
@ -13,7 +14,6 @@ use crate::{
|
||||
HpSysPower,
|
||||
LpAnalog,
|
||||
LpSysPower,
|
||||
RtcCalSel,
|
||||
SavedClockConfig,
|
||||
rtc_clk_cpu_freq_set_xtal,
|
||||
},
|
||||
|
@ -265,8 +265,10 @@ impl Chip {
|
||||
"uart_uart2",
|
||||
"soc_ref_tick_hz=\"1000000\"",
|
||||
"soc_ref_tick_hz_is_set",
|
||||
"soc_rc_fast_clk_default=\"8000000\"",
|
||||
"soc_rc_fast_clk_default=\"8500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"150000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_has_multiple_xtal_options",
|
||||
"aes_endianness_configurable",
|
||||
"gpio_has_bank_1",
|
||||
@ -419,8 +421,10 @@ impl Chip {
|
||||
"cargo:rustc-cfg=uart_uart2",
|
||||
"cargo:rustc-cfg=soc_ref_tick_hz=\"1000000\"",
|
||||
"cargo:rustc-cfg=soc_ref_tick_hz_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"8000000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"8500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"150000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_has_multiple_xtal_options",
|
||||
"cargo:rustc-cfg=aes_endianness_configurable",
|
||||
"cargo:rustc-cfg=gpio_has_bank_1",
|
||||
@ -537,6 +541,8 @@ impl Chip {
|
||||
"soc_cpu_has_csr_pc",
|
||||
"soc_rc_fast_clk_default=\"17500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"136000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_has_multiple_xtal_options",
|
||||
"assist_debug_has_sp_monitor",
|
||||
"gpio_gpio_function=\"1\"",
|
||||
@ -652,6 +658,8 @@ impl Chip {
|
||||
"cargo:rustc-cfg=soc_cpu_has_csr_pc",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"17500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"136000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_has_multiple_xtal_options",
|
||||
"cargo:rustc-cfg=assist_debug_has_sp_monitor",
|
||||
"cargo:rustc-cfg=gpio_gpio_function=\"1\"",
|
||||
@ -788,6 +796,8 @@ impl Chip {
|
||||
"soc_cpu_has_csr_pc",
|
||||
"soc_rc_fast_clk_default=\"17500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"136000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_xtal_frequency=\"40\"",
|
||||
"aes_dma",
|
||||
"aes_dma_mode_ecb",
|
||||
@ -933,6 +943,8 @@ impl Chip {
|
||||
"cargo:rustc-cfg=soc_cpu_has_csr_pc",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"17500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"136000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_xtal_frequency=\"40\"",
|
||||
"cargo:rustc-cfg=aes_dma",
|
||||
"cargo:rustc-cfg=aes_dma_mode_ecb",
|
||||
@ -1133,6 +1145,8 @@ impl Chip {
|
||||
"soc_cpu_has_prv_mode",
|
||||
"soc_rc_fast_clk_default=\"17500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"136000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_xtal_frequency=\"40\"",
|
||||
"aes_dma",
|
||||
"aes_dma_mode_ecb",
|
||||
@ -1333,6 +1347,8 @@ impl Chip {
|
||||
"cargo:rustc-cfg=soc_cpu_has_prv_mode",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"17500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"136000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_xtal_frequency=\"40\"",
|
||||
"cargo:rustc-cfg=aes_dma",
|
||||
"cargo:rustc-cfg=aes_dma_mode_ecb",
|
||||
@ -1512,8 +1528,10 @@ impl Chip {
|
||||
"uart_uart1",
|
||||
"soc_cpu_has_csr_pc",
|
||||
"soc_cpu_has_prv_mode",
|
||||
"soc_rc_fast_clk_default=\"8000000\"",
|
||||
"soc_rc_fast_clk_default=\"8500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"136000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_xtal_frequency=\"32\"",
|
||||
"aes_dma",
|
||||
"aes_dma_mode_ecb",
|
||||
@ -1687,8 +1705,10 @@ impl Chip {
|
||||
"cargo:rustc-cfg=uart_uart1",
|
||||
"cargo:rustc-cfg=soc_cpu_has_csr_pc",
|
||||
"cargo:rustc-cfg=soc_cpu_has_prv_mode",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"8000000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"8500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"136000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_xtal_frequency=\"32\"",
|
||||
"cargo:rustc-cfg=aes_dma",
|
||||
"cargo:rustc-cfg=aes_dma_mode_ecb",
|
||||
@ -1861,8 +1881,10 @@ impl Chip {
|
||||
"uart_uart1",
|
||||
"soc_ref_tick_hz=\"1000000\"",
|
||||
"soc_ref_tick_hz_is_set",
|
||||
"soc_rc_fast_clk_default=\"8000000\"",
|
||||
"soc_rc_fast_clk_default=\"8500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"90000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_xtal_frequency=\"40\"",
|
||||
"aes_dma",
|
||||
"aes_dma_mode_ecb",
|
||||
@ -2027,8 +2049,10 @@ impl Chip {
|
||||
"cargo:rustc-cfg=uart_uart1",
|
||||
"cargo:rustc-cfg=soc_ref_tick_hz=\"1000000\"",
|
||||
"cargo:rustc-cfg=soc_ref_tick_hz_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"8000000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"8500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"90000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_xtal_frequency=\"40\"",
|
||||
"cargo:rustc-cfg=aes_dma",
|
||||
"cargo:rustc-cfg=aes_dma_mode_ecb",
|
||||
@ -2213,6 +2237,8 @@ impl Chip {
|
||||
"uart_uart2",
|
||||
"soc_rc_fast_clk_default=\"17500000\"",
|
||||
"soc_rc_fast_clk_default_is_set",
|
||||
"soc_rc_slow_clock=\"136000\"",
|
||||
"soc_rc_slow_clock_is_set",
|
||||
"soc_xtal_frequency=\"40\"",
|
||||
"aes_dma",
|
||||
"aes_dma_mode_ecb",
|
||||
@ -2395,6 +2421,8 @@ impl Chip {
|
||||
"cargo:rustc-cfg=uart_uart2",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default=\"17500000\"",
|
||||
"cargo:rustc-cfg=soc_rc_fast_clk_default_is_set",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock=\"136000\"",
|
||||
"cargo:rustc-cfg=soc_rc_slow_clock_is_set",
|
||||
"cargo:rustc-cfg=soc_xtal_frequency=\"40\"",
|
||||
"cargo:rustc-cfg=aes_dma",
|
||||
"cargo:rustc-cfg=aes_dma_mode_ecb",
|
||||
@ -2574,6 +2602,7 @@ impl Config {
|
||||
println!("cargo:rustc-check-cfg=cfg(uart_uart2)");
|
||||
println!("cargo:rustc-check-cfg=cfg(soc_ref_tick_hz_is_set)");
|
||||
println!("cargo:rustc-check-cfg=cfg(soc_rc_fast_clk_default_is_set)");
|
||||
println!("cargo:rustc-check-cfg=cfg(soc_rc_slow_clock_is_set)");
|
||||
println!("cargo:rustc-check-cfg=cfg(soc_has_multiple_xtal_options)");
|
||||
println!("cargo:rustc-check-cfg=cfg(aes_endianness_configurable)");
|
||||
println!("cargo:rustc-check-cfg=cfg(gpio_has_bank_1)");
|
||||
@ -2729,7 +2758,10 @@ impl Config {
|
||||
println!("cargo:rustc-check-cfg=cfg(camera)");
|
||||
println!("cargo:rustc-check-cfg=cfg(soc_ref_tick_hz, values(\"1000000\"))");
|
||||
println!(
|
||||
"cargo:rustc-check-cfg=cfg(soc_rc_fast_clk_default, values(\"8000000\",\"17500000\"))"
|
||||
"cargo:rustc-check-cfg=cfg(soc_rc_fast_clk_default, values(\"8500000\",\"17500000\"))"
|
||||
);
|
||||
println!(
|
||||
"cargo:rustc-check-cfg=cfg(soc_rc_slow_clock, values(\"150000\",\"136000\",\"90000\"))"
|
||||
);
|
||||
println!("cargo:rustc-check-cfg=cfg(gpio_gpio_function, values(\"2\",\"1\"))");
|
||||
println!("cargo:rustc-check-cfg=cfg(gpio_constant_0_input, values(\"48\",\"31\",\"60\"))");
|
||||
|
@ -49,10 +49,16 @@ macro_rules! property {
|
||||
stringify!(1000000)
|
||||
};
|
||||
("soc.rc_fast_clk_default") => {
|
||||
8000000
|
||||
8500000
|
||||
};
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(8000000)
|
||||
stringify!(8500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
150000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(150000)
|
||||
};
|
||||
("soc.has_multiple_xtal_options") => {
|
||||
true
|
||||
|
@ -48,6 +48,12 @@ macro_rules! property {
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(17500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
136000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(136000)
|
||||
};
|
||||
("soc.has_multiple_xtal_options") => {
|
||||
true
|
||||
};
|
||||
|
@ -48,6 +48,12 @@ macro_rules! property {
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(17500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
136000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(136000)
|
||||
};
|
||||
("soc.xtal_frequency") => {
|
||||
40
|
||||
};
|
||||
|
@ -48,6 +48,12 @@ macro_rules! property {
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(17500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
136000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(136000)
|
||||
};
|
||||
("soc.xtal_frequency") => {
|
||||
40
|
||||
};
|
||||
|
@ -43,10 +43,16 @@ macro_rules! property {
|
||||
true
|
||||
};
|
||||
("soc.rc_fast_clk_default") => {
|
||||
8000000
|
||||
8500000
|
||||
};
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(8000000)
|
||||
stringify!(8500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
136000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(136000)
|
||||
};
|
||||
("soc.xtal_frequency") => {
|
||||
32
|
||||
|
@ -49,10 +49,16 @@ macro_rules! property {
|
||||
stringify!(1000000)
|
||||
};
|
||||
("soc.rc_fast_clk_default") => {
|
||||
8000000
|
||||
8500000
|
||||
};
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(8000000)
|
||||
stringify!(8500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
90000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(90000)
|
||||
};
|
||||
("soc.xtal_frequency") => {
|
||||
40
|
||||
|
@ -48,6 +48,12 @@ macro_rules! property {
|
||||
("soc.rc_fast_clk_default", str) => {
|
||||
stringify!(17500000)
|
||||
};
|
||||
("soc.rc_slow_clock") => {
|
||||
136000
|
||||
};
|
||||
("soc.rc_slow_clock", str) => {
|
||||
stringify!(136000)
|
||||
};
|
||||
("soc.xtal_frequency") => {
|
||||
40
|
||||
};
|
||||
|
@ -104,7 +104,8 @@ memory = [{ name = "dram", start = 0x3FFA_E000, end = 0x4000_0000 }]
|
||||
|
||||
[device.soc]
|
||||
ref_tick_hz = 1_000_000
|
||||
rc_fast_clk_default = 8_000_000
|
||||
rc_fast_clk_default = 8_500_000
|
||||
rc_slow_clock = 150_000
|
||||
xtal_options = [26, 40]
|
||||
|
||||
[device.adc]
|
||||
|
@ -83,6 +83,7 @@ memory = [{ name = "dram", start = 0x3FCA_0000, end = 0x3FCE_0000 }]
|
||||
[device.soc]
|
||||
cpu_has_csr_pc = true
|
||||
rc_fast_clk_default = 17_500_000
|
||||
rc_slow_clock = 136_000
|
||||
xtal_options = [26, 40]
|
||||
|
||||
[device.adc]
|
||||
|
@ -92,6 +92,7 @@ memory = [{ name = "dram", start = 0x3FC8_0000, end = 0x3FCE_0000 }]
|
||||
[device.soc]
|
||||
cpu_has_csr_pc = true
|
||||
rc_fast_clk_default = 17_500_000
|
||||
rc_slow_clock = 136_000
|
||||
xtal_options = [40]
|
||||
|
||||
[device.adc]
|
||||
|
@ -134,6 +134,7 @@ memory = [{ name = "dram", start = 0x4080_0000, end = 0x4088_0000 }]
|
||||
cpu_has_csr_pc = true
|
||||
cpu_has_prv_mode = true
|
||||
rc_fast_clk_default = 17_500_000
|
||||
rc_slow_clock = 136_000
|
||||
xtal_options = [40]
|
||||
|
||||
[device.adc]
|
||||
|
@ -112,7 +112,8 @@ memory = [{ name = "dram", start = 0x4080_0000, end = 0x4085_0000 }]
|
||||
[device.soc]
|
||||
cpu_has_csr_pc = true
|
||||
cpu_has_prv_mode = true
|
||||
rc_fast_clk_default = 8_000_000
|
||||
rc_fast_clk_default = 8_500_000
|
||||
rc_slow_clock = 136_000
|
||||
xtal_options = [32]
|
||||
|
||||
[device.adc]
|
||||
|
@ -103,7 +103,8 @@ memory = [{ name = "dram", start = 0x3FFB_0000, end = 0x4000_0000 }]
|
||||
|
||||
[device.soc]
|
||||
ref_tick_hz = 1_000_000
|
||||
rc_fast_clk_default = 8_000_000
|
||||
rc_fast_clk_default = 8_500_000
|
||||
rc_slow_clock = 90_000
|
||||
xtal_options = [40]
|
||||
|
||||
[device.adc]
|
||||
|
@ -116,6 +116,7 @@ memory = [{ name = "dram", start = 0x3FC8_8000, end = 0x3FD0_0000 }]
|
||||
|
||||
[device.soc]
|
||||
rc_fast_clk_default = 17_500_000
|
||||
rc_slow_clock = 136_000
|
||||
xtal_options = [40]
|
||||
|
||||
[device.adc]
|
||||
|
@ -285,6 +285,8 @@ driver_configs![
|
||||
ref_tick_hz: Option<u32>,
|
||||
#[serde(default)]
|
||||
rc_fast_clk_default: Option<u32>,
|
||||
#[serde(default)]
|
||||
rc_slow_clock: Option<u32>,
|
||||
xtal_options: Vec<u32>,
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user