aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarnaby Walters <[email protected]>2024-02-15 23:56:26 +0100
committerBarnaby Walters <[email protected]>2024-02-15 23:56:26 +0100
commit5b7eff65417e491fa7908dfd8b62013efb55d30b (patch)
treedb30781f8c7fc217578ed288c0594c1f23ff6354
parente8c998aad882d766988ac2c0cb0c357c600b28c1 (diff)
[embassy-stm32]: started stm32g4 RCC refactor
* Copied API from f.rs where applicable * HSE and HSI independantly configurable * Boost mode set by user rather * Added HSE, pll1_q and pll1_p frequencies to set_clocks call * Stubbed max module based on f.rs, needs cleanup
-rw-r--r--embassy-stm32/src/rcc/g4.rs204
-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.rs29
4 files changed, 158 insertions, 107 deletions
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 3e20bf6af..edd14ab23 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -1,10 +1,10 @@
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, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler, Pllm as PllPreDiv,
7 Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, 7 Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc, Ppre as APBPrescaler, Sw as Sysclk,
8}; 8};
9use crate::pac::{PWR, RCC}; 9use crate::pac::{PWR, RCC};
10use crate::time::Hertz; 10use crate::time::Hertz;
@@ -12,28 +12,20 @@ use crate::time::Hertz;
12/// HSI speed 12/// HSI speed
13pub const HSI_FREQ: Hertz = Hertz(16_000_000); 13pub const HSI_FREQ: Hertz = Hertz(16_000_000);
14 14
15/// System clock mux source 15#[derive(Clone, Copy, Eq, PartialEq)]
16#[derive(Clone, Copy)] 16pub enum HseMode {
17pub enum ClockSrc { 17 /// crystal/ceramic oscillator (HSEBYP=0)
18 HSE(Hertz), 18 Oscillator,
19 HSI, 19 /// external analog clock (low swing) (HSEBYP=1)
20 PLL, 20 Bypass,
21} 21}
22 22
23/// PLL clock input source 23#[derive(Clone, Copy, Eq, PartialEq)]
24#[derive(Clone, Copy, Debug)] 24pub struct Hse {
25pub enum PllSource { 25 /// HSE frequency.
26 HSI, 26 pub freq: Hertz,
27 HSE(Hertz), 27 /// HSE mode.
28} 28 pub mode: HseMode,
29
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} 29}
38 30
39/// PLL Configuration 31/// PLL Configuration
@@ -43,22 +35,22 @@ impl Into<Pllsrc> for PllSource {
43/// frequency ranges for each of these settings. 35/// frequency ranges for each of these settings.
44pub struct Pll { 36pub struct Pll {
45 /// PLL Source clock selection. 37 /// PLL Source clock selection.
46 pub source: PllSource, 38 pub source: Pllsrc,
47 39
48 /// PLL pre-divider 40 /// PLL pre-divider
49 pub prediv_m: PllM, 41 pub prediv: PllPreDiv,
50 42
51 /// PLL multiplication factor for VCO 43 /// PLL multiplication factor for VCO
52 pub mul_n: PllN, 44 pub mul: PllMul,
53 45
54 /// PLL division factor for P clock (ADC Clock) 46 /// PLL division factor for P clock (ADC Clock)
55 pub div_p: Option<PllP>, 47 pub divp: Option<PllPDiv>,
56 48
57 /// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI) 49 /// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI)
58 pub div_q: Option<PllQ>, 50 pub divq: Option<PllQDiv>,
59 51
60 /// PLL division factor for R clock (SYSCLK) 52 /// PLL division factor for R clock (SYSCLK)
61 pub div_r: Option<PllR>, 53 pub divr: Option<PllRDiv>,
62} 54}
63 55
64/// Sets the source for the 48MHz clock to the USB and RNG peripherals. 56/// Sets the source for the 48MHz clock to the USB and RNG peripherals.
@@ -73,39 +65,53 @@ pub enum Clock48MhzSrc {
73} 65}
74 66
75/// Clocks configutation 67/// Clocks configutation
68#[non_exhaustive]
76pub struct Config { 69pub struct Config {
77 pub mux: ClockSrc, 70 pub hsi: bool,
71 pub hse: Option<Hse>,
72 pub sys: Sysclk,
73 pub hsi48: Option<super::Hsi48Config>,
74
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,
81 pub low_power_run: bool, 82 pub low_power_run: bool,
82 /// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration 83
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. 84 /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
86 pub clock_48mhz_src: Option<Clock48MhzSrc>, 85 pub clk48_src: Option<Clock48MhzSrc>,
86
87 pub ls: super::LsConfig,
88
87 pub adc12_clock_source: AdcClockSource, 89 pub adc12_clock_source: AdcClockSource,
88 pub adc345_clock_source: AdcClockSource, 90 pub adc345_clock_source: AdcClockSource,
89 pub fdcan_clock_source: FdCanClockSource, 91 pub fdcan_clock_source: FdCanClockSource,
90 92
91 pub ls: super::LsConfig, 93 pub boost: bool,
92} 94}
93 95
94impl Default for Config { 96impl Default for Config {
95 #[inline] 97 #[inline]
96 fn default() -> Config { 98 fn default() -> Config {
97 Config { 99 Config {
98 mux: ClockSrc::HSI, 100 hsi: true,
101 hse: None,
102 sys: Sysclk::HSI,
103 hsi48: Some(Default::default()),
104 pll: None,
99 ahb_pre: AHBPrescaler::DIV1, 105 ahb_pre: AHBPrescaler::DIV1,
100 apb1_pre: APBPrescaler::DIV1, 106 apb1_pre: APBPrescaler::DIV1,
101 apb2_pre: APBPrescaler::DIV1, 107 apb2_pre: APBPrescaler::DIV1,
102 low_power_run: false, 108 low_power_run: false,
103 pll: None, 109 clk48_src: Some(Clock48MhzSrc::Hsi48(Default::default())),
104 clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())), 110 ls: Default::default(),
105 adc12_clock_source: Adcsel::DISABLE, 111 adc12_clock_source: Adcsel::DISABLE,
106 adc345_clock_source: Adcsel::DISABLE, 112 adc345_clock_source: Adcsel::DISABLE,
107 fdcan_clock_source: FdCanClockSource::PCLK1, 113 fdcan_clock_source: FdCanClockSource::PCLK1,
108 ls: Default::default(), 114 boost: false,
109 } 115 }
110 } 116 }
111} 117}
@@ -117,34 +123,60 @@ pub struct PllFreq {
117} 123}
118 124
119pub(crate) unsafe fn init(config: Config) { 125pub(crate) unsafe fn init(config: Config) {
120 let pll_freq = config.pll.map(|pll_config| { 126 // Configure HSI
121 let src_freq = match pll_config.source { 127 let hsi = match config.hsi {
122 PllSource::HSI => { 128 false => {
123 RCC.cr().write(|w| w.set_hsion(true)); 129 RCC.cr().modify(|w| w.set_hsion(false));
124 while !RCC.cr().read().hsirdy() {} 130 None
131 }
132 true => {
133 RCC.cr().modify(|w| w.set_hsion(true));
134 while !RCC.cr().read().hsirdy() {}
135 Some(HSI_FREQ)
136 }
137 };
125 138
126 HSI_FREQ 139 // Configure HSE
127 } 140 let hse = match config.hse {
128 PllSource::HSE(freq) => { 141 None => {
129 RCC.cr().write(|w| w.set_hseon(true)); 142 RCC.cr().modify(|w| w.set_hseon(false));
130 while !RCC.cr().read().hserdy() {} 143 None
131 freq 144 }
145 Some(hse) => {
146 match hse.mode {
147 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)),
148 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)),
132 } 149 }
150
151 RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator));
152 RCC.cr().modify(|w| w.set_hseon(true));
153 while !RCC.cr().read().hserdy() {}
154 Some(hse.freq)
155 }
156 };
157
158 let pll_freq = config.pll.map(|pll_config| {
159 let src_freq = match pll_config.source {
160 Pllsrc::HSI => unwrap!(hsi),
161 Pllsrc::HSE => unwrap!(hse),
162 _ => unreachable!(),
133 }; 163 };
134 164
165 // TODO: check PLL input, internal and output frequencies for validity
166
135 // Disable PLL before configuration 167 // Disable PLL before configuration
136 RCC.cr().modify(|w| w.set_pllon(false)); 168 RCC.cr().modify(|w| w.set_pllon(false));
137 while RCC.cr().read().pllrdy() {} 169 while RCC.cr().read().pllrdy() {}
138 170
139 let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; 171 let internal_freq = src_freq / pll_config.prediv * pll_config.mul;
140 172
141 RCC.pllcfgr().write(|w| { 173 RCC.pllcfgr().write(|w| {
142 w.set_plln(pll_config.mul_n); 174 w.set_plln(pll_config.mul);
143 w.set_pllm(pll_config.prediv_m); 175 w.set_pllm(pll_config.prediv);
144 w.set_pllsrc(pll_config.source.into()); 176 w.set_pllsrc(pll_config.source.into());
145 }); 177 });
146 178
147 let pll_p_freq = pll_config.div_p.map(|div_p| { 179 let pll_p_freq = pll_config.divp.map(|div_p| {
148 RCC.pllcfgr().modify(|w| { 180 RCC.pllcfgr().modify(|w| {
149 w.set_pllp(div_p); 181 w.set_pllp(div_p);
150 w.set_pllpen(true); 182 w.set_pllpen(true);
@@ -152,7 +184,7 @@ pub(crate) unsafe fn init(config: Config) {
152 internal_freq / div_p 184 internal_freq / div_p
153 }); 185 });
154 186
155 let pll_q_freq = pll_config.div_q.map(|div_q| { 187 let pll_q_freq = pll_config.divq.map(|div_q| {
156 RCC.pllcfgr().modify(|w| { 188 RCC.pllcfgr().modify(|w| {
157 w.set_pllq(div_q); 189 w.set_pllq(div_q);
158 w.set_pllqen(true); 190 w.set_pllqen(true);
@@ -160,7 +192,7 @@ pub(crate) unsafe fn init(config: Config) {
160 internal_freq / div_q 192 internal_freq / div_q
161 }); 193 });
162 194
163 let pll_r_freq = pll_config.div_r.map(|div_r| { 195 let pll_r_freq = pll_config.divr.map(|div_r| {
164 RCC.pllcfgr().modify(|w| { 196 RCC.pllcfgr().modify(|w| {
165 w.set_pllr(div_r); 197 w.set_pllr(div_r);
166 w.set_pllren(true); 198 w.set_pllren(true);
@@ -179,22 +211,10 @@ pub(crate) unsafe fn init(config: Config) {
179 } 211 }
180 }); 212 });
181 213
182 let (sys_clk, sw) = match config.mux { 214 let (sys_clk, sw) = match config.sys {
183 ClockSrc::HSI => { 215 Sysclk::HSI => (HSI_FREQ, Sw::HSI),
184 // Enable HSI 216 Sysclk::HSE => (unwrap!(hse), Sw::HSE),
185 RCC.cr().write(|w| w.set_hsion(true)); 217 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()); 218 assert!(pll_freq.is_some());
199 assert!(pll_freq.as_ref().unwrap().pll_r.is_some()); 219 assert!(pll_freq.as_ref().unwrap().pll_r.is_some());
200 220
@@ -202,10 +222,9 @@ pub(crate) unsafe fn init(config: Config) {
202 222
203 assert!(freq <= 170_000_000); 223 assert!(freq <= 170_000_000);
204 224
205 if freq >= 150_000_000 { 225 if config.boost {
206 // Enable Core Boost mode on freq >= 150Mhz ([RM0440] p234) 226 // Enable Core Boost mode ([RM0440] p234)
207 PWR.cr5().modify(|w| w.set_r1mode(false)); 227 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 { 228 if freq <= 36_000_000 {
210 FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); 229 FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
211 } else if freq <= 68_000_000 { 230 } else if freq <= 68_000_000 {
@@ -218,8 +237,8 @@ pub(crate) unsafe fn init(config: Config) {
218 FLASH.acr().modify(|w| w.set_latency(Latency::WS4)); 237 FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
219 } 238 }
220 } else { 239 } else {
240 // Enable Core Boost mode ([RM0440] p234)
221 PWR.cr5().modify(|w| w.set_r1mode(true)); 241 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 { 242 if freq <= 30_000_000 {
224 FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); 243 FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
225 } else if freq <= 60_000_000 { 244 } else if freq <= 60_000_000 {
@@ -235,6 +254,7 @@ pub(crate) unsafe fn init(config: Config) {
235 254
236 (Hertz(freq), Sw::PLL1_R) 255 (Hertz(freq), Sw::PLL1_R)
237 } 256 }
257 _ => unreachable!(),
238 }; 258 };
239 259
240 RCC.cfgr().modify(|w| { 260 RCC.cfgr().modify(|w| {
@@ -263,7 +283,7 @@ pub(crate) unsafe fn init(config: Config) {
263 }; 283 };
264 284
265 // Setup the 48 MHz clock if needed 285 // Setup the 48 MHz clock if needed
266 if let Some(clock_48mhz_src) = config.clock_48mhz_src { 286 if let Some(clock_48mhz_src) = config.clk48_src {
267 let source = match clock_48mhz_src { 287 let source = match clock_48mhz_src {
268 Clock48MhzSrc::PllQ => { 288 Clock48MhzSrc::PllQ => {
269 // Make sure the PLLQ is enabled and running at 48Mhz 289 // Make sure the PLLQ is enabled and running at 48Mhz
@@ -317,9 +337,33 @@ pub(crate) unsafe fn init(config: Config) {
317 pclk2_tim: Some(apb2_tim_freq), 337 pclk2_tim: Some(apb2_tim_freq),
318 adc: adc12_ck, 338 adc: adc12_ck,
319 adc34: adc345_ck, 339 adc34: adc345_ck,
320 pll1_p: None, 340 pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p),
321 pll1_q: None, // TODO 341 pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_p),
322 hse: None, // TODO 342 hse: hse,
323 rtc: rtc, 343 rtc: rtc,
324 ); 344 );
325} 345}
346
347// TODO: if necessary, make more of these gated behind cfg attrs
348mod max {
349 use core::ops::RangeInclusive;
350
351 use crate::time::Hertz;
352
353 /// HSE 4-48MHz (RM0440 p280)
354 pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000);
355
356 /// External Clock ?-48MHz (RM0440 p280)
357 pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000);
358
359 /// SYSCLK ?-170MHz (RM0440 p282)
360 pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
361
362 /// PLL Output frequency ?-170MHz (RM0440 p281)
363 pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
364
365 // Left over from f.rs, remove if not necessary
366 pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(12_500_000)..=Hertz(216_000_000);
367 pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(2_100_000);
368 pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(100_000_000)..=Hertz(432_000_000);
369}
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..d9207e4cd 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 Clock48MhzSrc, 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,30 @@ 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;
40 47
41 if USE_HSI48 { 48 if USE_HSI48 {
42 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. 49 // 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 })); 50 config.rcc.clk48_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true }));
44 } else { 51 } else {
45 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); 52 config.rcc.clk48_src = Some(Clock48MhzSrc::PllQ);
46 } 53 }
47 54
48 let p = embassy_stm32::init(config); 55 let p = embassy_stm32::init(config);