mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-10-02 14:44:32 +00:00
Introduce configration options for Pll fast modes.
Ensure that the auto calibration is applied to an active clock.
This commit is contained in:
parent
cf9856255e
commit
fd3cdfcf25
@ -5,7 +5,7 @@ pub use crate::pac::rcc::vals::{
|
|||||||
Hpre as AHBPrescaler, Msirange, Msirange as MSIRange, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul,
|
Hpre as AHBPrescaler, Msirange, Msirange as MSIRange, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul,
|
||||||
Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk,
|
Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk,
|
||||||
};
|
};
|
||||||
use crate::pac::rcc::vals::{Hseext, Msipllsel, Msirgsel, Pllmboost, Pllrge};
|
use crate::pac::rcc::vals::{Hseext, Msipllfast, Msipllsel, Msirgsel, Pllmboost, Pllrge};
|
||||||
#[cfg(all(peri_usb_otg_hs))]
|
#[cfg(all(peri_usb_otg_hs))]
|
||||||
pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG};
|
pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG};
|
||||||
use crate::pac::{FLASH, PWR, RCC};
|
use crate::pac::{FLASH, PWR, RCC};
|
||||||
@ -72,12 +72,30 @@ pub enum MsiAutoCalibration {
|
|||||||
MSIS,
|
MSIS,
|
||||||
/// MSIK is given priority for auto-calibration
|
/// MSIK is given priority for auto-calibration
|
||||||
MSIK,
|
MSIK,
|
||||||
|
/// MSIS with fast mode (always on)
|
||||||
|
MsisFast,
|
||||||
|
/// MSIK with fast mode (always on)
|
||||||
|
MsikFast,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MsiAutoCalibration {
|
impl MsiAutoCalibration {
|
||||||
const fn default() -> Self {
|
const fn default() -> Self {
|
||||||
MsiAutoCalibration::Disabled
|
MsiAutoCalibration::Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn base_mode(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
MsiAutoCalibration::Disabled => MsiAutoCalibration::Disabled,
|
||||||
|
MsiAutoCalibration::MSIS => MsiAutoCalibration::MSIS,
|
||||||
|
MsiAutoCalibration::MSIK => MsiAutoCalibration::MSIK,
|
||||||
|
MsiAutoCalibration::MsisFast => MsiAutoCalibration::MSIS,
|
||||||
|
MsiAutoCalibration::MsikFast => MsiAutoCalibration::MSIK,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_fast(&self) -> bool {
|
||||||
|
matches!(self, MsiAutoCalibration::MsisFast | MsiAutoCalibration::MsikFast)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MsiAutoCalibration {
|
impl Default for MsiAutoCalibration {
|
||||||
@ -159,7 +177,23 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
Some(lse_config) => {
|
Some(lse_config) => {
|
||||||
// Allow +/- 5% tolerance for LSE frequency
|
// Allow +/- 5% tolerance for LSE frequency
|
||||||
if lse_config.peripherals_clocked && (31_100..=34_400).contains(&lse_config.frequency.0) {
|
if lse_config.peripherals_clocked && (31_100..=34_400).contains(&lse_config.frequency.0) {
|
||||||
|
// Check that the calibration is applied to an active clock
|
||||||
|
match (
|
||||||
|
config.auto_calibration.base_mode(),
|
||||||
|
config.msis.is_some(),
|
||||||
|
config.msik.is_some(),
|
||||||
|
) {
|
||||||
|
(MsiAutoCalibration::MSIS, true, _) => {
|
||||||
|
// MSIS is active and using LSE for auto-calibration
|
||||||
Some(lse_config.frequency)
|
Some(lse_config.frequency)
|
||||||
|
}
|
||||||
|
(MsiAutoCalibration::MSIK, _, true) => {
|
||||||
|
// MSIK is active and using LSE for auto-calibration
|
||||||
|
Some(lse_config.frequency)
|
||||||
|
}
|
||||||
|
// improper configuration, no LSE calibration
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -192,7 +226,9 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
w.set_msipllen(false);
|
w.set_msipllen(false);
|
||||||
w.set_msison(true);
|
w.set_msison(true);
|
||||||
});
|
});
|
||||||
let msis = if let (Some(freq), MsiAutoCalibration::MSIS) = (lse_calibration_freq, config.auto_calibration) {
|
let msis = if let (Some(freq), MsiAutoCalibration::MSIS) =
|
||||||
|
(lse_calibration_freq, config.auto_calibration.base_mode())
|
||||||
|
{
|
||||||
// Enable the MSIS auto-calibration feature
|
// Enable the MSIS auto-calibration feature
|
||||||
RCC.cr().modify(|w| w.set_msipllsel(Msipllsel::MSIS));
|
RCC.cr().modify(|w| w.set_msipllsel(Msipllsel::MSIS));
|
||||||
RCC.cr().modify(|w| w.set_msipllen(true));
|
RCC.cr().modify(|w| w.set_msipllen(true));
|
||||||
@ -228,7 +264,9 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
RCC.cr().modify(|w| {
|
RCC.cr().modify(|w| {
|
||||||
w.set_msikon(true);
|
w.set_msikon(true);
|
||||||
});
|
});
|
||||||
let msik = if let (Some(freq), MsiAutoCalibration::MSIK) = (lse_calibration_freq, config.auto_calibration) {
|
let msik = if let (Some(freq), MsiAutoCalibration::MSIK) =
|
||||||
|
(lse_calibration_freq, config.auto_calibration.base_mode())
|
||||||
|
{
|
||||||
// Enable the MSIK auto-calibration feature
|
// Enable the MSIK auto-calibration feature
|
||||||
RCC.cr().modify(|w| w.set_msipllsel(Msipllsel::MSIK));
|
RCC.cr().modify(|w| w.set_msipllsel(Msipllsel::MSIK));
|
||||||
RCC.cr().modify(|w| w.set_msipllen(true));
|
RCC.cr().modify(|w| w.set_msipllen(true));
|
||||||
@ -242,10 +280,16 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
|
|
||||||
// If both MSIS and MSIK are enabled, we need to check if they are using the same internal source.
|
// If both MSIS and MSIK are enabled, we need to check if they are using the same internal source.
|
||||||
if let Some(lse_freq) = lse_calibration_freq {
|
if let Some(lse_freq) = lse_calibration_freq {
|
||||||
|
// Check if Fast mode should be used
|
||||||
|
if config.auto_calibration.is_fast() {
|
||||||
|
RCC.cr().modify(|w| {
|
||||||
|
w.set_msipllfast(Msipllfast::FAST);
|
||||||
|
});
|
||||||
|
}
|
||||||
if let (Some(msis_range), Some(msik_range)) = (config.msis, config.msik) {
|
if let (Some(msis_range), Some(msik_range)) = (config.msis, config.msik) {
|
||||||
if (msis_range as u8 >> 2) == (msik_range as u8 >> 2) {
|
if (msis_range as u8 >> 2) == (msik_range as u8 >> 2) {
|
||||||
// Clock source is shared, both will be auto calibrated.
|
// Clock source is shared, both will be auto calibrated.
|
||||||
match config.auto_calibration {
|
match config.auto_calibration.base_mode() {
|
||||||
MsiAutoCalibration::MSIS => {
|
MsiAutoCalibration::MSIS => {
|
||||||
// MSIS and MSIK are using the same clock source, recalibrate
|
// MSIS and MSIK are using the same clock source, recalibrate
|
||||||
msik = Some(calculate_calibrated_msi_frequency(msik_range, lse_freq));
|
msik = Some(calculate_calibrated_msi_frequency(msik_range, lse_freq));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user