aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-11-13 01:08:27 +0000
committerGitHub <[email protected]>2023-11-13 01:08:27 +0000
commitac7134ed0d304282d2b10b1efff316426757fdab (patch)
tree69cd68e35968cf0a5da5000308e338bdbad3724a
parentf00e97a5f14b25d261eafba7cbc63b035c938996 (diff)
parentace52210802a18a551f506bc3ad163703e3f9efa (diff)
Merge pull request #2178 from embassy-rs/rcc-no-spaghetti
stm32/rcc: unify f2 into f4/f7.
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/rcc/f.rs (renamed from embassy-stm32/src/rcc/f4f7.rs)153
-rw-r--r--embassy-stm32/src/rcc/f2.rs320
-rw-r--r--embassy-stm32/src/rcc/mod.rs9
-rw-r--r--examples/stm32f2/src/bin/pll.rs55
-rw-r--r--examples/stm32f4/src/bin/eth.rs2
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs4
-rw-r--r--examples/stm32f4/src/bin/usb_ethernet.rs4
-rw-r--r--examples/stm32f4/src/bin/usb_raw.rs4
-rw-r--r--examples/stm32f4/src/bin/usb_serial.rs4
-rw-r--r--examples/stm32f7/src/bin/eth.rs2
-rw-r--r--examples/stm32f7/src/bin/sdmmc.rs4
-rw-r--r--examples/stm32f7/src/bin/usb_serial.rs4
-rw-r--r--tests/stm32/src/common.rs25
14 files changed, 182 insertions, 412 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 373172760..4b650cc88 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -58,7 +58,7 @@ rand_core = "0.6.3"
58sdio-host = "0.5.0" 58sdio-host = "0.5.0"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f" } 61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b" }
62vcell = "0.1.3" 62vcell = "0.1.3"
63bxcan = "0.7.0" 63bxcan = "0.7.0"
64nb = "1.0.0" 64nb = "1.0.0"
@@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
76[build-dependencies] 76[build-dependencies]
77proc-macro2 = "1.0.36" 77proc-macro2 = "1.0.36"
78quote = "1.0.15" 78quote = "1.0.15"
79stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f", default-features = false, features = ["metadata"]} 79stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b", default-features = false, features = ["metadata"]}
80 80
81 81
82[features] 82[features]
diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f.rs
index 9e8c639d0..36d9f178f 100644
--- a/embassy-stm32/src/rcc/f4f7.rs
+++ b/embassy-stm32/src/rcc/f.rs
@@ -1,9 +1,12 @@
1use crate::pac::pwr::vals::Vos; 1use stm32_metapac::flash::vals::Latency;
2
2pub use crate::pac::rcc::vals::{ 3pub use crate::pac::rcc::vals::{
3 Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp, Pllq, Pllr, Pllsrc as PllSource, 4 Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv,
4 Ppre as APBPrescaler, Sw as Sysclk, 5 Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk,
5}; 6};
6use crate::pac::{FLASH, PWR, RCC}; 7#[cfg(any(stm32f4, stm32f7))]
8use crate::pac::PWR;
9use crate::pac::{FLASH, RCC};
7use crate::rcc::{set_freqs, Clocks}; 10use crate::rcc::{set_freqs, Clocks};
8use crate::time::Hertz; 11use crate::time::Hertz;
9 12
@@ -49,11 +52,27 @@ pub struct Pll {
49 pub mul: PllMul, 52 pub mul: PllMul,
50 53
51 /// PLL P division factor. If None, PLL P output is disabled. 54 /// PLL P division factor. If None, PLL P output is disabled.
52 pub divp: Option<Pllp>, 55 pub divp: Option<PllPDiv>,
53 /// PLL Q division factor. If None, PLL Q output is disabled. 56 /// PLL Q division factor. If None, PLL Q output is disabled.
54 pub divq: Option<Pllq>, 57 pub divq: Option<PllQDiv>,
55 /// PLL R division factor. If None, PLL R output is disabled. 58 /// PLL R division factor. If None, PLL R output is disabled.
56 pub divr: Option<Pllr>, 59 pub divr: Option<PllRDiv>,
60}
61
62/// Voltage range of the power supply used.
63///
64/// Used to calculate flash waitstates. See
65/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency
66#[cfg(stm32f2)]
67pub enum VoltageScale {
68 /// 2.7 to 3.6 V
69 Range0,
70 /// 2.4 to 2.7 V
71 Range1,
72 /// 2.1 to 2.4 V
73 Range2,
74 /// 1.8 to 2.1 V
75 Range3,
57} 76}
58 77
59/// Configuration of the core clocks 78/// Configuration of the core clocks
@@ -66,7 +85,7 @@ pub struct Config {
66 pub pll_src: PllSource, 85 pub pll_src: PllSource,
67 86
68 pub pll: Option<Pll>, 87 pub pll: Option<Pll>,
69 #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] 88 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
70 pub plli2s: Option<Pll>, 89 pub plli2s: Option<Pll>,
71 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] 90 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
72 pub pllsai: Option<Pll>, 91 pub pllsai: Option<Pll>,
@@ -76,6 +95,9 @@ pub struct Config {
76 pub apb2_pre: APBPrescaler, 95 pub apb2_pre: APBPrescaler,
77 96
78 pub ls: super::LsConfig, 97 pub ls: super::LsConfig,
98
99 #[cfg(stm32f2)]
100 pub voltage: VoltageScale,
79} 101}
80 102
81impl Default for Config { 103impl Default for Config {
@@ -86,7 +108,7 @@ impl Default for Config {
86 sys: Sysclk::HSI, 108 sys: Sysclk::HSI,
87 pll_src: PllSource::HSI, 109 pll_src: PllSource::HSI,
88 pll: None, 110 pll: None,
89 #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] 111 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
90 plli2s: None, 112 plli2s: None,
91 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] 113 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
92 pllsai: None, 114 pllsai: None,
@@ -96,6 +118,9 @@ impl Default for Config {
96 apb2_pre: APBPrescaler::DIV1, 118 apb2_pre: APBPrescaler::DIV1,
97 119
98 ls: Default::default(), 120 ls: Default::default(),
121
122 #[cfg(stm32f2)]
123 voltage: VoltageScale::Range3,
99 } 124 }
100 } 125 }
101} 126}
@@ -103,14 +128,13 @@ impl Default for Config {
103pub(crate) unsafe fn init(config: Config) { 128pub(crate) unsafe fn init(config: Config) {
104 // set VOS to SCALE1, if use PLL 129 // set VOS to SCALE1, if use PLL
105 // TODO: check real clock speed before set VOS 130 // TODO: check real clock speed before set VOS
131 #[cfg(any(stm32f4, stm32f7))]
106 if config.pll.is_some() { 132 if config.pll.is_some() {
107 PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); 133 PWR.cr1().modify(|w| w.set_vos(crate::pac::pwr::vals::Vos::SCALE1));
108 } 134 }
109 135
110 // always enable overdrive for now. Make it configurable in the future. 136 // always enable overdrive for now. Make it configurable in the future.
111 #[cfg(not(any( 137 #[cfg(any(stm32f446, stm32f4x9, stm32f427, stm32f437, stm32f7))]
112 stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f405, stm32f407, stm32f415, stm32f417
113 )))]
114 { 138 {
115 PWR.cr1().modify(|w| w.set_oden(true)); 139 PWR.cr1().modify(|w| w.set_oden(true));
116 while !PWR.csr1().read().odrdy() {} 140 while !PWR.csr1().read().odrdy() {}
@@ -158,7 +182,7 @@ pub(crate) unsafe fn init(config: Config) {
158 source: config.pll_src, 182 source: config.pll_src,
159 }; 183 };
160 let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); 184 let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
161 #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] 185 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
162 let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); 186 let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input);
163 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] 187 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
164 let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); 188 let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input);
@@ -182,7 +206,48 @@ pub(crate) unsafe fn init(config: Config) {
182 206
183 let rtc = config.ls.init(); 207 let rtc = config.ls.init();
184 208
185 flash_setup(hclk); 209 #[cfg(stm32f2)]
210 let latency = match (config.voltage, hclk.0) {
211 (VoltageScale::Range3, ..=16_000_000) => Latency::WS0,
212 (VoltageScale::Range3, ..=32_000_000) => Latency::WS1,
213 (VoltageScale::Range3, ..=48_000_000) => Latency::WS2,
214 (VoltageScale::Range3, ..=64_000_000) => Latency::WS3,
215 (VoltageScale::Range3, ..=80_000_000) => Latency::WS4,
216 (VoltageScale::Range3, ..=96_000_000) => Latency::WS5,
217 (VoltageScale::Range3, ..=112_000_000) => Latency::WS6,
218 (VoltageScale::Range3, ..=120_000_000) => Latency::WS7,
219 (VoltageScale::Range2, ..=18_000_000) => Latency::WS0,
220 (VoltageScale::Range2, ..=36_000_000) => Latency::WS1,
221 (VoltageScale::Range2, ..=54_000_000) => Latency::WS2,
222 (VoltageScale::Range2, ..=72_000_000) => Latency::WS3,
223 (VoltageScale::Range2, ..=90_000_000) => Latency::WS4,
224 (VoltageScale::Range2, ..=108_000_000) => Latency::WS5,
225 (VoltageScale::Range2, ..=120_000_000) => Latency::WS6,
226 (VoltageScale::Range1, ..=24_000_000) => Latency::WS0,
227 (VoltageScale::Range1, ..=48_000_000) => Latency::WS1,
228 (VoltageScale::Range1, ..=72_000_000) => Latency::WS2,
229 (VoltageScale::Range1, ..=96_000_000) => Latency::WS3,
230 (VoltageScale::Range1, ..=120_000_000) => Latency::WS4,
231 (VoltageScale::Range0, ..=30_000_000) => Latency::WS0,
232 (VoltageScale::Range0, ..=60_000_000) => Latency::WS1,
233 (VoltageScale::Range0, ..=90_000_000) => Latency::WS2,
234 (VoltageScale::Range0, ..=120_000_000) => Latency::WS3,
235 _ => unreachable!(),
236 };
237
238 #[cfg(any(stm32f4, stm32f7))]
239 let latency = {
240 // Be conservative with voltage ranges
241 const FLASH_LATENCY_STEP: u32 = 30_000_000;
242
243 let latency = (hclk.0 - 1) / FLASH_LATENCY_STEP;
244 debug!("flash: latency={}", latency);
245
246 Latency::from_bits(latency as u8)
247 };
248
249 FLASH.acr().write(|w| w.set_latency(latency));
250 while FLASH.acr().read().latency() != latency {}
186 251
187 RCC.cfgr().modify(|w| { 252 RCC.cfgr().modify(|w| {
188 w.set_sw(config.sys); 253 w.set_sw(config.sys);
@@ -232,7 +297,7 @@ struct PllOutput {
232#[derive(PartialEq, Eq, Clone, Copy)] 297#[derive(PartialEq, Eq, Clone, Copy)]
233enum PllInstance { 298enum PllInstance {
234 Pll, 299 Pll,
235 #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] 300 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
236 Plli2s, 301 Plli2s,
237 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] 302 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
238 Pllsai, 303 Pllsai,
@@ -244,7 +309,7 @@ fn pll_enable(instance: PllInstance, enabled: bool) {
244 RCC.cr().modify(|w| w.set_pllon(enabled)); 309 RCC.cr().modify(|w| w.set_pllon(enabled));
245 while RCC.cr().read().pllrdy() != enabled {} 310 while RCC.cr().read().pllrdy() != enabled {}
246 } 311 }
247 #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] 312 #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
248 PllInstance::Plli2s => { 313 PllInstance::Plli2s => {
249 RCC.cr().modify(|w| w.set_plli2son(enabled)); 314 RCC.cr().modify(|w| w.set_plli2son(enabled));
250 while RCC.cr().read().plli2srdy() != enabled {} 315 while RCC.cr().read().plli2srdy() != enabled {}
@@ -275,6 +340,18 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
275 let vco_freq = in_freq * pll.mul; 340 let vco_freq = in_freq * pll.mul;
276 assert!(max::PLL_VCO.contains(&vco_freq)); 341 assert!(max::PLL_VCO.contains(&vco_freq));
277 342
343 // stm32f2 plls are like swiss cheese
344 #[cfg(stm32f2)]
345 match instance {
346 PllInstance::Pll => {
347 assert!(pll.divr.is_none());
348 }
349 PllInstance::Plli2s => {
350 assert!(pll.divp.is_none());
351 assert!(pll.divq.is_none());
352 }
353 }
354
278 let p = pll.divp.map(|div| vco_freq / div); 355 let p = pll.divp.map(|div| vco_freq / div);
279 let q = pll.divq.map(|div| vco_freq / div); 356 let q = pll.divq.map(|div| vco_freq / div);
280 let r = pll.divr.map(|div| vco_freq / div); 357 let r = pll.divr.map(|div| vco_freq / div);
@@ -288,6 +365,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
288 if let Some(divq) = pll.divq { 365 if let Some(divq) = pll.divq {
289 $w.set_pllq(divq); 366 $w.set_pllq(divq);
290 } 367 }
368 #[cfg(any(stm32f4, stm32f7))]
291 if let Some(divr) = pll.divr { 369 if let Some(divr) = pll.divr {
292 $w.set_pllr(divr); 370 $w.set_pllr(divr);
293 } 371 }
@@ -304,6 +382,12 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
304 PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { 382 PllInstance::Plli2s => RCC.plli2scfgr().write(|w| {
305 write_fields!(w); 383 write_fields!(w);
306 }), 384 }),
385 #[cfg(stm32f2)]
386 PllInstance::Plli2s => RCC.plli2scfgr().write(|w| {
387 if let Some(divr) = pll.divr {
388 w.set_pllr(divr);
389 }
390 }),
307 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] 391 #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
308 PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| { 392 PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| {
309 write_fields!(w); 393 write_fields!(w);
@@ -316,22 +400,6 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
316 PllOutput { p, q, r } 400 PllOutput { p, q, r }
317} 401}
318 402
319fn flash_setup(clk: Hertz) {
320 use crate::pac::flash::vals::Latency;
321
322 // Be conservative with voltage ranges
323 const FLASH_LATENCY_STEP: u32 = 30_000_000;
324
325 let latency = (clk.0 - 1) / FLASH_LATENCY_STEP;
326 debug!("flash: latency={}", latency);
327
328 let latency = Latency::from_bits(latency as u8);
329 FLASH.acr().write(|w| {
330 w.set_latency(latency);
331 });
332 while FLASH.acr().read().latency() != latency {}
333}
334
335#[cfg(stm32f7)] 403#[cfg(stm32f7)]
336mod max { 404mod max {
337 use core::ops::RangeInclusive; 405 use core::ops::RangeInclusive;
@@ -380,3 +448,22 @@ mod max {
380 pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(2_100_000); 448 pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(2_100_000);
381 pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(100_000_000)..=Hertz(432_000_000); 449 pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(100_000_000)..=Hertz(432_000_000);
382} 450}
451
452#[cfg(stm32f2)]
453mod max {
454 use core::ops::RangeInclusive;
455
456 use crate::time::Hertz;
457
458 pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(26_000_000);
459 pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(26_000_000);
460
461 pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(120_000_000);
462
463 pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(SYSCLK.end().0);
464 pub(crate) const PCLK1: RangeInclusive<Hertz> = Hertz(0)..=Hertz(SYSCLK.end().0 / 4);
465 pub(crate) const PCLK2: RangeInclusive<Hertz> = Hertz(0)..=Hertz(SYSCLK.end().0 / 2);
466
467 pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(0_950_000)..=Hertz(2_100_000);
468 pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(192_000_000)..=Hertz(432_000_000);
469}
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs
deleted file mode 100644
index 00480222a..000000000
--- a/embassy-stm32/src/rcc/f2.rs
+++ /dev/null
@@ -1,320 +0,0 @@
1use crate::pac::flash::vals::Latency;
2use crate::pac::rcc::vals::Sw;
3pub use crate::pac::rcc::vals::{
4 Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllsrc as PllSource,
5 Ppre as APBPrescaler,
6};
7use crate::pac::{FLASH, RCC};
8use crate::rcc::{set_freqs, Clocks};
9use crate::time::Hertz;
10
11/// HSI speed
12pub const HSI_FREQ: Hertz = Hertz(16_000_000);
13
14#[derive(Clone, Copy)]
15pub struct HSEConfig {
16 pub frequency: Hertz,
17 pub source: HSESrc,
18}
19
20/// System clock mux source
21#[derive(Clone, Copy)]
22pub enum ClockSrc {
23 HSE,
24 HSI,
25 PLL,
26}
27
28/// HSE clock source
29#[derive(Clone, Copy)]
30pub enum HSESrc {
31 /// Crystal/ceramic resonator
32 Crystal,
33 /// External clock source, HSE bypassed
34 Bypass,
35}
36
37#[derive(Clone, Copy)]
38pub struct Pll {
39 pub pre_div: PllPreDiv,
40 pub mul: PllMul,
41 pub divp: PllPDiv,
42 pub divq: PllQDiv,
43}
44
45impl Default for Pll {
46 fn default() -> Self {
47 Pll {
48 pre_div: PllPreDiv::DIV16,
49 mul: PllMul::MUL192,
50 divp: PllPDiv::DIV2,
51 divq: PllQDiv::DIV4,
52 }
53 }
54}
55
56impl Pll {
57 pub fn clocks(&self, src_freq: Hertz) -> PLLClocks {
58 let in_freq = src_freq / self.pre_div;
59 let vco_freq = src_freq / self.pre_div * self.mul;
60 let main_freq = vco_freq / self.divp;
61 let pll48_freq = vco_freq / self.divq;
62 PLLClocks {
63 in_freq,
64 vco_freq,
65 main_freq,
66 pll48_freq,
67 }
68 }
69}
70#[derive(Clone, Copy, PartialEq)]
71pub struct PLLClocks {
72 pub in_freq: Hertz,
73 pub vco_freq: Hertz,
74 pub main_freq: Hertz,
75 pub pll48_freq: Hertz,
76}
77
78/// Voltage range of the power supply used.
79///
80/// Used to calculate flash waitstates. See
81/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency
82pub enum VoltageScale {
83 /// 2.7 to 3.6 V
84 Range0,
85 /// 2.4 to 2.7 V
86 Range1,
87 /// 2.1 to 2.4 V
88 Range2,
89 /// 1.8 to 2.1 V
90 Range3,
91}
92
93impl VoltageScale {
94 const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> {
95 let ahb_freq = ahb_freq.0;
96 // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock
97 // frequency
98 match self {
99 VoltageScale::Range3 => {
100 if ahb_freq <= 16_000_000 {
101 Some(Latency::WS0)
102 } else if ahb_freq <= 32_000_000 {
103 Some(Latency::WS1)
104 } else if ahb_freq <= 48_000_000 {
105 Some(Latency::WS2)
106 } else if ahb_freq <= 64_000_000 {
107 Some(Latency::WS3)
108 } else if ahb_freq <= 80_000_000 {
109 Some(Latency::WS4)
110 } else if ahb_freq <= 96_000_000 {
111 Some(Latency::WS5)
112 } else if ahb_freq <= 112_000_000 {
113 Some(Latency::WS6)
114 } else if ahb_freq <= 120_000_000 {
115 Some(Latency::WS7)
116 } else {
117 None
118 }
119 }
120 VoltageScale::Range2 => {
121 if ahb_freq <= 18_000_000 {
122 Some(Latency::WS0)
123 } else if ahb_freq <= 36_000_000 {
124 Some(Latency::WS1)
125 } else if ahb_freq <= 54_000_000 {
126 Some(Latency::WS2)
127 } else if ahb_freq <= 72_000_000 {
128 Some(Latency::WS3)
129 } else if ahb_freq <= 90_000_000 {
130 Some(Latency::WS4)
131 } else if ahb_freq <= 108_000_000 {
132 Some(Latency::WS5)
133 } else if ahb_freq <= 120_000_000 {
134 Some(Latency::WS6)
135 } else {
136 None
137 }
138 }
139 VoltageScale::Range1 => {
140 if ahb_freq <= 24_000_000 {
141 Some(Latency::WS0)
142 } else if ahb_freq <= 48_000_000 {
143 Some(Latency::WS1)
144 } else if ahb_freq <= 72_000_000 {
145 Some(Latency::WS2)
146 } else if ahb_freq <= 96_000_000 {
147 Some(Latency::WS3)
148 } else if ahb_freq <= 120_000_000 {
149 Some(Latency::WS4)
150 } else {
151 None
152 }
153 }
154 VoltageScale::Range0 => {
155 if ahb_freq <= 30_000_000 {
156 Some(Latency::WS0)
157 } else if ahb_freq <= 60_000_000 {
158 Some(Latency::WS1)
159 } else if ahb_freq <= 90_000_000 {
160 Some(Latency::WS2)
161 } else if ahb_freq <= 120_000_000 {
162 Some(Latency::WS3)
163 } else {
164 None
165 }
166 }
167 }
168 }
169}
170
171/// Clocks configuration
172pub struct Config {
173 pub hse: Option<HSEConfig>,
174 pub hsi: bool,
175 pub pll_mux: PllSource,
176 pub pll: Pll,
177 pub mux: ClockSrc,
178 pub voltage: VoltageScale,
179 pub ahb_pre: AHBPrescaler,
180 pub apb1_pre: APBPrescaler,
181 pub apb2_pre: APBPrescaler,
182 pub ls: super::LsConfig,
183}
184
185impl Default for Config {
186 #[inline]
187 fn default() -> Config {
188 Config {
189 hse: None,
190 hsi: true,
191 pll_mux: PllSource::HSI,
192 pll: Pll::default(),
193 voltage: VoltageScale::Range3,
194 mux: ClockSrc::HSI,
195 ahb_pre: AHBPrescaler::DIV1,
196 apb1_pre: APBPrescaler::DIV1,
197 apb2_pre: APBPrescaler::DIV1,
198 ls: Default::default(),
199 }
200 }
201}
202
203pub(crate) unsafe fn init(config: Config) {
204 // Make sure HSI is enabled
205 RCC.cr().write(|w| w.set_hsion(true));
206 while !RCC.cr().read().hsirdy() {}
207
208 if let Some(hse_config) = config.hse {
209 RCC.cr().modify(|w| {
210 w.set_hsebyp(match hse_config.source {
211 HSESrc::Bypass => true,
212 HSESrc::Crystal => false,
213 });
214 w.set_hseon(true)
215 });
216 while !RCC.cr().read().hserdy() {}
217 }
218
219 let pll_src_freq = match config.pll_mux {
220 PllSource::HSE => {
221 let hse_config = config
222 .hse
223 .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input"));
224 hse_config.frequency
225 }
226 PllSource::HSI => HSI_FREQ,
227 };
228
229 // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics
230 let pll_clocks = config.pll.clocks(pll_src_freq);
231 assert!(Hertz(950_000) <= pll_clocks.in_freq && pll_clocks.in_freq <= Hertz(2_100_000));
232 assert!(Hertz(192_000_000) <= pll_clocks.vco_freq && pll_clocks.vco_freq <= Hertz(432_000_000));
233 assert!(Hertz(24_000_000) <= pll_clocks.main_freq && pll_clocks.main_freq <= Hertz(120_000_000));
234 // USB actually requires == 48 MHz, but other PLL48 peripherals are fine with <= 48MHz
235 assert!(pll_clocks.pll48_freq <= Hertz(48_000_000));
236
237 RCC.pllcfgr().write(|w| {
238 w.set_pllsrc(config.pll_mux);
239 w.set_pllm(config.pll.pre_div);
240 w.set_plln(config.pll.mul);
241 w.set_pllp(config.pll.divp);
242 w.set_pllq(config.pll.divq);
243 });
244
245 let (sys_clk, sw) = match config.mux {
246 ClockSrc::HSI => {
247 assert!(config.hsi, "HSI must be enabled to be used as system clock");
248 (HSI_FREQ, Sw::HSI)
249 }
250 ClockSrc::HSE => {
251 let hse_config = config
252 .hse
253 .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input"));
254 (hse_config.frequency, Sw::HSE)
255 }
256 ClockSrc::PLL => {
257 RCC.cr().modify(|w| w.set_pllon(true));
258 while !RCC.cr().read().pllrdy() {}
259 (pll_clocks.main_freq, Sw::PLL1_P)
260 }
261 };
262 // RM0033 Figure 9. Clock tree suggests max SYSCLK/HCLK is 168 MHz, but datasheet specifies PLL
263 // max output to be 120 MHz, so there's no way to get higher frequencies
264 assert!(sys_clk <= Hertz(120_000_000));
265
266 let ahb_freq = sys_clk / config.ahb_pre;
267 // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions
268 assert!(ahb_freq <= Hertz(120_000_000));
269
270 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
271 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
272 pre => {
273 let freq = ahb_freq / pre;
274 (freq, Hertz(freq.0 * 2))
275 }
276 };
277 // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions
278 assert!(apb1_freq <= Hertz(30_000_000));
279
280 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
281 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
282 pre => {
283 let freq = ahb_freq / pre;
284 (freq, Hertz(freq.0 * 2))
285 }
286 };
287 // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions
288 assert!(apb2_freq <= Hertz(60_000_000));
289
290 let flash_ws = unwrap!(config.voltage.wait_states(ahb_freq));
291 FLASH.acr().modify(|w| w.set_latency(flash_ws));
292
293 RCC.cfgr().modify(|w| {
294 w.set_sw(sw.into());
295 w.set_hpre(config.ahb_pre);
296 w.set_ppre1(config.apb1_pre);
297 w.set_ppre2(config.apb2_pre);
298 });
299 while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {}
300
301 // Turn off HSI to save power if we don't need it
302 if !config.hsi {
303 RCC.cr().modify(|w| w.set_hsion(false));
304 }
305
306 let rtc = config.ls.init();
307
308 set_freqs(Clocks {
309 sys: sys_clk,
310 hclk1: ahb_freq,
311 hclk2: ahb_freq,
312 hclk3: ahb_freq,
313 pclk1: apb1_freq,
314 pclk1_tim: apb1_tim_freq,
315 pclk2: apb2_freq,
316 pclk2_tim: apb2_tim_freq,
317 pll1_q: Some(pll_clocks.pll48_freq),
318 rtc,
319 });
320}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index debd16ca1..2e144dc77 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -15,14 +15,13 @@ mod hsi48;
15pub use hsi48::*; 15pub use hsi48::*;
16 16
17#[cfg_attr(rcc_f0, path = "f0.rs")] 17#[cfg_attr(rcc_f0, path = "f0.rs")]
18#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] 18#[cfg_attr(any(stm32f1), path = "f1.rs")]
19#[cfg_attr(rcc_f2, path = "f2.rs")] 19#[cfg_attr(any(stm32f3), path = "f3.rs")]
20#[cfg_attr(any(rcc_f3, rcc_f3_v2), path = "f3.rs")] 20#[cfg_attr(any(stm32f2, stm32f4, stm32f7), path = "f.rs")]
21#[cfg_attr(any(rcc_f4, rcc_f410, rcc_f7), path = "f4f7.rs")]
22#[cfg_attr(rcc_c0, path = "c0.rs")] 21#[cfg_attr(rcc_c0, path = "c0.rs")]
23#[cfg_attr(rcc_g0, path = "g0.rs")] 22#[cfg_attr(rcc_g0, path = "g0.rs")]
24#[cfg_attr(rcc_g4, path = "g4.rs")] 23#[cfg_attr(rcc_g4, path = "g4.rs")]
25#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] 24#[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")]
26#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] 25#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")]
27#[cfg_attr(rcc_u5, path = "u5.rs")] 26#[cfg_attr(rcc_u5, path = "u5.rs")]
28#[cfg_attr(rcc_wba, path = "wba.rs")] 27#[cfg_attr(rcc_wba, path = "wba.rs")]
diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs
index feec90016..aae7637dc 100644
--- a/examples/stm32f2/src/bin/pll.rs
+++ b/examples/stm32f2/src/bin/pll.rs
@@ -6,9 +6,6 @@ use core::convert::TryFrom;
6 6
7use defmt::*; 7use defmt::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::rcc::{
10 APBPrescaler, ClockSrc, HSEConfig, HSESrc, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllSource,
11};
12use embassy_stm32::time::Hertz; 9use embassy_stm32::time::Hertz;
13use embassy_stm32::Config; 10use embassy_stm32::Config;
14use embassy_time::Timer; 11use embassy_time::Timer;
@@ -19,29 +16,35 @@ async fn main(_spawner: Spawner) {
19 // Example config for maximum performance on a NUCLEO-F207ZG board 16 // Example config for maximum performance on a NUCLEO-F207ZG board
20 17
21 let mut config = Config::default(); 18 let mut config = Config::default();
22 // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) 19
23 config.rcc.hse = Some(HSEConfig { 20 {
24 frequency: Hertz(8_000_000), 21 use embassy_stm32::rcc::*;
25 source: HSESrc::Bypass, 22
26 }); 23 // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal)
27 // PLL uses HSE as the clock source 24 config.rcc.hse = Some(Hse {
28 config.rcc.pll_mux = PllSource::HSE; 25 freq: Hertz(8_000_000),
29 config.rcc.pll = Pll { 26 mode: HseMode::Bypass,
30 // 8 MHz clock source / 8 = 1 MHz PLL input 27 });
31 pre_div: unwrap!(PllPreDiv::try_from(8)), 28 // PLL uses HSE as the clock source
32 // 1 MHz PLL input * 240 = 240 MHz PLL VCO 29 config.rcc.pll_src = PllSource::HSE;
33 mul: unwrap!(PllMul::try_from(240)), 30 config.rcc.pll = Some(Pll {
34 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output 31 // 8 MHz clock source / 8 = 1 MHz PLL input
35 divp: PllPDiv::DIV2, 32 prediv: unwrap!(PllPreDiv::try_from(8)),
36 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output 33 // 1 MHz PLL input * 240 = 240 MHz PLL VCO
37 divq: PllQDiv::DIV5, 34 mul: unwrap!(PllMul::try_from(240)),
38 }; 35 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output
39 // System clock comes from PLL (= the 120 MHz main PLL output) 36 divp: Some(PllPDiv::DIV2),
40 config.rcc.mux = ClockSrc::PLL; 37 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output
41 // 120 MHz / 4 = 30 MHz APB1 frequency 38 divq: Some(PllQDiv::DIV5),
42 config.rcc.apb1_pre = APBPrescaler::DIV4; 39 divr: None,
43 // 120 MHz / 2 = 60 MHz APB2 frequency 40 });
44 config.rcc.apb2_pre = APBPrescaler::DIV2; 41 // System clock comes from PLL (= the 120 MHz main PLL output)
42 config.rcc.sys = Sysclk::PLL1_P;
43 // 120 MHz / 4 = 30 MHz APB1 frequency
44 config.rcc.apb1_pre = APBPrescaler::DIV4;
45 // 120 MHz / 2 = 60 MHz APB2 frequency
46 config.rcc.apb2_pre = APBPrescaler::DIV2;
47 }
45 48
46 let _p = embassy_stm32::init(config); 49 let _p = embassy_stm32::init(config);
47 50
diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs
index 1747bbf4b..088d83c06 100644
--- a/examples/stm32f4/src/bin/eth.rs
+++ b/examples/stm32f4/src/bin/eth.rs
@@ -42,7 +42,7 @@ async fn main(spawner: Spawner) -> ! {
42 config.rcc.pll = Some(Pll { 42 config.rcc.pll = Some(Pll {
43 prediv: PllPreDiv::DIV4, 43 prediv: PllPreDiv::DIV4,
44 mul: PllMul::MUL180, 44 mul: PllMul::MUL180,
45 divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. 45 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz.
46 divq: None, 46 divq: None,
47 divr: None, 47 divr: None,
48 }); 48 });
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index 37e42384b..91747b2d5 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -30,8 +30,8 @@ async fn main(_spawner: Spawner) {
30 config.rcc.pll = Some(Pll { 30 config.rcc.pll = Some(Pll {
31 prediv: PllPreDiv::DIV4, 31 prediv: PllPreDiv::DIV4,
32 mul: PllMul::MUL168, 32 mul: PllMul::MUL168,
33 divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. 33 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz.
34 divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. 34 divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz.
35 divr: None, 35 divr: None,
36 }); 36 });
37 config.rcc.ahb_pre = AHBPrescaler::DIV1; 37 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs
index 34407b95a..6bf5b1cba 100644
--- a/examples/stm32f4/src/bin/usb_ethernet.rs
+++ b/examples/stm32f4/src/bin/usb_ethernet.rs
@@ -56,8 +56,8 @@ async fn main(spawner: Spawner) {
56 config.rcc.pll = Some(Pll { 56 config.rcc.pll = Some(Pll {
57 prediv: PllPreDiv::DIV4, 57 prediv: PllPreDiv::DIV4,
58 mul: PllMul::MUL168, 58 mul: PllMul::MUL168,
59 divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. 59 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz.
60 divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. 60 divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz.
61 divr: None, 61 divr: None,
62 }); 62 });
63 config.rcc.ahb_pre = AHBPrescaler::DIV1; 63 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs
index 689aea4fc..719b22bb9 100644
--- a/examples/stm32f4/src/bin/usb_raw.rs
+++ b/examples/stm32f4/src/bin/usb_raw.rs
@@ -85,8 +85,8 @@ async fn main(_spawner: Spawner) {
85 config.rcc.pll = Some(Pll { 85 config.rcc.pll = Some(Pll {
86 prediv: PllPreDiv::DIV4, 86 prediv: PllPreDiv::DIV4,
87 mul: PllMul::MUL168, 87 mul: PllMul::MUL168,
88 divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. 88 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz.
89 divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. 89 divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz.
90 divr: None, 90 divr: None,
91 }); 91 });
92 config.rcc.ahb_pre = AHBPrescaler::DIV1; 92 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs
index 3e05b0ef2..e2ccc9142 100644
--- a/examples/stm32f4/src/bin/usb_serial.rs
+++ b/examples/stm32f4/src/bin/usb_serial.rs
@@ -32,8 +32,8 @@ async fn main(_spawner: Spawner) {
32 config.rcc.pll = Some(Pll { 32 config.rcc.pll = Some(Pll {
33 prediv: PllPreDiv::DIV4, 33 prediv: PllPreDiv::DIV4,
34 mul: PllMul::MUL168, 34 mul: PllMul::MUL168,
35 divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. 35 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz.
36 divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. 36 divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz.
37 divr: None, 37 divr: None,
38 }); 38 });
39 config.rcc.ahb_pre = AHBPrescaler::DIV1; 39 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index 7c6c419a6..dd0069447 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -43,7 +43,7 @@ async fn main(spawner: Spawner) -> ! {
43 config.rcc.pll = Some(Pll { 43 config.rcc.pll = Some(Pll {
44 prediv: PllPreDiv::DIV4, 44 prediv: PllPreDiv::DIV4,
45 mul: PllMul::MUL216, 45 mul: PllMul::MUL216,
46 divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz 46 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz
47 divq: None, 47 divq: None,
48 divr: None, 48 divr: None,
49 }); 49 });
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 430aa781f..990de0ab1 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -26,8 +26,8 @@ async fn main(_spawner: Spawner) {
26 config.rcc.pll = Some(Pll { 26 config.rcc.pll = Some(Pll {
27 prediv: PllPreDiv::DIV4, 27 prediv: PllPreDiv::DIV4,
28 mul: PllMul::MUL216, 28 mul: PllMul::MUL216,
29 divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz 29 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz
30 divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz 30 divq: Some(PllQDiv::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz
31 divr: None, 31 divr: None,
32 }); 32 });
33 config.rcc.ahb_pre = AHBPrescaler::DIV1; 33 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs
index 6aca732b4..4991edbf0 100644
--- a/examples/stm32f7/src/bin/usb_serial.rs
+++ b/examples/stm32f7/src/bin/usb_serial.rs
@@ -32,8 +32,8 @@ async fn main(_spawner: Spawner) {
32 config.rcc.pll = Some(Pll { 32 config.rcc.pll = Some(Pll {
33 prediv: PllPreDiv::DIV4, 33 prediv: PllPreDiv::DIV4,
34 mul: PllMul::MUL216, 34 mul: PllMul::MUL216,
35 divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz 35 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz
36 divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz 36 divq: Some(PllQDiv::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz
37 divr: None, 37 divr: None,
38 }); 38 });
39 config.rcc.ahb_pre = AHBPrescaler::DIV1; 39 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index e7367d5ed..a44e8230f 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -236,24 +236,25 @@ pub fn config() -> Config {
236 { 236 {
237 use embassy_stm32::rcc::*; 237 use embassy_stm32::rcc::*;
238 // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) 238 // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal)
239 config.rcc.hse = Some(HSEConfig { 239 config.rcc.hse = Some(Hse {
240 frequency: Hertz(8_000_000), 240 freq: Hertz(8_000_000),
241 source: HSESrc::Bypass, 241 mode: HseMode::Bypass,
242 }); 242 });
243 // PLL uses HSE as the clock source 243 // PLL uses HSE as the clock source
244 config.rcc.pll_mux = PllSource::HSE; 244 config.rcc.pll_src = PllSource::HSE;
245 config.rcc.pll = Pll { 245 config.rcc.pll = Some(Pll {
246 // 8 MHz clock source / 8 = 1 MHz PLL input 246 // 8 MHz clock source / 8 = 1 MHz PLL input
247 pre_div: unwrap!(PllPreDiv::try_from(8)), 247 prediv: unwrap!(PllPreDiv::try_from(8)),
248 // 1 MHz PLL input * 240 = 240 MHz PLL VCO 248 // 1 MHz PLL input * 240 = 240 MHz PLL VCO
249 mul: unwrap!(PllMul::try_from(240)), 249 mul: unwrap!(PllMul::try_from(240)),
250 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output 250 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output
251 divp: PllPDiv::DIV2, 251 divp: Some(PllPDiv::DIV2),
252 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output 252 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output
253 divq: PllQDiv::DIV5, 253 divq: Some(PllQDiv::DIV5),
254 }; 254 divr: None,
255 });
255 // System clock comes from PLL (= the 120 MHz main PLL output) 256 // System clock comes from PLL (= the 120 MHz main PLL output)
256 config.rcc.mux = ClockSrc::PLL; 257 config.rcc.sys = Sysclk::PLL1_P;
257 // 120 MHz / 4 = 30 MHz APB1 frequency 258 // 120 MHz / 4 = 30 MHz APB1 frequency
258 config.rcc.apb1_pre = APBPrescaler::DIV4; 259 config.rcc.apb1_pre = APBPrescaler::DIV4;
259 // 120 MHz / 2 = 60 MHz APB2 frequency 260 // 120 MHz / 2 = 60 MHz APB2 frequency
@@ -271,7 +272,7 @@ pub fn config() -> Config {
271 config.rcc.pll = Some(Pll { 272 config.rcc.pll = Some(Pll {
272 prediv: PllPreDiv::DIV4, 273 prediv: PllPreDiv::DIV4,
273 mul: PllMul::MUL180, 274 mul: PllMul::MUL180,
274 divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. 275 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz.
275 divq: None, 276 divq: None,
276 divr: None, 277 divr: None,
277 }); 278 });
@@ -292,7 +293,7 @@ pub fn config() -> Config {
292 config.rcc.pll = Some(Pll { 293 config.rcc.pll = Some(Pll {
293 prediv: PllPreDiv::DIV4, 294 prediv: PllPreDiv::DIV4,
294 mul: PllMul::MUL216, 295 mul: PllMul::MUL216,
295 divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz. 296 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz.
296 divq: None, 297 divq: None,
297 divr: None, 298 divr: None,
298 }); 299 });