aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Stevenson <[email protected]>2025-06-17 14:27:37 +0200
committerFrank Stevenson <[email protected]>2025-06-17 14:27:37 +0200
commit7fe4547ecb8a2838b26e6e0a902fbef3a4d22e52 (patch)
treef455e3f78aeacf5a4eecdd75522e5a41633d44f7
parent6186d111a5c150946ee5b7e9e68d987a38c1a463 (diff)
U5: Apply auto-calibration on MSIK and calculate frequencies for detuned LSE input
-rw-r--r--embassy-stm32/src/rcc/u5.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 97eb2eb6d..7e5001499 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -5,7 +5,7 @@ pub use crate::pac::rcc::vals::{
5 Hpre as AHBPrescaler, Msirange, Msirange as MSIRange, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, 5 Hpre as AHBPrescaler, Msirange, Msirange as MSIRange, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul,
6 Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, 6 Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk,
7}; 7};
8use crate::pac::rcc::vals::{Hseext, Msirgsel, Pllmboost, Pllrge}; 8use crate::pac::rcc::vals::{Hseext, Msipllsel, Msirgsel, Pllmboost, Pllrge};
9#[cfg(all(peri_usb_otg_hs))] 9#[cfg(all(peri_usb_otg_hs))]
10pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG}; 10pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG};
11use crate::pac::{FLASH, PWR, RCC}; 11use crate::pac::{FLASH, PWR, RCC};
@@ -131,7 +131,18 @@ pub(crate) unsafe fn init(config: Config) {
131 PWR.vosr().modify(|w| w.set_vos(config.voltage_range)); 131 PWR.vosr().modify(|w| w.set_vos(config.voltage_range));
132 while !PWR.vosr().read().vosrdy() {} 132 while !PWR.vosr().read().vosrdy() {}
133 133
134 let msis = config.msis.map(|range| { 134 let lse_calibration_freq = match config.ls.lse {
135 Some(lse_config) => {
136 if lse_config.peripherals_clocked && (31_000..=34_000).contains(&lse_config.frequency.0) {
137 Some(lse_config.frequency)
138 } else {
139 None
140 }
141 }
142 _ => None,
143 };
144
145 let mut msis = config.msis.map(|range| {
135 // Check MSI output per RM0456 § 11.4.10 146 // Check MSI output per RM0456 § 11.4.10
136 match config.voltage_range { 147 match config.voltage_range {
137 VoltageScale::RANGE4 => { 148 VoltageScale::RANGE4 => {
@@ -184,8 +195,25 @@ pub(crate) unsafe fn init(config: Config) {
184 RCC.cr().modify(|w| { 195 RCC.cr().modify(|w| {
185 w.set_msikon(true); 196 w.set_msikon(true);
186 }); 197 });
198 if lse_calibration_freq.is_some() {
199 // Enable the MSIK auto-calibration feature
200 RCC.cr().modify(|w| w.set_msipllsel(Msipllsel::MSIK));
201 RCC.cr().modify(|w| w.set_msipllen(true));
202 }
187 while !RCC.cr().read().msikrdy() {} 203 while !RCC.cr().read().msikrdy() {}
188 msirange_to_hertz(range) 204 if let Some(freq) = lse_calibration_freq {
205 // Estimate frequency based on it being a fixed fractional multiple of LSE
206 let base = msirange_to_hertz(range).0;
207 let multiplier = (base + 8096) / 16384;
208 let msik_freq = Hertz(freq.0 * multiplier / 2);
209 if config.msis == config.msik {
210 // If MSIS and MSIK are the same range both will be auto calibrated to the same frequency
211 msis = Some(msik_freq)
212 }
213 msik_freq
214 } else {
215 msirange_to_hertz(range)
216 }
189 }); 217 });
190 218
191 let hsi = config.hsi.then(|| { 219 let hsi = config.hsi.then(|| {