aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBing Wen <[email protected]>2024-11-26 12:27:43 +0800
committerBing Wen <[email protected]>2024-11-26 12:46:20 +0800
commit8eaa3c8fd3385d50bbf844c6fff0790884ac56af (patch)
tree0374268aa6f34dc7dfe519c8d6bacabe8c1c3c21
parentb9408f051080398f38e03f7d0d20bba860213064 (diff)
Add new feature to enable overclocking
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/rcc/c0.rs13
-rw-r--r--embassy-stm32/src/rcc/f013.rs18
-rw-r--r--embassy-stm32/src/rcc/f247.rs14
-rw-r--r--embassy-stm32/src/rcc/g0.rs19
-rw-r--r--embassy-stm32/src/rcc/g4.rs18
6 files changed, 63 insertions, 23 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index ebcfb73c9..363bc9797 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/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs
index 6712aedc4..c6ac46491 100644
--- a/embassy-stm32/src/rcc/c0.rs
+++ b/embassy-stm32/src/rcc/c0.rs
@@ -109,9 +109,12 @@ pub(crate) unsafe fn init(config: Config) {
109 None 109 None
110 } 110 }
111 Some(hse) => { 111 Some(hse) => {
112 match hse.mode { 112 #[cfg(not(feature = "unchecked-overclocking"))]
113 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 113 {
114 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 114 match hse.mode {
115 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
116 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
117 }
115 } 118 }
116 119
117 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 120 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -126,14 +129,16 @@ pub(crate) unsafe fn init(config: Config) {
126 Sysclk::HSE => unwrap!(hse), 129 Sysclk::HSE => unwrap!(hse),
127 _ => unreachable!(), 130 _ => unreachable!(),
128 }; 131 };
129 132 #[cfg(not(feature = "unchecked-overclocking"))]
130 assert!(max::SYSCLK.contains(&sys)); 133 assert!(max::SYSCLK.contains(&sys));
131 134
132 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 135 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
133 let hclk = sys / config.ahb_pre; 136 let hclk = sys / config.ahb_pre;
137 #[cfg(not(feature = "unchecked-overclocking"))]
134 assert!(max::HCLK.contains(&hclk)); 138 assert!(max::HCLK.contains(&hclk));
135 139
136 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 140 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
141 #[cfg(not(feature = "unchecked-overclocking"))]
137 assert!(max::PCLK.contains(&pclk1)); 142 assert!(max::PCLK.contains(&pclk1));
138 143
139 let latency = match hclk.0 { 144 let latency = match hclk.0 {
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 60577b213..20a0f3940 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -157,9 +157,12 @@ pub(crate) unsafe fn init(config: Config) {
157 None 157 None
158 } 158 }
159 Some(hse) => { 159 Some(hse) => {
160 match hse.mode { 160 #[cfg(not(feature = "unchecked-overclocking"))]
161 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 161 {
162 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 162 match hse.mode {
163 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
164 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
165 }
163 } 166 }
164 167
165 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 168 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -192,7 +195,9 @@ pub(crate) unsafe fn init(config: Config) {
192 PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)), 195 PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)),
193 }; 196 };
194 let in_freq = src_freq / pll.prediv; 197 let in_freq = src_freq / pll.prediv;
198 #[cfg(not(feature = "unchecked-overclocking"))]
195 assert!(max::PLL_IN.contains(&in_freq)); 199 assert!(max::PLL_IN.contains(&in_freq));
200 #[cfg(not(feature = "unchecked-overclocking"))]
196 let out_freq = in_freq * pll.mul; 201 let out_freq = in_freq * pll.mul;
197 assert!(max::PLL_OUT.contains(&out_freq)); 202 assert!(max::PLL_OUT.contains(&out_freq));
198 203
@@ -238,15 +243,16 @@ pub(crate) unsafe fn init(config: Config) {
238 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre); 243 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre);
239 #[cfg(stm32f0)] 244 #[cfg(stm32f0)]
240 let (pclk2, pclk2_tim) = (pclk1, pclk1_tim); 245 let (pclk2, pclk2_tim) = (pclk1, pclk1_tim);
241 246 #[cfg(not(feature = "unchecked-overclocking"))]
242 assert!(max::HCLK.contains(&hclk)); 247 assert!(max::HCLK.contains(&hclk));
248 #[cfg(not(feature = "unchecked-overclocking"))]
243 assert!(max::PCLK1.contains(&pclk1)); 249 assert!(max::PCLK1.contains(&pclk1));
244 #[cfg(not(stm32f0))] 250 #[cfg(all(not(feature = "unchecked-overclocking"), not(stm32f0)))]
245 assert!(max::PCLK2.contains(&pclk2)); 251 assert!(max::PCLK2.contains(&pclk2));
246 252
247 #[cfg(stm32f1)] 253 #[cfg(stm32f1)]
248 let adc = pclk2 / config.adc_pre; 254 let adc = pclk2 / config.adc_pre;
249 #[cfg(stm32f1)] 255 #[cfg(all(not(feature = "unchecked-overclocking"), stm32f1))]
250 assert!(max::ADC.contains(&adc)); 256 assert!(max::ADC.contains(&adc));
251 257
252 // Set latency based on HCLK frquency 258 // Set latency based on HCLK frquency
diff --git a/embassy-stm32/src/rcc/f247.rs b/embassy-stm32/src/rcc/f247.rs
index 58056301a..83d4428cc 100644
--- a/embassy-stm32/src/rcc/f247.rs
+++ b/embassy-stm32/src/rcc/f247.rs
@@ -169,9 +169,12 @@ pub(crate) unsafe fn init(config: Config) {
169 None 169 None
170 } 170 }
171 Some(hse) => { 171 Some(hse) => {
172 match hse.mode { 172 #[cfg(not(feature = "unchecked-overclocking"))]
173 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 173 {
174 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 174 match hse.mode {
175 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
176 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
177 }
175 } 178 }
176 179
177 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 180 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -204,10 +207,13 @@ pub(crate) unsafe fn init(config: Config) {
204 let hclk = sys / config.ahb_pre; 207 let hclk = sys / config.ahb_pre;
205 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 208 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); 209 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre);
207 210 #[cfg(not(feature = "unchecked-overclocking"))]
208 assert!(max::SYSCLK.contains(&sys)); 211 assert!(max::SYSCLK.contains(&sys));
212 #[cfg(not(feature = "unchecked-overclocking"))]
209 assert!(max::HCLK.contains(&hclk)); 213 assert!(max::HCLK.contains(&hclk));
214 #[cfg(not(feature = "unchecked-overclocking"))]
210 assert!(max::PCLK1.contains(&pclk1)); 215 assert!(max::PCLK1.contains(&pclk1));
216 #[cfg(not(feature = "unchecked-overclocking"))]
211 assert!(max::PCLK2.contains(&pclk2)); 217 assert!(max::PCLK2.contains(&pclk2));
212 218
213 let rtc = config.ls.init(); 219 let rtc = config.ls.init();
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index c53c83b0e..9e1351eae 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -139,9 +139,12 @@ pub(crate) unsafe fn init(config: Config) {
139 None 139 None
140 } 140 }
141 Some(hse) => { 141 Some(hse) => {
142 match hse.mode { 142 #[cfg(not(feature = "unchecked-overclocking"))]
143 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 143 {
144 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 144 match hse.mode {
145 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
146 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
147 }
145 } 148 }
146 149
147 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 150 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -169,9 +172,10 @@ pub(crate) unsafe fn init(config: Config) {
169 while RCC.cr().read().pllrdy() {} 172 while RCC.cr().read().pllrdy() {}
170 173
171 let in_freq = src_freq / pll_config.prediv; 174 let in_freq = src_freq / pll_config.prediv;
175 #[cfg(not(feature = "unchecked-overclocking"))]
172 assert!(max::PLL_IN.contains(&in_freq)); 176 assert!(max::PLL_IN.contains(&in_freq));
173 let internal_freq = in_freq * pll_config.mul; 177 let internal_freq = in_freq * pll_config.mul;
174 178 #[cfg(not(feature = "unchecked-overclocking"))]
175 assert!(max::PLL_VCO.contains(&internal_freq)); 179 assert!(max::PLL_VCO.contains(&internal_freq));
176 180
177 RCC.pllcfgr().write(|w| { 181 RCC.pllcfgr().write(|w| {
@@ -186,6 +190,7 @@ pub(crate) unsafe fn init(config: Config) {
186 w.set_pllpen(true); 190 w.set_pllpen(true);
187 }); 191 });
188 let freq = internal_freq / div_p; 192 let freq = internal_freq / div_p;
193 #[cfg(not(feature = "unchecked-overclocking"))]
189 assert!(max::PLL_P.contains(&freq)); 194 assert!(max::PLL_P.contains(&freq));
190 freq 195 freq
191 }); 196 });
@@ -196,6 +201,7 @@ pub(crate) unsafe fn init(config: Config) {
196 w.set_pllqen(true); 201 w.set_pllqen(true);
197 }); 202 });
198 let freq = internal_freq / div_q; 203 let freq = internal_freq / div_q;
204 #[cfg(not(feature = "unchecked-overclocking"))]
199 assert!(max::PLL_Q.contains(&freq)); 205 assert!(max::PLL_Q.contains(&freq));
200 freq 206 freq
201 }); 207 });
@@ -206,6 +212,7 @@ pub(crate) unsafe fn init(config: Config) {
206 w.set_pllren(true); 212 w.set_pllren(true);
207 }); 213 });
208 let freq = internal_freq / div_r; 214 let freq = internal_freq / div_r;
215 #[cfg(not(feature = "unchecked-overclocking"))]
209 assert!(max::PLL_R.contains(&freq)); 216 assert!(max::PLL_R.contains(&freq));
210 freq 217 freq
211 }); 218 });
@@ -228,14 +235,16 @@ pub(crate) unsafe fn init(config: Config) {
228 Sysclk::PLL1_R => unwrap!(pll.pll_r), 235 Sysclk::PLL1_R => unwrap!(pll.pll_r),
229 _ => unreachable!(), 236 _ => unreachable!(),
230 }; 237 };
231 238 #[cfg(not(feature = "unchecked-overclocking"))]
232 assert!(max::SYSCLK.contains(&sys)); 239 assert!(max::SYSCLK.contains(&sys));
233 240
234 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 241 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
235 let hclk = sys / config.ahb_pre; 242 let hclk = sys / config.ahb_pre;
243 #[cfg(not(feature = "unchecked-overclocking"))]
236 assert!(max::HCLK.contains(&hclk)); 244 assert!(max::HCLK.contains(&hclk));
237 245
238 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 246 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre);
247 #[cfg(not(feature = "unchecked-overclocking"))]
239 assert!(max::PCLK.contains(&pclk1)); 248 assert!(max::PCLK.contains(&pclk1));
240 249
241 let latency = match (config.voltage_range, hclk.0) { 250 let latency = match (config.voltage_range, hclk.0) {
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 16561f908..09b2a8de8 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -140,9 +140,12 @@ pub(crate) unsafe fn init(config: Config) {
140 None 140 None
141 } 141 }
142 Some(hse) => { 142 Some(hse) => {
143 match hse.mode { 143 #[cfg(not(feature = "unchecked-overclocking"))]
144 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), 144 {
145 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), 145 match hse.mode {
146 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
147 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
148 }
146 } 149 }
147 150
148 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); 151 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
@@ -169,9 +172,11 @@ pub(crate) unsafe fn init(config: Config) {
169 while RCC.cr().read().pllrdy() {} 172 while RCC.cr().read().pllrdy() {}
170 173
171 let in_freq = src_freq / pll_config.prediv; 174 let in_freq = src_freq / pll_config.prediv;
175 #[cfg(not(feature = "unchecked-overclocking"))]
172 assert!(max::PLL_IN.contains(&in_freq)); 176 assert!(max::PLL_IN.contains(&in_freq));
173 let internal_freq = in_freq * pll_config.mul; 177 let internal_freq = in_freq * pll_config.mul;
174 178
179 #[cfg(not(feature = "unchecked-overclocking"))]
175 assert!(max::PLL_VCO.contains(&internal_freq)); 180 assert!(max::PLL_VCO.contains(&internal_freq));
176 181
177 RCC.pllcfgr().write(|w| { 182 RCC.pllcfgr().write(|w| {
@@ -186,6 +191,7 @@ pub(crate) unsafe fn init(config: Config) {
186 w.set_pllpen(true); 191 w.set_pllpen(true);
187 }); 192 });
188 let freq = internal_freq / div_p; 193 let freq = internal_freq / div_p;
194 #[cfg(not(feature = "unchecked-overclocking"))]
189 assert!(max::PLL_P.contains(&freq)); 195 assert!(max::PLL_P.contains(&freq));
190 freq 196 freq
191 }); 197 });
@@ -196,6 +202,7 @@ pub(crate) unsafe fn init(config: Config) {
196 w.set_pllqen(true); 202 w.set_pllqen(true);
197 }); 203 });
198 let freq = internal_freq / div_q; 204 let freq = internal_freq / div_q;
205 #[cfg(not(feature = "unchecked-overclocking"))]
199 assert!(max::PLL_Q.contains(&freq)); 206 assert!(max::PLL_Q.contains(&freq));
200 freq 207 freq
201 }); 208 });
@@ -206,6 +213,7 @@ pub(crate) unsafe fn init(config: Config) {
206 w.set_pllren(true); 213 w.set_pllren(true);
207 }); 214 });
208 let freq = internal_freq / div_r; 215 let freq = internal_freq / div_r;
216 #[cfg(not(feature = "unchecked-overclocking"))]
209 assert!(max::PLL_R.contains(&freq)); 217 assert!(max::PLL_R.contains(&freq));
210 freq 218 freq
211 }); 219 });
@@ -229,15 +237,17 @@ pub(crate) unsafe fn init(config: Config) {
229 _ => unreachable!(), 237 _ => unreachable!(),
230 }; 238 };
231 239
240 #[cfg(not(feature = "unchecked-overclocking"))]
232 assert!(max::SYSCLK.contains(&sys)); 241 assert!(max::SYSCLK.contains(&sys));
233 242
234 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 243 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
235 let hclk = sys / config.ahb_pre; 244 let hclk = sys / config.ahb_pre;
245 #[cfg(not(feature = "unchecked-overclocking"))]
236 assert!(max::HCLK.contains(&hclk)); 246 assert!(max::HCLK.contains(&hclk));
237 247
238 let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); 248 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); 249 let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre);
240 assert!(max::PCLK.contains(&pclk2)); 250 #[cfg(not(feature = "unchecked-overclocking"))]
241 assert!(max::PCLK.contains(&pclk2)); 251 assert!(max::PCLK.contains(&pclk2));
242 252
243 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!) 253 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!)