aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-16 23:38:49 +0000
committerGitHub <[email protected]>2024-02-16 23:38:49 +0000
commit9352621058bb4e96b8897ec431cc939838729442 (patch)
treeff6cbdc1f12e1cb2ab69c9b423a090038778e874
parente9907de39d640fee02df9eac1fbd7efa33e63da2 (diff)
parent6d7458dac7e768425342910e04a75c85e667cb82 (diff)
Merge pull request #2579 from barnabywalters/g4rcc
[embassy-stm32]: stm32g4 RCC refactor
-rw-r--r--embassy-stm32/src/rcc/g4.rs354
-rw-r--r--examples/stm32g4/src/bin/adc.rs16
-rw-r--r--examples/stm32g4/src/bin/pll.rs16
-rw-r--r--examples/stm32g4/src/bin/usb_serial.rs31
4 files changed, 239 insertions, 178 deletions
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 3e20bf6af..382ffbead 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -1,10 +1,11 @@
1use stm32_metapac::flash::vals::Latency; 1use stm32_metapac::flash::vals::Latency;
2use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw}; 2use stm32_metapac::rcc::vals::{Adcsel, Sw};
3use stm32_metapac::FLASH; 3use stm32_metapac::FLASH;
4 4
5pub use crate::pac::rcc::vals::{ 5pub use crate::pac::rcc::vals::{
6 Adcsel as AdcClockSource, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, 6 Adcsel as AdcClockSource, Clk48sel as Clk48Src, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler,
7 Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, 7 Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc, Ppre as APBPrescaler,
8 Sw as Sysclk,
8}; 9};
9use crate::pac::{PWR, RCC}; 10use crate::pac::{PWR, RCC};
10use crate::time::Hertz; 11use crate::time::Hertz;
@@ -12,28 +13,22 @@ use crate::time::Hertz;
12/// HSI speed 13/// HSI speed
13pub const HSI_FREQ: Hertz = Hertz(16_000_000); 14pub const HSI_FREQ: Hertz = Hertz(16_000_000);
14 15
15/// System clock mux source 16/// HSE Mode
16#[derive(Clone, Copy)] 17#[derive(Clone, Copy, Eq, PartialEq)]
17pub enum ClockSrc { 18pub enum HseMode {
18 HSE(Hertz), 19 /// crystal/ceramic oscillator (HSEBYP=0)
19 HSI, 20 Oscillator,
20 PLL, 21 /// external analog clock (low swing) (HSEBYP=1)
22 Bypass,
21} 23}
22 24
23/// PLL clock input source 25/// HSE Configuration
24#[derive(Clone, Copy, Debug)] 26#[derive(Clone, Copy, Eq, PartialEq)]
25pub enum PllSource { 27pub struct Hse {
26 HSI, 28 /// HSE frequency.
27 HSE(Hertz), 29 pub freq: Hertz,
28} 30 /// HSE mode.
29 31 pub mode: HseMode,
30impl Into<Pllsrc> for PllSource {
31 fn into(self) -> Pllsrc {
32 match self {
33 PllSource::HSE(..) => Pllsrc::HSE,
34 PllSource::HSI => Pllsrc::HSI,
35 }
36 }
37} 32}
38 33
39/// PLL Configuration 34/// PLL Configuration
@@ -43,69 +38,89 @@ impl Into<Pllsrc> for PllSource {
43/// frequency ranges for each of these settings. 38/// frequency ranges for each of these settings.
44pub struct Pll { 39pub struct Pll {
45 /// PLL Source clock selection. 40 /// PLL Source clock selection.
46 pub source: PllSource, 41 pub source: Pllsrc,
47 42
48 /// PLL pre-divider 43 /// PLL pre-divider
49 pub prediv_m: PllM, 44 pub prediv: PllPreDiv,
50 45
51 /// PLL multiplication factor for VCO 46 /// PLL multiplication factor for VCO
52 pub mul_n: PllN, 47 pub mul: PllMul,
53 48
54 /// PLL division factor for P clock (ADC Clock) 49 /// PLL division factor for P clock (ADC Clock)
55 pub div_p: Option<PllP>, 50 pub divp: Option<PllPDiv>,
56 51
57 /// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI) 52 /// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI)
58 pub div_q: Option<PllQ>, 53 pub divq: Option<PllQDiv>,
59 54
60 /// PLL division factor for R clock (SYSCLK) 55 /// PLL division factor for R clock (SYSCLK)
61 pub div_r: Option<PllR>, 56 pub divr: Option<PllRDiv>,
62}
63
64/// Sets the source for the 48MHz clock to the USB and RNG peripherals.
65pub enum Clock48MhzSrc {
66 /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the
67 /// oscillator to comply with the USB specification for oscillator tolerance.
68 Hsi48(super::Hsi48Config),
69 /// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. For USB usage the
70 /// PLL needs to be using the HSE source to comply with the USB specification for oscillator
71 /// tolerance.
72 PllQ,
73} 57}
74 58
75/// Clocks configutation 59/// Clocks configutation
60#[non_exhaustive]
76pub struct Config { 61pub struct Config {
77 pub mux: ClockSrc, 62 /// HSI Enable
63 pub hsi: bool,
64
65 /// HSE Configuration
66 pub hse: Option<Hse>,
67
68 /// System Clock Configuration
69 pub sys: Sysclk,
70
71 /// HSI48 Configuration
72 pub hsi48: Option<super::Hsi48Config>,
73
74 /// PLL Configuration
75 pub pll: Option<Pll>,
76
77 /// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration
78 /// MUST turn on the PLLR output.
78 pub ahb_pre: AHBPrescaler, 79 pub ahb_pre: AHBPrescaler,
79 pub apb1_pre: APBPrescaler, 80 pub apb1_pre: APBPrescaler,
80 pub apb2_pre: APBPrescaler, 81 pub apb2_pre: APBPrescaler,
82
81 pub low_power_run: bool, 83 pub low_power_run: bool,
82 /// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration 84
83 /// MUST turn on the PLLR output.
84 pub pll: Option<Pll>,
85 /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals. 85 /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
86 pub clock_48mhz_src: Option<Clock48MhzSrc>, 86 pub clk48_src: Clk48Src,
87
88 /// Low-Speed Clock Configuration
89 pub ls: super::LsConfig,
90
91 /// Clock Source for ADCs 1 and 2
87 pub adc12_clock_source: AdcClockSource, 92 pub adc12_clock_source: AdcClockSource,
93
94 /// Clock Source for ADCs 3, 4 and 5
88 pub adc345_clock_source: AdcClockSource, 95 pub adc345_clock_source: AdcClockSource,
96
97 /// Clock Source for FDCAN
89 pub fdcan_clock_source: FdCanClockSource, 98 pub fdcan_clock_source: FdCanClockSource,
90 99
91 pub ls: super::LsConfig, 100 /// Enable range1 boost mode
101 /// Recommended when the SYSCLK frequency is greater than 150MHz.
102 pub boost: bool,
92} 103}
93 104
94impl Default for Config { 105impl Default for Config {
95 #[inline] 106 #[inline]
96 fn default() -> Config { 107 fn default() -> Config {
97 Config { 108 Config {
98 mux: ClockSrc::HSI, 109 hsi: true,
110 hse: None,
111 sys: Sysclk::HSI,
112 hsi48: Some(Default::default()),
113 pll: None,
99 ahb_pre: AHBPrescaler::DIV1, 114 ahb_pre: AHBPrescaler::DIV1,
100 apb1_pre: APBPrescaler::DIV1, 115 apb1_pre: APBPrescaler::DIV1,
101 apb2_pre: APBPrescaler::DIV1, 116 apb2_pre: APBPrescaler::DIV1,
102 low_power_run: false, 117 low_power_run: false,
103 pll: None, 118 clk48_src: Clk48Src::HSI48,
104 clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())), 119 ls: Default::default(),
105 adc12_clock_source: Adcsel::DISABLE, 120 adc12_clock_source: Adcsel::DISABLE,
106 adc345_clock_source: Adcsel::DISABLE, 121 adc345_clock_source: Adcsel::DISABLE,
107 fdcan_clock_source: FdCanClockSource::PCLK1, 122 fdcan_clock_source: FdCanClockSource::PCLK1,
108 ls: Default::default(), 123 boost: false,
109 } 124 }
110 } 125 }
111} 126}
@@ -117,34 +132,65 @@ pub struct PllFreq {
117} 132}
118 133
119pub(crate) unsafe fn init(config: Config) { 134pub(crate) unsafe fn init(config: Config) {
120 let pll_freq = config.pll.map(|pll_config| { 135 // Configure HSI
121 let src_freq = match pll_config.source { 136 let hsi = match config.hsi {
122 PllSource::HSI => { 137 false => {
123 RCC.cr().write(|w| w.set_hsion(true)); 138 RCC.cr().modify(|w| w.set_hsion(false));
124 while !RCC.cr().read().hsirdy() {} 139 None
140 }
141 true => {
142 RCC.cr().modify(|w| w.set_hsion(true));
143 while !RCC.cr().read().hsirdy() {}
144 Some(HSI_FREQ)
145 }
146 };
125 147
126 HSI_FREQ 148 // Configure HSE
127 } 149 let hse = match config.hse {
128 PllSource::HSE(freq) => { 150 None => {
129 RCC.cr().write(|w| w.set_hseon(true)); 151 RCC.cr().modify(|w| w.set_hseon(false));
130 while !RCC.cr().read().hserdy() {} 152 None
131 freq 153 }
154 Some(hse) => {
155 match hse.mode {
156 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
157 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
132 } 158 }
159
160 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
161 RCC.cr().modify(|w| w.set_hseon(true));
162 while !RCC.cr().read().hserdy() {}
163 Some(hse.freq)
164 }
165 };
166
167 // Configure HSI48 if required
168 if let Some(hsi48_config) = config.hsi48 {
169 super::init_hsi48(hsi48_config);
170 }
171
172 let pll_freq = config.pll.map(|pll_config| {
173 let src_freq = match pll_config.source {
174 Pllsrc::HSI => unwrap!(hsi),
175 Pllsrc::HSE => unwrap!(hse),
176 _ => unreachable!(),
133 }; 177 };
134 178
179 // TODO: check PLL input, internal and output frequencies for validity
180
135 // Disable PLL before configuration 181 // Disable PLL before configuration
136 RCC.cr().modify(|w| w.set_pllon(false)); 182 RCC.cr().modify(|w| w.set_pllon(false));
137 while RCC.cr().read().pllrdy() {} 183 while RCC.cr().read().pllrdy() {}
138 184
139 let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; 185 let internal_freq = src_freq / pll_config.prediv * pll_config.mul;
140 186
141 RCC.pllcfgr().write(|w| { 187 RCC.pllcfgr().write(|w| {
142 w.set_plln(pll_config.mul_n); 188 w.set_plln(pll_config.mul);
143 w.set_pllm(pll_config.prediv_m); 189 w.set_pllm(pll_config.prediv);
144 w.set_pllsrc(pll_config.source.into()); 190 w.set_pllsrc(pll_config.source.into());
145 }); 191 });
146 192
147 let pll_p_freq = pll_config.div_p.map(|div_p| { 193 let pll_p_freq = pll_config.divp.map(|div_p| {
148 RCC.pllcfgr().modify(|w| { 194 RCC.pllcfgr().modify(|w| {
149 w.set_pllp(div_p); 195 w.set_pllp(div_p);
150 w.set_pllpen(true); 196 w.set_pllpen(true);
@@ -152,7 +198,7 @@ pub(crate) unsafe fn init(config: Config) {
152 internal_freq / div_p 198 internal_freq / div_p
153 }); 199 });
154 200
155 let pll_q_freq = pll_config.div_q.map(|div_q| { 201 let pll_q_freq = pll_config.divq.map(|div_q| {
156 RCC.pllcfgr().modify(|w| { 202 RCC.pllcfgr().modify(|w| {
157 w.set_pllq(div_q); 203 w.set_pllq(div_q);
158 w.set_pllqen(true); 204 w.set_pllqen(true);
@@ -160,7 +206,7 @@ pub(crate) unsafe fn init(config: Config) {
160 internal_freq / div_q 206 internal_freq / div_q
161 }); 207 });
162 208
163 let pll_r_freq = pll_config.div_r.map(|div_r| { 209 let pll_r_freq = pll_config.divr.map(|div_r| {
164 RCC.pllcfgr().modify(|w| { 210 RCC.pllcfgr().modify(|w| {
165 w.set_pllr(div_r); 211 w.set_pllr(div_r);
166 w.set_pllren(true); 212 w.set_pllren(true);
@@ -179,22 +225,10 @@ pub(crate) unsafe fn init(config: Config) {
179 } 225 }
180 }); 226 });
181 227
182 let (sys_clk, sw) = match config.mux { 228 let (sys_clk, sw) = match config.sys {
183 ClockSrc::HSI => { 229 Sysclk::HSI => (HSI_FREQ, Sw::HSI),
184 // Enable HSI 230 Sysclk::HSE => (unwrap!(hse), Sw::HSE),
185 RCC.cr().write(|w| w.set_hsion(true)); 231 Sysclk::PLL1_R => {
186 while !RCC.cr().read().hsirdy() {}
187
188 (HSI_FREQ, Sw::HSI)
189 }
190 ClockSrc::HSE(freq) => {
191 // Enable HSE
192 RCC.cr().write(|w| w.set_hseon(true));
193 while !RCC.cr().read().hserdy() {}
194
195 (freq, Sw::HSE)
196 }
197 ClockSrc::PLL => {
198 assert!(pll_freq.is_some()); 232 assert!(pll_freq.is_some());
199 assert!(pll_freq.as_ref().unwrap().pll_r.is_some()); 233 assert!(pll_freq.as_ref().unwrap().pll_r.is_some());
200 234
@@ -202,41 +236,51 @@ pub(crate) unsafe fn init(config: Config) {
202 236
203 assert!(freq <= 170_000_000); 237 assert!(freq <= 170_000_000);
204 238
205 if freq >= 150_000_000 {
206 // Enable Core Boost mode on freq >= 150Mhz ([RM0440] p234)
207 PWR.cr5().modify(|w| w.set_r1mode(false));
208 // Set flash wait state in boost mode based on frequency ([RM0440] p191)
209 if freq <= 36_000_000 {
210 FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
211 } else if freq <= 68_000_000 {
212 FLASH.acr().modify(|w| w.set_latency(Latency::WS1));
213 } else if freq <= 102_000_000 {
214 FLASH.acr().modify(|w| w.set_latency(Latency::WS2));
215 } else if freq <= 136_000_000 {
216 FLASH.acr().modify(|w| w.set_latency(Latency::WS3));
217 } else {
218 FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
219 }
220 } else {
221 PWR.cr5().modify(|w| w.set_r1mode(true));
222 // Set flash wait state in normal mode based on frequency ([RM0440] p191)
223 if freq <= 30_000_000 {
224 FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
225 } else if freq <= 60_000_000 {
226 FLASH.acr().modify(|w| w.set_latency(Latency::WS1));
227 } else if freq <= 80_000_000 {
228 FLASH.acr().modify(|w| w.set_latency(Latency::WS2));
229 } else if freq <= 120_000_000 {
230 FLASH.acr().modify(|w| w.set_latency(Latency::WS3));
231 } else {
232 FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
233 }
234 }
235
236 (Hertz(freq), Sw::PLL1_R) 239 (Hertz(freq), Sw::PLL1_R)
237 } 240 }
241 _ => unreachable!(),
238 }; 242 };
239 243
244 // 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;
246
247 // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!)
248 if config.boost {
249 // RM0440 p235
250 // “The sequence to switch from Range1 normal mode to Range1 boost mode is:
251 // 1. The system clock must be divided by 2 using the AHB prescaler before switching to a higher system frequency.
252 RCC.cfgr().modify(|w| w.set_hpre(AHBPrescaler::DIV2));
253 // 2. Clear the R1MODE bit in the PWR_CR5 register. (enables boost mode)
254 PWR.cr5().modify(|w| w.set_r1mode(false));
255
256 // Below:
257 // 3. Adjust wait states according to new freq target
258 // 4. Configure and switch to new frequency
259 }
260
261 // Configure flash read access latency based on boost mode and frequency (RM0440 p98)
262 FLASH.acr().modify(|w| {
263 w.set_latency(match (config.boost, hclk.0) {
264 (true, ..=34_000_000) => Latency::WS0,
265 (true, ..=68_000_000) => Latency::WS1,
266 (true, ..=102_000_000) => Latency::WS2,
267 (true, ..=136_000_000) => Latency::WS3,
268 (true, _) => Latency::WS4,
269
270 (false, ..=36_000_000) => Latency::WS0,
271 (false, ..=60_000_000) => Latency::WS1,
272 (false, ..=90_000_000) => Latency::WS2,
273 (false, ..=120_000_000) => Latency::WS3,
274 (false, _) => Latency::WS4,
275 })
276 });
277
278 if config.boost {
279 // 5. Wait for at least 1us and then reconfigure the AHB prescaler to get the needed HCLK clock frequency.
280 cortex_m::asm::delay(16);
281 }
282
283 // Now that boost mode and flash read access latency are configured, set up SYSCLK
240 RCC.cfgr().modify(|w| { 284 RCC.cfgr().modify(|w| {
241 w.set_sw(sw); 285 w.set_sw(sw);
242 w.set_hpre(config.ahb_pre); 286 w.set_hpre(config.ahb_pre);
@@ -244,42 +288,26 @@ pub(crate) unsafe fn init(config: Config) {
244 w.set_ppre2(config.apb2_pre); 288 w.set_ppre2(config.apb2_pre);
245 }); 289 });
246 290
247 let ahb_freq = sys_clk / config.ahb_pre; 291 let (apb1_freq, apb1_tim_freq) = super::util::calc_pclk(hclk, config.apb1_pre);
248 292 let (apb2_freq, apb2_tim_freq) = super::util::calc_pclk(hclk, config.apb2_pre);
249 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
250 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
251 pre => {
252 let freq = ahb_freq / pre;
253 (freq, freq * 2u32)
254 }
255 };
256
257 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
258 APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
259 pre => {
260 let freq = ahb_freq / pre;
261 (freq, freq * 2u32)
262 }
263 };
264
265 // Setup the 48 MHz clock if needed
266 if let Some(clock_48mhz_src) = config.clock_48mhz_src {
267 let source = match clock_48mhz_src {
268 Clock48MhzSrc::PllQ => {
269 // Make sure the PLLQ is enabled and running at 48Mhz
270 let pllq_freq = pll_freq.as_ref().and_then(|f| f.pll_q);
271 assert!(pllq_freq.is_some() && pllq_freq.unwrap().0 == 48_000_000);
272 293
294 // Configure the 48MHz clock source for USB and RNG peripherals.
295 RCC.ccipr().modify(|w| {
296 w.set_clk48sel(match config.clk48_src {
297 Clk48Src::PLL1_Q => {
298 // Not checking that PLL1_Q is 48MHz here so as not to require the user to have a 48MHz clock.
299 // Peripherals which require one (USB, RNG) should check that they‘re driven by a valid 48MHz
300 // clock at init.
273 crate::pac::rcc::vals::Clk48sel::PLL1_Q 301 crate::pac::rcc::vals::Clk48sel::PLL1_Q
274 } 302 }
275 Clock48MhzSrc::Hsi48(config) => { 303 Clk48Src::HSI48 => {
276 super::init_hsi48(config); 304 // Make sure HSI48 is enabled
305 assert!(config.hsi48.is_some());
277 crate::pac::rcc::vals::Clk48sel::HSI48 306 crate::pac::rcc::vals::Clk48sel::HSI48
278 } 307 }
279 }; 308 _ => unreachable!(),
280 309 })
281 RCC.ccipr().modify(|w| w.set_clk48sel(source)); 310 });
282 }
283 311
284 RCC.ccipr().modify(|w| w.set_adc12sel(config.adc12_clock_source)); 312 RCC.ccipr().modify(|w| w.set_adc12sel(config.adc12_clock_source));
285 RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source)); 313 RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source));
@@ -308,18 +336,42 @@ pub(crate) unsafe fn init(config: Config) {
308 336
309 set_clocks!( 337 set_clocks!(
310 sys: Some(sys_clk), 338 sys: Some(sys_clk),
311 hclk1: Some(ahb_freq), 339 hclk1: Some(hclk),
312 hclk2: Some(ahb_freq), 340 hclk2: Some(hclk),
313 hclk3: Some(ahb_freq), 341 hclk3: Some(hclk),
314 pclk1: Some(apb1_freq), 342 pclk1: Some(apb1_freq),
315 pclk1_tim: Some(apb1_tim_freq), 343 pclk1_tim: Some(apb1_tim_freq),
316 pclk2: Some(apb2_freq), 344 pclk2: Some(apb2_freq),
317 pclk2_tim: Some(apb2_tim_freq), 345 pclk2_tim: Some(apb2_tim_freq),
318 adc: adc12_ck, 346 adc: adc12_ck,
319 adc34: adc345_ck, 347 adc34: adc345_ck,
320 pll1_p: None, 348 pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p),
321 pll1_q: None, // TODO 349 pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_p),
322 hse: None, // TODO 350 hse: hse,
323 rtc: rtc, 351 rtc: rtc,
324 ); 352 );
325} 353}
354
355// TODO: if necessary, make more of these, gated behind cfg attrs
356mod max {
357 use core::ops::RangeInclusive;
358
359 use crate::time::Hertz;
360
361 /// HSE 4-48MHz (RM0440 p280)
362 pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000);
363
364 /// External Clock ?-48MHz (RM0440 p280)
365 pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000);
366
367 // SYSCLK ?-170MHz (RM0440 p282)
368 //pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
369
370 // PLL Output frequency ?-170MHz (RM0440 p281)
371 //pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
372
373 // Left over from f.rs, remove if not necessary
374 //pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(12_500_000)..=Hertz(216_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}
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 35324d931..99e3ef63b 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -4,7 +4,7 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSource}; 7use embassy_stm32::rcc::{AdcClockSource, Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk};
8use embassy_stm32::Config; 8use embassy_stm32::Config;
9use embassy_time::{Delay, Timer}; 9use embassy_time::{Delay, Timer};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -14,17 +14,17 @@ async fn main(_spawner: Spawner) {
14 let mut config = Config::default(); 14 let mut config = Config::default();
15 15
16 config.rcc.pll = Some(Pll { 16 config.rcc.pll = Some(Pll {
17 source: PllSource::HSI, 17 source: Pllsrc::HSI,
18 prediv_m: PllM::DIV4, 18 prediv: PllPreDiv::DIV4,
19 mul_n: PllN::MUL85, 19 mul: PllMul::MUL85,
20 div_p: None, 20 divp: None,
21 div_q: None, 21 divq: None,
22 // Main system clock at 170 MHz 22 // Main system clock at 170 MHz
23 div_r: Some(PllR::DIV2), 23 divr: Some(PllRDiv::DIV2),
24 }); 24 });
25 25
26 config.rcc.adc12_clock_source = AdcClockSource::SYS; 26 config.rcc.adc12_clock_source = AdcClockSource::SYS;
27 config.rcc.mux = ClockSrc::PLL; 27 config.rcc.sys = Sysclk::PLL1_R;
28 28
29 let mut p = embassy_stm32::init(config); 29 let mut p = embassy_stm32::init(config);
30 info!("Hello World!"); 30 info!("Hello World!");
diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs
index 46ebe0b0d..5274de79d 100644
--- a/examples/stm32g4/src/bin/pll.rs
+++ b/examples/stm32g4/src/bin/pll.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSource}; 6use embassy_stm32::rcc::{Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk};
7use embassy_stm32::Config; 7use embassy_stm32::Config;
8use embassy_time::Timer; 8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -13,16 +13,16 @@ async fn main(_spawner: Spawner) {
13 let mut config = Config::default(); 13 let mut config = Config::default();
14 14
15 config.rcc.pll = Some(Pll { 15 config.rcc.pll = Some(Pll {
16 source: PllSource::HSI, 16 source: Pllsrc::HSI,
17 prediv_m: PllM::DIV4, 17 prediv: PllPreDiv::DIV4,
18 mul_n: PllN::MUL85, 18 mul: PllMul::MUL85,
19 div_p: None, 19 divp: None,
20 div_q: None, 20 divq: None,
21 // Main system clock at 170 MHz 21 // Main system clock at 170 MHz
22 div_r: Some(PllR::DIV2), 22 divr: Some(PllRDiv::DIV2),
23 }); 23 });
24 24
25 config.rcc.mux = ClockSrc::PLL; 25 config.rcc.sys = Sysclk::PLL1_R;
26 26
27 let _p = embassy_stm32::init(config); 27 let _p = embassy_stm32::init(config);
28 info!("Hello World!"); 28 info!("Hello World!");
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs
index c26fa76b7..989fef5b0 100644
--- a/examples/stm32g4/src/bin/usb_serial.rs
+++ b/examples/stm32g4/src/bin/usb_serial.rs
@@ -3,7 +3,9 @@
3 3
4use defmt::{panic, *}; 4use defmt::{panic, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSource}; 6use embassy_stm32::rcc::{
7 Clk48Src, Hse, HseMode, Hsi48Config, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, Pllsrc, Sysclk,
8};
7use embassy_stm32::time::Hertz; 9use embassy_stm32::time::Hertz;
8use embassy_stm32::usb::{self, Driver, Instance}; 10use embassy_stm32::usb::{self, Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, Config}; 11use embassy_stm32::{bind_interrupts, peripherals, Config};
@@ -24,25 +26,32 @@ async fn main(_spawner: Spawner) {
24 // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. 26 // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE.
25 const USE_HSI48: bool = true; 27 const USE_HSI48: bool = true;
26 28
27 let plldivq = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; 29 let plldivq = if USE_HSI48 { None } else { Some(PllQDiv::DIV6) };
30
31 config.rcc.hse = Some(Hse {
32 freq: Hertz(8_000_000),
33 mode: HseMode::Oscillator,
34 });
28 35
29 config.rcc.pll = Some(Pll { 36 config.rcc.pll = Some(Pll {
30 source: PllSource::HSE(Hertz(8_000_000)), 37 source: Pllsrc::HSE,
31 prediv_m: PllM::DIV2, 38 prediv: PllPreDiv::DIV2,
32 mul_n: PllN::MUL72, 39 mul: PllMul::MUL72,
33 div_p: None, 40 divp: None,
34 div_q: plldivq, 41 divq: plldivq,
35 // Main system clock at 144 MHz 42 // Main system clock at 144 MHz
36 div_r: Some(PllR::DIV2), 43 divr: Some(PllRDiv::DIV2),
37 }); 44 });
38 45
39 config.rcc.mux = ClockSrc::PLL; 46 config.rcc.sys = Sysclk::PLL1_R;
47 config.rcc.boost = true; // BOOST!
40 48
41 if USE_HSI48 { 49 if USE_HSI48 {
42 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. 50 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
43 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true })); 51 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
52 config.rcc.clk48_src = Clk48Src::HSI48;
44 } else { 53 } else {
45 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); 54 config.rcc.clk48_src = Clk48Src::PLL1_Q;
46 } 55 }
47 56
48 let p = embassy_stm32::init(config); 57 let p = embassy_stm32::init(config);