diff options
| author | Frank Stevenson <[email protected]> | 2025-07-24 18:08:29 +0200 |
|---|---|---|
| committer | Frank Stevenson <[email protected]> | 2025-07-24 18:08:29 +0200 |
| commit | aa243e4d3e51719d32314ba47ea68674ecc6c95e (patch) | |
| tree | e1b20a678972e9724a3fa3c09a90b70ee6bcc93e /embassy-stm32 | |
| parent | 3394f3ab9d2c0640bbd0804d5fd28cc68153786d (diff) | |
Improved error checks, and some cleanup
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/src/rcc/u5.rs | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index d12416a72..7a7ffc939 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -173,31 +173,39 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 173 | PWR.vosr().modify(|w| w.set_vos(config.voltage_range)); | 173 | PWR.vosr().modify(|w| w.set_vos(config.voltage_range)); |
| 174 | while !PWR.vosr().read().vosrdy() {} | 174 | while !PWR.vosr().read().vosrdy() {} |
| 175 | 175 | ||
| 176 | let lse_calibration_freq = match config.ls.lse { | 176 | let lse_calibration_freq = if config.auto_calibration != MsiAutoCalibration::Disabled { |
| 177 | Some(lse_config) => { | 177 | // LSE must be configured and peripherals clocked for MSI auto-calibration |
| 178 | // Allow +/- 5% tolerance for LSE frequency | 178 | let lse_config = config |
| 179 | if lse_config.peripherals_clocked && (31_100..=34_400).contains(&lse_config.frequency.0) { | 179 | .ls |
| 180 | // Check that the calibration is applied to an active clock | 180 | .lse |
| 181 | match ( | 181 | .clone() |
| 182 | config.auto_calibration.base_mode(), | 182 | .expect("LSE must be configured for MSI auto-calibration"); |
| 183 | config.msis.is_some(), | 183 | assert!(lse_config.peripherals_clocked); |
| 184 | config.msik.is_some(), | 184 | |
| 185 | ) { | 185 | // Expect less than +/- 5% deviation for LSE frequency |
| 186 | (MsiAutoCalibration::MSIS, true, _) => { | 186 | if (31_100..=34_400).contains(&lse_config.frequency.0) { |
| 187 | // MSIS is active and using LSE for auto-calibration | 187 | // Check that the calibration is applied to an active clock |
| 188 | Some(lse_config.frequency) | 188 | match ( |
| 189 | } | 189 | config.auto_calibration.base_mode(), |
| 190 | (MsiAutoCalibration::MSIK, _, true) => { | 190 | config.msis.is_some(), |
| 191 | // MSIK is active and using LSE for auto-calibration | 191 | config.msik.is_some(), |
| 192 | Some(lse_config.frequency) | 192 | ) { |
| 193 | } | 193 | (MsiAutoCalibration::MSIS, true, _) => { |
| 194 | // improper configuration | 194 | // MSIS is active and using LSE for auto-calibration |
| 195 | _ => panic!("MSIx auto-calibration is enabled for a source that has not been configured.") } | 195 | Some(lse_config.frequency) |
| 196 | } else { | 196 | } |
| 197 | None | 197 | (MsiAutoCalibration::MSIK, _, true) => { |
| 198 | // MSIK is active and using LSE for auto-calibration | ||
| 199 | Some(lse_config.frequency) | ||
| 200 | } | ||
| 201 | // improper configuration | ||
| 202 | _ => panic!("MSIx auto-calibration is enabled for a source that has not been configured."), | ||
| 198 | } | 203 | } |
| 204 | } else { | ||
| 205 | panic!("LSE frequency more than 5% off from 32.768 kHz, cannot use for MSI auto-calibration"); | ||
| 199 | } | 206 | } |
| 200 | _ => None, | 207 | } else { |
| 208 | None | ||
| 201 | }; | 209 | }; |
| 202 | 210 | ||
| 203 | let mut msis = config.msis.map(|range| { | 211 | let mut msis = config.msis.map(|range| { |
| @@ -277,30 +285,28 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 277 | msik | 285 | msik |
| 278 | }); | 286 | }); |
| 279 | 287 | ||
| 280 | // If both MSIS and MSIK are enabled, we need to check if they are using the same internal source. | ||
| 281 | if let Some(lse_freq) = lse_calibration_freq { | 288 | if let Some(lse_freq) = lse_calibration_freq { |
| 282 | // Check if Fast mode should be used | 289 | // If both MSIS and MSIK are enabled, we need to check if they are using the same internal source. |
| 283 | if config.auto_calibration.is_fast() { | ||
| 284 | RCC.cr().modify(|w| { | ||
| 285 | w.set_msipllfast(Msipllfast::FAST); | ||
| 286 | }); | ||
| 287 | } | ||
| 288 | if let (Some(msis_range), Some(msik_range)) = (config.msis, config.msik) { | 290 | if let (Some(msis_range), Some(msik_range)) = (config.msis, config.msik) { |
| 289 | if (msis_range as u8 >> 2) == (msik_range as u8 >> 2) { | 291 | if (msis_range as u8 >> 2) == (msik_range as u8 >> 2) { |
| 290 | // Clock source is shared, both will be auto calibrated. | 292 | // Clock source is shared, both will be auto calibrated, recalculate other frequency |
| 291 | match config.auto_calibration.base_mode() { | 293 | match config.auto_calibration.base_mode() { |
| 292 | MsiAutoCalibration::MSIS => { | 294 | MsiAutoCalibration::MSIS => { |
| 293 | // MSIS and MSIK are using the same clock source, recalibrate | ||
| 294 | msik = Some(calculate_calibrated_msi_frequency(msik_range, lse_freq)); | 295 | msik = Some(calculate_calibrated_msi_frequency(msik_range, lse_freq)); |
| 295 | } | 296 | } |
| 296 | MsiAutoCalibration::MSIK => { | 297 | MsiAutoCalibration::MSIK => { |
| 297 | // MSIS and MSIK are using the same clock source, recalibrate | ||
| 298 | msis = Some(calculate_calibrated_msi_frequency(msis_range, lse_freq)); | 298 | msis = Some(calculate_calibrated_msi_frequency(msis_range, lse_freq)); |
| 299 | } | 299 | } |
| 300 | _ => {} | 300 | _ => {} |
| 301 | } | 301 | } |
| 302 | } | 302 | } |
| 303 | } | 303 | } |
| 304 | // Check if Fast mode should be used | ||
| 305 | if config.auto_calibration.is_fast() { | ||
| 306 | RCC.cr().modify(|w| { | ||
| 307 | w.set_msipllfast(Msipllfast::FAST); | ||
| 308 | }); | ||
| 309 | } | ||
| 304 | } | 310 | } |
| 305 | 311 | ||
| 306 | let hsi = config.hsi.then(|| { | 312 | let hsi = config.hsi.then(|| { |
