aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-23 13:05:01 +0000
committerGitHub <[email protected]>2024-02-23 13:05:01 +0000
commitf77d59500e9bbc0282f1ba4b6b27507f83f9d974 (patch)
tree3b3e54b5416f441cc401e82812fb0528c2f74eea
parent840a9a9ce7eaba61f4c3aceee1deb87271ea3421 (diff)
parentb091ffcb55840a1349c62f1e4218746d9d51b6c3 (diff)
Merge pull request #2618 from barnabywalters/g4rcc
[embassy-stm32] G4 RCC refactor amendments and additions
-rw-r--r--embassy-stm32/src/rcc/g4.rs52
1 files changed, 35 insertions, 17 deletions
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 382ffbead..6ed266284 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -176,7 +176,7 @@ pub(crate) unsafe fn init(config: Config) {
176 _ => unreachable!(), 176 _ => unreachable!(),
177 }; 177 };
178 178
179 // TODO: check PLL input, internal and output frequencies for validity 179 assert!(max::PLL_IN.contains(&src_freq));
180 180
181 // Disable PLL before configuration 181 // Disable PLL before configuration
182 RCC.cr().modify(|w| w.set_pllon(false)); 182 RCC.cr().modify(|w| w.set_pllon(false));
@@ -184,6 +184,8 @@ pub(crate) unsafe fn init(config: Config) {
184 184
185 let internal_freq = src_freq / pll_config.prediv * pll_config.mul; 185 let internal_freq = src_freq / pll_config.prediv * pll_config.mul;
186 186
187 assert!(max::PLL_VCO.contains(&internal_freq));
188
187 RCC.pllcfgr().write(|w| { 189 RCC.pllcfgr().write(|w| {
188 w.set_plln(pll_config.mul); 190 w.set_plln(pll_config.mul);
189 w.set_pllm(pll_config.prediv); 191 w.set_pllm(pll_config.prediv);
@@ -195,7 +197,9 @@ pub(crate) unsafe fn init(config: Config) {
195 w.set_pllp(div_p); 197 w.set_pllp(div_p);
196 w.set_pllpen(true); 198 w.set_pllpen(true);
197 }); 199 });
198 internal_freq / div_p 200 let freq = internal_freq / div_p;
201 assert!(max::PCLK.contains(&freq));
202 freq
199 }); 203 });
200 204
201 let pll_q_freq = pll_config.divq.map(|div_q| { 205 let pll_q_freq = pll_config.divq.map(|div_q| {
@@ -203,7 +207,9 @@ pub(crate) unsafe fn init(config: Config) {
203 w.set_pllq(div_q); 207 w.set_pllq(div_q);
204 w.set_pllqen(true); 208 w.set_pllqen(true);
205 }); 209 });
206 internal_freq / div_q 210 let freq = internal_freq / div_q;
211 assert!(max::PCLK.contains(&freq));
212 freq
207 }); 213 });
208 214
209 let pll_r_freq = pll_config.divr.map(|div_r| { 215 let pll_r_freq = pll_config.divr.map(|div_r| {
@@ -211,7 +217,9 @@ pub(crate) unsafe fn init(config: Config) {
211 w.set_pllr(div_r); 217 w.set_pllr(div_r);
212 w.set_pllren(true); 218 w.set_pllren(true);
213 }); 219 });
214 internal_freq / div_r 220 let freq = internal_freq / div_r;
221 assert!(max::PCLK.contains(&freq));
222 freq
215 }); 223 });
216 224
217 // Enable the PLL 225 // Enable the PLL
@@ -234,7 +242,7 @@ pub(crate) unsafe fn init(config: Config) {
234 242
235 let freq = pll_freq.as_ref().unwrap().pll_r.unwrap().0; 243 let freq = pll_freq.as_ref().unwrap().pll_r.unwrap().0;
236 244
237 assert!(freq <= 170_000_000); 245 assert!(max::SYSCLK.contains(&Hertz(freq)));
238 246
239 (Hertz(freq), Sw::PLL1_R) 247 (Hertz(freq), Sw::PLL1_R)
240 } 248 }
@@ -244,6 +252,8 @@ pub(crate) unsafe fn init(config: Config) {
244 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. 252 // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
245 let hclk = sys_clk / config.ahb_pre; 253 let hclk = sys_clk / config.ahb_pre;
246 254
255 assert!(max::HCLK.contains(&hclk));
256
247 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!) 257 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!)
248 if config.boost { 258 if config.boost {
249 // RM0440 p235 259 // RM0440 p235
@@ -346,32 +356,40 @@ pub(crate) unsafe fn init(config: Config) {
346 adc: adc12_ck, 356 adc: adc12_ck,
347 adc34: adc345_ck, 357 adc34: adc345_ck,
348 pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p), 358 pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p),
349 pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_p), 359 pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_q),
360 pll1_r: pll_freq.as_ref().and_then(|pll| pll.pll_r),
350 hse: hse, 361 hse: hse,
351 rtc: rtc, 362 rtc: rtc,
352 ); 363 );
353} 364}
354 365
355// TODO: if necessary, make more of these, gated behind cfg attrs 366/// Acceptable Frequency Ranges
367/// Currently assuming voltage scaling range 1 boost mode.
368/// Where not specified in the generic G4 reference manual (RM0440), values taken from the STM32G474 datasheet.
369/// If acceptable ranges for other G4-family chips differ, make additional max modules gated behind cfg attrs.
356mod max { 370mod max {
357 use core::ops::RangeInclusive; 371 use core::ops::RangeInclusive;
358 372
359 use crate::time::Hertz; 373 use crate::time::Hertz;
360 374
361 /// HSE 4-48MHz (RM0440 p280) 375 /// HSE Frequency Range (RM0440 p280)
362 pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000); 376 pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000);
363 377
364 /// External Clock ?-48MHz (RM0440 p280) 378 /// External Clock Frequency Range (RM0440 p280)
365 pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000); 379 pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000);
366 380
367 // SYSCLK ?-170MHz (RM0440 p282) 381 /// SYSCLK Frequency Range (RM0440 p282)
368 //pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000); 382 pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
383
384 /// PLL Output Frequency Range (RM0440 p281, STM32G474 Datasheet p123, Table 46)
385 pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(8)..=Hertz(170_000_000);
386
387 /// HCLK (AHB) Clock Frequency Range (STM32G474 Datasheet)
388 pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
369 389
370 // PLL Output frequency ?-170MHz (RM0440 p281) 390 /// PLL Source Frequency Range (STM32G474 Datasheet p123, Table 46)
371 //pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000); 391 pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(2_660_000)..=Hertz(16_000_000);
372 392
373 // Left over from f.rs, remove if not necessary 393 /// PLL VCO (internal) Frequency Range (STM32G474 Datasheet p123, Table 46)
374 //pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(12_500_000)..=Hertz(216_000_000); 394 pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(96_000_000)..=Hertz(344_000_000);
375 //pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(2_100_000);
376 //pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(100_000_000)..=Hertz(432_000_000);
377} 395}