aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/rcc/g4.rs50
-rw-r--r--embassy-stm32/src/rcc/h.rs16
-rw-r--r--embassy-stm32/src/rcc/hsi48.rs62
-rw-r--r--embassy-stm32/src/rcc/l0l1.rs38
-rw-r--r--embassy-stm32/src/rcc/l4l5.rs26
-rw-r--r--embassy-stm32/src/rcc/mod.rs5
-rw-r--r--embassy-stm32/src/rcc/u5.rs9
-rw-r--r--examples/stm32g4/src/bin/usb_serial.rs6
-rw-r--r--examples/stm32h5/src/bin/eth.rs2
-rw-r--r--examples/stm32h5/src/bin/usb_serial.rs46
-rw-r--r--examples/stm32h7/src/bin/eth.rs2
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs2
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs1
-rw-r--r--examples/stm32h7/src/bin/rng.rs2
-rw-r--r--examples/stm32h7/src/bin/usb_serial.rs2
-rw-r--r--examples/stm32l0/src/bin/button_exti.rs3
-rw-r--r--examples/stm32l0/src/bin/lora_cad.rs2
-rw-r--r--examples/stm32l0/src/bin/lora_lorawan.rs2
-rw-r--r--examples/stm32l0/src/bin/lora_p2p_receive.rs2
-rw-r--r--examples/stm32l0/src/bin/lora_p2p_send.rs2
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs2
-rw-r--r--examples/stm32l4/src/bin/usb_serial.rs2
-rw-r--r--examples/stm32u5/src/bin/usb_serial.rs3
-rw-r--r--tests/stm32/src/common.rs6
25 files changed, 136 insertions, 161 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 2a2df5c56..7e11e2631 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -58,7 +58,7 @@ rand_core = "0.6.3"
58sdio-host = "0.5.0" 58sdio-host = "0.5.0"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b" } 61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b" }
62vcell = "0.1.3" 62vcell = "0.1.3"
63bxcan = "0.7.0" 63bxcan = "0.7.0"
64nb = "1.0.0" 64nb = "1.0.0"
@@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
76[build-dependencies] 76[build-dependencies]
77proc-macro2 = "1.0.36" 77proc-macro2 = "1.0.36"
78quote = "1.0.15" 78quote = "1.0.15"
79stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b", default-features = false, features = ["metadata"]} 79stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b", default-features = false, features = ["metadata"]}
80 80
81 81
82[features] 82[features]
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index b14a61973..13eb0c48d 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
7 Pllr as PllR, Ppre as APBPrescaler, 7 Pllr as PllR, Ppre as APBPrescaler,
8}; 8};
9use crate::pac::{PWR, RCC}; 9use crate::pac::{PWR, RCC};
10use crate::rcc::sealed::RccPeripheral;
11use crate::rcc::{set_freqs, Clocks}; 10use crate::rcc::{set_freqs, Clocks};
12use crate::time::Hertz; 11use crate::time::Hertz;
13 12
@@ -67,23 +66,13 @@ pub struct Pll {
67pub enum Clock48MhzSrc { 66pub enum Clock48MhzSrc {
68 /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the 67 /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the
69 /// oscillator to comply with the USB specification for oscillator tolerance. 68 /// oscillator to comply with the USB specification for oscillator tolerance.
70 Hsi48(Option<CrsConfig>), 69 Hsi48(super::Hsi48Config),
71 /// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. For USB usage the 70 /// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. For USB usage the
72 /// PLL needs to be using the HSE source to comply with the USB specification for oscillator 71 /// PLL needs to be using the HSE source to comply with the USB specification for oscillator
73 /// tolerance. 72 /// tolerance.
74 PllQ, 73 PllQ,
75} 74}
76 75
77/// Sets the sync source for the Clock Recovery System (CRS).
78pub enum CrsSyncSource {
79 /// Use an external GPIO to sync the CRS.
80 Gpio,
81 /// Use the Low Speed External oscillator to sync the CRS.
82 Lse,
83 /// Use the USB SOF to sync the CRS.
84 Usb,
85}
86
87/// Clocks configutation 76/// Clocks configutation
88pub struct Config { 77pub struct Config {
89 pub mux: ClockSrc, 78 pub mux: ClockSrc,
@@ -102,12 +91,6 @@ pub struct Config {
102 pub ls: super::LsConfig, 91 pub ls: super::LsConfig,
103} 92}
104 93
105/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator.
106pub struct CrsConfig {
107 /// Sync source for the CRS.
108 pub sync_src: CrsSyncSource,
109}
110
111impl Default for Config { 94impl Default for Config {
112 #[inline] 95 #[inline]
113 fn default() -> Config { 96 fn default() -> Config {
@@ -118,7 +101,7 @@ impl Default for Config {
118 apb2_pre: APBPrescaler::DIV1, 101 apb2_pre: APBPrescaler::DIV1,
119 low_power_run: false, 102 low_power_run: false,
120 pll: None, 103 pll: None,
121 clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)), 104 clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())),
122 adc12_clock_source: Adcsel::DISABLE, 105 adc12_clock_source: Adcsel::DISABLE,
123 adc345_clock_source: Adcsel::DISABLE, 106 adc345_clock_source: Adcsel::DISABLE,
124 ls: Default::default(), 107 ls: Default::default(),
@@ -288,33 +271,8 @@ pub(crate) unsafe fn init(config: Config) {
288 271
289 crate::pac::rcc::vals::Clk48sel::PLL1_Q 272 crate::pac::rcc::vals::Clk48sel::PLL1_Q
290 } 273 }
291 Clock48MhzSrc::Hsi48(crs_config) => { 274 Clock48MhzSrc::Hsi48(config) => {
292 // Enable HSI48 275 super::init_hsi48(config);
293 RCC.crrcr().modify(|w| w.set_hsi48on(true));
294 // Wait for HSI48 to turn on
295 while RCC.crrcr().read().hsi48rdy() == false {}
296
297 // Enable and setup CRS if needed
298 if let Some(crs_config) = crs_config {
299 crate::peripherals::CRS::enable_and_reset();
300
301 let sync_src = match crs_config.sync_src {
302 CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO,
303 CrsSyncSource::Lse => crate::pac::crs::vals::Syncsrc::LSE,
304 CrsSyncSource::Usb => crate::pac::crs::vals::Syncsrc::USB,
305 };
306
307 crate::pac::CRS.cfgr().modify(|w| {
308 w.set_syncsrc(sync_src);
309 });
310
311 // These are the correct settings for standard USB operation. If other settings
312 // are needed there will need to be additional config options for the CRS.
313 crate::pac::CRS.cr().modify(|w| {
314 w.set_autotrimen(true);
315 w.set_cen(true);
316 });
317 }
318 crate::pac::rcc::vals::Clk48sel::HSI48 276 crate::pac::rcc::vals::Clk48sel::HSI48
319 } 277 }
320 }; 278 };
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 7e924f0ac..4407d9e93 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -21,9 +21,6 @@ pub const HSI_FREQ: Hertz = Hertz(64_000_000);
21/// CSI speed 21/// CSI speed
22pub const CSI_FREQ: Hertz = Hertz(4_000_000); 22pub const CSI_FREQ: Hertz = Hertz(4_000_000);
23 23
24/// HSI48 speed
25pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
26
27const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000); 24const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000);
28#[cfg(any(stm32h5, pwr_h7rm0455))] 25#[cfg(any(stm32h5, pwr_h7rm0455))]
29const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000); 26const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000);
@@ -126,7 +123,7 @@ pub struct Config {
126 pub hsi: Option<HSIPrescaler>, 123 pub hsi: Option<HSIPrescaler>,
127 pub hse: Option<Hse>, 124 pub hse: Option<Hse>,
128 pub csi: bool, 125 pub csi: bool,
129 pub hsi48: bool, 126 pub hsi48: Option<super::Hsi48Config>,
130 pub sys: Sysclk, 127 pub sys: Sysclk,
131 128
132 pub pll1: Option<Pll>, 129 pub pll1: Option<Pll>,
@@ -155,7 +152,7 @@ impl Default for Config {
155 hsi: Some(HSIPrescaler::DIV1), 152 hsi: Some(HSIPrescaler::DIV1),
156 hse: None, 153 hse: None,
157 csi: false, 154 csi: false,
158 hsi48: false, 155 hsi48: Some(Default::default()),
159 sys: Sysclk::HSI, 156 sys: Sysclk::HSI,
160 pll1: None, 157 pll1: None,
161 pll2: None, 158 pll2: None,
@@ -301,14 +298,7 @@ pub(crate) unsafe fn init(config: Config) {
301 }; 298 };
302 299
303 // Configure HSI48. 300 // Configure HSI48.
304 RCC.cr().modify(|w| w.set_hsi48on(config.hsi48)); 301 let _hsi48 = config.hsi48.map(super::init_hsi48);
305 let _hsi48 = match config.hsi48 {
306 false => None,
307 true => {
308 while !RCC.cr().read().hsi48rdy() {}
309 Some(CSI_FREQ)
310 }
311 };
312 302
313 // Configure CSI. 303 // Configure CSI.
314 RCC.cr().modify(|w| w.set_csion(config.csi)); 304 RCC.cr().modify(|w| w.set_csion(config.csi));
diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs
new file mode 100644
index 000000000..19a8c8cb9
--- /dev/null
+++ b/embassy-stm32/src/rcc/hsi48.rs
@@ -0,0 +1,62 @@
1#![allow(unused)]
2
3use crate::pac::crs::vals::Syncsrc;
4use crate::pac::{CRS, RCC};
5use crate::rcc::sealed::RccPeripheral;
6use crate::time::Hertz;
7
8/// HSI48 speed
9pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
10
11/// Configuration for the HSI48 clock
12#[derive(Clone, Copy, Debug)]
13pub struct Hsi48Config {
14 /// Enable CRS Sync from USB Start Of Frame (SOF) events.
15 /// Required if HSI48 is going to be used as USB clock.
16 ///
17 /// Other use cases of CRS are not supported yet.
18 pub sync_from_usb: bool,
19}
20
21impl Default for Hsi48Config {
22 fn default() -> Self {
23 Self { sync_from_usb: false }
24 }
25}
26
27pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz {
28 // Enable VREFINT reference for HSI48 oscillator
29 #[cfg(stm32l0)]
30 crate::pac::SYSCFG.cfgr3().modify(|w| {
31 w.set_enref_hsi48(true);
32 w.set_en_vrefint(true);
33 });
34
35 // Enable HSI48
36 #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba, stm32f0)))]
37 let r = RCC.crrcr();
38 #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba))]
39 let r = RCC.cr();
40 #[cfg(any(stm32f0))]
41 let r = RCC.cr2();
42
43 r.modify(|w| w.set_hsi48on(true));
44 while r.read().hsi48rdy() == false {}
45
46 if config.sync_from_usb {
47 crate::peripherals::CRS::enable_and_reset();
48
49 CRS.cfgr().modify(|w| {
50 w.set_syncsrc(Syncsrc::USB);
51 });
52
53 // These are the correct settings for standard USB operation. If other settings
54 // are needed there will need to be additional config options for the CRS.
55 crate::pac::CRS.cr().modify(|w| {
56 w.set_autotrimen(true);
57 w.set_cen(true);
58 });
59 }
60
61 HSI48_FREQ
62}
diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs
index 3af279595..25a7762a3 100644
--- a/embassy-stm32/src/rcc/l0l1.rs
+++ b/embassy-stm32/src/rcc/l0l1.rs
@@ -3,8 +3,6 @@ pub use crate::pac::rcc::vals::{
3 Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul, 3 Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul,
4 Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, 4 Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
5}; 5};
6#[cfg(crs)]
7use crate::pac::{crs, CRS, SYSCFG};
8use crate::pac::{FLASH, PWR, RCC}; 6use crate::pac::{FLASH, PWR, RCC};
9use crate::rcc::{set_freqs, Clocks}; 7use crate::rcc::{set_freqs, Clocks};
10use crate::time::Hertz; 8use crate::time::Hertz;
@@ -47,7 +45,7 @@ pub struct Config {
47 pub hsi: bool, 45 pub hsi: bool,
48 pub hse: Option<Hse>, 46 pub hse: Option<Hse>,
49 #[cfg(crs)] 47 #[cfg(crs)]
50 pub hsi48: bool, 48 pub hsi48: Option<super::Hsi48Config>,
51 49
52 pub pll: Option<Pll>, 50 pub pll: Option<Pll>,
53 51
@@ -68,7 +66,7 @@ impl Default for Config {
68 hse: None, 66 hse: None,
69 hsi: false, 67 hsi: false,
70 #[cfg(crs)] 68 #[cfg(crs)]
71 hsi48: false, 69 hsi48: Some(Default::default()),
72 70
73 pll: None, 71 pll: None,
74 72
@@ -174,37 +172,11 @@ pub(crate) unsafe fn init(config: Config) {
174 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); 172 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre);
175 173
176 #[cfg(crs)] 174 #[cfg(crs)]
177 if config.hsi48 { 175 let _hsi48 = config.hsi48.map(|config| {
178 // Reset CRS peripheral
179 RCC.apb1rstr().modify(|w| w.set_crsrst(true));
180 RCC.apb1rstr().modify(|w| w.set_crsrst(false));
181
182 // Enable CRS peripheral
183 RCC.apb1enr().modify(|w| w.set_crsen(true));
184
185 // Initialize CRS
186 CRS.cfgr().write(|w|
187
188 // Select LSE as synchronization source
189 w.set_syncsrc(crs::vals::Syncsrc::LSE));
190 CRS.cr().modify(|w| {
191 w.set_autotrimen(true);
192 w.set_cen(true);
193 });
194
195 // Enable VREFINT reference for HSI48 oscillator
196 SYSCFG.cfgr3().modify(|w| {
197 w.set_enref_hsi48(true);
198 w.set_en_vrefint(true);
199 });
200
201 // Select HSI48 as USB clock 176 // Select HSI48 as USB clock
202 RCC.ccipr().modify(|w| w.set_hsi48msel(true)); 177 RCC.ccipr().modify(|w| w.set_hsi48msel(true));
203 178 super::init_hsi48(config)
204 // Enable dedicated USB clock 179 });
205 RCC.crrcr().modify(|w| w.set_hsi48on(true));
206 while !RCC.crrcr().read().hsi48rdy() {}
207 }
208 180
209 set_freqs(Clocks { 181 set_freqs(Clocks {
210 sys: sys_clk, 182 sys: sys_clk,
diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs
index 44748620c..c44839104 100644
--- a/embassy-stm32/src/rcc/l4l5.rs
+++ b/embassy-stm32/src/rcc/l4l5.rs
@@ -58,8 +58,8 @@ pub struct Config {
58 pub msi: Option<MSIRange>, 58 pub msi: Option<MSIRange>,
59 pub hsi: bool, 59 pub hsi: bool,
60 pub hse: Option<Hse>, 60 pub hse: Option<Hse>,
61 #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] 61 #[cfg(crs)]
62 pub hsi48: bool, 62 pub hsi48: Option<super::Hsi48Config>,
63 63
64 // pll 64 // pll
65 pub pll: Option<Pll>, 65 pub pll: Option<Pll>,
@@ -108,8 +108,8 @@ impl Default for Config {
108 pllsai1: None, 108 pllsai1: None,
109 #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] 109 #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
110 pllsai2: None, 110 pllsai2: None,
111 #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] 111 #[cfg(crs)]
112 hsi48: true, 112 hsi48: Some(Default::default()),
113 #[cfg(any(stm32l4, stm32l5, stm32wb))] 113 #[cfg(any(stm32l4, stm32l5, stm32wb))]
114 clk48_src: Clk48Src::HSI48, 114 clk48_src: Clk48Src::HSI48,
115 ls: Default::default(), 115 ls: Default::default(),
@@ -126,7 +126,8 @@ pub const WPAN_DEFAULT: Config = Config {
126 prescaler: HsePrescaler::DIV1, 126 prescaler: HsePrescaler::DIV1,
127 }), 127 }),
128 mux: ClockSrc::PLL1_R, 128 mux: ClockSrc::PLL1_R,
129 hsi48: true, 129 #[cfg(crs)]
130 hsi48: Some(super::Hsi48Config { sync_from_usb: false }),
130 msi: None, 131 msi: None,
131 hsi: false, 132 hsi: false,
132 clk48_src: Clk48Src::PLL1_Q, 133 clk48_src: Clk48Src::PLL1_Q,
@@ -216,15 +217,10 @@ pub(crate) unsafe fn init(config: Config) {
216 hse.freq 217 hse.freq
217 }); 218 });
218 219
219 #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] 220 #[cfg(crs)]
220 let hsi48 = config.hsi48.then(|| { 221 let _hsi48 = config.hsi48.map(super::init_hsi48);
221 RCC.crrcr().modify(|w| w.set_hsi48on(true)); 222 #[cfg(not(crs))]
222 while !RCC.crrcr().read().hsi48rdy() {} 223 let _hsi48: Option<Hertz> = None;
223
224 Hertz(48_000_000)
225 });
226 #[cfg(any(stm32l47x, stm32l48x))]
227 let hsi48 = None;
228 224
229 let _plls = [ 225 let _plls = [
230 &config.pll, 226 &config.pll,
@@ -275,7 +271,7 @@ pub(crate) unsafe fn init(config: Config) {
275 RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); 271 RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src));
276 #[cfg(any(stm32l4, stm32l5, stm32wb))] 272 #[cfg(any(stm32l4, stm32l5, stm32wb))]
277 let _clk48 = match config.clk48_src { 273 let _clk48 = match config.clk48_src {
278 Clk48Src::HSI48 => hsi48, 274 Clk48Src::HSI48 => _hsi48,
279 Clk48Src::MSI => msi, 275 Clk48Src::MSI => msi,
280 Clk48Src::PLLSAI1_Q => pllsai1.q, 276 Clk48Src::PLLSAI1_Q => pllsai1.q,
281 Clk48Src::PLL1_Q => pll.q, 277 Clk48Src::PLL1_Q => pll.q,
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index c11a9cc6b..e15f4fe41 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -9,6 +9,11 @@ mod mco;
9pub use bd::*; 9pub use bd::*;
10pub use mco::*; 10pub use mco::*;
11 11
12#[cfg(crs)]
13mod hsi48;
14#[cfg(crs)]
15pub use hsi48::*;
16
12#[cfg_attr(rcc_f0, path = "f0.rs")] 17#[cfg_attr(rcc_f0, path = "f0.rs")]
13#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] 18#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")]
14#[cfg_attr(rcc_f2, path = "f2.rs")] 19#[cfg_attr(rcc_f2, path = "f2.rs")]
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index 2bbacbbdc..c111362bf 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -115,7 +115,7 @@ pub struct Config {
115 pub apb1_pre: APBPrescaler, 115 pub apb1_pre: APBPrescaler,
116 pub apb2_pre: APBPrescaler, 116 pub apb2_pre: APBPrescaler,
117 pub apb3_pre: APBPrescaler, 117 pub apb3_pre: APBPrescaler,
118 pub hsi48: bool, 118 pub hsi48: Option<super::Hsi48Config>,
119 /// The voltage range influences the maximum clock frequencies for different parts of the 119 /// The voltage range influences the maximum clock frequencies for different parts of the
120 /// device. In particular, system clocks exceeding 110 MHz require `RANGE1`, and system clocks 120 /// device. In particular, system clocks exceeding 110 MHz require `RANGE1`, and system clocks
121 /// exceeding 55 MHz require at least `RANGE2`. 121 /// exceeding 55 MHz require at least `RANGE2`.
@@ -189,7 +189,7 @@ impl Default for Config {
189 apb1_pre: APBPrescaler::DIV1, 189 apb1_pre: APBPrescaler::DIV1,
190 apb2_pre: APBPrescaler::DIV1, 190 apb2_pre: APBPrescaler::DIV1,
191 apb3_pre: APBPrescaler::DIV1, 191 apb3_pre: APBPrescaler::DIV1,
192 hsi48: true, 192 hsi48: Some(Default::default()),
193 voltage_range: VoltageScale::RANGE3, 193 voltage_range: VoltageScale::RANGE3,
194 ls: Default::default(), 194 ls: Default::default(),
195 } 195 }
@@ -322,10 +322,7 @@ pub(crate) unsafe fn init(config: Config) {
322 } 322 }
323 }; 323 };
324 324
325 if config.hsi48 { 325 let _hsi48 = config.hsi48.map(super::init_hsi48);
326 RCC.cr().modify(|w| w.set_hsi48on(true));
327 while !RCC.cr().read().hsi48rdy() {}
328 }
329 326
330 // The clock source is ready 327 // The clock source is ready
331 // Calculate and set the flash wait states 328 // Calculate and set the flash wait states
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs
index 9099b609a..188988b14 100644
--- a/examples/stm32g4/src/bin/usb_serial.rs
+++ b/examples/stm32g4/src/bin/usb_serial.rs
@@ -4,7 +4,7 @@
4 4
5use defmt::{panic, *}; 5use defmt::{panic, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, CrsConfig, CrsSyncSource, Pll, PllM, PllN, PllQ, PllR, PllSrc}; 7use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSrc};
8use embassy_stm32::time::Hertz; 8use embassy_stm32::time::Hertz;
9use embassy_stm32::usb::{self, Driver, Instance}; 9use embassy_stm32::usb::{self, Driver, Instance};
10use embassy_stm32::{bind_interrupts, peripherals, Config}; 10use embassy_stm32::{bind_interrupts, peripherals, Config};
@@ -41,9 +41,7 @@ async fn main(_spawner: Spawner) {
41 41
42 if USE_HSI48 { 42 if USE_HSI48 {
43 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. 43 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
44 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Some(CrsConfig { 44 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true }));
45 sync_src: CrsSyncSource::Usb,
46 })));
47 } else { 45 } else {
48 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); 46 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ);
49 } 47 }
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs
index 5bec9d447..b2758cba0 100644
--- a/examples/stm32h5/src/bin/eth.rs
+++ b/examples/stm32h5/src/bin/eth.rs
@@ -37,7 +37,7 @@ async fn net_task(stack: &'static Stack<Device>) -> ! {
37async fn main(spawner: Spawner) -> ! { 37async fn main(spawner: Spawner) -> ! {
38 let mut config = Config::default(); 38 let mut config = Config::default();
39 config.rcc.hsi = None; 39 config.rcc.hsi = None;
40 config.rcc.hsi48 = true; // needed for rng 40 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
41 config.rcc.hse = Some(Hse { 41 config.rcc.hse = Some(Hse {
42 freq: Hertz(8_000_000), 42 freq: Hertz(8_000_000),
43 mode: HseMode::BypassDigital, 43 mode: HseMode::BypassDigital,
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs
index 735826a69..13b218d00 100644
--- a/examples/stm32h5/src/bin/usb_serial.rs
+++ b/examples/stm32h5/src/bin/usb_serial.rs
@@ -4,9 +4,6 @@
4 4
5use defmt::{panic, *}; 5use defmt::{panic, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::rcc::{
8 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllDiv, PllMul, PllPreDiv, PllSource, Sysclk, VoltageScale,
9};
10use embassy_stm32::time::Hertz; 7use embassy_stm32::time::Hertz;
11use embassy_stm32::usb::{Driver, Instance}; 8use embassy_stm32::usb::{Driver, Instance};
12use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; 9use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config};
@@ -23,26 +20,29 @@ bind_interrupts!(struct Irqs {
23#[embassy_executor::main] 20#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
25 let mut config = Config::default(); 22 let mut config = Config::default();
26 config.rcc.hsi = None; 23 {
27 config.rcc.hsi48 = true; // needed for usb 24 use embassy_stm32::rcc::*;
28 config.rcc.hse = Some(Hse { 25 config.rcc.hsi = None;
29 freq: Hertz(8_000_000), 26 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
30 mode: HseMode::BypassDigital, 27 config.rcc.hse = Some(Hse {
31 }); 28 freq: Hertz(8_000_000),
32 config.rcc.pll1 = Some(Pll { 29 mode: HseMode::BypassDigital,
33 source: PllSource::HSE, 30 });
34 prediv: PllPreDiv::DIV2, 31 config.rcc.pll1 = Some(Pll {
35 mul: PllMul::MUL125, 32 source: PllSource::HSE,
36 divp: Some(PllDiv::DIV2), // 250mhz 33 prediv: PllPreDiv::DIV2,
37 divq: None, 34 mul: PllMul::MUL125,
38 divr: None, 35 divp: Some(PllDiv::DIV2), // 250mhz
39 }); 36 divq: None,
40 config.rcc.ahb_pre = AHBPrescaler::DIV2; 37 divr: None,
41 config.rcc.apb1_pre = APBPrescaler::DIV4; 38 });
42 config.rcc.apb2_pre = APBPrescaler::DIV2; 39 config.rcc.ahb_pre = AHBPrescaler::DIV2;
43 config.rcc.apb3_pre = APBPrescaler::DIV4; 40 config.rcc.apb1_pre = APBPrescaler::DIV4;
44 config.rcc.sys = Sysclk::PLL1_P; 41 config.rcc.apb2_pre = APBPrescaler::DIV2;
45 config.rcc.voltage_scale = VoltageScale::Scale0; 42 config.rcc.apb3_pre = APBPrescaler::DIV4;
43 config.rcc.sys = Sysclk::PLL1_P;
44 config.rcc.voltage_scale = VoltageScale::Scale0;
45 }
46 let p = embassy_stm32::init(config); 46 let p = embassy_stm32::init(config);
47 47
48 info!("Hello World!"); 48 info!("Hello World!");
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index e37d8797b..b7a077374 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -36,7 +36,7 @@ async fn main(spawner: Spawner) -> ! {
36 use embassy_stm32::rcc::*; 36 use embassy_stm32::rcc::*;
37 config.rcc.hsi = Some(HSIPrescaler::DIV1); 37 config.rcc.hsi = Some(HSIPrescaler::DIV1);
38 config.rcc.csi = true; 38 config.rcc.csi = true;
39 config.rcc.hsi48 = true; // needed for RNG 39 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
40 config.rcc.pll1 = Some(Pll { 40 config.rcc.pll1 = Some(Pll {
41 source: PllSource::HSI, 41 source: PllSource::HSI,
42 prediv: PllPreDiv::DIV4, 42 prediv: PllPreDiv::DIV4,
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 88df53f01..f0f28ec9c 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -37,7 +37,7 @@ async fn main(spawner: Spawner) -> ! {
37 use embassy_stm32::rcc::*; 37 use embassy_stm32::rcc::*;
38 config.rcc.hsi = Some(HSIPrescaler::DIV1); 38 config.rcc.hsi = Some(HSIPrescaler::DIV1);
39 config.rcc.csi = true; 39 config.rcc.csi = true;
40 config.rcc.hsi48 = true; // needed for RNG 40 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
41 config.rcc.pll1 = Some(Pll { 41 config.rcc.pll1 = Some(Pll {
42 source: PllSource::HSI, 42 source: PllSource::HSI,
43 prediv: PllPreDiv::DIV4, 43 prediv: PllPreDiv::DIV4,
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index e4bac8a5a..e0be495d1 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -19,7 +19,6 @@ async fn main(_spawner: Spawner) {
19 use embassy_stm32::rcc::*; 19 use embassy_stm32::rcc::*;
20 config.rcc.hsi = Some(HSIPrescaler::DIV1); 20 config.rcc.hsi = Some(HSIPrescaler::DIV1);
21 config.rcc.csi = true; 21 config.rcc.csi = true;
22 config.rcc.hsi48 = true; // needed for RNG
23 config.rcc.pll1 = Some(Pll { 22 config.rcc.pll1 = Some(Pll {
24 source: PllSource::HSI, 23 source: PllSource::HSI,
25 prediv: PllPreDiv::DIV4, 24 prediv: PllPreDiv::DIV4,
diff --git a/examples/stm32h7/src/bin/rng.rs b/examples/stm32h7/src/bin/rng.rs
index af1d6ebb8..1fb4cfec0 100644
--- a/examples/stm32h7/src/bin/rng.rs
+++ b/examples/stm32h7/src/bin/rng.rs
@@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs {
15#[embassy_executor::main] 15#[embassy_executor::main]
16async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
17 let mut config = Config::default(); 17 let mut config = Config::default();
18 config.rcc.hsi48 = true; // needed for RNG. 18 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
19 let p = embassy_stm32::init(config); 19 let p = embassy_stm32::init(config);
20 info!("Hello World!"); 20 info!("Hello World!");
21 21
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs
index 19d77183b..648ff6eea 100644
--- a/examples/stm32h7/src/bin/usb_serial.rs
+++ b/examples/stm32h7/src/bin/usb_serial.rs
@@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) {
25 use embassy_stm32::rcc::*; 25 use embassy_stm32::rcc::*;
26 config.rcc.hsi = Some(HSIPrescaler::DIV1); 26 config.rcc.hsi = Some(HSIPrescaler::DIV1);
27 config.rcc.csi = true; 27 config.rcc.csi = true;
28 config.rcc.hsi48 = true; // needed for USB 28 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
29 config.rcc.pll1 = Some(Pll { 29 config.rcc.pll1 = Some(Pll {
30 source: PllSource::HSI, 30 source: PllSource::HSI,
31 prediv: PllPreDiv::DIV4, 31 prediv: PllPreDiv::DIV4,
diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs
index 441b00c6d..ffede253e 100644
--- a/examples/stm32l0/src/bin/button_exti.rs
+++ b/examples/stm32l0/src/bin/button_exti.rs
@@ -11,8 +11,7 @@ use {defmt_rtt as _, panic_probe as _};
11 11
12#[embassy_executor::main] 12#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 13async fn main(_spawner: Spawner) {
14 let mut config = Config::default(); 14 let config = Config::default();
15 config.rcc.hsi48 = true;
16 let p = embassy_stm32::init(config); 15 let p = embassy_stm32::init(config);
17 16
18 let button = Input::new(p.PB2, Pull::Up); 17 let button = Input::new(p.PB2, Pull::Up);
diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs
index 61024ef79..8ca9e8b22 100644
--- a/examples/stm32l0/src/bin/lora_cad.rs
+++ b/examples/stm32l0/src/bin/lora_cad.rs
@@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel
23#[embassy_executor::main] 23#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
25 let mut config = embassy_stm32::Config::default(); 25 let mut config = embassy_stm32::Config::default();
26 config.rcc.hsi = true;
26 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; 27 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
27 config.rcc.hsi48 = true;
28 let p = embassy_stm32::init(config); 28 let p = embassy_stm32::init(config);
29 29
30 let mut spi_config = spi::Config::default(); 30 let mut spi_config = spi::Config::default();
diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs
index 9c4f32916..4365c4cf6 100644
--- a/examples/stm32l0/src/bin/lora_lorawan.rs
+++ b/examples/stm32l0/src/bin/lora_lorawan.rs
@@ -33,8 +33,8 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th
33#[embassy_executor::main] 33#[embassy_executor::main]
34async fn main(_spawner: Spawner) { 34async fn main(_spawner: Spawner) {
35 let mut config = embassy_stm32::Config::default(); 35 let mut config = embassy_stm32::Config::default();
36 config.rcc.hsi = true;
36 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; 37 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
37 config.rcc.hsi48 = true;
38 let p = embassy_stm32::init(config); 38 let p = embassy_stm32::init(config);
39 39
40 let mut spi_config = spi::Config::default(); 40 let mut spi_config = spi::Config::default();
diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs
index 4a50182c2..0627ac087 100644
--- a/examples/stm32l0/src/bin/lora_p2p_receive.rs
+++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs
@@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel
23#[embassy_executor::main] 23#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
25 let mut config = embassy_stm32::Config::default(); 25 let mut config = embassy_stm32::Config::default();
26 config.rcc.hsi = true;
26 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; 27 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
27 config.rcc.hsi48 = true;
28 let p = embassy_stm32::init(config); 28 let p = embassy_stm32::init(config);
29 29
30 let mut spi_config = spi::Config::default(); 30 let mut spi_config = spi::Config::default();
diff --git a/examples/stm32l0/src/bin/lora_p2p_send.rs b/examples/stm32l0/src/bin/lora_p2p_send.rs
index f6de6a5cd..4f12cadc8 100644
--- a/examples/stm32l0/src/bin/lora_p2p_send.rs
+++ b/examples/stm32l0/src/bin/lora_p2p_send.rs
@@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel
23#[embassy_executor::main] 23#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
25 let mut config = embassy_stm32::Config::default(); 25 let mut config = embassy_stm32::Config::default();
26 config.rcc.hsi = true;
26 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; 27 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI;
27 config.rcc.hsi48 = true;
28 let p = embassy_stm32::init(config); 28 let p = embassy_stm32::init(config);
29 29
30 let mut spi_config = spi::Config::default(); 30 let mut spi_config = spi::Config::default();
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index f76b504a7..62caeea55 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -90,7 +90,7 @@ async fn main(spawner: Spawner) {
90 divq: None, 90 divq: None,
91 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) 91 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2)
92 }); 92 });
93 config.rcc.hsi48 = true; // needed for rng 93 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
94 } 94 }
95 95
96 let dp = embassy_stm32::init(config); 96 let dp = embassy_stm32::init(config);
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs
index 15c6f1982..d459245d5 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.hsi48 = true; 26 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
27 config.rcc.mux = ClockSrc::PLL1_R; 27 config.rcc.mux = ClockSrc::PLL1_R;
28 config.rcc.hsi = true; 28 config.rcc.hsi = true;
29 config.rcc.pll = Some(Pll { 29 config.rcc.pll = Some(Pll {
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs
index f59f623b3..eaa1c2912 100644
--- a/examples/stm32u5/src/bin/usb_serial.rs
+++ b/examples/stm32u5/src/bin/usb_serial.rs
@@ -29,8 +29,7 @@ async fn main(_spawner: Spawner) {
29 n: Plln::MUL10, 29 n: Plln::MUL10,
30 r: Plldiv::DIV1, 30 r: Plldiv::DIV1,
31 }); 31 });
32 //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); 32 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
33 config.rcc.hsi48 = true;
34 33
35 let p = embassy_stm32::init(config); 34 let p = embassy_stm32::init(config);
36 35
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 54e23e436..3668e18ce 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -306,7 +306,7 @@ pub fn config() -> Config {
306 { 306 {
307 use embassy_stm32::rcc::*; 307 use embassy_stm32::rcc::*;
308 config.rcc.hsi = None; 308 config.rcc.hsi = None;
309 config.rcc.hsi48 = true; // needed for rng 309 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
310 config.rcc.hse = Some(Hse { 310 config.rcc.hse = Some(Hse {
311 freq: Hertz(8_000_000), 311 freq: Hertz(8_000_000),
312 mode: HseMode::BypassDigital, 312 mode: HseMode::BypassDigital,
@@ -332,7 +332,7 @@ pub fn config() -> Config {
332 use embassy_stm32::rcc::*; 332 use embassy_stm32::rcc::*;
333 config.rcc.hsi = Some(HSIPrescaler::DIV1); 333 config.rcc.hsi = Some(HSIPrescaler::DIV1);
334 config.rcc.csi = true; 334 config.rcc.csi = true;
335 config.rcc.hsi48 = true; // needed for RNG 335 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
336 config.rcc.pll1 = Some(Pll { 336 config.rcc.pll1 = Some(Pll {
337 source: PllSource::HSI, 337 source: PllSource::HSI,
338 prediv: PllPreDiv::DIV4, 338 prediv: PllPreDiv::DIV4,
@@ -364,7 +364,7 @@ pub fn config() -> Config {
364 use embassy_stm32::rcc::*; 364 use embassy_stm32::rcc::*;
365 config.rcc.hsi = Some(HSIPrescaler::DIV1); 365 config.rcc.hsi = Some(HSIPrescaler::DIV1);
366 config.rcc.csi = true; 366 config.rcc.csi = true;
367 config.rcc.hsi48 = true; // needed for RNG 367 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
368 config.rcc.pll1 = Some(Pll { 368 config.rcc.pll1 = Some(Pll {
369 source: PllSource::HSI, 369 source: PllSource::HSI,
370 prediv: PllPreDiv::DIV4, 370 prediv: PllPreDiv::DIV4,