aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2024-11-27 07:38:00 +0000
committerGitHub <[email protected]>2024-11-27 07:38:00 +0000
commit8e25bc56f6970bfccad571c0ead860104b5f986f (patch)
tree44332df4ce83e66da5eeb50a9be14f59b8f5a94c
parent37111a891ca0e55efc6326e518f423e5fc677839 (diff)
parentb225d73dc5ea6632c35d5ba063467e8b32abd14c (diff)
Merge pull request #3574 from itswenb/main
feat: Add new feature to enable overclocking
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/fmt.rs22
-rw-r--r--embassy-stm32/src/rcc/c0.rs10
-rw-r--r--embassy-stm32/src/rcc/f013.rs16
-rw-r--r--embassy-stm32/src/rcc/f247.rs12
-rw-r--r--embassy-stm32/src/rcc/g0.rs21
-rw-r--r--embassy-stm32/src/rcc/g4.rs21
7 files changed, 65 insertions, 41 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 5b0a88404..f6ffa29fa 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -138,6 +138,10 @@ trustzone-secure = []
138## There are no plans to make this stable. 138## There are no plans to make this stable.
139unstable-pac = [] 139unstable-pac = []
140 140
141## Enable this feature to disable the overclocking check.
142## DO NOT ENABLE THIS FEATURE UNLESS YOU KNOW WHAT YOU'RE DOING.
143unchecked-overclocking = []
144
141#! ## Time 145#! ## Time
142 146
143## Enables additional driver features that depend on embassy-time 147## Enables additional driver features that depend on embassy-time
diff --git a/embassy-stm32/src/fmt.rs b/embassy-stm32/src/fmt.rs
index 8ca61bc39..b6ae24ee8 100644
--- a/embassy-stm32/src/fmt.rs
+++ b/embassy-stm32/src/fmt.rs
@@ -7,6 +7,28 @@ use core::fmt::{Debug, Display, LowerHex};
7compile_error!("You may not enable both `defmt` and `log` features."); 7compile_error!("You may not enable both `defmt` and `log` features.");
8 8
9#[collapse_debuginfo(yes)] 9#[collapse_debuginfo(yes)]
10macro_rules! rcc_assert {
11 ($($x:tt)*) => {
12 {
13 #[cfg(not(feature = "unchecked-overclocking"))]
14 {
15 #[cfg(not(feature = "defmt"))]
16 ::core::assert!($($x)*);
17 #[cfg(feature = "defmt")]
18 ::defmt::assert!($($x)*);
19 }
20 #[cfg(feature = "unchecked-overclocking")]
21 {
22 #[cfg(feature = "log")]
23 ::log::warn!("`rcc_assert!` skipped: `unchecked-overclocking` feature is enabled.");
24 #[cfg(feature = "defmt")]
25 ::defmt::warn!("`rcc_assert!` skipped: `unchecked-overclocking` feature is enabled.");
26 }
27 }
28 };
29}
30
31#[collapse_debuginfo(yes)]
10macro_rules! assert { 32macro_rules! assert {
11 ($($x:tt)*) => { 33 ($($x:tt)*) => {
12 { 34 {
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs
index 6712aedc4..977b2e7a2 100644
--- a/embassy-stm32/src/rcc/c0.rs
+++ b/embassy-stm32/src/rcc/c0.rs
@@ -110,8 +110,8 @@ pub(crate) unsafe fn init(config: Config) {
110 } 110 }
111 Some(hse) => { 111 Some(hse) => {
112 match hse.mode { 112 match hse.mode {
113 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 113 HseMode::Bypass => rcc_assert!(max::HSE_BYP.contains(&hse.freq)),
114 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 114 HseMode::Oscillator => rcc_assert!(max::HSE_OSC.contains(&hse.freq)),
115 } 115 }
116 116
117 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 117 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -127,14 +127,14 @@ pub(crate) unsafe fn init(config: Config) {
127 _ => unreachable!(), 127 _ => unreachable!(),
128 }; 128 };
129 129
130 assert!(max::SYSCLK.contains(&sys)); 130 rcc_assert!(max::SYSCLK.contains(&sys));
131 131
132 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 132 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
133 let hclk = sys / config.ahb_pre; 133 let hclk = sys / config.ahb_pre;
134 assert!(max::HCLK.contains(&hclk)); 134 rcc_assert!(max::HCLK.contains(&hclk));
135 135
136 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 136 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
137 assert!(max::PCLK.contains(&pclk1)); 137 rcc_assert!(max::PCLK.contains(&pclk1));
138 138
139 let latency = match hclk.0 { 139 let latency = match hclk.0 {
140 ..=24_000_000 => Latency::WS0, 140 ..=24_000_000 => Latency::WS0,
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 60577b213..c915f1b16 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -158,8 +158,8 @@ pub(crate) unsafe fn init(config: Config) {
158 } 158 }
159 Some(hse) => { 159 Some(hse) => {
160 match hse.mode { 160 match hse.mode {
161 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 161 HseMode::Bypass => rcc_assert!(max::HSE_BYP.contains(&hse.freq)),
162 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 162 HseMode::Oscillator => rcc_assert!(max::HSE_OSC.contains(&hse.freq)),
163 } 163 }
164 164
165 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 165 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -192,9 +192,9 @@ pub(crate) unsafe fn init(config: Config) {
192 PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)), 192 PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)),
193 }; 193 };
194 let in_freq = src_freq / pll.prediv; 194 let in_freq = src_freq / pll.prediv;
195 assert!(max::PLL_IN.contains(&in_freq)); 195 rcc_assert!(max::PLL_IN.contains(&in_freq));
196 let out_freq = in_freq * pll.mul; 196 let out_freq = in_freq * pll.mul;
197 assert!(max::PLL_OUT.contains(&out_freq)); 197 rcc_assert!(max::PLL_OUT.contains(&out_freq));
198 198
199 #[cfg(not(stm32f1))] 199 #[cfg(not(stm32f1))]
200 RCC.cfgr2().modify(|w| w.set_prediv(pll.prediv)); 200 RCC.cfgr2().modify(|w| w.set_prediv(pll.prediv));
@@ -239,15 +239,15 @@ pub(crate) unsafe fn init(config: Config) {
239 #[cfg(stm32f0)] 239 #[cfg(stm32f0)]
240 let (pclk2, pclk2_tim) = (pclk1, pclk1_tim); 240 let (pclk2, pclk2_tim) = (pclk1, pclk1_tim);
241 241
242 assert!(max::HCLK.contains(&hclk)); 242 rcc_assert!(max::HCLK.contains(&hclk));
243 assert!(max::PCLK1.contains(&pclk1)); 243 rcc_assert!(max::PCLK1.contains(&pclk1));
244 #[cfg(not(stm32f0))] 244 #[cfg(not(stm32f0))]
245 assert!(max::PCLK2.contains(&pclk2)); 245 rcc_assert!(max::PCLK2.contains(&pclk2));
246 246
247 #[cfg(stm32f1)] 247 #[cfg(stm32f1)]
248 let adc = pclk2 / config.adc_pre; 248 let adc = pclk2 / config.adc_pre;
249 #[cfg(stm32f1)] 249 #[cfg(stm32f1)]
250 assert!(max::ADC.contains(&adc)); 250 rcc_assert!(max::ADC.contains(&adc));
251 251
252 // Set latency based on HCLK frquency 252 // Set latency based on HCLK frquency
253 #[cfg(stm32f0)] 253 #[cfg(stm32f0)]
diff --git a/embassy-stm32/src/rcc/f247.rs b/embassy-stm32/src/rcc/f247.rs
index 58056301a..3e7aff02d 100644
--- a/embassy-stm32/src/rcc/f247.rs
+++ b/embassy-stm32/src/rcc/f247.rs
@@ -170,8 +170,8 @@ pub(crate) unsafe fn init(config: Config) {
170 } 170 }
171 Some(hse) => { 171 Some(hse) => {
172 match hse.mode { 172 match hse.mode {
173 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 173 HseMode::Bypass => rcc_assert!(max::HSE_BYP.contains(&hse.freq)),
174 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 174 HseMode::Oscillator => rcc_assert!(max::HSE_OSC.contains(&hse.freq)),
175 } 175 }
176 176
177 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 177 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -205,10 +205,10 @@ pub(crate) unsafe fn init(config: Config) {
205 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 205 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
206 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre); 206 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre);
207 207
208 assert!(max::SYSCLK.contains(&sys)); 208 rcc_assert!(max::SYSCLK.contains(&sys));
209 assert!(max::HCLK.contains(&hclk)); 209 rcc_assert!(max::HCLK.contains(&hclk));
210 assert!(max::PCLK1.contains(&pclk1)); 210 rcc_assert!(max::PCLK1.contains(&pclk1));
211 assert!(max::PCLK2.contains(&pclk2)); 211 rcc_assert!(max::PCLK2.contains(&pclk2));
212 212
213 let rtc = config.ls.init(); 213 let rtc = config.ls.init();
214 214
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index c53c83b0e..5da33720c 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -140,8 +140,8 @@ pub(crate) unsafe fn init(config: Config) {
140 } 140 }
141 Some(hse) => { 141 Some(hse) => {
142 match hse.mode { 142 match hse.mode {
143 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 143 HseMode::Bypass => rcc_assert!(max::HSE_BYP.contains(&hse.freq)),
144 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 144 HseMode::Oscillator => rcc_assert!(max::HSE_OSC.contains(&hse.freq)),
145 } 145 }
146 146
147 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 147 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -169,10 +169,9 @@ pub(crate) unsafe fn init(config: Config) {
169 while RCC.cr().read().pllrdy() {} 169 while RCC.cr().read().pllrdy() {}
170 170
171 let in_freq = src_freq / pll_config.prediv; 171 let in_freq = src_freq / pll_config.prediv;
172 assert!(max::PLL_IN.contains(&in_freq)); 172 rcc_assert!(max::PLL_IN.contains(&in_freq));
173 let internal_freq = in_freq * pll_config.mul; 173 let internal_freq = in_freq * pll_config.mul;
174 174 rcc_assert!(max::PLL_VCO.contains(&internal_freq));
175 assert!(max::PLL_VCO.contains(&internal_freq));
176 175
177 RCC.pllcfgr().write(|w| { 176 RCC.pllcfgr().write(|w| {
178 w.set_plln(pll_config.mul); 177 w.set_plln(pll_config.mul);
@@ -186,7 +185,7 @@ pub(crate) unsafe fn init(config: Config) {
186 w.set_pllpen(true); 185 w.set_pllpen(true);
187 }); 186 });
188 let freq = internal_freq / div_p; 187 let freq = internal_freq / div_p;
189 assert!(max::PLL_P.contains(&freq)); 188 rcc_assert!(max::PLL_P.contains(&freq));
190 freq 189 freq
191 }); 190 });
192 191
@@ -196,7 +195,7 @@ pub(crate) unsafe fn init(config: Config) {
196 w.set_pllqen(true); 195 w.set_pllqen(true);
197 }); 196 });
198 let freq = internal_freq / div_q; 197 let freq = internal_freq / div_q;
199 assert!(max::PLL_Q.contains(&freq)); 198 rcc_assert!(max::PLL_Q.contains(&freq));
200 freq 199 freq
201 }); 200 });
202 201
@@ -206,7 +205,7 @@ pub(crate) unsafe fn init(config: Config) {
206 w.set_pllren(true); 205 w.set_pllren(true);
207 }); 206 });
208 let freq = internal_freq / div_r; 207 let freq = internal_freq / div_r;
209 assert!(max::PLL_R.contains(&freq)); 208 rcc_assert!(max::PLL_R.contains(&freq));
210 freq 209 freq
211 }); 210 });
212 211
@@ -229,14 +228,14 @@ pub(crate) unsafe fn init(config: Config) {
229 _ => unreachable!(), 228 _ => unreachable!(),
230 }; 229 };
231 230
232 assert!(max::SYSCLK.contains(&sys)); 231 rcc_assert!(max::SYSCLK.contains(&sys));
233 232
234 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 233 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
235 let hclk = sys / config.ahb_pre; 234 let hclk = sys / config.ahb_pre;
236 assert!(max::HCLK.contains(&hclk)); 235 rcc_assert!(max::HCLK.contains(&hclk));
237 236
238 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 237 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
239 assert!(max::PCLK.contains(&pclk1)); 238 rcc_assert!(max::PCLK.contains(&pclk1));
240 239
241 let latency = match (config.voltage_range, hclk.0) { 240 let latency = match (config.voltage_range, hclk.0) {
242 (VoltageRange::RANGE1, ..=24_000_000) => Latency::WS0, 241 (VoltageRange::RANGE1, ..=24_000_000) => Latency::WS0,
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 16561f908..e09b2915e 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -141,8 +141,8 @@ pub(crate) unsafe fn init(config: Config) {
141 } 141 }
142 Some(hse) => { 142 Some(hse) => {
143 match hse.mode { 143 match hse.mode {
144 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 144 HseMode::Bypass => rcc_assert!(max::HSE_BYP.contains(&hse.freq)),
145 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 145 HseMode::Oscillator => rcc_assert!(max::HSE_OSC.contains(&hse.freq)),
146 } 146 }
147 147
148 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 148 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -169,10 +169,10 @@ pub(crate) unsafe fn init(config: Config) {
169 while RCC.cr().read().pllrdy() {} 169 while RCC.cr().read().pllrdy() {}
170 170
171 let in_freq = src_freq / pll_config.prediv; 171 let in_freq = src_freq / pll_config.prediv;
172 assert!(max::PLL_IN.contains(&in_freq)); 172 rcc_assert!(max::PLL_IN.contains(&in_freq));
173 let internal_freq = in_freq * pll_config.mul; 173 let internal_freq = in_freq * pll_config.mul;
174 174
175 assert!(max::PLL_VCO.contains(&internal_freq)); 175 rcc_assert!(max::PLL_VCO.contains(&internal_freq));
176 176
177 RCC.pllcfgr().write(|w| { 177 RCC.pllcfgr().write(|w| {
178 w.set_plln(pll_config.mul); 178 w.set_plln(pll_config.mul);
@@ -186,7 +186,7 @@ pub(crate) unsafe fn init(config: Config) {
186 w.set_pllpen(true); 186 w.set_pllpen(true);
187 }); 187 });
188 let freq = internal_freq / div_p; 188 let freq = internal_freq / div_p;
189 assert!(max::PLL_P.contains(&freq)); 189 rcc_assert!(max::PLL_P.contains(&freq));
190 freq 190 freq
191 }); 191 });
192 192
@@ -196,7 +196,7 @@ pub(crate) unsafe fn init(config: Config) {
196 w.set_pllqen(true); 196 w.set_pllqen(true);
197 }); 197 });
198 let freq = internal_freq / div_q; 198 let freq = internal_freq / div_q;
199 assert!(max::PLL_Q.contains(&freq)); 199 rcc_assert!(max::PLL_Q.contains(&freq));
200 freq 200 freq
201 }); 201 });
202 202
@@ -206,7 +206,7 @@ pub(crate) unsafe fn init(config: Config) {
206 w.set_pllren(true); 206 w.set_pllren(true);
207 }); 207 });
208 let freq = internal_freq / div_r; 208 let freq = internal_freq / div_r;
209 assert!(max::PLL_R.contains(&freq)); 209 rcc_assert!(max::PLL_R.contains(&freq));
210 freq 210 freq
211 }); 211 });
212 212
@@ -229,16 +229,15 @@ pub(crate) unsafe fn init(config: Config) {
229 _ => unreachable!(), 229 _ => unreachable!(),
230 }; 230 };
231 231
232 assert!(max::SYSCLK.contains(&sys)); 232 rcc_assert!(max::SYSCLK.contains(&sys));
233 233
234 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 234 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
235 let hclk = sys / config.ahb_pre; 235 let hclk = sys / config.ahb_pre;
236 assert!(max::HCLK.contains(&hclk)); 236 rcc_assert!(max::HCLK.contains(&hclk));
237 237
238 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 238 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
239 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre); 239 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre);
240 assert!(max::PCLK.contains(&pclk2)); 240 rcc_assert!(max::PCLK.contains(&pclk2));
241 assert!(max::PCLK.contains(&pclk2));
242 241
243 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!) 242 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!)
244 if config.boost { 243 if config.boost {