aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/rcc/f4f7.rs13
-rw-r--r--embassy-stm32/src/rcc/h.rs110
-rw-r--r--embassy-stm32/src/rcc/l0l1.rs30
-rw-r--r--embassy-stm32/src/rcc/l4l5.rs123
-rw-r--r--embassy-stm32/src/rcc/mod.rs30
-rw-r--r--examples/stm32h5/src/bin/eth.rs4
-rw-r--r--examples/stm32h5/src/bin/usb_serial.rs4
-rw-r--r--examples/stm32h7/src/bin/adc.rs7
-rw-r--r--examples/stm32h7/src/bin/camera.rs6
-rw-r--r--examples/stm32h7/src/bin/dac.rs7
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs7
-rw-r--r--examples/stm32h7/src/bin/eth.rs6
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs6
-rw-r--r--examples/stm32h7/src/bin/fmc.rs6
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs6
-rw-r--r--examples/stm32h7/src/bin/pwm.rs6
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs6
-rw-r--r--examples/stm32h7/src/bin/spi.rs6
-rw-r--r--examples/stm32h7/src/bin/spi_dma.rs6
-rw-r--r--examples/stm32h7/src/bin/usb_serial.rs6
-rw-r--r--tests/stm32/src/common.rs18
21 files changed, 175 insertions, 238 deletions
diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs
index 3f9a2be67..2e4f95722 100644
--- a/embassy-stm32/src/rcc/f4f7.rs
+++ b/embassy-stm32/src/rcc/f4f7.rs
@@ -166,8 +166,8 @@ pub(crate) unsafe fn init(config: Config) {
166 }; 166 };
167 167
168 let hclk = sys / config.ahb_pre; 168 let hclk = sys / config.ahb_pre;
169 let (pclk1, pclk1_tim) = calc_pclk(hclk, config.apb1_pre); 169 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
170 let (pclk2, pclk2_tim) = calc_pclk(hclk, config.apb2_pre); 170 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre);
171 171
172 assert!(max::SYSCLK.contains(&sys)); 172 assert!(max::SYSCLK.contains(&sys));
173 assert!(max::HCLK.contains(&hclk)); 173 assert!(max::HCLK.contains(&hclk));
@@ -326,15 +326,6 @@ fn flash_setup(clk: Hertz) {
326 while FLASH.acr().read().latency() != latency {} 326 while FLASH.acr().read().latency() != latency {}
327} 327}
328 328
329fn calc_pclk<D>(hclk: Hertz, ppre: D) -> (Hertz, Hertz)
330where
331 Hertz: core::ops::Div<D, Output = Hertz>,
332{
333 let pclk = hclk / ppre;
334 let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 };
335 (pclk, pclk_tim)
336}
337
338#[cfg(stm32f7)] 329#[cfg(stm32f7)]
339mod max { 330mod max {
340 use core::ops::RangeInclusive; 331 use core::ops::RangeInclusive;
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 8883763ec..7e924f0ac 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -6,8 +6,11 @@ use crate::pac::pwr::vals::Vos;
6pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource; 6pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource;
7#[cfg(stm32h7)] 7#[cfg(stm32h7)]
8pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; 8pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
9use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; 9pub use crate::pac::rcc::vals::{
10pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul}; 10 Ckpersel as PerClockSource, Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul,
11 Pllsrc as PllSource, Sw as Sysclk,
12};
13use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre};
11use crate::pac::{FLASH, PWR, RCC}; 14use crate::pac::{FLASH, PWR, RCC};
12use crate::rcc::{set_freqs, Clocks}; 15use crate::rcc::{set_freqs, Clocks};
13use crate::time::Hertz; 16use crate::time::Hertz;
@@ -58,41 +61,9 @@ pub struct Hse {
58 pub mode: HseMode, 61 pub mode: HseMode,
59} 62}
60 63
61#[derive(Clone, Copy, Eq, PartialEq)]
62pub enum Hsi {
63 /// 64Mhz
64 Mhz64,
65 /// 32Mhz (divided by 2)
66 Mhz32,
67 /// 16Mhz (divided by 4)
68 Mhz16,
69 /// 8Mhz (divided by 8)
70 Mhz8,
71}
72
73#[derive(Clone, Copy, Eq, PartialEq)]
74pub enum Sysclk {
75 /// HSI selected as sysclk
76 HSI,
77 /// HSE selected as sysclk
78 HSE,
79 /// CSI selected as sysclk
80 CSI,
81 /// PLL1_P selected as sysclk
82 Pll1P,
83}
84
85#[derive(Clone, Copy, Eq, PartialEq)]
86pub enum PllSource {
87 Hsi,
88 Csi,
89 Hse,
90}
91
92#[derive(Clone, Copy)] 64#[derive(Clone, Copy)]
93pub struct Pll { 65pub struct Pll {
94 /// Source clock selection. 66 /// Source clock selection.
95 #[cfg(stm32h5)]
96 pub source: PllSource, 67 pub source: PllSource,
97 68
98 /// PLL pre-divider (DIVM). 69 /// PLL pre-divider (DIVM).
@@ -152,15 +123,12 @@ impl From<TimerPrescaler> for Timpre {
152/// Configuration of the core clocks 123/// Configuration of the core clocks
153#[non_exhaustive] 124#[non_exhaustive]
154pub struct Config { 125pub struct Config {
155 pub hsi: Option<Hsi>, 126 pub hsi: Option<HSIPrescaler>,
156 pub hse: Option<Hse>, 127 pub hse: Option<Hse>,
157 pub csi: bool, 128 pub csi: bool,
158 pub hsi48: bool, 129 pub hsi48: bool,
159 pub sys: Sysclk, 130 pub sys: Sysclk,
160 131
161 #[cfg(stm32h7)]
162 pub pll_src: PllSource,
163
164 pub pll1: Option<Pll>, 132 pub pll1: Option<Pll>,
165 pub pll2: Option<Pll>, 133 pub pll2: Option<Pll>,
166 #[cfg(any(rcc_h5, stm32h7))] 134 #[cfg(any(rcc_h5, stm32h7))]
@@ -184,13 +152,11 @@ pub struct Config {
184impl Default for Config { 152impl Default for Config {
185 fn default() -> Self { 153 fn default() -> Self {
186 Self { 154 Self {
187 hsi: Some(Hsi::Mhz64), 155 hsi: Some(HSIPrescaler::DIV1),
188 hse: None, 156 hse: None,
189 csi: false, 157 csi: false,
190 hsi48: false, 158 hsi48: false,
191 sys: Sysclk::HSI, 159 sys: Sysclk::HSI,
192 #[cfg(stm32h7)]
193 pll_src: PllSource::Hsi,
194 pll1: None, 160 pll1: None,
195 pll2: None, 161 pll2: None,
196 #[cfg(any(rcc_h5, stm32h7))] 162 #[cfg(any(rcc_h5, stm32h7))]
@@ -303,19 +269,13 @@ pub(crate) unsafe fn init(config: Config) {
303 RCC.cr().modify(|w| w.set_hsion(false)); 269 RCC.cr().modify(|w| w.set_hsion(false));
304 None 270 None
305 } 271 }
306 Some(hsi) => { 272 Some(hsidiv) => {
307 let (freq, hsidiv) = match hsi {
308 Hsi::Mhz64 => (HSI_FREQ / 1u32, Hsidiv::DIV1),
309 Hsi::Mhz32 => (HSI_FREQ / 2u32, Hsidiv::DIV2),
310 Hsi::Mhz16 => (HSI_FREQ / 4u32, Hsidiv::DIV4),
311 Hsi::Mhz8 => (HSI_FREQ / 8u32, Hsidiv::DIV8),
312 };
313 RCC.cr().modify(|w| { 273 RCC.cr().modify(|w| {
314 w.set_hsidiv(hsidiv); 274 w.set_hsidiv(hsidiv);
315 w.set_hsion(true); 275 w.set_hsion(true);
316 }); 276 });
317 while !RCC.cr().read().hsirdy() {} 277 while !RCC.cr().read().hsirdy() {}
318 Some(freq) 278 Some(HSI_FREQ / hsidiv)
319 } 279 }
320 }; 280 };
321 281
@@ -360,25 +320,29 @@ pub(crate) unsafe fn init(config: Config) {
360 } 320 }
361 }; 321 };
362 322
323 // H7 has shared PLLSRC, check it's equal in all PLLs.
324 #[cfg(stm32h7)]
325 {
326 let plls = [&config.pll1, &config.pll2, &config.pll3];
327 if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) {
328 panic!("Source must be equal across all enabled PLLs.")
329 };
330 }
331
363 // Configure PLLs. 332 // Configure PLLs.
364 let pll_input = PllInput { 333 let pll_input = PllInput { csi, hse, hsi };
365 csi,
366 hse,
367 hsi,
368 #[cfg(stm32h7)]
369 source: config.pll_src,
370 };
371 let pll1 = init_pll(0, config.pll1, &pll_input); 334 let pll1 = init_pll(0, config.pll1, &pll_input);
372 let pll2 = init_pll(1, config.pll2, &pll_input); 335 let pll2 = init_pll(1, config.pll2, &pll_input);
373 #[cfg(any(rcc_h5, stm32h7))] 336 #[cfg(any(rcc_h5, stm32h7))]
374 let pll3 = init_pll(2, config.pll3, &pll_input); 337 let pll3 = init_pll(2, config.pll3, &pll_input);
375 338
376 // Configure sysclk 339 // Configure sysclk
377 let (sys, sw) = match config.sys { 340 let sys = match config.sys {
378 Sysclk::HSI => (unwrap!(hsi), Sw::HSI), 341 Sysclk::HSI => unwrap!(hsi),
379 Sysclk::HSE => (unwrap!(hse), Sw::HSE), 342 Sysclk::HSE => unwrap!(hse),
380 Sysclk::CSI => (unwrap!(csi), Sw::CSI), 343 Sysclk::CSI => unwrap!(csi),
381 Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1_P), 344 Sysclk::PLL1_P => unwrap!(pll1.p),
345 _ => unreachable!(),
382 }; 346 };
383 347
384 // Check limits. 348 // Check limits.
@@ -502,8 +466,8 @@ pub(crate) unsafe fn init(config: Config) {
502 466
503 RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into())); 467 RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into()));
504 468
505 RCC.cfgr().modify(|w| w.set_sw(sw)); 469 RCC.cfgr().modify(|w| w.set_sw(config.sys));
506 while RCC.cfgr().read().sws() != sw {} 470 while RCC.cfgr().read().sws() != config.sys {}
507 471
508 // IO compensation cell - Requires CSI clock and SYSCFG 472 // IO compensation cell - Requires CSI clock and SYSCFG
509 #[cfg(stm32h7)] // TODO h5 473 #[cfg(stm32h7)] // TODO h5
@@ -588,8 +552,6 @@ struct PllInput {
588 hsi: Option<Hertz>, 552 hsi: Option<Hertz>,
589 hse: Option<Hertz>, 553 hse: Option<Hertz>,
590 csi: Option<Hertz>, 554 csi: Option<Hertz>,
591 #[cfg(stm32h7)]
592 source: PllSource,
593} 555}
594 556
595struct PllOutput { 557struct PllOutput {
@@ -619,15 +581,11 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
619 }; 581 };
620 }; 582 };
621 583
622 #[cfg(stm32h5)] 584 let in_clk = match config.source {
623 let source = config.source; 585 PllSource::DISABLE => panic!("must not set PllSource::Disable"),
624 #[cfg(stm32h7)] 586 PllSource::HSI => unwrap!(input.hsi),
625 let source = input.source; 587 PllSource::HSE => unwrap!(input.hse),
626 588 PllSource::CSI => unwrap!(input.csi),
627 let (in_clk, src) = match source {
628 PllSource::Hsi => (unwrap!(input.hsi), Pllsrc::HSI),
629 PllSource::Hse => (unwrap!(input.hse), Pllsrc::HSE),
630 PllSource::Csi => (unwrap!(input.csi), Pllsrc::CSI),
631 }; 589 };
632 590
633 let ref_clk = in_clk / config.prediv as u32; 591 let ref_clk = in_clk / config.prediv as u32;
@@ -667,7 +625,7 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
667 625
668 #[cfg(stm32h5)] 626 #[cfg(stm32h5)]
669 RCC.pllcfgr(num).write(|w| { 627 RCC.pllcfgr(num).write(|w| {
670 w.set_pllsrc(src); 628 w.set_pllsrc(config.source);
671 w.set_divm(config.prediv); 629 w.set_divm(config.prediv);
672 w.set_pllvcosel(vco_range); 630 w.set_pllvcosel(vco_range);
673 w.set_pllrge(ref_range); 631 w.set_pllrge(ref_range);
@@ -681,7 +639,7 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
681 { 639 {
682 RCC.pllckselr().modify(|w| { 640 RCC.pllckselr().modify(|w| {
683 w.set_divm(num, config.prediv); 641 w.set_divm(num, config.prediv);
684 w.set_pllsrc(src); 642 w.set_pllsrc(config.source);
685 }); 643 });
686 RCC.pllcfgr().modify(|w| { 644 RCC.pllcfgr().modify(|w| {
687 w.set_pllvcosel(num, vco_range); 645 w.set_pllvcosel(num, vco_range);
diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs
index 52e9ccb3c..9fb2062d6 100644
--- a/embassy-stm32/src/rcc/l0l1.rs
+++ b/embassy-stm32/src/rcc/l0l1.rs
@@ -156,23 +156,9 @@ pub(crate) unsafe fn init(config: Config) {
156 w.set_ppre2(config.apb2_pre); 156 w.set_ppre2(config.apb2_pre);
157 }); 157 });
158 158
159 let ahb_freq = sys_clk / config.ahb_pre; 159 let hclk1 = sys_clk / config.ahb_pre;
160 160 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre);
161 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { 161 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre);
162 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
163 pre => {
164 let freq = ahb_freq / pre;
165 (freq, freq * 2u32)
166 }
167 };
168
169 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
170 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
171 pre => {
172 let freq = ahb_freq / pre;
173 (freq, freq * 2u32)
174 }
175 };
176 162
177 #[cfg(crs)] 163 #[cfg(crs)]
178 if config.enable_hsi48 { 164 if config.enable_hsi48 {
@@ -209,11 +195,11 @@ pub(crate) unsafe fn init(config: Config) {
209 195
210 set_freqs(Clocks { 196 set_freqs(Clocks {
211 sys: sys_clk, 197 sys: sys_clk,
212 hclk1: ahb_freq, 198 hclk1,
213 pclk1: apb1_freq, 199 pclk1,
214 pclk2: apb2_freq, 200 pclk2,
215 pclk1_tim: apb1_tim_freq, 201 pclk1_tim,
216 pclk2_tim: apb2_tim_freq, 202 pclk2_tim,
217 rtc, 203 rtc,
218 }); 204 });
219} 205}
diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs
index 50128d389..2f89f6821 100644
--- a/embassy-stm32/src/rcc/l4l5.rs
+++ b/embassy-stm32/src/rcc/l4l5.rs
@@ -235,7 +235,7 @@ pub(crate) unsafe fn init(config: Config) {
235 235
236 // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs. 236 // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs.
237 #[cfg(all(stm32l4, not(rcc_l4plus)))] 237 #[cfg(all(stm32l4, not(rcc_l4plus)))]
238 match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) { 238 match super::util::get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) {
239 Err(()) => panic!("Source must be equal across all enabled PLLs."), 239 Err(()) => panic!("Source must be equal across all enabled PLLs."),
240 Ok(None) => {} 240 Ok(None) => {}
241 Ok(Some((source, prediv))) => RCC.pllcfgr().write(|w| { 241 Ok(Some((source, prediv))) => RCC.pllcfgr().write(|w| {
@@ -246,7 +246,7 @@ pub(crate) unsafe fn init(config: Config) {
246 246
247 // L4+, WL has shared PLLSRC, check it's equal in all PLLs. 247 // L4+, WL has shared PLLSRC, check it's equal in all PLLs.
248 #[cfg(any(rcc_l4plus, stm32wl))] 248 #[cfg(any(rcc_l4plus, stm32wl))]
249 match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { 249 match super::util::get_equal(_plls.into_iter().flatten().map(|p| p.source)) {
250 Err(()) => panic!("Source must be equal across all enabled PLLs."), 250 Err(()) => panic!("Source must be equal across all enabled PLLs."),
251 Ok(None) => {} 251 Ok(None) => {}
252 Ok(Some(source)) => RCC.pllcfgr().write(|w| { 252 Ok(Some(source)) => RCC.pllcfgr().write(|w| {
@@ -265,7 +265,7 @@ pub(crate) unsafe fn init(config: Config) {
265 ClockSrc::HSE => hse.unwrap(), 265 ClockSrc::HSE => hse.unwrap(),
266 ClockSrc::HSI => hsi.unwrap(), 266 ClockSrc::HSI => hsi.unwrap(),
267 ClockSrc::MSI => msi.unwrap(), 267 ClockSrc::MSI => msi.unwrap(),
268 ClockSrc::PLL1_R => pll._r.unwrap(), 268 ClockSrc::PLL1_R => pll.r.unwrap(),
269 }; 269 };
270 270
271 #[cfg(stm32l4)] 271 #[cfg(stm32l4)]
@@ -276,8 +276,8 @@ pub(crate) unsafe fn init(config: Config) {
276 let _clk48 = match config.clk48_src { 276 let _clk48 = match config.clk48_src {
277 Clk48Src::HSI48 => hsi48, 277 Clk48Src::HSI48 => hsi48,
278 Clk48Src::MSI => msi, 278 Clk48Src::MSI => msi,
279 Clk48Src::PLLSAI1_Q => pllsai1._q, 279 Clk48Src::PLLSAI1_Q => pllsai1.q,
280 Clk48Src::PLL1_Q => pll._q, 280 Clk48Src::PLL1_Q => pll.q,
281 }; 281 };
282 282
283 #[cfg(rcc_l4plus)] 283 #[cfg(rcc_l4plus)]
@@ -285,32 +285,21 @@ pub(crate) unsafe fn init(config: Config) {
285 #[cfg(all(stm32l4, not(rcc_l4plus)))] 285 #[cfg(all(stm32l4, not(rcc_l4plus)))]
286 assert!(sys_clk.0 <= 80_000_000); 286 assert!(sys_clk.0 <= 80_000_000);
287 287
288 let ahb_freq = sys_clk / config.ahb_pre; 288 let hclk1 = sys_clk / config.ahb_pre;
289 289 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre);
290 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { 290 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre);
291 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 291 #[cfg(not(any(stm32wl5x, stm32wb)))]
292 pre => { 292 let hclk2 = hclk1;
293 let freq = ahb_freq / pre;
294 (freq, freq * 2u32)
295 }
296 };
297
298 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
299 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
300 pre => {
301 let freq = ahb_freq / pre;
302 (freq, freq * 2u32)
303 }
304 };
305
306 #[cfg(any(stm32wl5x, stm32wb))] 293 #[cfg(any(stm32wl5x, stm32wb))]
307 let _ahb2_freq = sys_clk / config.core2_ahb_pre; 294 let hclk2 = sys_clk / config.core2_ahb_pre;
295 #[cfg(not(any(stm32wl, stm32wb)))]
296 let hclk3 = hclk1;
308 #[cfg(any(stm32wl, stm32wb))] 297 #[cfg(any(stm32wl, stm32wb))]
309 let ahb3_freq = sys_clk / config.shared_ahb_pre; 298 let hclk3 = sys_clk / config.shared_ahb_pre;
310 299
311 // Set flash wait states 300 // Set flash wait states
312 #[cfg(stm32l4)] 301 #[cfg(stm32l4)]
313 let latency = match sys_clk.0 { 302 let latency = match hclk1.0 {
314 0..=16_000_000 => 0, 303 0..=16_000_000 => 0,
315 0..=32_000_000 => 1, 304 0..=32_000_000 => 1,
316 0..=48_000_000 => 2, 305 0..=48_000_000 => 2,
@@ -318,7 +307,7 @@ pub(crate) unsafe fn init(config: Config) {
318 _ => 4, 307 _ => 4,
319 }; 308 };
320 #[cfg(stm32l5)] 309 #[cfg(stm32l5)]
321 let latency = match sys_clk.0 { 310 let latency = match hclk1.0 {
322 // VCORE Range 0 (performance), others TODO 311 // VCORE Range 0 (performance), others TODO
323 0..=20_000_000 => 0, 312 0..=20_000_000 => 0,
324 0..=40_000_000 => 1, 313 0..=40_000_000 => 1,
@@ -328,14 +317,14 @@ pub(crate) unsafe fn init(config: Config) {
328 _ => 5, 317 _ => 5,
329 }; 318 };
330 #[cfg(stm32wl)] 319 #[cfg(stm32wl)]
331 let latency = match ahb3_freq.0 { 320 let latency = match hclk3.0 {
332 // VOS RANGE1, others TODO. 321 // VOS RANGE1, others TODO.
333 ..=18_000_000 => 0, 322 ..=18_000_000 => 0,
334 ..=36_000_000 => 1, 323 ..=36_000_000 => 1,
335 _ => 2, 324 _ => 2,
336 }; 325 };
337 #[cfg(stm32wb)] 326 #[cfg(stm32wb)]
338 let latency = match ahb3_freq.0 { 327 let latency = match hclk3.0 {
339 // VOS RANGE1, others TODO. 328 // VOS RANGE1, others TODO.
340 ..=18_000_000 => 0, 329 ..=18_000_000 => 0,
341 ..=36_000_000 => 1, 330 ..=36_000_000 => 1,
@@ -369,18 +358,15 @@ pub(crate) unsafe fn init(config: Config) {
369 358
370 set_freqs(Clocks { 359 set_freqs(Clocks {
371 sys: sys_clk, 360 sys: sys_clk,
372 hclk1: ahb_freq, 361 hclk1,
373 hclk2: ahb_freq, 362 hclk2,
374 #[cfg(not(stm32wl))] 363 hclk3,
375 hclk3: ahb_freq, 364 pclk1,
376 pclk1: apb1_freq, 365 pclk2,
377 pclk2: apb2_freq, 366 pclk1_tim,
378 pclk1_tim: apb1_tim_freq, 367 pclk2_tim,
379 pclk2_tim: apb2_tim_freq,
380 #[cfg(stm32wl)]
381 hclk3: ahb3_freq,
382 #[cfg(stm32wl)] 368 #[cfg(stm32wl)]
383 pclk3: ahb3_freq, 369 pclk3: hclk3,
384 #[cfg(rcc_l4)] 370 #[cfg(rcc_l4)]
385 hsi: None, 371 hsi: None,
386 #[cfg(rcc_l4)] 372 #[cfg(rcc_l4)]
@@ -419,26 +405,18 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz {
419 } 405 }
420} 406}
421 407
422#[allow(unused)]
423fn get_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> Result<Option<T>, ()> {
424 let Some(x) = iter.next() else { return Ok(None) };
425 if !iter.all(|y| y == x) {
426 return Err(());
427 }
428 return Ok(Some(x));
429}
430
431struct PllInput { 408struct PllInput {
432 hsi: Option<Hertz>, 409 hsi: Option<Hertz>,
433 hse: Option<Hertz>, 410 hse: Option<Hertz>,
434 msi: Option<Hertz>, 411 msi: Option<Hertz>,
435} 412}
436 413
414#[allow(unused)]
437#[derive(Default)] 415#[derive(Default)]
438struct PllOutput { 416struct PllOutput {
439 _p: Option<Hertz>, 417 p: Option<Hertz>,
440 _q: Option<Hertz>, 418 q: Option<Hertz>,
441 _r: Option<Hertz>, 419 r: Option<Hertz>,
442} 420}
443 421
444#[derive(PartialEq, Eq, Clone, Copy)] 422#[derive(PartialEq, Eq, Clone, Copy)]
@@ -450,29 +428,33 @@ enum PllInstance {
450 Pllsai2, 428 Pllsai2,
451} 429}
452 430
453fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> PllOutput { 431fn pll_enable(instance: PllInstance, enabled: bool) {
454 // Disable PLL
455 match instance { 432 match instance {
456 PllInstance::Pll => { 433 PllInstance::Pll => {
457 RCC.cr().modify(|w| w.set_pllon(false)); 434 RCC.cr().modify(|w| w.set_pllon(enabled));
458 while RCC.cr().read().pllrdy() {} 435 while RCC.cr().read().pllrdy() != enabled {}
459 } 436 }
460 #[cfg(any(stm32l4, stm32l5, stm32wb))] 437 #[cfg(any(stm32l4, stm32l5, stm32wb))]
461 PllInstance::Pllsai1 => { 438 PllInstance::Pllsai1 => {
462 RCC.cr().modify(|w| w.set_pllsai1on(false)); 439 RCC.cr().modify(|w| w.set_pllsai1on(enabled));
463 while RCC.cr().read().pllsai1rdy() {} 440 while RCC.cr().read().pllsai1rdy() != enabled {}
464 } 441 }
465 #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] 442 #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
466 PllInstance::Pllsai2 => { 443 PllInstance::Pllsai2 => {
467 RCC.cr().modify(|w| w.set_pllsai2on(false)); 444 RCC.cr().modify(|w| w.set_pllsai2on(enabled));
468 while RCC.cr().read().pllsai2rdy() {} 445 while RCC.cr().read().pllsai2rdy() != enabled {}
469 } 446 }
470 } 447 }
448}
449
450fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> PllOutput {
451 // Disable PLL
452 pll_enable(instance, false);
471 453
472 let Some(pll) = config else { return PllOutput::default() }; 454 let Some(pll) = config else { return PllOutput::default() };
473 455
474 let pll_src = match pll.source { 456 let pll_src = match pll.source {
475 PLLSource::DISABLE => panic!("must not select PLL source as NONE"), 457 PLLSource::DISABLE => panic!("must not select PLL source as DISABLE"),
476 PLLSource::HSE => input.hse, 458 PLLSource::HSE => input.hse,
477 PLLSource::HSI => input.hsi, 459 PLLSource::HSI => input.hsi,
478 PLLSource::MSI => input.msi, 460 PLLSource::MSI => input.msi,
@@ -535,22 +517,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
535 } 517 }
536 518
537 // Enable PLL 519 // Enable PLL
538 match instance { 520 pll_enable(instance, true);
539 PllInstance::Pll => {
540 RCC.cr().modify(|w| w.set_pllon(true));
541 while !RCC.cr().read().pllrdy() {}
542 }
543 #[cfg(any(stm32l4, stm32l5, stm32wb))]
544 PllInstance::Pllsai1 => {
545 RCC.cr().modify(|w| w.set_pllsai1on(true));
546 while !RCC.cr().read().pllsai1rdy() {}
547 }
548 #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
549 PllInstance::Pllsai2 => {
550 RCC.cr().modify(|w| w.set_pllsai2on(true));
551 while !RCC.cr().read().pllsai2rdy() {}
552 }
553 }
554 521
555 PllOutput { _p: p, _q: q, _r: r } 522 PllOutput { p, q, r }
556} 523}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 4f3d5b98b..8cf2d6ab0 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -246,3 +246,33 @@ pub(crate) mod sealed {
246} 246}
247 247
248pub trait RccPeripheral: sealed::RccPeripheral + 'static {} 248pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
249
250#[allow(unused)]
251mod util {
252 use crate::time::Hertz;
253
254 pub fn calc_pclk<D>(hclk: Hertz, ppre: D) -> (Hertz, Hertz)
255 where
256 Hertz: core::ops::Div<D, Output = Hertz>,
257 {
258 let pclk = hclk / ppre;
259 let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 };
260 (pclk, pclk_tim)
261 }
262
263 pub fn all_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> bool {
264 let Some(x) = iter.next() else { return true };
265 if !iter.all(|y| y == x) {
266 return false;
267 }
268 true
269 }
270
271 pub fn get_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> Result<Option<T>, ()> {
272 let Some(x) = iter.next() else { return Ok(None) };
273 if !iter.all(|y| y == x) {
274 return Err(());
275 }
276 Ok(Some(x))
277 }
278}
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs
index 6e40f0ac0..5bec9d447 100644
--- a/examples/stm32h5/src/bin/eth.rs
+++ b/examples/stm32h5/src/bin/eth.rs
@@ -43,7 +43,7 @@ async fn main(spawner: Spawner) -> ! {
43 mode: HseMode::BypassDigital, 43 mode: HseMode::BypassDigital,
44 }); 44 });
45 config.rcc.pll1 = Some(Pll { 45 config.rcc.pll1 = Some(Pll {
46 source: PllSource::Hse, 46 source: PllSource::HSE,
47 prediv: PllPreDiv::DIV2, 47 prediv: PllPreDiv::DIV2,
48 mul: PllMul::MUL125, 48 mul: PllMul::MUL125,
49 divp: Some(PllDiv::DIV2), 49 divp: Some(PllDiv::DIV2),
@@ -54,7 +54,7 @@ async fn main(spawner: Spawner) -> ! {
54 config.rcc.apb1_pre = APBPrescaler::DIV1; 54 config.rcc.apb1_pre = APBPrescaler::DIV1;
55 config.rcc.apb2_pre = APBPrescaler::DIV1; 55 config.rcc.apb2_pre = APBPrescaler::DIV1;
56 config.rcc.apb3_pre = APBPrescaler::DIV1; 56 config.rcc.apb3_pre = APBPrescaler::DIV1;
57 config.rcc.sys = Sysclk::Pll1P; 57 config.rcc.sys = Sysclk::PLL1_P;
58 config.rcc.voltage_scale = VoltageScale::Scale0; 58 config.rcc.voltage_scale = VoltageScale::Scale0;
59 let p = embassy_stm32::init(config); 59 let p = embassy_stm32::init(config);
60 info!("Hello World!"); 60 info!("Hello World!");
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs
index 3b3c38e17..735826a69 100644
--- a/examples/stm32h5/src/bin/usb_serial.rs
+++ b/examples/stm32h5/src/bin/usb_serial.rs
@@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) {
30 mode: HseMode::BypassDigital, 30 mode: HseMode::BypassDigital,
31 }); 31 });
32 config.rcc.pll1 = Some(Pll { 32 config.rcc.pll1 = Some(Pll {
33 source: PllSource::Hse, 33 source: PllSource::HSE,
34 prediv: PllPreDiv::DIV2, 34 prediv: PllPreDiv::DIV2,
35 mul: PllMul::MUL125, 35 mul: PllMul::MUL125,
36 divp: Some(PllDiv::DIV2), // 250mhz 36 divp: Some(PllDiv::DIV2), // 250mhz
@@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) {
41 config.rcc.apb1_pre = APBPrescaler::DIV4; 41 config.rcc.apb1_pre = APBPrescaler::DIV4;
42 config.rcc.apb2_pre = APBPrescaler::DIV2; 42 config.rcc.apb2_pre = APBPrescaler::DIV2;
43 config.rcc.apb3_pre = APBPrescaler::DIV4; 43 config.rcc.apb3_pre = APBPrescaler::DIV4;
44 config.rcc.sys = Sysclk::Pll1P; 44 config.rcc.sys = Sysclk::PLL1_P;
45 config.rcc.voltage_scale = VoltageScale::Scale0; 45 config.rcc.voltage_scale = VoltageScale::Scale0;
46 let p = embassy_stm32::init(config); 46 let p = embassy_stm32::init(config);
47 47
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index 4a358a35f..e367827e9 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -14,10 +14,10 @@ async fn main(_spawner: Spawner) {
14 let mut config = Config::default(); 14 let mut config = Config::default();
15 { 15 {
16 use embassy_stm32::rcc::*; 16 use embassy_stm32::rcc::*;
17 config.rcc.hsi = Some(Hsi::Mhz64); 17 config.rcc.hsi = Some(HSIPrescaler::DIV1);
18 config.rcc.csi = true; 18 config.rcc.csi = true;
19 config.rcc.pll_src = PllSource::Hsi;
20 config.rcc.pll1 = Some(Pll { 19 config.rcc.pll1 = Some(Pll {
20 source: PllSource::HSI,
21 prediv: PllPreDiv::DIV4, 21 prediv: PllPreDiv::DIV4,
22 mul: PllMul::MUL50, 22 mul: PllMul::MUL50,
23 divp: Some(PllDiv::DIV2), 23 divp: Some(PllDiv::DIV2),
@@ -25,13 +25,14 @@ async fn main(_spawner: Spawner) {
25 divr: None, 25 divr: None,
26 }); 26 });
27 config.rcc.pll2 = Some(Pll { 27 config.rcc.pll2 = Some(Pll {
28 source: PllSource::HSI,
28 prediv: PllPreDiv::DIV4, 29 prediv: PllPreDiv::DIV4,
29 mul: PllMul::MUL50, 30 mul: PllMul::MUL50,
30 divp: Some(PllDiv::DIV8), // 100mhz 31 divp: Some(PllDiv::DIV8), // 100mhz
31 divq: None, 32 divq: None,
32 divr: None, 33 divr: None,
33 }); 34 });
34 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 35 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
35 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 36 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
36 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 37 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
37 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 38 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs
index 8195430b2..23ece1c38 100644
--- a/examples/stm32h7/src/bin/camera.rs
+++ b/examples/stm32h7/src/bin/camera.rs
@@ -28,17 +28,17 @@ async fn main(_spawner: Spawner) {
28 let mut config = Config::default(); 28 let mut config = Config::default();
29 { 29 {
30 use embassy_stm32::rcc::*; 30 use embassy_stm32::rcc::*;
31 config.rcc.hsi = Some(Hsi::Mhz64); 31 config.rcc.hsi = Some(HSIPrescaler::DIV1);
32 config.rcc.csi = true; 32 config.rcc.csi = true;
33 config.rcc.pll_src = PllSource::Hsi;
34 config.rcc.pll1 = Some(Pll { 33 config.rcc.pll1 = Some(Pll {
34 source: PllSource::HSI,
35 prediv: PllPreDiv::DIV4, 35 prediv: PllPreDiv::DIV4,
36 mul: PllMul::MUL50, 36 mul: PllMul::MUL50,
37 divp: Some(PllDiv::DIV2), 37 divp: Some(PllDiv::DIV2),
38 divq: Some(PllDiv::DIV8), // 100mhz 38 divq: Some(PllDiv::DIV8), // 100mhz
39 divr: None, 39 divr: None,
40 }); 40 });
41 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 41 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
42 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 42 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
43 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 43 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
44 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 44 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index 821221897..35fd6550f 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -16,10 +16,10 @@ fn main() -> ! {
16 let mut config = Config::default(); 16 let mut config = Config::default();
17 { 17 {
18 use embassy_stm32::rcc::*; 18 use embassy_stm32::rcc::*;
19 config.rcc.hsi = Some(Hsi::Mhz64); 19 config.rcc.hsi = Some(HSIPrescaler::DIV1);
20 config.rcc.csi = true; 20 config.rcc.csi = true;
21 config.rcc.pll_src = PllSource::Hsi;
22 config.rcc.pll1 = Some(Pll { 21 config.rcc.pll1 = Some(Pll {
22 source: PllSource::HSI,
23 prediv: PllPreDiv::DIV4, 23 prediv: PllPreDiv::DIV4,
24 mul: PllMul::MUL50, 24 mul: PllMul::MUL50,
25 divp: Some(PllDiv::DIV2), 25 divp: Some(PllDiv::DIV2),
@@ -27,13 +27,14 @@ fn main() -> ! {
27 divr: None, 27 divr: None,
28 }); 28 });
29 config.rcc.pll2 = Some(Pll { 29 config.rcc.pll2 = Some(Pll {
30 source: PllSource::HSI,
30 prediv: PllPreDiv::DIV4, 31 prediv: PllPreDiv::DIV4,
31 mul: PllMul::MUL50, 32 mul: PllMul::MUL50,
32 divp: Some(PllDiv::DIV8), // 100mhz 33 divp: Some(PllDiv::DIV8), // 100mhz
33 divq: None, 34 divq: None,
34 divr: None, 35 divr: None,
35 }); 36 });
36 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 37 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
37 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 38 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
38 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 39 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
39 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 40 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
index 334986a05..e141fc484 100644
--- a/examples/stm32h7/src/bin/dac_dma.rs
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -24,10 +24,10 @@ async fn main(spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 24 let mut config = embassy_stm32::Config::default();
25 { 25 {
26 use embassy_stm32::rcc::*; 26 use embassy_stm32::rcc::*;
27 config.rcc.hsi = Some(Hsi::Mhz64); 27 config.rcc.hsi = Some(HSIPrescaler::DIV1);
28 config.rcc.csi = true; 28 config.rcc.csi = true;
29 config.rcc.pll_src = PllSource::Hsi;
30 config.rcc.pll1 = Some(Pll { 29 config.rcc.pll1 = Some(Pll {
30 source: PllSource::HSI,
31 prediv: PllPreDiv::DIV4, 31 prediv: PllPreDiv::DIV4,
32 mul: PllMul::MUL50, 32 mul: PllMul::MUL50,
33 divp: Some(PllDiv::DIV2), 33 divp: Some(PllDiv::DIV2),
@@ -35,13 +35,14 @@ async fn main(spawner: Spawner) {
35 divr: None, 35 divr: None,
36 }); 36 });
37 config.rcc.pll2 = Some(Pll { 37 config.rcc.pll2 = Some(Pll {
38 source: PllSource::HSI,
38 prediv: PllPreDiv::DIV4, 39 prediv: PllPreDiv::DIV4,
39 mul: PllMul::MUL50, 40 mul: PllMul::MUL50,
40 divp: Some(PllDiv::DIV8), // 100mhz 41 divp: Some(PllDiv::DIV8), // 100mhz
41 divq: None, 42 divq: None,
42 divr: None, 43 divr: None,
43 }); 44 });
44 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 45 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
45 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 46 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
46 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 47 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
47 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 48 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 81d9c7347..e37d8797b 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -34,18 +34,18 @@ async fn main(spawner: Spawner) -> ! {
34 let mut config = Config::default(); 34 let mut config = Config::default();
35 { 35 {
36 use embassy_stm32::rcc::*; 36 use embassy_stm32::rcc::*;
37 config.rcc.hsi = Some(Hsi::Mhz64); 37 config.rcc.hsi = Some(HSIPrescaler::DIV1);
38 config.rcc.csi = true; 38 config.rcc.csi = true;
39 config.rcc.hsi48 = true; // needed for RNG 39 config.rcc.hsi48 = true; // needed for RNG
40 config.rcc.pll_src = PllSource::Hsi;
41 config.rcc.pll1 = Some(Pll { 40 config.rcc.pll1 = Some(Pll {
41 source: PllSource::HSI,
42 prediv: PllPreDiv::DIV4, 42 prediv: PllPreDiv::DIV4,
43 mul: PllMul::MUL50, 43 mul: PllMul::MUL50,
44 divp: Some(PllDiv::DIV2), 44 divp: Some(PllDiv::DIV2),
45 divq: None, 45 divq: None,
46 divr: None, 46 divr: None,
47 }); 47 });
48 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 48 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
49 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 49 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
50 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 50 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
51 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 51 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 338137069..88df53f01 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -35,18 +35,18 @@ async fn main(spawner: Spawner) -> ! {
35 let mut config = Config::default(); 35 let mut config = Config::default();
36 { 36 {
37 use embassy_stm32::rcc::*; 37 use embassy_stm32::rcc::*;
38 config.rcc.hsi = Some(Hsi::Mhz64); 38 config.rcc.hsi = Some(HSIPrescaler::DIV1);
39 config.rcc.csi = true; 39 config.rcc.csi = true;
40 config.rcc.hsi48 = true; // needed for RNG 40 config.rcc.hsi48 = true; // needed for RNG
41 config.rcc.pll_src = PllSource::Hsi;
42 config.rcc.pll1 = Some(Pll { 41 config.rcc.pll1 = Some(Pll {
42 source: PllSource::HSI,
43 prediv: PllPreDiv::DIV4, 43 prediv: PllPreDiv::DIV4,
44 mul: PllMul::MUL50, 44 mul: PllMul::MUL50,
45 divp: Some(PllDiv::DIV2), 45 divp: Some(PllDiv::DIV2),
46 divq: None, 46 divq: None,
47 divr: None, 47 divr: None,
48 }); 48 });
49 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 49 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
50 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 50 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
51 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 51 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
52 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 52 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs
index cffd47093..54e2c3629 100644
--- a/examples/stm32h7/src/bin/fmc.rs
+++ b/examples/stm32h7/src/bin/fmc.rs
@@ -14,17 +14,17 @@ async fn main(_spawner: Spawner) {
14 let mut config = Config::default(); 14 let mut config = Config::default();
15 { 15 {
16 use embassy_stm32::rcc::*; 16 use embassy_stm32::rcc::*;
17 config.rcc.hsi = Some(Hsi::Mhz64); 17 config.rcc.hsi = Some(HSIPrescaler::DIV1);
18 config.rcc.csi = true; 18 config.rcc.csi = true;
19 config.rcc.pll_src = PllSource::Hsi;
20 config.rcc.pll1 = Some(Pll { 19 config.rcc.pll1 = Some(Pll {
20 source: PllSource::HSI,
21 prediv: PllPreDiv::DIV4, 21 prediv: PllPreDiv::DIV4,
22 mul: PllMul::MUL50, 22 mul: PllMul::MUL50,
23 divp: Some(PllDiv::DIV2), 23 divp: Some(PllDiv::DIV2),
24 divq: Some(PllDiv::DIV8), // 100mhz 24 divq: Some(PllDiv::DIV8), // 100mhz
25 divr: None, 25 divr: None,
26 }); 26 });
27 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 27 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
28 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 28 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
29 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 29 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
30 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 30 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index 0355ac073..e4bac8a5a 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -17,18 +17,18 @@ async fn main(_spawner: Spawner) {
17 let mut config = Config::default(); 17 let mut config = Config::default();
18 { 18 {
19 use embassy_stm32::rcc::*; 19 use embassy_stm32::rcc::*;
20 config.rcc.hsi = Some(Hsi::Mhz64); 20 config.rcc.hsi = Some(HSIPrescaler::DIV1);
21 config.rcc.csi = true; 21 config.rcc.csi = true;
22 config.rcc.hsi48 = true; // needed for RNG 22 config.rcc.hsi48 = true; // needed for RNG
23 config.rcc.pll_src = PllSource::Hsi;
24 config.rcc.pll1 = Some(Pll { 23 config.rcc.pll1 = Some(Pll {
24 source: PllSource::HSI,
25 prediv: PllPreDiv::DIV4, 25 prediv: PllPreDiv::DIV4,
26 mul: PllMul::MUL50, 26 mul: PllMul::MUL50,
27 divp: Some(PllDiv::DIV2), 27 divp: Some(PllDiv::DIV2),
28 divq: Some(PllDiv::DIV8), // 100mhz 28 divq: Some(PllDiv::DIV8), // 100mhz
29 divr: None, 29 divr: None,
30 }); 30 });
31 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 31 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
32 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 32 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
33 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 33 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
34 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 34 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs
index 973a10cdd..c55d780a0 100644
--- a/examples/stm32h7/src/bin/pwm.rs
+++ b/examples/stm32h7/src/bin/pwm.rs
@@ -17,17 +17,17 @@ async fn main(_spawner: Spawner) {
17 let mut config = Config::default(); 17 let mut config = Config::default();
18 { 18 {
19 use embassy_stm32::rcc::*; 19 use embassy_stm32::rcc::*;
20 config.rcc.hsi = Some(Hsi::Mhz64); 20 config.rcc.hsi = Some(HSIPrescaler::DIV1);
21 config.rcc.csi = true; 21 config.rcc.csi = true;
22 config.rcc.pll_src = PllSource::Hsi;
23 config.rcc.pll1 = Some(Pll { 22 config.rcc.pll1 = Some(Pll {
23 source: PllSource::HSI,
24 prediv: PllPreDiv::DIV4, 24 prediv: PllPreDiv::DIV4,
25 mul: PllMul::MUL50, 25 mul: PllMul::MUL50,
26 divp: Some(PllDiv::DIV2), 26 divp: Some(PllDiv::DIV2),
27 divq: None, 27 divq: None,
28 divr: None, 28 divr: None,
29 }); 29 });
30 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 30 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
31 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 31 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
32 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 32 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
33 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 33 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index ecb8d6542..be968ff77 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -18,17 +18,17 @@ async fn main(_spawner: Spawner) -> ! {
18 let mut config = Config::default(); 18 let mut config = Config::default();
19 { 19 {
20 use embassy_stm32::rcc::*; 20 use embassy_stm32::rcc::*;
21 config.rcc.hsi = Some(Hsi::Mhz64); 21 config.rcc.hsi = Some(HSIPrescaler::DIV1);
22 config.rcc.csi = true; 22 config.rcc.csi = true;
23 config.rcc.pll_src = PllSource::Hsi;
24 config.rcc.pll1 = Some(Pll { 23 config.rcc.pll1 = Some(Pll {
24 source: PllSource::HSI,
25 prediv: PllPreDiv::DIV4, 25 prediv: PllPreDiv::DIV4,
26 mul: PllMul::MUL50, 26 mul: PllMul::MUL50,
27 divp: Some(PllDiv::DIV2), 27 divp: Some(PllDiv::DIV2),
28 divq: Some(PllDiv::DIV4), // default clock chosen by SDMMCSEL. 200 Mhz 28 divq: Some(PllDiv::DIV4), // default clock chosen by SDMMCSEL. 200 Mhz
29 divr: None, 29 divr: None,
30 }); 30 });
31 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 31 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
32 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 32 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
33 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 33 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
34 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 34 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs
index f128d4a56..a8db0ff77 100644
--- a/examples/stm32h7/src/bin/spi.rs
+++ b/examples/stm32h7/src/bin/spi.rs
@@ -40,17 +40,17 @@ fn main() -> ! {
40 let mut config = Config::default(); 40 let mut config = Config::default();
41 { 41 {
42 use embassy_stm32::rcc::*; 42 use embassy_stm32::rcc::*;
43 config.rcc.hsi = Some(Hsi::Mhz64); 43 config.rcc.hsi = Some(HSIPrescaler::DIV1);
44 config.rcc.csi = true; 44 config.rcc.csi = true;
45 config.rcc.pll_src = PllSource::Hsi;
46 config.rcc.pll1 = Some(Pll { 45 config.rcc.pll1 = Some(Pll {
46 source: PllSource::HSI,
47 prediv: PllPreDiv::DIV4, 47 prediv: PllPreDiv::DIV4,
48 mul: PllMul::MUL50, 48 mul: PllMul::MUL50,
49 divp: Some(PllDiv::DIV2), 49 divp: Some(PllDiv::DIV2),
50 divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. 50 divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz.
51 divr: None, 51 divr: None,
52 }); 52 });
53 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 53 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
54 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 54 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
55 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 55 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
56 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 56 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index d4c0bcdbd..561052e48 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -36,17 +36,17 @@ fn main() -> ! {
36 let mut config = Config::default(); 36 let mut config = Config::default();
37 { 37 {
38 use embassy_stm32::rcc::*; 38 use embassy_stm32::rcc::*;
39 config.rcc.hsi = Some(Hsi::Mhz64); 39 config.rcc.hsi = Some(HSIPrescaler::DIV1);
40 config.rcc.csi = true; 40 config.rcc.csi = true;
41 config.rcc.pll_src = PllSource::Hsi;
42 config.rcc.pll1 = Some(Pll { 41 config.rcc.pll1 = Some(Pll {
42 source: PllSource::HSI,
43 prediv: PllPreDiv::DIV4, 43 prediv: PllPreDiv::DIV4,
44 mul: PllMul::MUL50, 44 mul: PllMul::MUL50,
45 divp: Some(PllDiv::DIV2), 45 divp: Some(PllDiv::DIV2),
46 divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. 46 divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz.
47 divr: None, 47 divr: None,
48 }); 48 });
49 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 49 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
50 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 50 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
51 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 51 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
52 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 52 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs
index c1e5144be..19d77183b 100644
--- a/examples/stm32h7/src/bin/usb_serial.rs
+++ b/examples/stm32h7/src/bin/usb_serial.rs
@@ -23,18 +23,18 @@ async fn main(_spawner: Spawner) {
23 let mut config = Config::default(); 23 let mut config = Config::default();
24 { 24 {
25 use embassy_stm32::rcc::*; 25 use embassy_stm32::rcc::*;
26 config.rcc.hsi = Some(Hsi::Mhz64); 26 config.rcc.hsi = Some(HSIPrescaler::DIV1);
27 config.rcc.csi = true; 27 config.rcc.csi = true;
28 config.rcc.hsi48 = true; // needed for USB 28 config.rcc.hsi48 = true; // needed for USB
29 config.rcc.pll_src = PllSource::Hsi;
30 config.rcc.pll1 = Some(Pll { 29 config.rcc.pll1 = Some(Pll {
30 source: PllSource::HSI,
31 prediv: PllPreDiv::DIV4, 31 prediv: PllPreDiv::DIV4,
32 mul: PllMul::MUL50, 32 mul: PllMul::MUL50,
33 divp: Some(PllDiv::DIV2), 33 divp: Some(PllDiv::DIV2),
34 divq: None, 34 divq: None,
35 divr: None, 35 divr: None,
36 }); 36 });
37 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 37 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
38 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 38 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
39 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 39 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
40 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 40 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 4f51e4f6a..ff808281a 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -312,7 +312,7 @@ pub fn config() -> Config {
312 mode: HseMode::BypassDigital, 312 mode: HseMode::BypassDigital,
313 }); 313 });
314 config.rcc.pll1 = Some(Pll { 314 config.rcc.pll1 = Some(Pll {
315 source: PllSource::Hse, 315 source: PllSource::HSE,
316 prediv: PllPreDiv::DIV2, 316 prediv: PllPreDiv::DIV2,
317 mul: PllMul::MUL125, 317 mul: PllMul::MUL125,
318 divp: Some(PllDiv::DIV2), 318 divp: Some(PllDiv::DIV2),
@@ -323,18 +323,18 @@ pub fn config() -> Config {
323 config.rcc.apb1_pre = APBPrescaler::DIV1; 323 config.rcc.apb1_pre = APBPrescaler::DIV1;
324 config.rcc.apb2_pre = APBPrescaler::DIV1; 324 config.rcc.apb2_pre = APBPrescaler::DIV1;
325 config.rcc.apb3_pre = APBPrescaler::DIV1; 325 config.rcc.apb3_pre = APBPrescaler::DIV1;
326 config.rcc.sys = Sysclk::Pll1P; 326 config.rcc.sys = Sysclk::PLL1_P;
327 config.rcc.voltage_scale = VoltageScale::Scale0; 327 config.rcc.voltage_scale = VoltageScale::Scale0;
328 } 328 }
329 329
330 #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] 330 #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))]
331 { 331 {
332 use embassy_stm32::rcc::*; 332 use embassy_stm32::rcc::*;
333 config.rcc.hsi = Some(Hsi::Mhz64); 333 config.rcc.hsi = Some(HSIPrescaler::DIV1);
334 config.rcc.csi = true; 334 config.rcc.csi = true;
335 config.rcc.hsi48 = true; // needed for RNG 335 config.rcc.hsi48 = true; // needed for RNG
336 config.rcc.pll_src = PllSource::Hsi;
337 config.rcc.pll1 = Some(Pll { 336 config.rcc.pll1 = Some(Pll {
337 source: PllSource::HSI,
338 prediv: PllPreDiv::DIV4, 338 prediv: PllPreDiv::DIV4,
339 mul: PllMul::MUL50, 339 mul: PllMul::MUL50,
340 divp: Some(PllDiv::DIV2), 340 divp: Some(PllDiv::DIV2),
@@ -342,13 +342,14 @@ pub fn config() -> Config {
342 divr: None, 342 divr: None,
343 }); 343 });
344 config.rcc.pll2 = Some(Pll { 344 config.rcc.pll2 = Some(Pll {
345 source: PllSource::HSI,
345 prediv: PllPreDiv::DIV4, 346 prediv: PllPreDiv::DIV4,
346 mul: PllMul::MUL50, 347 mul: PllMul::MUL50,
347 divp: Some(PllDiv::DIV8), // 100mhz 348 divp: Some(PllDiv::DIV8), // 100mhz
348 divq: None, 349 divq: None,
349 divr: None, 350 divr: None,
350 }); 351 });
351 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz 352 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
352 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz 353 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
353 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz 354 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
354 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz 355 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
@@ -361,11 +362,11 @@ pub fn config() -> Config {
361 #[cfg(any(feature = "stm32h7a3zi"))] 362 #[cfg(any(feature = "stm32h7a3zi"))]
362 { 363 {
363 use embassy_stm32::rcc::*; 364 use embassy_stm32::rcc::*;
364 config.rcc.hsi = Some(Hsi::Mhz64); 365 config.rcc.hsi = Some(HSIPrescaler::DIV1);
365 config.rcc.csi = true; 366 config.rcc.csi = true;
366 config.rcc.hsi48 = true; // needed for RNG 367 config.rcc.hsi48 = true; // needed for RNG
367 config.rcc.pll_src = PllSource::Hsi;
368 config.rcc.pll1 = Some(Pll { 368 config.rcc.pll1 = Some(Pll {
369 source: PllSource::HSI,
369 prediv: PllPreDiv::DIV4, 370 prediv: PllPreDiv::DIV4,
370 mul: PllMul::MUL35, 371 mul: PllMul::MUL35,
371 divp: Some(PllDiv::DIV2), // 280 Mhz 372 divp: Some(PllDiv::DIV2), // 280 Mhz
@@ -373,13 +374,14 @@ pub fn config() -> Config {
373 divr: None, 374 divr: None,
374 }); 375 });
375 config.rcc.pll2 = Some(Pll { 376 config.rcc.pll2 = Some(Pll {
377 source: PllSource::HSI,
376 prediv: PllPreDiv::DIV4, 378 prediv: PllPreDiv::DIV4,
377 mul: PllMul::MUL35, 379 mul: PllMul::MUL35,
378 divp: Some(PllDiv::DIV8), // 70 Mhz 380 divp: Some(PllDiv::DIV8), // 70 Mhz
379 divq: None, 381 divq: None,
380 divr: None, 382 divr: None,
381 }); 383 });
382 config.rcc.sys = Sysclk::Pll1P; // 280 Mhz 384 config.rcc.sys = Sysclk::PLL1_P; // 280 Mhz
383 config.rcc.ahb_pre = AHBPrescaler::DIV1; // 280 Mhz 385 config.rcc.ahb_pre = AHBPrescaler::DIV1; // 280 Mhz
384 config.rcc.apb1_pre = APBPrescaler::DIV2; // 140 Mhz 386 config.rcc.apb1_pre = APBPrescaler::DIV2; // 140 Mhz
385 config.rcc.apb2_pre = APBPrescaler::DIV2; // 140 Mhz 387 config.rcc.apb2_pre = APBPrescaler::DIV2; // 140 Mhz