aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-10-09 02:48:22 +0200
committerDario Nieuwenhuis <[email protected]>2023-10-09 02:48:22 +0200
commit6186fe08070c5f497d72586640db287193b41894 (patch)
treeaaef02d5344086bde66725a853851546961520fa
parentc4cff0b79bc54634db9d0fa24a24add49b7ec7fe (diff)
stm32/rcc: use PLL enums from PAC.
-rw-r--r--embassy-stm32/Cargo.toml5
-rw-r--r--embassy-stm32/build.rs99
-rw-r--r--embassy-stm32/src/rcc/bus.rs56
-rw-r--r--embassy-stm32/src/rcc/c0.rs2
-rw-r--r--embassy-stm32/src/rcc/f2.rs161
-rw-r--r--embassy-stm32/src/rcc/f4.rs10
-rw-r--r--embassy-stm32/src/rcc/f7.rs10
-rw-r--r--embassy-stm32/src/rcc/g0.rs165
-rw-r--r--embassy-stm32/src/rcc/g4.rs197
-rw-r--r--embassy-stm32/src/rcc/h.rs53
-rw-r--r--embassy-stm32/src/rcc/l0.rs2
-rw-r--r--embassy-stm32/src/rcc/l1.rs2
-rw-r--r--embassy-stm32/src/rcc/l4.rs334
-rw-r--r--embassy-stm32/src/rcc/l5.rs351
-rw-r--r--embassy-stm32/src/rcc/mod.rs1
-rw-r--r--embassy-stm32/src/rcc/u5.rs276
-rw-r--r--embassy-stm32/src/rcc/wb.rs2
-rw-r--r--embassy-stm32/src/rcc/wl.rs2
-rw-r--r--examples/stm32f2/src/bin/pll.rs6
-rw-r--r--examples/stm32g4/src/bin/adc.rs6
-rw-r--r--examples/stm32g4/src/bin/pll.rs6
-rw-r--r--examples/stm32g4/src/bin/usb_serial.rs8
-rw-r--r--examples/stm32h5/src/bin/eth.rs12
-rw-r--r--examples/stm32h5/src/bin/usb_serial.rs10
-rw-r--r--examples/stm32h7/src/bin/adc.rs14
-rw-r--r--examples/stm32h7/src/bin/camera.rs8
-rw-r--r--examples/stm32h7/src/bin/dac.rs14
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs14
-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.rs8
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs8
-rw-r--r--examples/stm32h7/src/bin/pwm.rs6
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs8
-rw-r--r--examples/stm32h7/src/bin/spi.rs8
-rw-r--r--examples/stm32h7/src/bin/spi_dma.rs8
-rw-r--r--examples/stm32h7/src/bin/usb_serial.rs6
-rw-r--r--examples/stm32l4/src/bin/rng.rs10
-rw-r--r--examples/stm32l4/src/bin/rtc.rs8
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs8
-rw-r--r--examples/stm32l4/src/bin/usb_serial.rs2
-rw-r--r--examples/stm32l5/src/bin/rng.rs10
-rw-r--r--examples/stm32l5/src/bin/usb_ethernet.rs2
-rw-r--r--examples/stm32l5/src/bin/usb_hid_mouse.rs2
-rw-r--r--examples/stm32l5/src/bin/usb_serial.rs2
-rw-r--r--examples/stm32u5/src/bin/usb_serial.rs6
-rw-r--r--tests/stm32/src/common.rs42
47 files changed, 599 insertions, 1383 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 18010fb9b..70e8f2e29 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -59,12 +59,11 @@ sdio-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"
61atomic-polyfill = "1.0.1" 61atomic-polyfill = "1.0.1"
62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eecd80c34d4a3035be31404857e6c6e115376f41" } 62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026" }
63vcell = "0.1.3" 63vcell = "0.1.3"
64bxcan = "0.7.0" 64bxcan = "0.7.0"
65nb = "1.0.0" 65nb = "1.0.0"
66stm32-fmc = "0.3.0" 66stm32-fmc = "0.3.0"
67seq-macro = "0.3.0"
68cfg-if = "1.0.0" 67cfg-if = "1.0.0"
69embedded-io = { version = "0.6.0" } 68embedded-io = { version = "0.6.0" }
70embedded-io-async = { version = "0.6.0", optional = true } 69embedded-io-async = { version = "0.6.0", optional = true }
@@ -78,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] }
78[build-dependencies] 77[build-dependencies]
79proc-macro2 = "1.0.36" 78proc-macro2 = "1.0.36"
80quote = "1.0.15" 79quote = "1.0.15"
81stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eecd80c34d4a3035be31404857e6c6e115376f41", default-features = false, features = ["metadata"]} 80stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026", default-features = false, features = ["metadata"]}
82 81
83 82
84[features] 83[features]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 3f85d9e61..643f1b6e9 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -894,6 +894,105 @@ fn main() {
894 } 894 }
895 895
896 // ======== 896 // ========
897 // Generate Div/Mul impls for RCC prescalers/dividers/multipliers.
898 let rcc_registers = METADATA
899 .peripherals
900 .iter()
901 .filter_map(|p| p.registers.as_ref())
902 .find(|r| r.kind == "rcc")
903 .unwrap()
904 .ir;
905
906 for e in rcc_registers.enums {
907 fn is_rcc_name(e: &str) -> bool {
908 match e {
909 "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true,
910 "Timpre" | "Pllrclkpre" => false,
911 e if e.ends_with("pre") || e.ends_with("div") || e.ends_with("mul") => true,
912 _ => false,
913 }
914 }
915
916 #[derive(Copy, Clone, Debug)]
917 struct Frac {
918 num: u32,
919 denom: u32,
920 }
921
922 impl Frac {
923 fn simplify(self) -> Self {
924 let d = gcd(self.num, self.denom);
925 Self {
926 num: self.num / d,
927 denom: self.denom / d,
928 }
929 }
930 }
931
932 fn gcd(a: u32, b: u32) -> u32 {
933 if b == 0 {
934 return a;
935 }
936 gcd(b, a % b)
937 }
938
939 fn parse_num(n: &str) -> Result<Frac, ()> {
940 for prefix in ["DIV", "MUL"] {
941 if let Some(n) = n.strip_prefix(prefix) {
942 let exponent = n.find('_').map(|e| n.len() - 1 - e).unwrap_or(0) as u32;
943 let mantissa = n.replace('_', "").parse().map_err(|_| ())?;
944 let f = Frac {
945 num: mantissa,
946 denom: 10u32.pow(exponent),
947 };
948 return Ok(f.simplify());
949 }
950 }
951 Err(())
952 }
953
954 if is_rcc_name(e.name) {
955 let enum_name = format_ident!("{}", e.name);
956 let mut muls = Vec::new();
957 let mut divs = Vec::new();
958 for v in e.variants {
959 let Ok(val) = parse_num(v.name) else {
960 panic!("could not parse mul/div. enum={} variant={}", e.name, v.name)
961 };
962 let variant_name = format_ident!("{}", v.name);
963 let variant = quote!(crate::pac::rcc::vals::#enum_name::#variant_name);
964 let num = val.num;
965 let denom = val.denom;
966 muls.push(quote!(#variant => self * #num / #denom,));
967 divs.push(quote!(#variant => self * #denom / #num,));
968 }
969
970 g.extend(quote! {
971 impl core::ops::Div<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz {
972 type Output = crate::time::Hertz;
973 fn div(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output {
974 match rhs {
975 #(#divs)*
976 #[allow(unreachable_patterns)]
977 _ => unreachable!(),
978 }
979 }
980 }
981 impl core::ops::Mul<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz {
982 type Output = crate::time::Hertz;
983 fn mul(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output {
984 match rhs {
985 #(#muls)*
986 #[allow(unreachable_patterns)]
987 _ => unreachable!(),
988 }
989 }
990 }
991 });
992 }
993 }
994
995 // ========
897 // Write foreach_foo! macrotables 996 // Write foreach_foo! macrotables
898 997
899 let mut flash_regions_table: Vec<Vec<String>> = Vec::new(); 998 let mut flash_regions_table: Vec<Vec<String>> = Vec::new();
diff --git a/embassy-stm32/src/rcc/bus.rs b/embassy-stm32/src/rcc/bus.rs
deleted file mode 100644
index 495cf7fe1..000000000
--- a/embassy-stm32/src/rcc/bus.rs
+++ /dev/null
@@ -1,56 +0,0 @@
1use core::ops::Div;
2
3#[allow(unused_imports)]
4use crate::pac::rcc;
5pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
6use crate::time::Hertz;
7
8impl Div<AHBPrescaler> for Hertz {
9 type Output = Hertz;
10
11 fn div(self, rhs: AHBPrescaler) -> Self::Output {
12 let divisor = match rhs {
13 AHBPrescaler::DIV1 => 1,
14 AHBPrescaler::DIV2 => 2,
15 #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
16 AHBPrescaler::DIV3 => 3,
17 AHBPrescaler::DIV4 => 4,
18 #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
19 AHBPrescaler::DIV5 => 5,
20 #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
21 AHBPrescaler::DIV6 => 6,
22 AHBPrescaler::DIV8 => 8,
23 #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
24 AHBPrescaler::DIV10 => 10,
25 AHBPrescaler::DIV16 => 16,
26 #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
27 AHBPrescaler::DIV32 => 32,
28 #[cfg(not(rcc_wba))]
29 AHBPrescaler::DIV64 => 64,
30 #[cfg(not(rcc_wba))]
31 AHBPrescaler::DIV128 => 128,
32 #[cfg(not(rcc_wba))]
33 AHBPrescaler::DIV256 => 256,
34 #[cfg(not(rcc_wba))]
35 AHBPrescaler::DIV512 => 512,
36 _ => unreachable!(),
37 };
38 Hertz(self.0 / divisor)
39 }
40}
41
42impl Div<APBPrescaler> for Hertz {
43 type Output = Hertz;
44
45 fn div(self, rhs: APBPrescaler) -> Self::Output {
46 let divisor = match rhs {
47 APBPrescaler::DIV1 => 1,
48 APBPrescaler::DIV2 => 2,
49 APBPrescaler::DIV4 => 4,
50 APBPrescaler::DIV8 => 8,
51 APBPrescaler::DIV16 => 16,
52 _ => unreachable!(),
53 };
54 Hertz(self.0 / divisor)
55 }
56}
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs
index 8f45e7c0f..efa56de7b 100644
--- a/embassy-stm32/src/rcc/c0.rs
+++ b/embassy-stm32/src/rcc/c0.rs
@@ -1,5 +1,5 @@
1pub use super::bus::{AHBPrescaler, APBPrescaler};
2use crate::pac::flash::vals::Latency; 1use crate::pac::flash::vals::Latency;
2pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
3use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; 3use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw};
4use crate::pac::{FLASH, RCC}; 4use crate::pac::{FLASH, RCC};
5use crate::rcc::{set_freqs, Clocks}; 5use crate::rcc::{set_freqs, Clocks};
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs
index 44de5bf19..07b816bf5 100644
--- a/embassy-stm32/src/rcc/f2.rs
+++ b/embassy-stm32/src/rcc/f2.rs
@@ -1,9 +1,9 @@
1use core::convert::TryFrom;
2use core::ops::{Div, Mul};
3
4pub use super::bus::{AHBPrescaler, APBPrescaler};
5use crate::pac::flash::vals::Latency; 1use crate::pac::flash::vals::Latency;
6use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; 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 PLLSrc,
5 Ppre as APBPrescaler,
6};
7use crate::pac::{FLASH, RCC}; 7use crate::pac::{FLASH, RCC};
8use crate::rcc::bd::BackupDomain; 8use crate::rcc::bd::BackupDomain;
9use crate::rcc::{set_freqs, Clocks}; 9use crate::rcc::{set_freqs, Clocks};
@@ -43,17 +43,17 @@ pub enum HSESrc {
43pub struct PLLConfig { 43pub struct PLLConfig {
44 pub pre_div: PLLPreDiv, 44 pub pre_div: PLLPreDiv,
45 pub mul: PLLMul, 45 pub mul: PLLMul,
46 pub main_div: PLLMainDiv, 46 pub p_div: PLLPDiv,
47 pub pll48_div: PLL48Div, 47 pub q_div: PLLQDiv,
48} 48}
49 49
50impl Default for PLLConfig { 50impl Default for PLLConfig {
51 fn default() -> Self { 51 fn default() -> Self {
52 PLLConfig { 52 PLLConfig {
53 pre_div: PLLPreDiv(16), 53 pre_div: PLLPreDiv::DIV16,
54 mul: PLLMul(192), 54 mul: PLLMul::MUL192,
55 main_div: PLLMainDiv::Div2, 55 p_div: PLLPDiv::DIV2,
56 pll48_div: PLL48Div(4), 56 q_div: PLLQDiv::DIV4,
57 } 57 }
58 } 58 }
59} 59}
@@ -61,9 +61,9 @@ impl Default for PLLConfig {
61impl PLLConfig { 61impl PLLConfig {
62 pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { 62 pub fn clocks(&self, src_freq: Hertz) -> PLLClocks {
63 let in_freq = src_freq / self.pre_div; 63 let in_freq = src_freq / self.pre_div;
64 let vco_freq = Hertz((src_freq.0 as u64 * self.mul.0 as u64 / self.pre_div.0 as u64) as u32); 64 let vco_freq = src_freq / self.pre_div * self.mul;
65 let main_freq = vco_freq / self.main_div; 65 let main_freq = vco_freq / self.p_div;
66 let pll48_freq = vco_freq / self.pll48_div; 66 let pll48_freq = vco_freq / self.q_div;
67 PLLClocks { 67 PLLClocks {
68 in_freq, 68 in_freq,
69 vco_freq, 69 vco_freq,
@@ -72,129 +72,6 @@ impl PLLConfig {
72 } 72 }
73 } 73 }
74} 74}
75
76/// Clock source for both main PLL and PLLI2S
77#[derive(Clone, Copy, PartialEq)]
78pub enum PLLSrc {
79 HSE,
80 HSI,
81}
82
83impl Into<Pllsrc> for PLLSrc {
84 fn into(self) -> Pllsrc {
85 match self {
86 PLLSrc::HSE => Pllsrc::HSE,
87 PLLSrc::HSI => Pllsrc::HSI,
88 }
89 }
90}
91
92/// Division factor for both main PLL and PLLI2S
93#[derive(Clone, Copy, PartialEq)]
94#[repr(transparent)]
95pub struct PLLPreDiv(u8);
96
97impl TryFrom<u8> for PLLPreDiv {
98 type Error = &'static str;
99
100 fn try_from(value: u8) -> Result<Self, Self::Error> {
101 match value {
102 2..=63 => Ok(PLLPreDiv(value)),
103 _ => Err("PLLPreDiv must be within range 2..=63"),
104 }
105 }
106}
107
108impl Div<PLLPreDiv> for Hertz {
109 type Output = Hertz;
110
111 fn div(self, rhs: PLLPreDiv) -> Self::Output {
112 Hertz(self.0 / u32::from(rhs.0))
113 }
114}
115
116/// Multiplication factor for main PLL
117#[derive(Clone, Copy, PartialEq)]
118#[repr(transparent)]
119pub struct PLLMul(u16);
120
121impl Mul<PLLMul> for Hertz {
122 type Output = Hertz;
123
124 fn mul(self, rhs: PLLMul) -> Self::Output {
125 Hertz(self.0 * u32::from(rhs.0))
126 }
127}
128
129impl TryFrom<u16> for PLLMul {
130 type Error = &'static str;
131
132 fn try_from(value: u16) -> Result<Self, Self::Error> {
133 match value {
134 192..=432 => Ok(PLLMul(value)),
135 _ => Err("PLLMul must be within range 192..=432"),
136 }
137 }
138}
139
140/// PLL division factor for the main system clock
141#[derive(Clone, Copy, PartialEq)]
142pub enum PLLMainDiv {
143 Div2,
144 Div4,
145 Div6,
146 Div8,
147}
148
149impl Into<Pllp> for PLLMainDiv {
150 fn into(self) -> Pllp {
151 match self {
152 PLLMainDiv::Div2 => Pllp::DIV2,
153 PLLMainDiv::Div4 => Pllp::DIV4,
154 PLLMainDiv::Div6 => Pllp::DIV6,
155 PLLMainDiv::Div8 => Pllp::DIV8,
156 }
157 }
158}
159
160impl Div<PLLMainDiv> for Hertz {
161 type Output = Hertz;
162
163 fn div(self, rhs: PLLMainDiv) -> Self::Output {
164 let divisor = match rhs {
165 PLLMainDiv::Div2 => 2,
166 PLLMainDiv::Div4 => 4,
167 PLLMainDiv::Div6 => 6,
168 PLLMainDiv::Div8 => 8,
169 };
170 Hertz(self.0 / divisor)
171 }
172}
173
174/// PLL division factor for USB OTG FS / SDIO / RNG
175#[derive(Clone, Copy, PartialEq)]
176#[repr(transparent)]
177pub struct PLL48Div(u8);
178
179impl Div<PLL48Div> for Hertz {
180 type Output = Hertz;
181
182 fn div(self, rhs: PLL48Div) -> Self::Output {
183 Hertz(self.0 / u32::from(rhs.0))
184 }
185}
186
187impl TryFrom<u8> for PLL48Div {
188 type Error = &'static str;
189
190 fn try_from(value: u8) -> Result<Self, Self::Error> {
191 match value {
192 2..=15 => Ok(PLL48Div(value)),
193 _ => Err("PLL48Div must be within range 2..=15"),
194 }
195 }
196}
197
198#[derive(Clone, Copy, PartialEq)] 75#[derive(Clone, Copy, PartialEq)]
199pub struct PLLClocks { 76pub struct PLLClocks {
200 pub in_freq: Hertz, 77 pub in_freq: Hertz,
@@ -367,11 +244,11 @@ pub(crate) unsafe fn init(config: Config) {
367 assert!(pll_clocks.pll48_freq <= Hertz(48_000_000)); 244 assert!(pll_clocks.pll48_freq <= Hertz(48_000_000));
368 245
369 RCC.pllcfgr().write(|w| { 246 RCC.pllcfgr().write(|w| {
370 w.set_pllsrc(config.pll_mux.into()); 247 w.set_pllsrc(config.pll_mux);
371 w.set_pllm(config.pll.pre_div.0); 248 w.set_pllm(config.pll.pre_div);
372 w.set_plln(config.pll.mul.0); 249 w.set_plln(config.pll.mul);
373 w.set_pllp(config.pll.main_div.into()); 250 w.set_pllp(config.pll.p_div);
374 w.set_pllq(config.pll.pll48_div.0); 251 w.set_pllq(config.pll.q_div);
375 }); 252 });
376 253
377 let (sys_clk, sw) = match config.mux { 254 let (sys_clk, sw) = match config.mux {
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index ad106ce38..754a0d570 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -1,3 +1,5 @@
1use stm32_metapac::rcc::vals::{Pllm, Plln, Pllq, Pllr};
2
1use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; 3use crate::pac::rcc::vals::{Hpre, Ppre, Sw};
2use crate::pac::{FLASH, PWR, RCC}; 4use crate::pac::{FLASH, PWR, RCC};
3use crate::rcc::bd::{BackupDomain, RtcClockSource}; 5use crate::rcc::bd::{BackupDomain, RtcClockSource};
@@ -170,12 +172,12 @@ fn setup_pll(
170 let real_pll48clk = vco_in * plln / pllq; 172 let real_pll48clk = vco_in * plln / pllq;
171 173
172 RCC.pllcfgr().modify(|w| { 174 RCC.pllcfgr().modify(|w| {
173 w.set_pllm(pllm as u8); 175 w.set_pllm(Pllm::from_bits(pllm as u8));
174 w.set_plln(plln as u16); 176 w.set_plln(Plln::from_bits(plln as u16));
175 w.set_pllp(Pllp::from_bits(pllp as u8)); 177 w.set_pllp(Pllp::from_bits(pllp as u8));
176 w.set_pllq(pllq as u8); 178 w.set_pllq(Pllq::from_bits(pllq as u8));
177 w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); 179 w.set_pllsrc(Pllsrc::from_bits(use_hse as u8));
178 w.set_pllr(0); 180 w.set_pllr(Pllr::from_bits(0));
179 }); 181 });
180 182
181 let real_pllsysclk = vco_in * plln / sysclk_div; 183 let real_pllsysclk = vco_in * plln / sysclk_div;
diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs
index f32559e26..565f6aa9f 100644
--- a/embassy-stm32/src/rcc/f7.rs
+++ b/embassy-stm32/src/rcc/f7.rs
@@ -1,5 +1,5 @@
1use crate::pac::pwr::vals::Vos; 1use crate::pac::pwr::vals::Vos;
2use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; 2use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw};
3use crate::pac::{FLASH, PWR, RCC}; 3use crate::pac::{FLASH, PWR, RCC};
4use crate::rcc::bd::{BackupDomain, RtcClockSource}; 4use crate::rcc::bd::{BackupDomain, RtcClockSource};
5use crate::rcc::{set_freqs, Clocks}; 5use crate::rcc::{set_freqs, Clocks};
@@ -29,8 +29,6 @@ pub struct Config {
29} 29}
30 30
31fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults { 31fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults {
32 use crate::pac::rcc::vals::{Pllp, Pllsrc};
33
34 let sysclk = pllsysclk.unwrap_or(pllsrcclk); 32 let sysclk = pllsysclk.unwrap_or(pllsrcclk);
35 if pllsysclk.is_none() && !pll48clk { 33 if pllsysclk.is_none() && !pll48clk {
36 RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8))); 34 RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)));
@@ -84,10 +82,10 @@ fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bo
84 let real_pll48clk = vco_in * plln / pllq; 82 let real_pll48clk = vco_in * plln / pllq;
85 83
86 RCC.pllcfgr().modify(|w| { 84 RCC.pllcfgr().modify(|w| {
87 w.set_pllm(pllm as u8); 85 w.set_pllm(Pllm::from_bits(pllm as u8));
88 w.set_plln(plln as u16); 86 w.set_plln(Plln::from_bits(plln as u16));
89 w.set_pllp(Pllp::from_bits(pllp as u8)); 87 w.set_pllp(Pllp::from_bits(pllp as u8));
90 w.set_pllq(pllq as u8); 88 w.set_pllq(Pllq::from_bits(pllq as u8));
91 w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); 89 w.set_pllsrc(Pllsrc::from_bits(use_hse as u8));
92 }); 90 });
93 91
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index 7f0a2c7fb..5ac409113 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -1,6 +1,6 @@
1pub use super::bus::{AHBPrescaler, APBPrescaler};
2use crate::pac::flash::vals::Latency; 1use crate::pac::flash::vals::Latency;
3use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; 2use crate::pac::rcc::vals::{self, Hsidiv, Sw};
3pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler};
4use crate::pac::{FLASH, PWR, RCC}; 4use crate::pac::{FLASH, PWR, RCC};
5use crate::rcc::{set_freqs, Clocks}; 5use crate::rcc::{set_freqs, Clocks};
6use crate::time::Hertz; 6use crate::time::Hertz;
@@ -60,15 +60,15 @@ pub struct PllConfig {
60 /// The initial divisor of that clock signal 60 /// The initial divisor of that clock signal
61 pub m: Pllm, 61 pub m: Pllm,
62 /// The PLL VCO multiplier, which must be in the range `8..=86`. 62 /// The PLL VCO multiplier, which must be in the range `8..=86`.
63 pub n: u8, 63 pub n: Plln,
64 /// The final divisor for `PLLRCLK` output which drives the system clock 64 /// The final divisor for `PLLRCLK` output which drives the system clock
65 pub r: Pllr, 65 pub r: Pllr,
66 66
67 /// The divisor for the `PLLQCLK` output, if desired 67 /// The divisor for the `PLLQCLK` output, if desired
68 pub q: Option<Pllr>, 68 pub q: Option<Pllq>,
69 69
70 /// The divisor for the `PLLPCLK` output, if desired 70 /// The divisor for the `PLLPCLK` output, if desired
71 pub p: Option<Pllr>, 71 pub p: Option<Pllp>,
72} 72}
73 73
74impl Default for PllConfig { 74impl Default for PllConfig {
@@ -77,9 +77,9 @@ impl Default for PllConfig {
77 // HSI16 / 1 * 8 / 2 = 64 MHz 77 // HSI16 / 1 * 8 / 2 = 64 MHz
78 PllConfig { 78 PllConfig {
79 source: PllSrc::HSI16, 79 source: PllSrc::HSI16,
80 m: Pllm::Div1, 80 m: Pllm::DIV1,
81 n: 8, 81 n: Plln::MUL8,
82 r: Pllr::Div2, 82 r: Pllr::DIV2,
83 q: None, 83 q: None,
84 p: None, 84 p: None,
85 } 85 }
@@ -92,87 +92,6 @@ pub enum PllSrc {
92 HSE(Hertz), 92 HSE(Hertz),
93} 93}
94 94
95#[derive(Clone, Copy)]
96pub enum Pllm {
97 Div1,
98 Div2,
99 Div3,
100 Div4,
101 Div5,
102 Div6,
103 Div7,
104 Div8,
105}
106
107impl From<Pllm> for u8 {
108 fn from(v: Pllm) -> Self {
109 match v {
110 Pllm::Div1 => 0b000,
111 Pllm::Div2 => 0b001,
112 Pllm::Div3 => 0b010,
113 Pllm::Div4 => 0b011,
114 Pllm::Div5 => 0b100,
115 Pllm::Div6 => 0b101,
116 Pllm::Div7 => 0b110,
117 Pllm::Div8 => 0b111,
118 }
119 }
120}
121
122impl From<Pllm> for u32 {
123 fn from(v: Pllm) -> Self {
124 match v {
125 Pllm::Div1 => 1,
126 Pllm::Div2 => 2,
127 Pllm::Div3 => 3,
128 Pllm::Div4 => 4,
129 Pllm::Div5 => 5,
130 Pllm::Div6 => 6,
131 Pllm::Div7 => 7,
132 Pllm::Div8 => 8,
133 }
134 }
135}
136
137#[derive(Clone, Copy)]
138pub enum Pllr {
139 Div2,
140 Div3,
141 Div4,
142 Div5,
143 Div6,
144 Div7,
145 Div8,
146}
147
148impl From<Pllr> for u8 {
149 fn from(v: Pllr) -> Self {
150 match v {
151 Pllr::Div2 => 0b000,
152 Pllr::Div3 => 0b001,
153 Pllr::Div4 => 0b010,
154 Pllr::Div5 => 0b011,
155 Pllr::Div6 => 0b101,
156 Pllr::Div7 => 0b110,
157 Pllr::Div8 => 0b111,
158 }
159 }
160}
161
162impl From<Pllr> for u32 {
163 fn from(v: Pllr) -> Self {
164 match v {
165 Pllr::Div2 => 2,
166 Pllr::Div3 => 3,
167 Pllr::Div4 => 4,
168 Pllr::Div5 => 5,
169 Pllr::Div6 => 6,
170 Pllr::Div7 => 7,
171 Pllr::Div8 => 8,
172 }
173 }
174}
175
176/// Clocks configutation 95/// Clocks configutation
177pub struct Config { 96pub struct Config {
178 pub mux: ClockSrc, 97 pub mux: ClockSrc,
@@ -194,29 +113,28 @@ impl Default for Config {
194} 113}
195 114
196impl PllConfig { 115impl PllConfig {
197 pub(crate) fn init(self) -> u32 { 116 pub(crate) fn init(self) -> Hertz {
198 assert!(self.n >= 8 && self.n <= 86);
199 let (src, input_freq) = match self.source { 117 let (src, input_freq) = match self.source {
200 PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ.0), 118 PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ),
201 PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq.0), 119 PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq),
202 }; 120 };
203 121
204 let m_freq = input_freq / u32::from(self.m); 122 let m_freq = input_freq / self.m;
205 // RM0454 § 5.4.4: 123 // RM0454 § 5.4.4:
206 // > Caution: The software must set these bits so that the PLL input frequency after the 124 // > Caution: The software must set these bits so that the PLL input frequency after the
207 // > /M divider is between 2.66 and 16 MHz. 125 // > /M divider is between 2.66 and 16 MHz.
208 debug_assert!(m_freq >= 2_660_000 && m_freq <= 16_000_000); 126 debug_assert!(m_freq.0 >= 2_660_000 && m_freq.0 <= 16_000_000);
209 127
210 let n_freq = m_freq * self.n as u32; 128 let n_freq = m_freq * self.n as u32;
211 // RM0454 § 5.4.4: 129 // RM0454 § 5.4.4:
212 // > Caution: The software must set these bits so that the VCO output frequency is between 130 // > Caution: The software must set these bits so that the VCO output frequency is between
213 // > 64 and 344 MHz. 131 // > 64 and 344 MHz.
214 debug_assert!(n_freq >= 64_000_000 && n_freq <= 344_000_000); 132 debug_assert!(n_freq.0 >= 64_000_000 && n_freq.0 <= 344_000_000);
215 133
216 let r_freq = n_freq / u32::from(self.r); 134 let r_freq = n_freq / self.r;
217 // RM0454 § 5.4.4: 135 // RM0454 § 5.4.4:
218 // > Caution: The software must set this bitfield so as not to exceed 64 MHz on this clock. 136 // > Caution: The software must set this bitfield so as not to exceed 64 MHz on this clock.
219 debug_assert!(r_freq <= 64_000_000); 137 debug_assert!(r_freq.0 <= 64_000_000);
220 138
221 // RM0454 § 5.2.3: 139 // RM0454 § 5.2.3:
222 // > To modify the PLL configuration, proceed as follows: 140 // > To modify the PLL configuration, proceed as follows:
@@ -239,25 +157,16 @@ impl PllConfig {
239 } 157 }
240 } 158 }
241 159
242 // Configure PLLSYSCFGR 160 // Configure PLLCFGR
243 RCC.pllsyscfgr().modify(|w| { 161 RCC.pllcfgr().modify(|w| {
244 w.set_pllr(u8::from(self.r)); 162 w.set_pllr(self.r);
245 w.set_pllren(false); 163 w.set_pllren(false);
246 164 w.set_pllq(self.q.unwrap_or(Pllq::DIV2));
247 if let Some(q) = self.q {
248 w.set_pllq(u8::from(q));
249 }
250 w.set_pllqen(false); 165 w.set_pllqen(false);
251 166 w.set_pllp(self.p.unwrap_or(Pllp::DIV2));
252 if let Some(p) = self.p {
253 w.set_pllp(u8::from(p));
254 }
255 w.set_pllpen(false); 167 w.set_pllpen(false);
256
257 w.set_plln(self.n); 168 w.set_plln(self.n);
258 169 w.set_pllm(self.m);
259 w.set_pllm(self.m as u8);
260
261 w.set_pllsrc(src) 170 w.set_pllsrc(src)
262 }); 171 });
263 172
@@ -269,7 +178,7 @@ impl PllConfig {
269 178
270 // > 5. Enable the desired PLL outputs by configuring PLLPEN, PLLQEN, and PLLREN in PLL 179 // > 5. Enable the desired PLL outputs by configuring PLLPEN, PLLQEN, and PLLREN in PLL
271 // > configuration register (RCC_PLLCFGR). 180 // > configuration register (RCC_PLLCFGR).
272 RCC.pllsyscfgr().modify(|w| { 181 RCC.pllcfgr().modify(|w| {
273 // We'll use R for system clock, so enable that unconditionally 182 // We'll use R for system clock, so enable that unconditionally
274 w.set_pllren(true); 183 w.set_pllren(true);
275 184
@@ -293,14 +202,14 @@ pub(crate) unsafe fn init(config: Config) {
293 }); 202 });
294 while !RCC.cr().read().hsirdy() {} 203 while !RCC.cr().read().hsirdy() {}
295 204
296 (HSI_FREQ.0 >> div.to_bits(), Sw::HSI) 205 (HSI_FREQ / div, Sw::HSI)
297 } 206 }
298 ClockSrc::HSE(freq) => { 207 ClockSrc::HSE(freq) => {
299 // Enable HSE 208 // Enable HSE
300 RCC.cr().write(|w| w.set_hseon(true)); 209 RCC.cr().write(|w| w.set_hseon(true));
301 while !RCC.cr().read().hserdy() {} 210 while !RCC.cr().read().hserdy() {}
302 211
303 (freq.0, Sw::HSE) 212 (freq, Sw::HSE)
304 } 213 }
305 ClockSrc::PLL(pll) => { 214 ClockSrc::PLL(pll) => {
306 let freq = pll.init(); 215 let freq = pll.init();
@@ -310,15 +219,15 @@ pub(crate) unsafe fn init(config: Config) {
310 // Enable LSI 219 // Enable LSI
311 RCC.csr().write(|w| w.set_lsion(true)); 220 RCC.csr().write(|w| w.set_lsion(true));
312 while !RCC.csr().read().lsirdy() {} 221 while !RCC.csr().read().lsirdy() {}
313 (LSI_FREQ.0, Sw::LSI) 222 (LSI_FREQ, Sw::LSI)
314 } 223 }
315 }; 224 };
316 225
317 // Determine the flash latency implied by the target clock speed 226 // Determine the flash latency implied by the target clock speed
318 // RM0454 § 3.3.4: 227 // RM0454 § 3.3.4:
319 let target_flash_latency = if sys_clk <= 24_000_000 { 228 let target_flash_latency = if sys_clk.0 <= 24_000_000 {
320 Latency::WS0 229 Latency::WS0
321 } else if sys_clk <= 48_000_000 { 230 } else if sys_clk.0 <= 48_000_000 {
322 Latency::WS1 231 Latency::WS1
323 } else { 232 } else {
324 Latency::WS2 233 Latency::WS2
@@ -374,27 +283,25 @@ pub(crate) unsafe fn init(config: Config) {
374 FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); 283 FLASH.acr().modify(|w| w.set_latency(target_flash_latency));
375 } 284 }
376 285
377 let ahb_freq = Hertz(sys_clk) / config.ahb_pre; 286 let ahb_freq = sys_clk / config.ahb_pre;
378 287
379 let (apb_freq, apb_tim_freq) = match config.apb_pre { 288 let (apb_freq, apb_tim_freq) = match config.apb_pre {
380 APBPrescaler::DIV1 => (ahb_freq.0, ahb_freq.0), 289 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
381 pre => { 290 pre => {
382 let pre: Ppre = pre.into(); 291 let freq = ahb_freq / pre;
383 let pre: u8 = 1 << (pre.to_bits() - 3); 292 (freq, freq * 2u32)
384 let freq = ahb_freq.0 / pre as u32;
385 (freq, freq * 2)
386 } 293 }
387 }; 294 };
388 295
389 if config.low_power_run { 296 if config.low_power_run {
390 assert!(sys_clk <= 2_000_000); 297 assert!(sys_clk.0 <= 2_000_000);
391 PWR.cr1().modify(|w| w.set_lpr(true)); 298 PWR.cr1().modify(|w| w.set_lpr(true));
392 } 299 }
393 300
394 set_freqs(Clocks { 301 set_freqs(Clocks {
395 sys: Hertz(sys_clk), 302 sys: sys_clk,
396 ahb1: ahb_freq, 303 ahb1: ahb_freq,
397 apb1: Hertz(apb_freq), 304 apb1: apb_freq,
398 apb1_tim: Hertz(apb_tim_freq), 305 apb1_tim: apb_tim_freq,
399 }); 306 });
400} 307}
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 41bebc918..08ccc5fe9 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -2,7 +2,9 @@ use stm32_metapac::flash::vals::Latency;
2use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw}; 2use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw};
3use stm32_metapac::FLASH; 3use stm32_metapac::FLASH;
4 4
5pub use super::bus::{AHBPrescaler, APBPrescaler}; 5pub use crate::pac::rcc::vals::{
6 Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler,
7};
6use crate::pac::{PWR, RCC}; 8use crate::pac::{PWR, RCC};
7use crate::rcc::sealed::RccPeripheral; 9use crate::rcc::sealed::RccPeripheral;
8use crate::rcc::{set_freqs, Clocks}; 10use crate::rcc::{set_freqs, Clocks};
@@ -61,181 +63,6 @@ impl Into<Pllsrc> for PllSrc {
61 } 63 }
62} 64}
63 65
64seq_macro::seq!(P in 2..=31 {
65 /// Output divider for the PLL P output.
66 #[derive(Clone, Copy)]
67 pub enum PllP {
68 // Note: If PLL P is set to 0 the PLLP bit controls the output division. There does not seem to
69 // a good reason to do this so the API does not support it.
70 // Div1 is invalid
71 #(
72 Div~P,
73 )*
74 }
75
76 impl From<PllP> for u8 {
77 /// Returns the register value for the P output divider.
78 fn from(val: PllP) -> u8 {
79 match val {
80 #(
81 PllP::Div~P => P,
82 )*
83 }
84 }
85 }
86});
87
88impl PllP {
89 /// Returns the numeric value of the P output divider.
90 pub fn to_div(self) -> u32 {
91 let val: u8 = self.into();
92 val as u32
93 }
94}
95
96/// Output divider for the PLL Q output.
97#[derive(Clone, Copy)]
98pub enum PllQ {
99 Div2,
100 Div4,
101 Div6,
102 Div8,
103}
104
105impl PllQ {
106 /// Returns the numeric value of the Q output divider.
107 pub fn to_div(self) -> u32 {
108 let val: u8 = self.into();
109 (val as u32 + 1) * 2
110 }
111}
112
113impl From<PllQ> for u8 {
114 /// Returns the register value for the Q output divider.
115 fn from(val: PllQ) -> u8 {
116 match val {
117 PllQ::Div2 => 0b00,
118 PllQ::Div4 => 0b01,
119 PllQ::Div6 => 0b10,
120 PllQ::Div8 => 0b11,
121 }
122 }
123}
124
125/// Output divider for the PLL R output.
126#[derive(Clone, Copy)]
127pub enum PllR {
128 Div2,
129 Div4,
130 Div6,
131 Div8,
132}
133
134impl PllR {
135 /// Returns the numeric value of the R output divider.
136 pub fn to_div(self) -> u32 {
137 let val: u8 = self.into();
138 (val as u32 + 1) * 2
139 }
140}
141
142impl From<PllR> for u8 {
143 /// Returns the register value for the R output divider.
144 fn from(val: PllR) -> u8 {
145 match val {
146 PllR::Div2 => 0b00,
147 PllR::Div4 => 0b01,
148 PllR::Div6 => 0b10,
149 PllR::Div8 => 0b11,
150 }
151 }
152}
153
154seq_macro::seq!(N in 8..=127 {
155 /// Multiplication factor for the PLL VCO input clock.
156 #[derive(Clone, Copy)]
157 pub enum PllN {
158 #(
159 Mul~N,
160 )*
161 }
162
163 impl From<PllN> for u8 {
164 /// Returns the register value for the N multiplication factor.
165 fn from(val: PllN) -> u8 {
166 match val {
167 #(
168 PllN::Mul~N => N,
169 )*
170 }
171 }
172 }
173
174 impl PllN {
175 /// Returns the numeric value of the N multiplication factor.
176 pub fn to_mul(self) -> u32 {
177 match self {
178 #(
179 PllN::Mul~N => N,
180 )*
181 }
182 }
183 }
184});
185
186/// PLL Pre-division. This must be set such that the PLL input is between 2.66 MHz and 16 MHz.
187#[derive(Copy, Clone)]
188pub enum PllM {
189 Div1,
190 Div2,
191 Div3,
192 Div4,
193 Div5,
194 Div6,
195 Div7,
196 Div8,
197 Div9,
198 Div10,
199 Div11,
200 Div12,
201 Div13,
202 Div14,
203 Div15,
204 Div16,
205}
206
207impl PllM {
208 /// Returns the numeric value of the M pre-division.
209 pub fn to_div(self) -> u32 {
210 let val: u8 = self.into();
211 val as u32 + 1
212 }
213}
214
215impl From<PllM> for u8 {
216 /// Returns the register value for the M pre-division.
217 fn from(val: PllM) -> u8 {
218 match val {
219 PllM::Div1 => 0b0000,
220 PllM::Div2 => 0b0001,
221 PllM::Div3 => 0b0010,
222 PllM::Div4 => 0b0011,
223 PllM::Div5 => 0b0100,
224 PllM::Div6 => 0b0101,
225 PllM::Div7 => 0b0110,
226 PllM::Div8 => 0b0111,
227 PllM::Div9 => 0b1000,
228 PllM::Div10 => 0b1001,
229 PllM::Div11 => 0b1010,
230 PllM::Div12 => 0b1011,
231 PllM::Div13 => 0b1100,
232 PllM::Div14 => 0b1101,
233 PllM::Div15 => 0b1110,
234 PllM::Div16 => 0b1111,
235 }
236 }
237}
238
239/// PLL Configuration 66/// PLL Configuration
240/// 67///
241/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output 68/// Use this struct to configure the PLL source, input frequency, multiplication factor, and output
@@ -360,12 +187,12 @@ pub(crate) unsafe fn init(config: Config) {
360 RCC.cr().write(|w| w.set_hsion(true)); 187 RCC.cr().write(|w| w.set_hsion(true));
361 while !RCC.cr().read().hsirdy() {} 188 while !RCC.cr().read().hsirdy() {}
362 189
363 HSI_FREQ.0 190 HSI_FREQ
364 } 191 }
365 PllSrc::HSE(freq) => { 192 PllSrc::HSE(freq) => {
366 RCC.cr().write(|w| w.set_hseon(true)); 193 RCC.cr().write(|w| w.set_hseon(true));
367 while !RCC.cr().read().hserdy() {} 194 while !RCC.cr().read().hserdy() {}
368 freq.0 195 freq
369 } 196 }
370 }; 197 };
371 198
@@ -373,7 +200,7 @@ pub(crate) unsafe fn init(config: Config) {
373 RCC.cr().modify(|w| w.set_pllon(false)); 200 RCC.cr().modify(|w| w.set_pllon(false));
374 while RCC.cr().read().pllrdy() {} 201 while RCC.cr().read().pllrdy() {}
375 202
376 let internal_freq = src_freq / pll_config.prediv_m.to_div() * pll_config.mul_n.to_mul(); 203 let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n;
377 204
378 RCC.pllcfgr().write(|w| { 205 RCC.pllcfgr().write(|w| {
379 w.set_plln(pll_config.mul_n.into()); 206 w.set_plln(pll_config.mul_n.into());
@@ -383,26 +210,26 @@ pub(crate) unsafe fn init(config: Config) {
383 210
384 let pll_p_freq = pll_config.div_p.map(|div_p| { 211 let pll_p_freq = pll_config.div_p.map(|div_p| {
385 RCC.pllcfgr().modify(|w| { 212 RCC.pllcfgr().modify(|w| {
386 w.set_pllpdiv(div_p.into()); 213 w.set_pllp(div_p);
387 w.set_pllpen(true); 214 w.set_pllpen(true);
388 }); 215 });
389 Hertz(internal_freq / div_p.to_div()) 216 internal_freq / div_p
390 }); 217 });
391 218
392 let pll_q_freq = pll_config.div_q.map(|div_q| { 219 let pll_q_freq = pll_config.div_q.map(|div_q| {
393 RCC.pllcfgr().modify(|w| { 220 RCC.pllcfgr().modify(|w| {
394 w.set_pllq(div_q.into()); 221 w.set_pllq(div_q);
395 w.set_pllqen(true); 222 w.set_pllqen(true);
396 }); 223 });
397 Hertz(internal_freq / div_q.to_div()) 224 internal_freq / div_q
398 }); 225 });
399 226
400 let pll_r_freq = pll_config.div_r.map(|div_r| { 227 let pll_r_freq = pll_config.div_r.map(|div_r| {
401 RCC.pllcfgr().modify(|w| { 228 RCC.pllcfgr().modify(|w| {
402 w.set_pllr(div_r.into()); 229 w.set_pllr(div_r);
403 w.set_pllren(true); 230 w.set_pllren(true);
404 }); 231 });
405 Hertz(internal_freq / div_r.to_div()) 232 internal_freq / div_r
406 }); 233 });
407 234
408 // Enable the PLL 235 // Enable the PLL
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 5f9cc1c8b..a11fd4737 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -6,8 +6,8 @@ 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;
9pub use crate::pac::rcc::vals::Ckpersel as PerClockSource;
10use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; 9use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre};
10pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul};
11use crate::pac::{FLASH, PWR, RCC}; 11use crate::pac::{FLASH, PWR, RCC};
12#[cfg(stm32h7)] 12#[cfg(stm32h7)]
13use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource}; 13use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource};
@@ -34,7 +34,7 @@ const VCO_WIDE_RANGE: RangeInclusive<u32> = 192_000_000..=836_000_000;
34#[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] 34#[cfg(any(pwr_h7rm0399, pwr_h7rm0433))]
35const VCO_WIDE_RANGE: RangeInclusive<u32> = 192_000_000..=960_000_000; 35const VCO_WIDE_RANGE: RangeInclusive<u32> = 192_000_000..=960_000_000;
36 36
37pub use super::bus::{AHBPrescaler, APBPrescaler}; 37pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
38 38
39#[derive(Clone, Copy, Eq, PartialEq)] 39#[derive(Clone, Copy, Eq, PartialEq)]
40pub enum VoltageScale { 40pub enum VoltageScale {
@@ -109,19 +109,19 @@ pub struct Pll {
109 #[cfg(stm32h5)] 109 #[cfg(stm32h5)]
110 pub source: PllSource, 110 pub source: PllSource,
111 111
112 /// PLL pre-divider (DIVM). Must be between 1 and 63. 112 /// PLL pre-divider (DIVM).
113 pub prediv: u8, 113 pub prediv: PllPreDiv,
114 114
115 /// PLL multiplication factor. Must be between 4 and 512. 115 /// PLL multiplication factor.
116 pub mul: u16, 116 pub mul: PllMul,
117 117
118 /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. 118 /// PLL P division factor. If None, PLL P output is disabled.
119 /// On PLL1, it must be even (in particular, it cannot be 1.) 119 /// On PLL1, it must be even (in particular, it cannot be 1.)
120 pub divp: Option<u16>, 120 pub divp: Option<PllDiv>,
121 /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. 121 /// PLL Q division factor. If None, PLL Q output is disabled.
122 pub divq: Option<u16>, 122 pub divq: Option<PllDiv>,
123 /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. 123 /// PLL R division factor. If None, PLL R output is disabled.
124 pub divr: Option<u16>, 124 pub divr: Option<PllDiv>,
125} 125}
126 126
127fn apb_div_tim(apb: &APBPrescaler, clk: Hertz, tim: TimerPrescaler) -> Hertz { 127fn apb_div_tim(apb: &APBPrescaler, clk: Hertz, tim: TimerPrescaler) -> Hertz {
@@ -604,9 +604,9 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
604 604
605 // "To save power when PLL1 is not used, the value of PLL1M must be set to 0."" 605 // "To save power when PLL1 is not used, the value of PLL1M must be set to 0.""
606 #[cfg(stm32h7)] 606 #[cfg(stm32h7)]
607 RCC.pllckselr().write(|w| w.set_divm(num, 0)); 607 RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0)));
608 #[cfg(stm32h5)] 608 #[cfg(stm32h5)]
609 RCC.pllcfgr(num).write(|w| w.set_divm(0)); 609 RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0)));
610 610
611 return PllOutput { 611 return PllOutput {
612 p: None, 612 p: None,
@@ -615,9 +615,6 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
615 }; 615 };
616 }; 616 };
617 617
618 assert!(1 <= config.prediv && config.prediv <= 63);
619 assert!(4 <= config.mul && config.mul <= 512);
620
621 #[cfg(stm32h5)] 618 #[cfg(stm32h5)]
622 let source = config.source; 619 let source = config.source;
623 #[cfg(stm32h7)] 620 #[cfg(stm32h7)]
@@ -653,22 +650,16 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
653 }; 650 };
654 651
655 let p = config.divp.map(|div| { 652 let p = config.divp.map(|div| {
656 assert!(1 <= div && div <= 128);
657 if num == 0 { 653 if num == 0 {
658 // on PLL1, DIVP must be even. 654 // on PLL1, DIVP must be even.
659 assert!(div % 2 == 0); 655 // The enum value is 1 less than the divider, so check it's odd.
656 assert!(div.to_bits() % 2 == 1);
660 } 657 }
661 658
662 vco_clk / div 659 vco_clk / div
663 }); 660 });
664 let q = config.divq.map(|div| { 661 let q = config.divq.map(|div| vco_clk / div);
665 assert!(1 <= div && div <= 128); 662 let r = config.divr.map(|div| vco_clk / div);
666 vco_clk / div
667 });
668 let r = config.divr.map(|div| {
669 assert!(1 <= div && div <= 128);
670 vco_clk / div
671 });
672 663
673 #[cfg(stm32h5)] 664 #[cfg(stm32h5)]
674 RCC.pllcfgr(num).write(|w| { 665 RCC.pllcfgr(num).write(|w| {
@@ -699,10 +690,10 @@ fn init_pll(num: usize, config: Option<Pll>, input: &PllInput) -> PllOutput {
699 } 690 }
700 691
701 RCC.plldivr(num).write(|w| { 692 RCC.plldivr(num).write(|w| {
702 w.set_plln(config.mul - 1); 693 w.set_plln(config.mul);
703 w.set_pllp((config.divp.unwrap_or(1) - 1) as u8); 694 w.set_pllp(config.divp.unwrap_or(PllDiv::DIV2));
704 w.set_pllq((config.divq.unwrap_or(1) - 1) as u8); 695 w.set_pllq(config.divq.unwrap_or(PllDiv::DIV2));
705 w.set_pllr((config.divr.unwrap_or(1) - 1) as u8); 696 w.set_pllr(config.divr.unwrap_or(PllDiv::DIV2));
706 }); 697 });
707 698
708 RCC.cr().modify(|w| w.set_pllon(num, true)); 699 RCC.cr().modify(|w| w.set_pllon(num, true));
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs
index 7358be31b..b42361268 100644
--- a/embassy-stm32/src/rcc/l0.rs
+++ b/embassy-stm32/src/rcc/l0.rs
@@ -1,8 +1,8 @@
1use super::bd::BackupDomain; 1use super::bd::BackupDomain;
2pub use super::bus::{AHBPrescaler, APBPrescaler};
3use super::RtcClockSource; 2use super::RtcClockSource;
4pub use crate::pac::pwr::vals::Vos as VoltageScale; 3pub use crate::pac::pwr::vals::Vos as VoltageScale;
5use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; 4use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw};
5pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
6#[cfg(crs)] 6#[cfg(crs)]
7use crate::pac::{crs, CRS, SYSCFG}; 7use crate::pac::{crs, CRS, SYSCFG};
8use crate::pac::{FLASH, PWR, RCC}; 8use crate::pac::{FLASH, PWR, RCC};
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs
index 90524fb37..e445a716e 100644
--- a/embassy-stm32/src/rcc/l1.rs
+++ b/embassy-stm32/src/rcc/l1.rs
@@ -1,5 +1,5 @@
1pub use super::bus::{AHBPrescaler, APBPrescaler};
2use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; 1use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw};
2pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
3use crate::pac::{FLASH, RCC}; 3use crate::pac::{FLASH, RCC};
4use crate::rcc::{set_freqs, Clocks}; 4use crate::rcc::{set_freqs, Clocks};
5use crate::time::Hertz; 5use crate::time::Hertz;
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs
index 2fbb9920e..0e35b42e8 100644
--- a/embassy-stm32/src/rcc/l4.rs
+++ b/embassy-stm32/src/rcc/l4.rs
@@ -1,7 +1,9 @@
1use stm32_metapac::rcc::regs::Cfgr; 1use crate::pac::rcc::regs::Cfgr;
2 2pub use crate::pac::rcc::vals::{
3pub use super::bus::{AHBPrescaler, APBPrescaler}; 3 Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
4use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; 4 Pllr as PllRDiv, Ppre as APBPrescaler,
5};
6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
5use crate::pac::{FLASH, RCC}; 7use crate::pac::{FLASH, RCC};
6use crate::rcc::bd::{BackupDomain, RtcClockSource}; 8use crate::rcc::bd::{BackupDomain, RtcClockSource};
7use crate::rcc::{set_freqs, Clocks}; 9use crate::rcc::{set_freqs, Clocks};
@@ -17,62 +19,11 @@ pub const LSI_FREQ: Hertz = Hertz(32_000);
17#[derive(Clone, Copy)] 19#[derive(Clone, Copy)]
18pub enum ClockSrc { 20pub enum ClockSrc {
19 MSI(MSIRange), 21 MSI(MSIRange),
20 PLL(PLLSource, PLLClkDiv, PLLSrcDiv, PLLMul, Option<PLL48Div>), 22 PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option<PllQDiv>),
21 HSE(Hertz), 23 HSE(Hertz),
22 HSI16, 24 HSI16,
23} 25}
24 26
25/// MSI Clock Range
26///
27/// These ranges control the frequency of the MSI. Internally, these ranges map
28/// to the `MSIRANGE` bits in the `RCC_ICSCR` register.
29#[derive(Clone, Copy)]
30pub enum MSIRange {
31 /// Around 100 kHz
32 Range0,
33 /// Around 200 kHz
34 Range1,
35 /// Around 400 kHz
36 Range2,
37 /// Around 800 kHz
38 Range3,
39 /// Around 1 MHz
40 Range4,
41 /// Around 2 MHz
42 Range5,
43 /// Around 4 MHz (reset value)
44 Range6,
45 /// Around 8 MHz
46 Range7,
47 /// Around 16 MHz
48 Range8,
49 /// Around 24 MHz
50 Range9,
51 /// Around 32 MHz
52 Range10,
53 /// Around 48 MHz
54 Range11,
55}
56
57impl Default for MSIRange {
58 fn default() -> MSIRange {
59 MSIRange::Range6
60 }
61}
62
63pub type PLL48Div = PLLClkDiv;
64pub type PLLSAI1RDiv = PLLClkDiv;
65pub type PLLSAI1QDiv = PLLClkDiv;
66pub type PLLSAI1PDiv = PLLClkDiv;
67
68/// PLL divider
69#[derive(Clone, Copy)]
70pub enum PLLDiv {
71 Div2,
72 Div3,
73 Div4,
74}
75
76/// PLL clock input source 27/// PLL clock input source
77#[derive(Clone, Copy)] 28#[derive(Clone, Copy)]
78pub enum PLLSource { 29pub enum PLLSource {
@@ -81,95 +32,6 @@ pub enum PLLSource {
81 MSI(MSIRange), 32 MSI(MSIRange),
82} 33}
83 34
84seq_macro::seq!(N in 8..=86 {
85 #[derive(Clone, Copy)]
86 pub enum PLLMul {
87 #(
88 Mul~N,
89 )*
90 }
91
92 impl From<PLLMul> for u8 {
93 fn from(val: PLLMul) -> u8 {
94 match val {
95 #(
96 PLLMul::Mul~N => N,
97 )*
98 }
99 }
100 }
101
102 impl PLLMul {
103 pub fn to_mul(self) -> u32 {
104 match self {
105 #(
106 PLLMul::Mul~N => N,
107 )*
108 }
109 }
110 }
111});
112
113#[derive(Clone, Copy)]
114pub enum PLLClkDiv {
115 Div2,
116 Div4,
117 Div6,
118 Div8,
119}
120
121impl PLLClkDiv {
122 pub fn to_div(self) -> u32 {
123 let val: u8 = self.into();
124 (val as u32 + 1) * 2
125 }
126}
127
128impl From<PLLClkDiv> for u8 {
129 fn from(val: PLLClkDiv) -> u8 {
130 match val {
131 PLLClkDiv::Div2 => 0b00,
132 PLLClkDiv::Div4 => 0b01,
133 PLLClkDiv::Div6 => 0b10,
134 PLLClkDiv::Div8 => 0b11,
135 }
136 }
137}
138
139#[derive(Clone, Copy)]
140pub enum PLLSrcDiv {
141 Div1,
142 Div2,
143 Div3,
144 Div4,
145 Div5,
146 Div6,
147 Div7,
148 Div8,
149}
150
151impl PLLSrcDiv {
152 pub fn to_div(self) -> u32 {
153 let val: u8 = self.into();
154 val as u32 + 1
155 }
156}
157
158impl From<PLLSrcDiv> for u8 {
159 fn from(val: PLLSrcDiv) -> u8 {
160 match val {
161 PLLSrcDiv::Div1 => 0b000,
162 PLLSrcDiv::Div2 => 0b001,
163 PLLSrcDiv::Div3 => 0b010,
164 PLLSrcDiv::Div4 => 0b011,
165 PLLSrcDiv::Div5 => 0b100,
166 PLLSrcDiv::Div6 => 0b101,
167 PLLSrcDiv::Div7 => 0b110,
168 PLLSrcDiv::Div8 => 0b111,
169 }
170 }
171}
172
173impl From<PLLSource> for Pllsrc { 35impl From<PLLSource> for Pllsrc {
174 fn from(val: PLLSource) -> Pllsrc { 36 fn from(val: PLLSource) -> Pllsrc {
175 match val { 37 match val {
@@ -180,57 +42,13 @@ impl From<PLLSource> for Pllsrc {
180 } 42 }
181} 43}
182 44
183impl From<MSIRange> for Msirange {
184 fn from(val: MSIRange) -> Msirange {
185 match val {
186 MSIRange::Range0 => Msirange::RANGE100K,
187 MSIRange::Range1 => Msirange::RANGE200K,
188 MSIRange::Range2 => Msirange::RANGE400K,
189 MSIRange::Range3 => Msirange::RANGE800K,
190 MSIRange::Range4 => Msirange::RANGE1M,
191 MSIRange::Range5 => Msirange::RANGE2M,
192 MSIRange::Range6 => Msirange::RANGE4M,
193 MSIRange::Range7 => Msirange::RANGE8M,
194 MSIRange::Range8 => Msirange::RANGE16M,
195 MSIRange::Range9 => Msirange::RANGE24M,
196 MSIRange::Range10 => Msirange::RANGE32M,
197 MSIRange::Range11 => Msirange::RANGE48M,
198 }
199 }
200}
201
202impl From<MSIRange> for u32 {
203 fn from(val: MSIRange) -> u32 {
204 match val {
205 MSIRange::Range0 => 100_000,
206 MSIRange::Range1 => 200_000,
207 MSIRange::Range2 => 400_000,
208 MSIRange::Range3 => 800_000,
209 MSIRange::Range4 => 1_000_000,
210 MSIRange::Range5 => 2_000_000,
211 MSIRange::Range6 => 4_000_000,
212 MSIRange::Range7 => 8_000_000,
213 MSIRange::Range8 => 16_000_000,
214 MSIRange::Range9 => 24_000_000,
215 MSIRange::Range10 => 32_000_000,
216 MSIRange::Range11 => 48_000_000,
217 }
218 }
219}
220
221/// Clocks configutation 45/// Clocks configutation
222pub struct Config { 46pub struct Config {
223 pub mux: ClockSrc, 47 pub mux: ClockSrc,
224 pub ahb_pre: AHBPrescaler, 48 pub ahb_pre: AHBPrescaler,
225 pub apb1_pre: APBPrescaler, 49 pub apb1_pre: APBPrescaler,
226 pub apb2_pre: APBPrescaler, 50 pub apb2_pre: APBPrescaler,
227 pub pllsai1: Option<( 51 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
228 PLLMul,
229 PLLSrcDiv,
230 Option<PLLSAI1RDiv>,
231 Option<PLLSAI1QDiv>,
232 Option<PLLSAI1PDiv>,
233 )>,
234 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] 52 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
235 pub hsi48: bool, 53 pub hsi48: bool,
236 pub rtc_mux: RtcClockSource, 54 pub rtc_mux: RtcClockSource,
@@ -242,7 +60,7 @@ impl Default for Config {
242 #[inline] 60 #[inline]
243 fn default() -> Config { 61 fn default() -> Config {
244 Config { 62 Config {
245 mux: ClockSrc::MSI(MSIRange::Range6), 63 mux: ClockSrc::MSI(MSIRange::RANGE4M),
246 ahb_pre: AHBPrescaler::DIV1, 64 ahb_pre: AHBPrescaler::DIV1,
247 apb1_pre: APBPrescaler::DIV1, 65 apb1_pre: APBPrescaler::DIV1,
248 apb2_pre: APBPrescaler::DIV1, 66 apb2_pre: APBPrescaler::DIV1,
@@ -262,7 +80,7 @@ pub(crate) unsafe fn init(config: Config) {
262 // Turn on MSI and configure it to 4MHz. 80 // Turn on MSI and configure it to 4MHz.
263 RCC.cr().modify(|w| { 81 RCC.cr().modify(|w| {
264 w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0]. 82 w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0].
265 w.set_msirange(MSIRange::default().into()); 83 w.set_msirange(MSIRange::RANGE4M);
266 w.set_msipllen(false); 84 w.set_msipllen(false);
267 w.set_msion(true) 85 w.set_msion(true)
268 }); 86 });
@@ -298,40 +116,40 @@ pub(crate) unsafe fn init(config: Config) {
298 while !RCC.cr().read().msirdy() {} 116 while !RCC.cr().read().msirdy() {}
299 117
300 // Enable as clock source for USB, RNG if running at 48 MHz 118 // Enable as clock source for USB, RNG if running at 48 MHz
301 if let MSIRange::Range11 = range { 119 if range == MSIRange::RANGE48M {
302 RCC.ccipr().modify(|w| { 120 RCC.ccipr().modify(|w| {
303 w.set_clk48sel(0b11); 121 w.set_clk48sel(0b11);
304 }); 122 });
305 } 123 }
306 (range.into(), Sw::MSI) 124 (msirange_to_hertz(range), Sw::MSI)
307 } 125 }
308 ClockSrc::HSI16 => { 126 ClockSrc::HSI16 => {
309 // Enable HSI16 127 // Enable HSI16
310 RCC.cr().write(|w| w.set_hsion(true)); 128 RCC.cr().write(|w| w.set_hsion(true));
311 while !RCC.cr().read().hsirdy() {} 129 while !RCC.cr().read().hsirdy() {}
312 130
313 (HSI_FREQ.0, Sw::HSI16) 131 (HSI_FREQ, Sw::HSI16)
314 } 132 }
315 ClockSrc::HSE(freq) => { 133 ClockSrc::HSE(freq) => {
316 // Enable HSE 134 // Enable HSE
317 RCC.cr().write(|w| w.set_hseon(true)); 135 RCC.cr().write(|w| w.set_hseon(true));
318 while !RCC.cr().read().hserdy() {} 136 while !RCC.cr().read().hserdy() {}
319 137
320 (freq.0, Sw::HSE) 138 (freq, Sw::HSE)
321 } 139 }
322 ClockSrc::PLL(src, div, prediv, mul, pll48div) => { 140 ClockSrc::PLL(src, divr, prediv, mul, divq) => {
323 let src_freq = match src { 141 let src_freq = match src {
324 PLLSource::HSE(freq) => { 142 PLLSource::HSE(freq) => {
325 // Enable HSE 143 // Enable HSE
326 RCC.cr().write(|w| w.set_hseon(true)); 144 RCC.cr().write(|w| w.set_hseon(true));
327 while !RCC.cr().read().hserdy() {} 145 while !RCC.cr().read().hserdy() {}
328 freq.0 146 freq
329 } 147 }
330 PLLSource::HSI16 => { 148 PLLSource::HSI16 => {
331 // Enable HSI 149 // Enable HSI
332 RCC.cr().write(|w| w.set_hsion(true)); 150 RCC.cr().write(|w| w.set_hsion(true));
333 while !RCC.cr().read().hsirdy() {} 151 while !RCC.cr().read().hsirdy() {}
334 HSI_FREQ.0 152 HSI_FREQ
335 } 153 }
336 PLLSource::MSI(range) => { 154 PLLSource::MSI(range) => {
337 // Enable MSI 155 // Enable MSI
@@ -343,7 +161,8 @@ pub(crate) unsafe fn init(config: Config) {
343 w.set_msion(true); 161 w.set_msion(true);
344 }); 162 });
345 while !RCC.cr().read().msirdy() {} 163 while !RCC.cr().read().msirdy() {}
346 range.into() 164
165 msirange_to_hertz(range)
347 } 166 }
348 }; 167 };
349 168
@@ -351,28 +170,28 @@ pub(crate) unsafe fn init(config: Config) {
351 RCC.cr().modify(|w| w.set_pllon(false)); 170 RCC.cr().modify(|w| w.set_pllon(false));
352 while RCC.cr().read().pllrdy() {} 171 while RCC.cr().read().pllrdy() {}
353 172
354 let freq = (src_freq / prediv.to_div() * mul.to_mul()) / div.to_div(); 173 let freq = src_freq / prediv * mul / divr;
355 174
356 #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] 175 #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))]
357 assert!(freq <= 120_000_000); 176 assert!(freq.0 <= 120_000_000);
358 #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] 177 #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))]
359 assert!(freq <= 80_000_000); 178 assert!(freq.0 <= 80_000_000);
360 179
361 RCC.pllcfgr().write(move |w| { 180 RCC.pllcfgr().write(move |w| {
362 w.set_plln(mul.into()); 181 w.set_plln(mul);
363 w.set_pllm(prediv.into()); 182 w.set_pllm(prediv);
364 w.set_pllr(div.into()); 183 w.set_pllr(divr);
365 if let Some(pll48div) = pll48div { 184 if let Some(divq) = divq {
366 w.set_pllq(pll48div.into()); 185 w.set_pllq(divq);
367 w.set_pllqen(true); 186 w.set_pllqen(true);
368 } 187 }
369 w.set_pllsrc(src.into()); 188 w.set_pllsrc(src.into());
370 }); 189 });
371 190
372 // Enable as clock source for USB, RNG if PLL48 divisor is provided 191 // Enable as clock source for USB, RNG if PLL48 divisor is provided
373 if let Some(pll48div) = pll48div { 192 if let Some(divq) = divq {
374 let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div(); 193 let freq = src_freq / prediv * mul / divq;
375 assert!(freq == 48_000_000); 194 assert!(freq.0 == 48_000_000);
376 RCC.ccipr().modify(|w| { 195 RCC.ccipr().modify(|w| {
377 w.set_clk48sel(0b10); 196 w.set_clk48sel(0b10);
378 }); 197 });
@@ -380,25 +199,25 @@ pub(crate) unsafe fn init(config: Config) {
380 199
381 if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { 200 if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 {
382 RCC.pllsai1cfgr().write(move |w| { 201 RCC.pllsai1cfgr().write(move |w| {
383 w.set_pllsai1n(mul.into()); 202 w.set_plln(mul);
384 w.set_pllsai1m(prediv.into()); 203 w.set_pllm(prediv);
385 if let Some(r_div) = r_div { 204 if let Some(r_div) = r_div {
386 w.set_pllsai1r(r_div.into()); 205 w.set_pllr(r_div);
387 w.set_pllsai1ren(true); 206 w.set_pllren(true);
388 } 207 }
389 if let Some(q_div) = q_div { 208 if let Some(q_div) = q_div {
390 w.set_pllsai1q(q_div.into()); 209 w.set_pllq(q_div);
391 w.set_pllsai1qen(true); 210 w.set_pllqen(true);
392 let freq = (src_freq / prediv.to_div() * mul.to_mul()) / q_div.to_div(); 211 let freq = src_freq / prediv * mul / q_div;
393 if freq == 48_000_000 { 212 if freq.0 == 48_000_000 {
394 RCC.ccipr().modify(|w| { 213 RCC.ccipr().modify(|w| {
395 w.set_clk48sel(0b1); 214 w.set_clk48sel(0b1);
396 }); 215 });
397 } 216 }
398 } 217 }
399 if let Some(p_div) = p_div { 218 if let Some(p_div) = p_div {
400 w.set_pllsai1pdiv(p_div.into()); 219 w.set_pllp(p_div);
401 w.set_pllsai1pen(true); 220 w.set_pllpen(true);
402 } 221 }
403 }); 222 });
404 223
@@ -425,17 +244,13 @@ pub(crate) unsafe fn init(config: Config) {
425 244
426 // Set flash wait states 245 // Set flash wait states
427 FLASH.acr().modify(|w| { 246 FLASH.acr().modify(|w| {
428 w.set_latency(if sys_clk <= 16_000_000 { 247 w.set_latency(match sys_clk.0 {
429 0b000 248 0..=16_000_000 => 0,
430 } else if sys_clk <= 32_000_000 { 249 0..=32_000_000 => 1,
431 0b001 250 0..=48_000_000 => 2,
432 } else if sys_clk <= 48_000_000 { 251 0..=64_000_000 => 3,
433 0b010 252 _ => 4,
434 } else if sys_clk <= 64_000_000 { 253 })
435 0b011
436 } else {
437 0b100
438 });
439 }); 254 });
440 255
441 RCC.cfgr().modify(|w| { 256 RCC.cfgr().modify(|w| {
@@ -445,43 +260,50 @@ pub(crate) unsafe fn init(config: Config) {
445 w.set_ppre2(config.apb2_pre.into()); 260 w.set_ppre2(config.apb2_pre.into());
446 }); 261 });
447 262
448 let ahb_freq: u32 = match config.ahb_pre { 263 let ahb_freq = sys_clk / config.ahb_pre;
449 AHBPrescaler::DIV1 => sys_clk,
450 pre => {
451 let pre: Hpre = pre.into();
452 let pre = 1 << (pre.to_bits() as u32 - 7);
453 sys_clk / pre
454 }
455 };
456 264
457 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { 265 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
458 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 266 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
459 pre => { 267 pre => {
460 let pre: Ppre = pre.into(); 268 let freq = ahb_freq / pre;
461 let pre: u8 = 1 << (pre.to_bits() - 3); 269 (freq, freq * 2u32)
462 let freq = ahb_freq / pre as u32;
463 (freq, freq * 2)
464 } 270 }
465 }; 271 };
466 272
467 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { 273 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
468 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 274 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
469 pre => { 275 pre => {
470 let pre: Ppre = pre.into(); 276 let freq = ahb_freq / pre;
471 let pre: u8 = 1 << (pre.to_bits() - 3); 277 (freq, freq * 2u32)
472 let freq = ahb_freq / pre as u32;
473 (freq, freq * 2)
474 } 278 }
475 }; 279 };
476 280
477 set_freqs(Clocks { 281 set_freqs(Clocks {
478 sys: Hertz(sys_clk), 282 sys: sys_clk,
479 ahb1: Hertz(ahb_freq), 283 ahb1: ahb_freq,
480 ahb2: Hertz(ahb_freq), 284 ahb2: ahb_freq,
481 ahb3: Hertz(ahb_freq), 285 ahb3: ahb_freq,
482 apb1: Hertz(apb1_freq), 286 apb1: apb1_freq,
483 apb2: Hertz(apb2_freq), 287 apb2: apb2_freq,
484 apb1_tim: Hertz(apb1_tim_freq), 288 apb1_tim: apb1_tim_freq,
485 apb2_tim: Hertz(apb2_tim_freq), 289 apb2_tim: apb2_tim_freq,
486 }); 290 });
487} 291}
292
293fn msirange_to_hertz(range: Msirange) -> Hertz {
294 match range {
295 MSIRange::RANGE100K => Hertz(100_000),
296 MSIRange::RANGE200K => Hertz(200_000),
297 MSIRange::RANGE400K => Hertz(400_000),
298 MSIRange::RANGE800K => Hertz(800_000),
299 MSIRange::RANGE1M => Hertz(1_000_000),
300 MSIRange::RANGE2M => Hertz(2_000_000),
301 MSIRange::RANGE4M => Hertz(4_000_000),
302 MSIRange::RANGE8M => Hertz(8_000_000),
303 MSIRange::RANGE16M => Hertz(16_000_000),
304 MSIRange::RANGE24M => Hertz(24_000_000),
305 MSIRange::RANGE32M => Hertz(32_000_000),
306 MSIRange::RANGE48M => Hertz(48_000_000),
307 _ => unreachable!(),
308 }
309}
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs
index 652bdcb7b..d9b3ee282 100644
--- a/embassy-stm32/src/rcc/l5.rs
+++ b/embassy-stm32/src/rcc/l5.rs
@@ -1,8 +1,11 @@
1use stm32_metapac::PWR; 1use crate::pac::rcc::regs::Cfgr;
2 2pub use crate::pac::rcc::vals::{
3pub use super::bus::{AHBPrescaler, APBPrescaler}; 3 Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
4use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; 4 Pllr as PllRDiv, Ppre as APBPrescaler,
5use crate::pac::{FLASH, RCC}; 5};
6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
7use crate::pac::{FLASH, PWR, RCC};
8use crate::rcc::bd::RtcClockSource;
6use crate::rcc::{set_freqs, Clocks}; 9use crate::rcc::{set_freqs, Clocks};
7use crate::time::Hertz; 10use crate::time::Hertz;
8 11
@@ -16,62 +19,11 @@ pub const LSI_FREQ: Hertz = Hertz(32_000);
16#[derive(Clone, Copy)] 19#[derive(Clone, Copy)]
17pub enum ClockSrc { 20pub enum ClockSrc {
18 MSI(MSIRange), 21 MSI(MSIRange),
19 PLL(PLLSource, PLLClkDiv, PLLSrcDiv, PLLMul, Option<PLL48Div>), 22 PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option<PllQDiv>),
20 HSE(Hertz), 23 HSE(Hertz),
21 HSI16, 24 HSI16,
22} 25}
23 26
24/// MSI Clock Range
25///
26/// These ranges control the frequency of the MSI. Internally, these ranges map
27/// to the `MSIRANGE` bits in the `RCC_ICSCR` register.
28#[derive(Clone, Copy)]
29pub enum MSIRange {
30 /// Around 100 kHz
31 Range0,
32 /// Around 200 kHz
33 Range1,
34 /// Around 400 kHz
35 Range2,
36 /// Around 800 kHz
37 Range3,
38 /// Around 1 MHz
39 Range4,
40 /// Around 2 MHz
41 Range5,
42 /// Around 4 MHz (reset value)
43 Range6,
44 /// Around 8 MHz
45 Range7,
46 /// Around 16 MHz
47 Range8,
48 /// Around 24 MHz
49 Range9,
50 /// Around 32 MHz
51 Range10,
52 /// Around 48 MHz
53 Range11,
54}
55
56impl Default for MSIRange {
57 fn default() -> MSIRange {
58 MSIRange::Range6
59 }
60}
61
62pub type PLL48Div = PLLClkDiv;
63pub type PLLSAI1RDiv = PLLClkDiv;
64pub type PLLSAI1QDiv = PLLClkDiv;
65pub type PLLSAI1PDiv = PLLClkDiv;
66
67/// PLL divider
68#[derive(Clone, Copy)]
69pub enum PLLDiv {
70 Div2,
71 Div3,
72 Div4,
73}
74
75/// PLL clock input source 27/// PLL clock input source
76#[derive(Clone, Copy)] 28#[derive(Clone, Copy)]
77pub enum PLLSource { 29pub enum PLLSource {
@@ -80,95 +32,6 @@ pub enum PLLSource {
80 MSI(MSIRange), 32 MSI(MSIRange),
81} 33}
82 34
83seq_macro::seq!(N in 8..=86 {
84 #[derive(Clone, Copy)]
85 pub enum PLLMul {
86 #(
87 Mul~N,
88 )*
89 }
90
91 impl From<PLLMul> for u8 {
92 fn from(val: PLLMul) -> u8 {
93 match val {
94 #(
95 PLLMul::Mul~N => N,
96 )*
97 }
98 }
99 }
100
101 impl PLLMul {
102 pub fn to_mul(self) -> u32 {
103 match self {
104 #(
105 PLLMul::Mul~N => N,
106 )*
107 }
108 }
109 }
110});
111
112#[derive(Clone, Copy)]
113pub enum PLLClkDiv {
114 Div2,
115 Div4,
116 Div6,
117 Div8,
118}
119
120impl PLLClkDiv {
121 pub fn to_div(self) -> u32 {
122 let val: u8 = self.into();
123 (val as u32 + 1) * 2
124 }
125}
126
127impl From<PLLClkDiv> for u8 {
128 fn from(val: PLLClkDiv) -> u8 {
129 match val {
130 PLLClkDiv::Div2 => 0b00,
131 PLLClkDiv::Div4 => 0b01,
132 PLLClkDiv::Div6 => 0b10,
133 PLLClkDiv::Div8 => 0b11,
134 }
135 }
136}
137
138#[derive(Clone, Copy)]
139pub enum PLLSrcDiv {
140 Div1,
141 Div2,
142 Div3,
143 Div4,
144 Div5,
145 Div6,
146 Div7,
147 Div8,
148}
149
150impl PLLSrcDiv {
151 pub fn to_div(self) -> u32 {
152 let val: u8 = self.into();
153 val as u32 + 1
154 }
155}
156
157impl From<PLLSrcDiv> for u8 {
158 fn from(val: PLLSrcDiv) -> u8 {
159 match val {
160 PLLSrcDiv::Div1 => 0b000,
161 PLLSrcDiv::Div2 => 0b001,
162 PLLSrcDiv::Div3 => 0b010,
163 PLLSrcDiv::Div4 => 0b011,
164 PLLSrcDiv::Div5 => 0b100,
165 PLLSrcDiv::Div6 => 0b101,
166 PLLSrcDiv::Div7 => 0b110,
167 PLLSrcDiv::Div8 => 0b111,
168 }
169 }
170}
171
172impl From<PLLSource> for Pllsrc { 35impl From<PLLSource> for Pllsrc {
173 fn from(val: PLLSource) -> Pllsrc { 36 fn from(val: PLLSource) -> Pllsrc {
174 match val { 37 match val {
@@ -179,75 +42,59 @@ impl From<PLLSource> for Pllsrc {
179 } 42 }
180} 43}
181 44
182impl From<MSIRange> for Msirange {
183 fn from(val: MSIRange) -> Msirange {
184 match val {
185 MSIRange::Range0 => Msirange::RANGE100K,
186 MSIRange::Range1 => Msirange::RANGE200K,
187 MSIRange::Range2 => Msirange::RANGE400K,
188 MSIRange::Range3 => Msirange::RANGE800K,
189 MSIRange::Range4 => Msirange::RANGE1M,
190 MSIRange::Range5 => Msirange::RANGE2M,
191 MSIRange::Range6 => Msirange::RANGE4M,
192 MSIRange::Range7 => Msirange::RANGE8M,
193 MSIRange::Range8 => Msirange::RANGE16M,
194 MSIRange::Range9 => Msirange::RANGE24M,
195 MSIRange::Range10 => Msirange::RANGE32M,
196 MSIRange::Range11 => Msirange::RANGE48M,
197 }
198 }
199}
200
201impl From<MSIRange> for u32 {
202 fn from(val: MSIRange) -> u32 {
203 match val {
204 MSIRange::Range0 => 100_000,
205 MSIRange::Range1 => 200_000,
206 MSIRange::Range2 => 400_000,
207 MSIRange::Range3 => 800_000,
208 MSIRange::Range4 => 1_000_000,
209 MSIRange::Range5 => 2_000_000,
210 MSIRange::Range6 => 4_000_000,
211 MSIRange::Range7 => 8_000_000,
212 MSIRange::Range8 => 16_000_000,
213 MSIRange::Range9 => 24_000_000,
214 MSIRange::Range10 => 32_000_000,
215 MSIRange::Range11 => 48_000_000,
216 }
217 }
218}
219
220/// Clocks configutation 45/// Clocks configutation
221pub struct Config { 46pub struct Config {
222 pub mux: ClockSrc, 47 pub mux: ClockSrc,
223 pub ahb_pre: AHBPrescaler, 48 pub ahb_pre: AHBPrescaler,
224 pub apb1_pre: APBPrescaler, 49 pub apb1_pre: APBPrescaler,
225 pub apb2_pre: APBPrescaler, 50 pub apb2_pre: APBPrescaler,
226 pub pllsai1: Option<( 51 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
227 PLLMul,
228 PLLSrcDiv,
229 Option<PLLSAI1RDiv>,
230 Option<PLLSAI1QDiv>,
231 Option<PLLSAI1PDiv>,
232 )>,
233 pub hsi48: bool, 52 pub hsi48: bool,
53 pub rtc_mux: RtcClockSource,
54 pub lse: Option<Hertz>,
55 pub lsi: bool,
234} 56}
235 57
236impl Default for Config { 58impl Default for Config {
237 #[inline] 59 #[inline]
238 fn default() -> Config { 60 fn default() -> Config {
239 Config { 61 Config {
240 mux: ClockSrc::MSI(MSIRange::Range6), 62 mux: ClockSrc::MSI(MSIRange::RANGE4M),
241 ahb_pre: AHBPrescaler::DIV1, 63 ahb_pre: AHBPrescaler::DIV1,
242 apb1_pre: APBPrescaler::DIV1, 64 apb1_pre: APBPrescaler::DIV1,
243 apb2_pre: APBPrescaler::DIV1, 65 apb2_pre: APBPrescaler::DIV1,
244 pllsai1: None, 66 pllsai1: None,
245 hsi48: false, 67 hsi48: false,
68 rtc_mux: RtcClockSource::LSI,
69 lsi: true,
70 lse: None,
246 } 71 }
247 } 72 }
248} 73}
249 74
250pub(crate) unsafe fn init(config: Config) { 75pub(crate) unsafe fn init(config: Config) {
76 // Switch to MSI to prevent problems with PLL configuration.
77 if !RCC.cr().read().msion() {
78 // Turn on MSI and configure it to 4MHz.
79 RCC.cr().modify(|w| {
80 w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0].
81 w.set_msirange(MSIRange::RANGE4M);
82 w.set_msipllen(false);
83 w.set_msion(true)
84 });
85
86 // Wait until MSI is running
87 while !RCC.cr().read().msirdy() {}
88 }
89 if RCC.cfgr().read().sws() != Sw::MSI {
90 // Set MSI as a clock source, reset prescalers.
91 RCC.cfgr().write_value(Cfgr::default());
92 // Wait for clock switch status bits to change.
93 while RCC.cfgr().read().sws() != Sw::MSI {}
94 }
95
96 //BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default()));
97
251 PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0)); 98 PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0));
252 let (sys_clk, sw) = match config.mux { 99 let (sys_clk, sw) = match config.mux {
253 ClockSrc::MSI(range) => { 100 ClockSrc::MSI(range) => {
@@ -255,47 +102,53 @@ pub(crate) unsafe fn init(config: Config) {
255 RCC.cr().write(|w| { 102 RCC.cr().write(|w| {
256 let bits: Msirange = range.into(); 103 let bits: Msirange = range.into();
257 w.set_msirange(bits); 104 w.set_msirange(bits);
258 w.set_msipllen(false);
259 w.set_msirgsel(true); 105 w.set_msirgsel(true);
260 w.set_msion(true); 106 w.set_msion(true);
107
108 if config.rtc_mux == RtcClockSource::LSE {
109 // If LSE is enabled, enable calibration of MSI
110 w.set_msipllen(true);
111 } else {
112 w.set_msipllen(false);
113 }
261 }); 114 });
262 while !RCC.cr().read().msirdy() {} 115 while !RCC.cr().read().msirdy() {}
263 116
264 // Enable as clock source for USB, RNG if running at 48 MHz 117 // Enable as clock source for USB, RNG if running at 48 MHz
265 if let MSIRange::Range11 = range { 118 if range == MSIRange::RANGE48M {
266 RCC.ccipr1().modify(|w| { 119 RCC.ccipr1().modify(|w| {
267 w.set_clk48msel(0b11); 120 w.set_clk48msel(0b11);
268 }); 121 });
269 } 122 }
270 (range.into(), Sw::MSI) 123 (msirange_to_hertz(range), Sw::MSI)
271 } 124 }
272 ClockSrc::HSI16 => { 125 ClockSrc::HSI16 => {
273 // Enable HSI16 126 // Enable HSI16
274 RCC.cr().write(|w| w.set_hsion(true)); 127 RCC.cr().write(|w| w.set_hsion(true));
275 while !RCC.cr().read().hsirdy() {} 128 while !RCC.cr().read().hsirdy() {}
276 129
277 (HSI_FREQ.0, Sw::HSI16) 130 (HSI_FREQ, Sw::HSI16)
278 } 131 }
279 ClockSrc::HSE(freq) => { 132 ClockSrc::HSE(freq) => {
280 // Enable HSE 133 // Enable HSE
281 RCC.cr().write(|w| w.set_hseon(true)); 134 RCC.cr().write(|w| w.set_hseon(true));
282 while !RCC.cr().read().hserdy() {} 135 while !RCC.cr().read().hserdy() {}
283 136
284 (freq.0, Sw::HSE) 137 (freq, Sw::HSE)
285 } 138 }
286 ClockSrc::PLL(src, div, prediv, mul, pll48div) => { 139 ClockSrc::PLL(src, divr, prediv, mul, divq) => {
287 let src_freq = match src { 140 let src_freq = match src {
288 PLLSource::HSE(freq) => { 141 PLLSource::HSE(freq) => {
289 // Enable HSE 142 // Enable HSE
290 RCC.cr().write(|w| w.set_hseon(true)); 143 RCC.cr().write(|w| w.set_hseon(true));
291 while !RCC.cr().read().hserdy() {} 144 while !RCC.cr().read().hserdy() {}
292 freq.0 145 freq
293 } 146 }
294 PLLSource::HSI16 => { 147 PLLSource::HSI16 => {
295 // Enable HSI 148 // Enable HSI
296 RCC.cr().write(|w| w.set_hsion(true)); 149 RCC.cr().write(|w| w.set_hsion(true));
297 while !RCC.cr().read().hsirdy() {} 150 while !RCC.cr().read().hsirdy() {}
298 HSI_FREQ.0 151 HSI_FREQ
299 } 152 }
300 PLLSource::MSI(range) => { 153 PLLSource::MSI(range) => {
301 // Enable MSI 154 // Enable MSI
@@ -307,7 +160,8 @@ pub(crate) unsafe fn init(config: Config) {
307 w.set_msion(true); 160 w.set_msion(true);
308 }); 161 });
309 while !RCC.cr().read().msirdy() {} 162 while !RCC.cr().read().msirdy() {}
310 range.into() 163
164 msirange_to_hertz(range)
311 } 165 }
312 }; 166 };
313 167
@@ -315,23 +169,23 @@ pub(crate) unsafe fn init(config: Config) {
315 RCC.cr().modify(|w| w.set_pllon(false)); 169 RCC.cr().modify(|w| w.set_pllon(false));
316 while RCC.cr().read().pllrdy() {} 170 while RCC.cr().read().pllrdy() {}
317 171
318 let freq = (src_freq / prediv.to_div() * mul.to_mul()) / div.to_div(); 172 let freq = src_freq / prediv * mul / divr;
319 173
320 RCC.pllcfgr().write(move |w| { 174 RCC.pllcfgr().write(move |w| {
321 w.set_plln(mul.into()); 175 w.set_plln(mul);
322 w.set_pllm(prediv.into()); 176 w.set_pllm(prediv);
323 w.set_pllr(div.into()); 177 w.set_pllr(divr);
324 if let Some(pll48div) = pll48div { 178 if let Some(divq) = divq {
325 w.set_pllq(pll48div.into()); 179 w.set_pllq(divq);
326 w.set_pllqen(true); 180 w.set_pllqen(true);
327 } 181 }
328 w.set_pllsrc(src.into()); 182 w.set_pllsrc(src.into());
329 }); 183 });
330 184
331 // Enable as clock source for USB, RNG if PLL48 divisor is provided 185 // Enable as clock source for USB, RNG if PLL48 divisor is provided
332 if let Some(pll48div) = pll48div { 186 if let Some(divq) = divq {
333 let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div(); 187 let freq = src_freq / prediv * mul / divq;
334 assert!(freq == 48_000_000); 188 assert!(freq.0 == 48_000_000);
335 RCC.ccipr1().modify(|w| { 189 RCC.ccipr1().modify(|w| {
336 w.set_clk48msel(0b10); 190 w.set_clk48msel(0b10);
337 }); 191 });
@@ -339,25 +193,25 @@ pub(crate) unsafe fn init(config: Config) {
339 193
340 if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { 194 if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 {
341 RCC.pllsai1cfgr().write(move |w| { 195 RCC.pllsai1cfgr().write(move |w| {
342 w.set_pllsai1n(mul.into()); 196 w.set_plln(mul);
343 w.set_pllsai1m(prediv.into()); 197 w.set_pllm(prediv);
344 if let Some(r_div) = r_div { 198 if let Some(r_div) = r_div {
345 w.set_pllsai1r(r_div.into()); 199 w.set_pllr(r_div);
346 w.set_pllsai1ren(true); 200 w.set_pllren(true);
347 } 201 }
348 if let Some(q_div) = q_div { 202 if let Some(q_div) = q_div {
349 w.set_pllsai1q(q_div.into()); 203 w.set_pllq(q_div);
350 w.set_pllsai1qen(true); 204 w.set_pllqen(true);
351 let freq = (src_freq / prediv.to_div() * mul.to_mul()) / q_div.to_div(); 205 let freq = src_freq / prediv * mul / q_div;
352 if freq == 48_000_000 { 206 if freq.0 == 48_000_000 {
353 RCC.ccipr1().modify(|w| { 207 RCC.ccipr1().modify(|w| {
354 w.set_clk48msel(0b1); 208 w.set_clk48msel(0b1);
355 }); 209 });
356 } 210 }
357 } 211 }
358 if let Some(p_div) = p_div { 212 if let Some(p_div) = p_div {
359 w.set_pllsai1pdiv(p_div.into()); 213 w.set_pllp(p_div);
360 w.set_pllsai1pen(true); 214 w.set_pllpen(true);
361 } 215 }
362 }); 216 });
363 217
@@ -384,7 +238,7 @@ pub(crate) unsafe fn init(config: Config) {
384 // Set flash wait states 238 // Set flash wait states
385 // VCORE Range 0 (performance), others TODO 239 // VCORE Range 0 (performance), others TODO
386 FLASH.acr().modify(|w| { 240 FLASH.acr().modify(|w| {
387 w.set_latency(match sys_clk { 241 w.set_latency(match sys_clk.0 {
388 0..=20_000_000 => 0, 242 0..=20_000_000 => 0,
389 0..=40_000_000 => 1, 243 0..=40_000_000 => 1,
390 0..=60_000_000 => 2, 244 0..=60_000_000 => 2,
@@ -401,43 +255,50 @@ pub(crate) unsafe fn init(config: Config) {
401 w.set_ppre2(config.apb2_pre.into()); 255 w.set_ppre2(config.apb2_pre.into());
402 }); 256 });
403 257
404 let ahb_freq: u32 = match config.ahb_pre { 258 let ahb_freq = sys_clk / config.ahb_pre;
405 AHBPrescaler::DIV1 => sys_clk,
406 pre => {
407 let pre: Hpre = pre.into();
408 let pre = 1 << (pre.to_bits() as u32 - 7);
409 sys_clk / pre
410 }
411 };
412 259
413 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { 260 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
414 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 261 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
415 pre => { 262 pre => {
416 let pre: Ppre = pre.into(); 263 let freq = ahb_freq / pre;
417 let pre: u8 = 1 << (pre.to_bits() - 3); 264 (freq, freq * 2u32)
418 let freq = ahb_freq / pre as u32;
419 (freq, freq * 2)
420 } 265 }
421 }; 266 };
422 267
423 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { 268 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
424 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 269 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
425 pre => { 270 pre => {
426 let pre: Ppre = pre.into(); 271 let freq = ahb_freq / pre;
427 let pre: u8 = 1 << (pre.to_bits() - 3); 272 (freq, freq * 2u32)
428 let freq = ahb_freq / pre as u32;
429 (freq, freq * 2)
430 } 273 }
431 }; 274 };
432 275
433 set_freqs(Clocks { 276 set_freqs(Clocks {
434 sys: Hertz(sys_clk), 277 sys: sys_clk,
435 ahb1: Hertz(ahb_freq), 278 ahb1: ahb_freq,
436 ahb2: Hertz(ahb_freq), 279 ahb2: ahb_freq,
437 ahb3: Hertz(ahb_freq), 280 ahb3: ahb_freq,
438 apb1: Hertz(apb1_freq), 281 apb1: apb1_freq,
439 apb2: Hertz(apb2_freq), 282 apb2: apb2_freq,
440 apb1_tim: Hertz(apb1_tim_freq), 283 apb1_tim: apb1_tim_freq,
441 apb2_tim: Hertz(apb2_tim_freq), 284 apb2_tim: apb2_tim_freq,
442 }); 285 });
443} 286}
287
288fn msirange_to_hertz(range: Msirange) -> Hertz {
289 match range {
290 MSIRange::RANGE100K => Hertz(100_000),
291 MSIRange::RANGE200K => Hertz(200_000),
292 MSIRange::RANGE400K => Hertz(400_000),
293 MSIRange::RANGE800K => Hertz(800_000),
294 MSIRange::RANGE1M => Hertz(1_000_000),
295 MSIRange::RANGE2M => Hertz(2_000_000),
296 MSIRange::RANGE4M => Hertz(4_000_000),
297 MSIRange::RANGE8M => Hertz(8_000_000),
298 MSIRange::RANGE16M => Hertz(16_000_000),
299 MSIRange::RANGE24M => Hertz(24_000_000),
300 MSIRange::RANGE32M => Hertz(32_000_000),
301 MSIRange::RANGE48M => Hertz(48_000_000),
302 _ => unreachable!(),
303 }
304}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index a32990890..52dc386b4 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -6,7 +6,6 @@ pub use crate::rcc::bd::RtcClockSource;
6use crate::time::Hertz; 6use crate::time::Hertz;
7 7
8pub(crate) mod bd; 8pub(crate) mod bd;
9mod bus;
10mod mco; 9mod mco;
11pub use mco::*; 10pub use mco::*;
12 11
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 14b8577df..d8fb17301 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -1,6 +1,5 @@
1use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllmboost, Pllrge, Pllsrc, Sw}; 1pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange, Plldiv, Pllm, Plln, Ppre as APBPrescaler};
2 2use crate::pac::rcc::vals::{Msirgsel, Pllmboost, Pllrge, Pllsrc, Sw};
3pub use super::bus::{AHBPrescaler, APBPrescaler};
4use crate::pac::{FLASH, PWR, RCC}; 3use crate::pac::{FLASH, PWR, RCC};
5use crate::rcc::{set_freqs, Clocks}; 4use crate::rcc::{set_freqs, Clocks};
6use crate::time::Hertz; 5use crate::time::Hertz;
@@ -16,7 +15,7 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale;
16#[derive(Copy, Clone)] 15#[derive(Copy, Clone)]
17pub enum ClockSrc { 16pub enum ClockSrc {
18 /// Use an internal medium speed oscillator (MSIS) as the system clock. 17 /// Use an internal medium speed oscillator (MSIS) as the system clock.
19 MSI(MSIRange), 18 MSI(Msirange),
20 /// Use the external high speed clock as the system clock. 19 /// Use the external high speed clock as the system clock.
21 /// 20 ///
22 /// HSE clocks faster than 25 MHz require at least `VoltageScale::RANGE3`, and HSE clocks must 21 /// HSE clocks faster than 25 MHz require at least `VoltageScale::RANGE3`, and HSE clocks must
@@ -31,29 +30,29 @@ pub enum ClockSrc {
31impl Default for ClockSrc { 30impl Default for ClockSrc {
32 fn default() -> Self { 31 fn default() -> Self {
33 // The default system clock source is MSIS @ 4 MHz, per RM0456 § 11.4.9 32 // The default system clock source is MSIS @ 4 MHz, per RM0456 § 11.4.9
34 ClockSrc::MSI(MSIRange::Range4mhz) 33 ClockSrc::MSI(Msirange::RANGE_4MHZ)
35 } 34 }
36} 35}
37 36
38#[derive(Clone, Copy, Debug)] 37#[derive(Clone, Copy)]
39pub struct PllConfig { 38pub struct PllConfig {
40 /// The clock source for the PLL. 39 /// The clock source for the PLL.
41 pub source: PllSrc, 40 pub source: PllSrc,
42 /// The PLL prescaler. 41 /// The PLL prescaler.
43 /// 42 ///
44 /// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz. 43 /// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz.
45 pub m: PllM, 44 pub m: Pllm,
46 /// The PLL multiplier. 45 /// The PLL multiplier.
47 /// 46 ///
48 /// The multiplied clock – `source` divided by `m` times `n` – must be between 128 and 544 47 /// The multiplied clock – `source` divided by `m` times `n` – must be between 128 and 544
49 /// MHz. The upper limit may be lower depending on the `Config { voltage_range }`. 48 /// MHz. The upper limit may be lower depending on the `Config { voltage_range }`.
50 pub n: PllN, 49 pub n: Plln,
51 /// The divider for the R output. 50 /// The divider for the R output.
52 /// 51 ///
53 /// When used to drive the system clock, `source` divided by `m` times `n` divided by `r` 52 /// When used to drive the system clock, `source` divided by `m` times `n` divided by `r`
54 /// must not exceed 160 MHz. System clocks above 55 MHz require a non-default 53 /// must not exceed 160 MHz. System clocks above 55 MHz require a non-default
55 /// `Config { voltage_range }`. 54 /// `Config { voltage_range }`.
56 pub r: PllClkDiv, 55 pub r: Plldiv,
57} 56}
58 57
59impl PllConfig { 58impl PllConfig {
@@ -61,27 +60,27 @@ impl PllConfig {
61 pub const fn hsi16_160mhz() -> Self { 60 pub const fn hsi16_160mhz() -> Self {
62 PllConfig { 61 PllConfig {
63 source: PllSrc::HSI16, 62 source: PllSrc::HSI16,
64 m: PllM::NotDivided, 63 m: Pllm::DIV1,
65 n: PllN::Mul10, 64 n: Plln::MUL10,
66 r: PllClkDiv::NotDivided, 65 r: Plldiv::DIV1,
67 } 66 }
68 } 67 }
69 68
70 /// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz 69 /// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz
71 pub const fn msis_160mhz() -> Self { 70 pub const fn msis_160mhz() -> Self {
72 PllConfig { 71 PllConfig {
73 source: PllSrc::MSIS(MSIRange::Range48mhz), 72 source: PllSrc::MSIS(Msirange::RANGE_48MHZ),
74 m: PllM::Div3, 73 m: Pllm::DIV3,
75 n: PllN::Mul10, 74 n: Plln::MUL10,
76 r: PllClkDiv::NotDivided, 75 r: Plldiv::DIV1,
77 } 76 }
78 } 77 }
79} 78}
80 79
81#[derive(Clone, Copy, Debug)] 80#[derive(Clone, Copy)]
82pub enum PllSrc { 81pub enum PllSrc {
83 /// Use an internal medium speed oscillator as the PLL source. 82 /// Use an internal medium speed oscillator as the PLL source.
84 MSIS(MSIRange), 83 MSIS(Msirange),
85 /// Use the external high speed clock as the system PLL source. 84 /// Use the external high speed clock as the system PLL source.
86 /// 85 ///
87 /// HSE clocks faster than 25 MHz require at least `VoltageScale::RANGE3`, and HSE clocks must 86 /// HSE clocks faster than 25 MHz require at least `VoltageScale::RANGE3`, and HSE clocks must
@@ -101,75 +100,6 @@ impl Into<Pllsrc> for PllSrc {
101 } 100 }
102} 101}
103 102
104seq_macro::seq!(N in 2..=128 {
105 #[derive(Copy, Clone, Debug)]
106 pub enum PllClkDiv {
107 NotDivided = 1,
108 #(
109 Div~N = N,
110 )*
111 }
112
113 impl PllClkDiv {
114 fn to_div(&self) -> u8 {
115 match self {
116 PllClkDiv::NotDivided => 0,
117 #(
118 PllClkDiv::Div~N => N - 1,
119 )*
120 }
121 }
122 }
123});
124
125seq_macro::seq!(N in 4..=512 {
126 #[derive(Copy, Clone, Debug)]
127 pub enum PllN {
128 NotMultiplied = 1,
129 #(
130 Mul~N = N,
131 )*
132 }
133
134 impl PllN {
135 fn to_mul(&self) -> u16 {
136 match self {
137 PllN::NotMultiplied => 0,
138 #(
139 PllN::Mul~N => N - 1,
140 )*
141 }
142 }
143 }
144});
145
146// Pre-division
147#[derive(Copy, Clone, Debug)]
148pub enum PllM {
149 NotDivided = 0b0000,
150 Div2 = 0b0001,
151 Div3 = 0b0010,
152 Div4 = 0b0011,
153 Div5 = 0b0100,
154 Div6 = 0b0101,
155 Div7 = 0b0110,
156 Div8 = 0b0111,
157 Div9 = 0b1000,
158 Div10 = 0b1001,
159 Div11 = 0b1010,
160 Div12 = 0b1011,
161 Div13 = 0b1100,
162 Div14 = 0b1101,
163 Div15 = 0b1110,
164 Div16 = 0b1111,
165}
166
167impl Into<Pllm> for PllM {
168 fn into(self) -> Pllm {
169 Pllm::from_bits(self as u8)
170 }
171}
172
173impl Into<Sw> for ClockSrc { 103impl Into<Sw> for ClockSrc {
174 fn into(self) -> Sw { 104 fn into(self) -> Sw {
175 match self { 105 match self {
@@ -181,56 +111,6 @@ impl Into<Sw> for ClockSrc {
181 } 111 }
182} 112}
183 113
184#[derive(Debug, Copy, Clone)]
185pub enum MSIRange {
186 /// The 48 MHz MSI speed is unavailable in `VoltageScale::RANGE4`.
187 Range48mhz = 48_000_000,
188 Range24mhz = 24_000_000,
189 Range16mhz = 16_000_000,
190 Range12mhz = 12_000_000,
191 Range4mhz = 4_000_000,
192 Range2mhz = 2_000_000,
193 Range1_33mhz = 1_330_000,
194 Range1mhz = 1_000_000,
195 Range3_072mhz = 3_072_000,
196 Range1_536mhz = 1_536_000,
197 Range1_024mhz = 1_024_000,
198 Range768khz = 768_000,
199 Range400khz = 400_000,
200 Range200khz = 200_000,
201 Range133khz = 133_000,
202 Range100khz = 100_000,
203}
204
205impl Into<u32> for MSIRange {
206 fn into(self) -> u32 {
207 self as u32
208 }
209}
210
211impl Into<Msirange> for MSIRange {
212 fn into(self) -> Msirange {
213 match self {
214 MSIRange::Range48mhz => Msirange::RANGE_48MHZ,
215 MSIRange::Range24mhz => Msirange::RANGE_24MHZ,
216 MSIRange::Range16mhz => Msirange::RANGE_16MHZ,
217 MSIRange::Range12mhz => Msirange::RANGE_12MHZ,
218 MSIRange::Range4mhz => Msirange::RANGE_4MHZ,
219 MSIRange::Range2mhz => Msirange::RANGE_2MHZ,
220 MSIRange::Range1_33mhz => Msirange::RANGE_1_33MHZ,
221 MSIRange::Range1mhz => Msirange::RANGE_1MHZ,
222 MSIRange::Range3_072mhz => Msirange::RANGE_3_072MHZ,
223 MSIRange::Range1_536mhz => Msirange::RANGE_1_536MHZ,
224 MSIRange::Range1_024mhz => Msirange::RANGE_1_024MHZ,
225 MSIRange::Range768khz => Msirange::RANGE_768KHZ,
226 MSIRange::Range400khz => Msirange::RANGE_400KHZ,
227 MSIRange::Range200khz => Msirange::RANGE_200KHZ,
228 MSIRange::Range133khz => Msirange::RANGE_133KHZ,
229 MSIRange::Range100khz => Msirange::RANGE_100KHZ,
230 }
231 }
232}
233
234#[derive(Copy, Clone)] 114#[derive(Copy, Clone)]
235pub struct Config { 115pub struct Config {
236 pub mux: ClockSrc, 116 pub mux: ClockSrc,
@@ -273,11 +153,11 @@ impl Config {
273 frequency 153 frequency
274 } 154 }
275 155
276 unsafe fn init_msis(&self, range: MSIRange) -> Hertz { 156 unsafe fn init_msis(&self, range: Msirange) -> Hertz {
277 // Check MSI output per RM0456 § 11.4.10 157 // Check MSI output per RM0456 § 11.4.10
278 match self.voltage_range { 158 match self.voltage_range {
279 VoltageScale::RANGE4 => { 159 VoltageScale::RANGE4 => {
280 assert!(range as u32 <= 24_000_000); 160 assert!(msirange_to_hertz(range).0 <= 24_000_000);
281 } 161 }
282 _ => {} 162 _ => {}
283 } 163 }
@@ -291,8 +171,7 @@ impl Config {
291 } 171 }
292 172
293 RCC.icscr1().modify(|w| { 173 RCC.icscr1().modify(|w| {
294 let bits: Msirange = range.into(); 174 w.set_msisrange(range);
295 w.set_msisrange(bits);
296 w.set_msirgsel(Msirgsel::RCC_ICSCR1); 175 w.set_msirgsel(Msirgsel::RCC_ICSCR1);
297 }); 176 });
298 RCC.cr().write(|w| { 177 RCC.cr().write(|w| {
@@ -300,7 +179,7 @@ impl Config {
300 w.set_msison(true); 179 w.set_msison(true);
301 }); 180 });
302 while !RCC.cr().read().msisrdy() {} 181 while !RCC.cr().read().msisrdy() {}
303 Hertz(range as u32) 182 msirange_to_hertz(range)
304 } 183 }
305} 184}
306 185
@@ -344,14 +223,14 @@ pub(crate) unsafe fn init(config: Config) {
344 }; 223 };
345 224
346 // Calculate the reference clock, which is the source divided by m 225 // Calculate the reference clock, which is the source divided by m
347 let reference_clk = source_clk / (pll.m as u8 as u32 + 1); 226 let reference_clk = source_clk / pll.m;
348 227
349 // Check limits per RM0456 § 11.4.6 228 // Check limits per RM0456 § 11.4.6
350 assert!(Hertz::mhz(4) <= reference_clk && reference_clk <= Hertz::mhz(16)); 229 assert!(Hertz::mhz(4) <= reference_clk && reference_clk <= Hertz::mhz(16));
351 230
352 // Calculate the PLL1 VCO clock and PLL1 R output clock 231 // Calculate the PLL1 VCO clock and PLL1 R output clock
353 let pll1_clk = reference_clk * (pll.n as u8 as u32); 232 let pll1_clk = reference_clk * pll.n;
354 let pll1r_clk = pll1_clk / (pll.r as u8 as u32); 233 let pll1r_clk = pll1_clk / pll.r;
355 234
356 // Check system clock per RM0456 § 11.4.9 235 // Check system clock per RM0456 § 11.4.9
357 assert!(pll1r_clk <= Hertz::mhz(160)); 236 assert!(pll1r_clk <= Hertz::mhz(160));
@@ -387,11 +266,11 @@ pub(crate) unsafe fn init(config: Config) {
387 Pllmboost::DIV2 266 Pllmboost::DIV2
388 } else { 267 } else {
389 // Bypass, giving EPOD 4-16 MHz 268 // Bypass, giving EPOD 4-16 MHz
390 Pllmboost::BYPASS 269 Pllmboost::DIV1
391 } 270 }
392 } else { 271 } else {
393 // Nothing to do 272 // Nothing to do
394 Pllmboost::BYPASS 273 Pllmboost::DIV1
395 }; 274 };
396 275
397 // Disable the PLL, and wait for it to disable 276 // Disable the PLL, and wait for it to disable
@@ -402,7 +281,7 @@ pub(crate) unsafe fn init(config: Config) {
402 RCC.pll1cfgr().write(|w| { 281 RCC.pll1cfgr().write(|w| {
403 // Configure PLL1 source and prescaler 282 // Configure PLL1 source and prescaler
404 w.set_pllsrc(pll.source.into()); 283 w.set_pllsrc(pll.source.into());
405 w.set_pllm(pll.m.into()); 284 w.set_pllm(pll.m);
406 285
407 // Configure PLL1 input frequncy range 286 // Configure PLL1 input frequncy range
408 let input_range = if reference_clk <= Hertz::mhz(8) { 287 let input_range = if reference_clk <= Hertz::mhz(8) {
@@ -422,9 +301,9 @@ pub(crate) unsafe fn init(config: Config) {
422 // Configure the PLL divisors 301 // Configure the PLL divisors
423 RCC.pll1divr().modify(|w| { 302 RCC.pll1divr().modify(|w| {
424 // Set the VCO multiplier 303 // Set the VCO multiplier
425 w.set_plln(pll.n.to_mul()); 304 w.set_plln(pll.n);
426 // Set the R output divisor 305 // Set the R output divisor
427 w.set_pllr(pll.r.to_div()); 306 w.set_pllr(pll.r);
428 }); 307 });
429 308
430 // Do we need the EPOD booster to reach the target clock speed per § 10.5.4? 309 // Do we need the EPOD booster to reach the target clock speed per § 10.5.4?
@@ -442,8 +321,7 @@ pub(crate) unsafe fn init(config: Config) {
442 321
443 pll1r_clk 322 pll1r_clk
444 } 323 }
445 } 324 };
446 .0;
447 325
448 if config.hsi48 { 326 if config.hsi48 {
449 RCC.cr().modify(|w| w.set_hsi48on(true)); 327 RCC.cr().modify(|w| w.set_hsi48on(true));
@@ -455,13 +333,13 @@ pub(crate) unsafe fn init(config: Config) {
455 let wait_states = match config.voltage_range { 333 let wait_states = match config.voltage_range {
456 // VOS 1 range VCORE 1.26V - 1.40V 334 // VOS 1 range VCORE 1.26V - 1.40V
457 VoltageScale::RANGE1 => { 335 VoltageScale::RANGE1 => {
458 if sys_clk < 32_000_000 { 336 if sys_clk.0 < 32_000_000 {
459 0 337 0
460 } else if sys_clk < 64_000_000 { 338 } else if sys_clk.0 < 64_000_000 {
461 1 339 1
462 } else if sys_clk < 96_000_000 { 340 } else if sys_clk.0 < 96_000_000 {
463 2 341 2
464 } else if sys_clk < 128_000_000 { 342 } else if sys_clk.0 < 128_000_000 {
465 3 343 3
466 } else { 344 } else {
467 4 345 4
@@ -469,11 +347,11 @@ pub(crate) unsafe fn init(config: Config) {
469 } 347 }
470 // VOS 2 range VCORE 1.15V - 1.26V 348 // VOS 2 range VCORE 1.15V - 1.26V
471 VoltageScale::RANGE2 => { 349 VoltageScale::RANGE2 => {
472 if sys_clk < 30_000_000 { 350 if sys_clk.0 < 30_000_000 {
473 0 351 0
474 } else if sys_clk < 60_000_000 { 352 } else if sys_clk.0 < 60_000_000 {
475 1 353 1
476 } else if sys_clk < 90_000_000 { 354 } else if sys_clk.0 < 90_000_000 {
477 2 355 2
478 } else { 356 } else {
479 3 357 3
@@ -481,9 +359,9 @@ pub(crate) unsafe fn init(config: Config) {
481 } 359 }
482 // VOS 3 range VCORE 1.05V - 1.15V 360 // VOS 3 range VCORE 1.05V - 1.15V
483 VoltageScale::RANGE3 => { 361 VoltageScale::RANGE3 => {
484 if sys_clk < 24_000_000 { 362 if sys_clk.0 < 24_000_000 {
485 0 363 0
486 } else if sys_clk < 48_000_000 { 364 } else if sys_clk.0 < 48_000_000 {
487 1 365 1
488 } else { 366 } else {
489 2 367 2
@@ -491,7 +369,7 @@ pub(crate) unsafe fn init(config: Config) {
491 } 369 }
492 // VOS 4 range VCORE 0.95V - 1.05V 370 // VOS 4 range VCORE 0.95V - 1.05V
493 VoltageScale::RANGE4 => { 371 VoltageScale::RANGE4 => {
494 if sys_clk < 12_000_000 { 372 if sys_clk.0 < 12_000_000 {
495 0 373 0
496 } else { 374 } else {
497 1 375 1
@@ -522,62 +400,70 @@ pub(crate) unsafe fn init(config: Config) {
522 400
523 // Configure the bus prescalers 401 // Configure the bus prescalers
524 RCC.cfgr2().modify(|w| { 402 RCC.cfgr2().modify(|w| {
525 w.set_hpre(config.ahb_pre.into()); 403 w.set_hpre(config.ahb_pre);
526 w.set_ppre1(config.apb1_pre.into()); 404 w.set_ppre1(config.apb1_pre);
527 w.set_ppre2(config.apb2_pre.into()); 405 w.set_ppre2(config.apb2_pre);
528 }); 406 });
529 RCC.cfgr3().modify(|w| { 407 RCC.cfgr3().modify(|w| {
530 w.set_ppre3(config.apb3_pre.into()); 408 w.set_ppre3(config.apb3_pre);
531 }); 409 });
532 410
533 let ahb_freq: u32 = match config.ahb_pre { 411 let ahb_freq = sys_clk / config.ahb_pre;
534 AHBPrescaler::DIV1 => sys_clk,
535 pre => {
536 let pre: u8 = pre.into();
537 let pre = 1 << (pre as u32 - 7);
538 sys_clk / pre
539 }
540 };
541 412
542 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { 413 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
543 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 414 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
544 pre => { 415 pre => {
545 let pre: u8 = pre.into(); 416 let freq = ahb_freq / pre;
546 let pre: u8 = 1 << (pre - 3); 417 (freq, freq * 2u32)
547 let freq = ahb_freq / pre as u32;
548 (freq, freq * 2)
549 } 418 }
550 }; 419 };
551 420
552 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { 421 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
553 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 422 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
554 pre => { 423 pre => {
555 let pre: u8 = pre.into(); 424 let freq = ahb_freq / pre;
556 let pre: u8 = 1 << (pre - 3); 425 (freq, freq * 2u32)
557 let freq = ahb_freq / pre as u32;
558 (freq, freq * 2)
559 } 426 }
560 }; 427 };
561 428
562 let (apb3_freq, _apb3_tim_freq) = match config.apb3_pre { 429 let (apb3_freq, _apb3_tim_freq) = match config.apb3_pre {
563 APBPrescaler::DIV1 => (ahb_freq, ahb_freq), 430 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
564 pre => { 431 pre => {
565 let pre: u8 = pre.into(); 432 let freq = ahb_freq / pre;
566 let pre: u8 = 1 << (pre - 3); 433 (freq, freq * 2u32)
567 let freq = ahb_freq / pre as u32;
568 (freq, freq * 2)
569 } 434 }
570 }; 435 };
571 436
572 set_freqs(Clocks { 437 set_freqs(Clocks {
573 sys: Hertz(sys_clk), 438 sys: sys_clk,
574 ahb1: Hertz(ahb_freq), 439 ahb1: ahb_freq,
575 ahb2: Hertz(ahb_freq), 440 ahb2: ahb_freq,
576 ahb3: Hertz(ahb_freq), 441 ahb3: ahb_freq,
577 apb1: Hertz(apb1_freq), 442 apb1: apb1_freq,
578 apb2: Hertz(apb2_freq), 443 apb2: apb2_freq,
579 apb3: Hertz(apb3_freq), 444 apb3: apb3_freq,
580 apb1_tim: Hertz(apb1_tim_freq), 445 apb1_tim: apb1_tim_freq,
581 apb2_tim: Hertz(apb2_tim_freq), 446 apb2_tim: apb2_tim_freq,
582 }); 447 });
583} 448}
449
450fn msirange_to_hertz(range: Msirange) -> Hertz {
451 match range {
452 Msirange::RANGE_48MHZ => Hertz(48_000_000),
453 Msirange::RANGE_24MHZ => Hertz(24_000_000),
454 Msirange::RANGE_16MHZ => Hertz(16_000_000),
455 Msirange::RANGE_12MHZ => Hertz(12_000_000),
456 Msirange::RANGE_4MHZ => Hertz(4_000_000),
457 Msirange::RANGE_2MHZ => Hertz(2_000_000),
458 Msirange::RANGE_1_33MHZ => Hertz(1_330_000),
459 Msirange::RANGE_1MHZ => Hertz(1_000_000),
460 Msirange::RANGE_3_072MHZ => Hertz(3_072_000),
461 Msirange::RANGE_1_536MHZ => Hertz(1_536_000),
462 Msirange::RANGE_1_024MHZ => Hertz(1_024_000),
463 Msirange::RANGE_768KHZ => Hertz(768_000),
464 Msirange::RANGE_400KHZ => Hertz(400_000),
465 Msirange::RANGE_200KHZ => Hertz(200_000),
466 Msirange::RANGE_133KHZ => Hertz(133_000),
467 Msirange::RANGE_100KHZ => Hertz(100_000),
468 }
469}
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs
index ee45a342b..ee2a8ae10 100644
--- a/embassy-stm32/src/rcc/wb.rs
+++ b/embassy-stm32/src/rcc/wb.rs
@@ -1,4 +1,4 @@
1pub use super::bus::{AHBPrescaler, APBPrescaler}; 1pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
2use crate::rcc::bd::{BackupDomain, RtcClockSource}; 2use crate::rcc::bd::{BackupDomain, RtcClockSource};
3use crate::rcc::Clocks; 3use crate::rcc::Clocks;
4use crate::time::{khz, mhz, Hertz}; 4use crate::time::{khz, mhz, Hertz};
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs
index 937f55503..7baedfcdb 100644
--- a/embassy-stm32/src/rcc/wl.rs
+++ b/embassy-stm32/src/rcc/wl.rs
@@ -1,6 +1,6 @@
1pub use super::bus::{AHBPrescaler, APBPrescaler};
2pub use crate::pac::pwr::vals::Vos as VoltageScale; 1pub use crate::pac::pwr::vals::Vos as VoltageScale;
3use crate::pac::rcc::vals::Adcsel; 2use crate::pac::rcc::vals::Adcsel;
3pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
4use crate::pac::{FLASH, RCC}; 4use crate::pac::{FLASH, RCC};
5use crate::rcc::bd::{BackupDomain, RtcClockSource}; 5use crate::rcc::bd::{BackupDomain, RtcClockSource};
6use crate::rcc::{set_freqs, Clocks}; 6use crate::rcc::{set_freqs, Clocks};
diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs
index 894937614..62aaa9800 100644
--- a/examples/stm32f2/src/bin/pll.rs
+++ b/examples/stm32f2/src/bin/pll.rs
@@ -7,7 +7,7 @@ use core::convert::TryFrom;
7use defmt::*; 7use defmt::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::rcc::{ 9use embassy_stm32::rcc::{
10 APBPrescaler, ClockSrc, HSEConfig, HSESrc, PLL48Div, PLLConfig, PLLMainDiv, PLLMul, PLLPreDiv, PLLSrc, 10 APBPrescaler, ClockSrc, HSEConfig, HSESrc, PLLConfig, PLLMul, PLLPDiv, PLLPreDiv, PLLQDiv, PLLSrc,
11}; 11};
12use embassy_stm32::time::Hertz; 12use embassy_stm32::time::Hertz;
13use embassy_stm32::Config; 13use embassy_stm32::Config;
@@ -32,9 +32,9 @@ async fn main(_spawner: Spawner) {
32 // 1 MHz PLL input * 240 = 240 MHz PLL VCO 32 // 1 MHz PLL input * 240 = 240 MHz PLL VCO
33 mul: unwrap!(PLLMul::try_from(240)), 33 mul: unwrap!(PLLMul::try_from(240)),
34 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output 34 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output
35 main_div: PLLMainDiv::Div2, 35 p_div: PLLPDiv::DIV2,
36 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output 36 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output
37 pll48_div: unwrap!(PLL48Div::try_from(5)), 37 q_div: PLLQDiv::DIV5,
38 }; 38 };
39 // System clock comes from PLL (= the 120 MHz main PLL output) 39 // System clock comes from PLL (= the 120 MHz main PLL output)
40 config.rcc.mux = ClockSrc::PLL; 40 config.rcc.mux = ClockSrc::PLL;
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index a792748bc..da9b18a0e 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -16,12 +16,12 @@ async fn main(_spawner: Spawner) {
16 16
17 config.rcc.pll = Some(Pll { 17 config.rcc.pll = Some(Pll {
18 source: PllSrc::HSI16, 18 source: PllSrc::HSI16,
19 prediv_m: PllM::Div4, 19 prediv_m: PllM::DIV4,
20 mul_n: PllN::Mul85, 20 mul_n: PllN::MUL85,
21 div_p: None, 21 div_p: None,
22 div_q: None, 22 div_q: None,
23 // Main system clock at 170 MHz 23 // Main system clock at 170 MHz
24 div_r: Some(PllR::Div2), 24 div_r: Some(PllR::DIV2),
25 }); 25 });
26 26
27 config.rcc.adc12_clock_source = AdcClockSource::SysClk; 27 config.rcc.adc12_clock_source = AdcClockSource::SysClk;
diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs
index ef7d4800c..f8159cb53 100644
--- a/examples/stm32g4/src/bin/pll.rs
+++ b/examples/stm32g4/src/bin/pll.rs
@@ -15,12 +15,12 @@ async fn main(_spawner: Spawner) {
15 15
16 config.rcc.pll = Some(Pll { 16 config.rcc.pll = Some(Pll {
17 source: PllSrc::HSI16, 17 source: PllSrc::HSI16,
18 prediv_m: PllM::Div4, 18 prediv_m: PllM::DIV4,
19 mul_n: PllN::Mul85, 19 mul_n: PllN::MUL85,
20 div_p: None, 20 div_p: None,
21 div_q: None, 21 div_q: None,
22 // Main system clock at 170 MHz 22 // Main system clock at 170 MHz
23 div_r: Some(PllR::Div2), 23 div_r: Some(PllR::DIV2),
24 }); 24 });
25 25
26 config.rcc.mux = ClockSrc::PLL; 26 config.rcc.mux = ClockSrc::PLL;
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs
index 77cfa67d3..9099b609a 100644
--- a/examples/stm32g4/src/bin/usb_serial.rs
+++ b/examples/stm32g4/src/bin/usb_serial.rs
@@ -25,16 +25,16 @@ async fn main(_spawner: Spawner) {
25 // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. 25 // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE.
26 const USE_HSI48: bool = true; 26 const USE_HSI48: bool = true;
27 27
28 let pllq_div = if USE_HSI48 { None } else { Some(PllQ::Div6) }; 28 let pllq_div = if USE_HSI48 { None } else { Some(PllQ::DIV6) };
29 29
30 config.rcc.pll = Some(Pll { 30 config.rcc.pll = Some(Pll {
31 source: PllSrc::HSE(Hertz(8_000_000)), 31 source: PllSrc::HSE(Hertz(8_000_000)),
32 prediv_m: PllM::Div2, 32 prediv_m: PllM::DIV2,
33 mul_n: PllN::Mul72, 33 mul_n: PllN::MUL72,
34 div_p: None, 34 div_p: None,
35 div_q: pllq_div, 35 div_q: pllq_div,
36 // Main system clock at 144 MHz 36 // Main system clock at 144 MHz
37 div_r: Some(PllR::Div2), 37 div_r: Some(PllR::DIV2),
38 }); 38 });
39 39
40 config.rcc.mux = ClockSrc::PLL; 40 config.rcc.mux = ClockSrc::PLL;
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs
index 4e92d0647..2f4454761 100644
--- a/examples/stm32h5/src/bin/eth.rs
+++ b/examples/stm32h5/src/bin/eth.rs
@@ -9,7 +9,9 @@ use embassy_net::{Ipv4Address, Stack, StackResources};
9use embassy_stm32::eth::generic_smi::GenericSMI; 9use embassy_stm32::eth::generic_smi::GenericSMI;
10use embassy_stm32::eth::{Ethernet, PacketQueue}; 10use embassy_stm32::eth::{Ethernet, PacketQueue};
11use embassy_stm32::peripherals::ETH; 11use embassy_stm32::peripherals::ETH;
12use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; 12use embassy_stm32::rcc::{
13 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllDiv, PllMul, PllPreDiv, PllSource, Sysclk, VoltageScale,
14};
13use embassy_stm32::rng::Rng; 15use embassy_stm32::rng::Rng;
14use embassy_stm32::time::Hertz; 16use embassy_stm32::time::Hertz;
15use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; 17use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
@@ -42,10 +44,10 @@ async fn main(spawner: Spawner) -> ! {
42 }); 44 });
43 config.rcc.pll1 = Some(Pll { 45 config.rcc.pll1 = Some(Pll {
44 source: PllSource::Hse, 46 source: PllSource::Hse,
45 prediv: 2, 47 prediv: PllPreDiv::DIV2,
46 mul: 125, 48 mul: PllMul::MUL125,
47 divp: Some(2), 49 divp: Some(PllDiv::DIV2),
48 divq: Some(2), 50 divq: Some(PllDiv::DIV2),
49 divr: None, 51 divr: None,
50 }); 52 });
51 config.rcc.ahb_pre = AHBPrescaler::DIV1; 53 config.rcc.ahb_pre = AHBPrescaler::DIV1;
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs
index cbe540a06..3b3c38e17 100644
--- a/examples/stm32h5/src/bin/usb_serial.rs
+++ b/examples/stm32h5/src/bin/usb_serial.rs
@@ -4,7 +4,9 @@
4 4
5use defmt::{panic, *}; 5use defmt::{panic, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; 7use embassy_stm32::rcc::{
8 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllDiv, PllMul, PllPreDiv, PllSource, Sysclk, VoltageScale,
9};
8use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
9use embassy_stm32::usb::{Driver, Instance}; 11use embassy_stm32::usb::{Driver, Instance};
10use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; 12use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config};
@@ -29,9 +31,9 @@ async fn main(_spawner: Spawner) {
29 }); 31 });
30 config.rcc.pll1 = Some(Pll { 32 config.rcc.pll1 = Some(Pll {
31 source: PllSource::Hse, 33 source: PllSource::Hse,
32 prediv: 2, 34 prediv: PllPreDiv::DIV2,
33 mul: 125, 35 mul: PllMul::MUL125,
34 divp: Some(2), // 250mhz 36 divp: Some(PllDiv::DIV2), // 250mhz
35 divq: None, 37 divq: None,
36 divr: None, 38 divr: None,
37 }); 39 });
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index 77922d4bc..7859b86db 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -18,16 +18,16 @@ async fn main(_spawner: Spawner) {
18 config.rcc.csi = true; 18 config.rcc.csi = true;
19 config.rcc.pll_src = PllSource::Hsi; 19 config.rcc.pll_src = PllSource::Hsi;
20 config.rcc.pll1 = Some(Pll { 20 config.rcc.pll1 = Some(Pll {
21 prediv: 4, 21 prediv: PllPreDiv::DIV4,
22 mul: 50, 22 mul: PllMul::MUL50,
23 divp: Some(2), 23 divp: Some(PllDiv::DIV2),
24 divq: Some(8), // SPI1 cksel defaults to pll1_q 24 divq: Some(PllDiv::DIV8), // SPI1 cksel defaults to pll1_q
25 divr: None, 25 divr: None,
26 }); 26 });
27 config.rcc.pll2 = Some(Pll { 27 config.rcc.pll2 = Some(Pll {
28 prediv: 4, 28 prediv: PllPreDiv::DIV4,
29 mul: 50, 29 mul: PllMul::MUL50,
30 divp: Some(8), // 100mhz 30 divp: Some(PllDiv::DIV8), // 100mhz
31 divq: None, 31 divq: None,
32 divr: None, 32 divr: None,
33 }); 33 });
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs
index 64ca65a02..40ef16cfc 100644
--- a/examples/stm32h7/src/bin/camera.rs
+++ b/examples/stm32h7/src/bin/camera.rs
@@ -32,10 +32,10 @@ async fn main(_spawner: Spawner) {
32 config.rcc.csi = true; 32 config.rcc.csi = true;
33 config.rcc.pll_src = PllSource::Hsi; 33 config.rcc.pll_src = PllSource::Hsi;
34 config.rcc.pll1 = Some(Pll { 34 config.rcc.pll1 = Some(Pll {
35 prediv: 4, 35 prediv: PllPreDiv::DIV4,
36 mul: 50, 36 mul: PllMul::MUL50,
37 divp: Some(2), 37 divp: Some(PllDiv::DIV2),
38 divq: Some(8), // 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::Pll1P; // 400 Mhz
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index 93df7a319..821221897 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -20,16 +20,16 @@ fn main() -> ! {
20 config.rcc.csi = true; 20 config.rcc.csi = true;
21 config.rcc.pll_src = PllSource::Hsi; 21 config.rcc.pll_src = PllSource::Hsi;
22 config.rcc.pll1 = Some(Pll { 22 config.rcc.pll1 = Some(Pll {
23 prediv: 4, 23 prediv: PllPreDiv::DIV4,
24 mul: 50, 24 mul: PllMul::MUL50,
25 divp: Some(2), 25 divp: Some(PllDiv::DIV2),
26 divq: Some(8), // SPI1 cksel defaults to pll1_q 26 divq: Some(PllDiv::DIV8), // 100mhz
27 divr: None, 27 divr: None,
28 }); 28 });
29 config.rcc.pll2 = Some(Pll { 29 config.rcc.pll2 = Some(Pll {
30 prediv: 4, 30 prediv: PllPreDiv::DIV4,
31 mul: 50, 31 mul: PllMul::MUL50,
32 divp: Some(8), // 100mhz 32 divp: Some(PllDiv::DIV8), // 100mhz
33 divq: None, 33 divq: None,
34 divr: None, 34 divr: None,
35 }); 35 });
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
index 8c921abca..933641ae4 100644
--- a/examples/stm32h7/src/bin/dac_dma.rs
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -28,16 +28,16 @@ async fn main(spawner: Spawner) {
28 config.rcc.csi = true; 28 config.rcc.csi = true;
29 config.rcc.pll_src = PllSource::Hsi; 29 config.rcc.pll_src = PllSource::Hsi;
30 config.rcc.pll1 = Some(Pll { 30 config.rcc.pll1 = Some(Pll {
31 prediv: 4, 31 prediv: PllPreDiv::DIV4,
32 mul: 50, 32 mul: PllMul::MUL50,
33 divp: Some(2), 33 divp: Some(PllDiv::DIV2),
34 divq: Some(8), // SPI1 cksel defaults to pll1_q 34 divq: Some(PllDiv::DIV8), // 100mhz
35 divr: None, 35 divr: None,
36 }); 36 });
37 config.rcc.pll2 = Some(Pll { 37 config.rcc.pll2 = Some(Pll {
38 prediv: 4, 38 prediv: PllPreDiv::DIV4,
39 mul: 50, 39 mul: PllMul::MUL50,
40 divp: Some(8), // 100mhz 40 divp: Some(PllDiv::DIV8), // 100mhz
41 divq: None, 41 divq: None,
42 divr: None, 42 divr: None,
43 }); 43 });
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 1b5d71ed3..a6603d507 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -39,9 +39,9 @@ async fn main(spawner: Spawner) -> ! {
39 config.rcc.hsi48 = true; // needed for RNG 39 config.rcc.hsi48 = true; // needed for RNG
40 config.rcc.pll_src = PllSource::Hsi; 40 config.rcc.pll_src = PllSource::Hsi;
41 config.rcc.pll1 = Some(Pll { 41 config.rcc.pll1 = Some(Pll {
42 prediv: 4, 42 prediv: PllPreDiv::DIV4,
43 mul: 50, 43 mul: PllMul::MUL50,
44 divp: Some(2), 44 divp: Some(PllDiv::DIV2),
45 divq: None, 45 divq: None,
46 divr: None, 46 divr: None,
47 }); 47 });
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 3abd31c73..596de2f40 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -40,9 +40,9 @@ async fn main(spawner: Spawner) -> ! {
40 config.rcc.hsi48 = true; // needed for RNG 40 config.rcc.hsi48 = true; // needed for RNG
41 config.rcc.pll_src = PllSource::Hsi; 41 config.rcc.pll_src = PllSource::Hsi;
42 config.rcc.pll1 = Some(Pll { 42 config.rcc.pll1 = Some(Pll {
43 prediv: 4, 43 prediv: PllPreDiv::DIV4,
44 mul: 50, 44 mul: PllMul::MUL50,
45 divp: Some(2), 45 divp: Some(PllDiv::DIV2),
46 divq: None, 46 divq: None,
47 divr: None, 47 divr: None,
48 }); 48 });
diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs
index de0b351df..7ae87b02c 100644
--- a/examples/stm32h7/src/bin/fmc.rs
+++ b/examples/stm32h7/src/bin/fmc.rs
@@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) {
18 config.rcc.csi = true; 18 config.rcc.csi = true;
19 config.rcc.pll_src = PllSource::Hsi; 19 config.rcc.pll_src = PllSource::Hsi;
20 config.rcc.pll1 = Some(Pll { 20 config.rcc.pll1 = Some(Pll {
21 prediv: 4, 21 prediv: PllPreDiv::DIV4,
22 mul: 50, 22 mul: PllMul::MUL50,
23 divp: Some(2), 23 divp: Some(PllDiv::DIV2),
24 divq: Some(8), // 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::Pll1P; // 400 Mhz
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index a1e955c39..f4fa06909 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -22,10 +22,10 @@ async fn main(_spawner: Spawner) {
22 config.rcc.hsi48 = true; // needed for RNG 22 config.rcc.hsi48 = true; // needed for RNG
23 config.rcc.pll_src = PllSource::Hsi; 23 config.rcc.pll_src = PllSource::Hsi;
24 config.rcc.pll1 = Some(Pll { 24 config.rcc.pll1 = Some(Pll {
25 prediv: 4, 25 prediv: PllPreDiv::DIV4,
26 mul: 50, 26 mul: PllMul::MUL50,
27 divp: Some(2), 27 divp: Some(PllDiv::DIV2),
28 divq: Some(8), // 100 Mhz 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::Pll1P; // 400 Mhz
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs
index 5c8e57aa2..37e4c92cc 100644
--- a/examples/stm32h7/src/bin/pwm.rs
+++ b/examples/stm32h7/src/bin/pwm.rs
@@ -21,9 +21,9 @@ async fn main(_spawner: Spawner) {
21 config.rcc.csi = true; 21 config.rcc.csi = true;
22 config.rcc.pll_src = PllSource::Hsi; 22 config.rcc.pll_src = PllSource::Hsi;
23 config.rcc.pll1 = Some(Pll { 23 config.rcc.pll1 = Some(Pll {
24 prediv: 4, 24 prediv: PllPreDiv::DIV4,
25 mul: 50, 25 mul: PllMul::MUL50,
26 divp: Some(2), 26 divp: Some(PllDiv::DIV2),
27 divq: None, 27 divq: None,
28 divr: None, 28 divr: None,
29 }); 29 });
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index 752aefdf7..ecb8d6542 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -22,10 +22,10 @@ async fn main(_spawner: Spawner) -> ! {
22 config.rcc.csi = true; 22 config.rcc.csi = true;
23 config.rcc.pll_src = PllSource::Hsi; 23 config.rcc.pll_src = PllSource::Hsi;
24 config.rcc.pll1 = Some(Pll { 24 config.rcc.pll1 = Some(Pll {
25 prediv: 4, 25 prediv: PllPreDiv::DIV4,
26 mul: 50, 26 mul: PllMul::MUL50,
27 divp: Some(2), 27 divp: Some(PllDiv::DIV2),
28 divq: Some(4), // 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::Pll1P; // 400 Mhz
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs
index 9fe46f031..f128d4a56 100644
--- a/examples/stm32h7/src/bin/spi.rs
+++ b/examples/stm32h7/src/bin/spi.rs
@@ -44,10 +44,10 @@ fn main() -> ! {
44 config.rcc.csi = true; 44 config.rcc.csi = true;
45 config.rcc.pll_src = PllSource::Hsi; 45 config.rcc.pll_src = PllSource::Hsi;
46 config.rcc.pll1 = Some(Pll { 46 config.rcc.pll1 = Some(Pll {
47 prediv: 4, 47 prediv: PllPreDiv::DIV4,
48 mul: 50, 48 mul: PllMul::MUL50,
49 divp: Some(2), 49 divp: Some(PllDiv::DIV2),
50 divq: Some(4), // 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::Pll1P; // 400 Mhz
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index 88d65d5be..d4c0bcdbd 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -40,10 +40,10 @@ fn main() -> ! {
40 config.rcc.csi = true; 40 config.rcc.csi = true;
41 config.rcc.pll_src = PllSource::Hsi; 41 config.rcc.pll_src = PllSource::Hsi;
42 config.rcc.pll1 = Some(Pll { 42 config.rcc.pll1 = Some(Pll {
43 prediv: 4, 43 prediv: PllPreDiv::DIV4,
44 mul: 50, 44 mul: PllMul::MUL50,
45 divp: Some(2), 45 divp: Some(PllDiv::DIV2),
46 divq: Some(4), // 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::Pll1P; // 400 Mhz
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs
index 14de43568..c1e5144be 100644
--- a/examples/stm32h7/src/bin/usb_serial.rs
+++ b/examples/stm32h7/src/bin/usb_serial.rs
@@ -28,9 +28,9 @@ async fn main(_spawner: Spawner) {
28 config.rcc.hsi48 = true; // needed for USB 28 config.rcc.hsi48 = true; // needed for USB
29 config.rcc.pll_src = PllSource::Hsi; 29 config.rcc.pll_src = PllSource::Hsi;
30 config.rcc.pll1 = Some(Pll { 30 config.rcc.pll1 = Some(Pll {
31 prediv: 4, 31 prediv: PllPreDiv::DIV4,
32 mul: 50, 32 mul: PllMul::MUL50,
33 divp: Some(2), 33 divp: Some(PllDiv::DIV2),
34 divq: None, 34 divq: None,
35 divr: None, 35 divr: None,
36 }); 36 });
diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs
index 806e49f59..d0208d8a3 100644
--- a/examples/stm32l4/src/bin/rng.rs
+++ b/examples/stm32l4/src/bin/rng.rs
@@ -4,7 +4,7 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; 7use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv};
8use embassy_stm32::rng::Rng; 8use embassy_stm32::rng::Rng;
9use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; 9use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -19,10 +19,10 @@ async fn main(_spawner: Spawner) {
19 // 72Mhz clock (16 / 1 * 18 / 4) 19 // 72Mhz clock (16 / 1 * 18 / 4)
20 config.rcc.mux = ClockSrc::PLL( 20 config.rcc.mux = ClockSrc::PLL(
21 PLLSource::HSI16, 21 PLLSource::HSI16,
22 PLLClkDiv::Div4, 22 PllRDiv::DIV4,
23 PLLSrcDiv::Div1, 23 PllPreDiv::DIV1,
24 PLLMul::Mul18, 24 PllMul::MUL18,
25 Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6) 25 Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6)
26 ); 26 );
27 let p = embassy_stm32::init(config); 27 let p = embassy_stm32::init(config);
28 28
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs
index eb1eed012..7e2b8c783 100644
--- a/examples/stm32l4/src/bin/rtc.rs
+++ b/examples/stm32l4/src/bin/rtc.rs
@@ -5,7 +5,7 @@
5use chrono::{NaiveDate, NaiveDateTime}; 5use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::rcc::{self, ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; 8use embassy_stm32::rcc::{self, ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv};
9use embassy_stm32::rtc::{Rtc, RtcConfig}; 9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::Config; 11use embassy_stm32::Config;
@@ -18,9 +18,9 @@ async fn main(_spawner: Spawner) {
18 let mut config = Config::default(); 18 let mut config = Config::default();
19 config.rcc.mux = ClockSrc::PLL( 19 config.rcc.mux = ClockSrc::PLL(
20 PLLSource::HSE(Hertz::mhz(8)), 20 PLLSource::HSE(Hertz::mhz(8)),
21 PLLClkDiv::Div2, 21 PllRDiv::DIV2,
22 PLLSrcDiv::Div1, 22 PllPreDiv::DIV1,
23 PLLMul::Mul20, 23 PllMul::MUL20,
24 None, 24 None,
25 ); 25 );
26 config.rcc.lse = Some(Hertz(32_768)); 26 config.rcc.lse = Some(Hertz(32_768));
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index ba4a9d230..8db89be24 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -49,7 +49,7 @@ use embassy_net_adin1110::{self, Device, Runner, ADIN1110};
49use embedded_hal_bus::spi::ExclusiveDevice; 49use embedded_hal_bus::spi::ExclusiveDevice;
50use hal::gpio::Pull; 50use hal::gpio::Pull;
51use hal::i2c::Config as I2C_Config; 51use hal::i2c::Config as I2C_Config;
52use hal::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; 52use hal::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv};
53use hal::spi::{Config as SPI_Config, Spi}; 53use hal::spi::{Config as SPI_Config, Spi};
54use hal::time::Hertz; 54use hal::time::Hertz;
55 55
@@ -80,9 +80,9 @@ async fn main(spawner: Spawner) {
80 // 80MHz highest frequency for flash 0 wait. 80 // 80MHz highest frequency for flash 0 wait.
81 config.rcc.mux = ClockSrc::PLL( 81 config.rcc.mux = ClockSrc::PLL(
82 PLLSource::HSE(Hertz(8_000_000)), 82 PLLSource::HSE(Hertz(8_000_000)),
83 PLLClkDiv::Div2, 83 PllRDiv::DIV2,
84 PLLSrcDiv::Div1, 84 PllPreDiv::DIV1,
85 PLLMul::Mul20, 85 PllMul::MUL20,
86 None, 86 None,
87 ); 87 );
88 config.rcc.hsi48 = true; // needed for rng 88 config.rcc.hsi48 = true; // needed for rng
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs
index 410d6891b..dc0d98ad4 100644
--- a/examples/stm32l4/src/bin/usb_serial.rs
+++ b/examples/stm32l4/src/bin/usb_serial.rs
@@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) {
23 info!("Hello World!"); 23 info!("Hello World!");
24 24
25 let mut config = Config::default(); 25 let mut config = Config::default();
26 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); 26 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
27 config.rcc.hsi48 = true; 27 config.rcc.hsi48 = true;
28 28
29 let p = embassy_stm32::init(config); 29 let p = embassy_stm32::init(config);
diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs
index 9549d64d8..cc3c99b57 100644
--- a/examples/stm32l5/src/bin/rng.rs
+++ b/examples/stm32l5/src/bin/rng.rs
@@ -4,7 +4,7 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; 7use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv};
8use embassy_stm32::rng::Rng; 8use embassy_stm32::rng::Rng;
9use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; 9use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) {
18 let mut config = Config::default(); 18 let mut config = Config::default();
19 config.rcc.mux = ClockSrc::PLL( 19 config.rcc.mux = ClockSrc::PLL(
20 PLLSource::HSI16, 20 PLLSource::HSI16,
21 PLLClkDiv::Div2, 21 PllRDiv::DIV2,
22 PLLSrcDiv::Div1, 22 PllPreDiv::DIV1,
23 PLLMul::Mul8, 23 PllMul::MUL8,
24 Some(PLLClkDiv::Div2), 24 Some(PllQDiv::DIV2),
25 ); 25 );
26 let p = embassy_stm32::init(config); 26 let p = embassy_stm32::init(config);
27 27
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs
index 15b84761b..498147f9d 100644
--- a/examples/stm32l5/src/bin/usb_ethernet.rs
+++ b/examples/stm32l5/src/bin/usb_ethernet.rs
@@ -45,7 +45,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
45#[embassy_executor::main] 45#[embassy_executor::main]
46async fn main(spawner: Spawner) { 46async fn main(spawner: Spawner) {
47 let mut config = Config::default(); 47 let mut config = Config::default();
48 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); 48 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
49 config.rcc.hsi48 = true; 49 config.rcc.hsi48 = true;
50 let p = embassy_stm32::init(config); 50 let p = embassy_stm32::init(config);
51 51
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index 7e894e407..db6a9c76f 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs
@@ -22,7 +22,7 @@ bind_interrupts!(struct Irqs {
22#[embassy_executor::main] 22#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 23async fn main(_spawner: Spawner) {
24 let mut config = Config::default(); 24 let mut config = Config::default();
25 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); 25 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
26 config.rcc.hsi48 = true; 26 config.rcc.hsi48 = true;
27 let p = embassy_stm32::init(config); 27 let p = embassy_stm32::init(config);
28 28
diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs
index 0c719560f..e19ecbf08 100644
--- a/examples/stm32l5/src/bin/usb_serial.rs
+++ b/examples/stm32l5/src/bin/usb_serial.rs
@@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs {
20#[embassy_executor::main] 20#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
22 let mut config = Config::default(); 22 let mut config = Config::default();
23 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); 23 config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None);
24 config.rcc.hsi48 = true; 24 config.rcc.hsi48 = true;
25 let p = embassy_stm32::init(config); 25 let p = embassy_stm32::init(config);
26 26
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs
index 278bd30f0..9b2adb0ac 100644
--- a/examples/stm32u5/src/bin/usb_serial.rs
+++ b/examples/stm32u5/src/bin/usb_serial.rs
@@ -25,9 +25,9 @@ async fn main(_spawner: Spawner) {
25 let mut config = Config::default(); 25 let mut config = Config::default();
26 config.rcc.mux = ClockSrc::PLL1R(PllConfig { 26 config.rcc.mux = ClockSrc::PLL1R(PllConfig {
27 source: PllSrc::HSI16, 27 source: PllSrc::HSI16,
28 m: PllM::Div2, 28 m: Pllm::DIV2,
29 n: PllN::Mul10, 29 n: Plln::MUL10,
30 r: PllClkDiv::NotDivided, 30 r: Plldiv::DIV1,
31 }); 31 });
32 //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); 32 //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz);
33 config.rcc.hsi48 = true; 33 config.rcc.hsi48 = true;
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 32ba03e4f..79a9b5e86 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -202,9 +202,9 @@ pub fn config() -> Config {
202 // 1 MHz PLL input * 240 = 240 MHz PLL VCO 202 // 1 MHz PLL input * 240 = 240 MHz PLL VCO
203 mul: unwrap!(PLLMul::try_from(240)), 203 mul: unwrap!(PLLMul::try_from(240)),
204 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output 204 // 240 MHz PLL VCO / 2 = 120 MHz main PLL output
205 main_div: PLLMainDiv::Div2, 205 p_div: PLLPDiv::DIV2,
206 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output 206 // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output
207 pll48_div: unwrap!(PLL48Div::try_from(5)), 207 q_div: PLLQDiv::DIV5,
208 }; 208 };
209 // System clock comes from PLL (= the 120 MHz main PLL output) 209 // System clock comes from PLL (= the 120 MHz main PLL output)
210 config.rcc.mux = ClockSrc::PLL; 210 config.rcc.mux = ClockSrc::PLL;
@@ -239,10 +239,10 @@ pub fn config() -> Config {
239 }); 239 });
240 config.rcc.pll1 = Some(Pll { 240 config.rcc.pll1 = Some(Pll {
241 source: PllSource::Hse, 241 source: PllSource::Hse,
242 prediv: 2, 242 prediv: PllPreDiv::DIV2,
243 mul: 125, 243 mul: PllMul::MUL125,
244 divp: Some(2), 244 divp: Some(PllDiv::DIV2),
245 divq: Some(2), 245 divq: Some(PllDiv::DIV2),
246 divr: None, 246 divr: None,
247 }); 247 });
248 config.rcc.ahb_pre = AHBPrescaler::DIV1; 248 config.rcc.ahb_pre = AHBPrescaler::DIV1;
@@ -261,16 +261,16 @@ pub fn config() -> Config {
261 config.rcc.hsi48 = true; // needed for RNG 261 config.rcc.hsi48 = true; // needed for RNG
262 config.rcc.pll_src = PllSource::Hsi; 262 config.rcc.pll_src = PllSource::Hsi;
263 config.rcc.pll1 = Some(Pll { 263 config.rcc.pll1 = Some(Pll {
264 prediv: 4, 264 prediv: PllPreDiv::DIV4,
265 mul: 50, 265 mul: PllMul::MUL50,
266 divp: Some(2), 266 divp: Some(PllDiv::DIV2),
267 divq: Some(8), // SPI1 cksel defaults to pll1_q 267 divq: Some(PllDiv::DIV8), // SPI1 cksel defaults to pll1_q
268 divr: None, 268 divr: None,
269 }); 269 });
270 config.rcc.pll2 = Some(Pll { 270 config.rcc.pll2 = Some(Pll {
271 prediv: 4, 271 prediv: PllPreDiv::DIV4,
272 mul: 50, 272 mul: PllMul::MUL50,
273 divp: Some(8), // 100mhz 273 divp: Some(PllDiv::DIV8), // 100mhz
274 divq: None, 274 divq: None,
275 divr: None, 275 divr: None,
276 }); 276 });
@@ -290,10 +290,10 @@ pub fn config() -> Config {
290 config.rcc.mux = ClockSrc::PLL( 290 config.rcc.mux = ClockSrc::PLL(
291 // 72Mhz clock (16 / 1 * 18 / 4) 291 // 72Mhz clock (16 / 1 * 18 / 4)
292 PLLSource::HSI16, 292 PLLSource::HSI16,
293 PLLClkDiv::Div4, 293 PllRDiv::DIV4,
294 PLLSrcDiv::Div1, 294 PllPreDiv::DIV1,
295 PLLMul::Mul18, 295 PllMul::MUL18,
296 Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6) 296 Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6)
297 ); 297 );
298 } 298 }
299 299
@@ -303,9 +303,9 @@ pub fn config() -> Config {
303 config.rcc.mux = ClockSrc::PLL( 303 config.rcc.mux = ClockSrc::PLL(
304 // 110Mhz clock (16 / 4 * 55 / 2) 304 // 110Mhz clock (16 / 4 * 55 / 2)
305 PLLSource::HSI16, 305 PLLSource::HSI16,
306 PLLClkDiv::Div2, 306 PllRDiv::DIV2,
307 PLLSrcDiv::Div4, 307 PllPreDiv::DIV4,
308 PLLMul::Mul55, 308 PllMul::MUL55,
309 None, 309 None,
310 ); 310 );
311 } 311 }
@@ -313,7 +313,7 @@ pub fn config() -> Config {
313 #[cfg(feature = "stm32u585ai")] 313 #[cfg(feature = "stm32u585ai")]
314 { 314 {
315 use embassy_stm32::rcc::*; 315 use embassy_stm32::rcc::*;
316 config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); 316 config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ);
317 } 317 }
318 318
319 #[cfg(feature = "stm32l073rz")] 319 #[cfg(feature = "stm32l073rz")]