aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2022-06-26 22:59:39 +0200
committerTimo Kröger <[email protected]>2022-08-26 15:44:58 +0200
commit84240d49eaf208691d0785e060ee13a7a14f0671 (patch)
tree2f4bf109dc5879ab0337173fe490b90b79d26ea0
parentf31116cafaeea7746aec19903fb1c73adaea9ea6 (diff)
stm32wl: Fix RCC
* `MSIRGSEL = 1` was required for MSI accept the updated MSI range * Reorder enable and clock switching to properly handle the jump from the default 4MHz MSI to a higher MSI freuquency
-rw-r--r--embassy-stm32/src/rcc/wl.rs116
1 files changed, 59 insertions, 57 deletions
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs
index 69c192c67..347674918 100644
--- a/embassy-stm32/src/rcc/wl.rs
+++ b/embassy-stm32/src/rcc/wl.rs
@@ -202,54 +202,11 @@ impl Default for Config {
202 202
203pub(crate) unsafe fn init(config: Config) { 203pub(crate) unsafe fn init(config: Config) {
204 let (sys_clk, sw, vos) = match config.mux { 204 let (sys_clk, sw, vos) = match config.mux {
205 ClockSrc::HSI16 => { 205 ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Range2),
206 // Enable HSI16 206 ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Range1),
207 RCC.cr().write(|w| w.set_hsion(true)); 207 ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()),
208 while !RCC.cr().read().hsirdy() {}
209
210 (HSI_FREQ.0, 0x01, VoltageScale::Range2)
211 }
212 ClockSrc::HSE32 => {
213 // Enable HSE32
214 RCC.cr().write(|w| {
215 w.set_hsebyppwr(true);
216 w.set_hseon(true);
217 });
218 while !RCC.cr().read().hserdy() {}
219
220 (HSE32_FREQ.0, 0x02, VoltageScale::Range1)
221 }
222 ClockSrc::MSI(range) => {
223 RCC.cr().write(|w| {
224 w.set_msirange(range.into());
225 w.set_msion(true);
226 });
227
228 while !RCC.cr().read().msirdy() {}
229
230 (range.freq(), 0x00, range.vos())
231 }
232 }; 208 };
233 209
234 RCC.cfgr().modify(|w| {
235 w.set_sw(sw.into());
236 if config.ahb_pre == AHBPrescaler::NotDivided {
237 w.set_hpre(0);
238 } else {
239 w.set_hpre(config.ahb_pre.into());
240 }
241 w.set_ppre1(config.apb1_pre.into());
242 w.set_ppre2(config.apb2_pre.into());
243 });
244
245 RCC.extcfgr().modify(|w| {
246 if config.shd_ahb_pre == AHBPrescaler::NotDivided {
247 w.set_shdhpre(0);
248 } else {
249 w.set_shdhpre(config.shd_ahb_pre.into());
250 }
251 });
252
253 let ahb_freq: u32 = match config.ahb_pre { 210 let ahb_freq: u32 = match config.ahb_pre {
254 AHBPrescaler::NotDivided => sys_clk, 211 AHBPrescaler::NotDivided => sys_clk,
255 pre => { 212 pre => {
@@ -288,16 +245,6 @@ pub(crate) unsafe fn init(config: Config) {
288 } 245 }
289 }; 246 };
290 247
291 let apb3_freq = shd_ahb_freq;
292
293 if config.enable_lsi {
294 let csr = RCC.csr().read();
295 if !csr.lsion() {
296 RCC.csr().modify(|w| w.set_lsion(true));
297 while !RCC.csr().read().lsirdy() {}
298 }
299 }
300
301 // Adjust flash latency 248 // Adjust flash latency
302 let flash_clk_src_freq: u32 = shd_ahb_freq; 249 let flash_clk_src_freq: u32 = shd_ahb_freq;
303 let ws = match vos { 250 let ws = match vos {
@@ -319,6 +266,61 @@ pub(crate) unsafe fn init(config: Config) {
319 266
320 while FLASH.acr().read().latency() != ws {} 267 while FLASH.acr().read().latency() != ws {}
321 268
269 match config.mux {
270 ClockSrc::HSI16 => {
271 // Enable HSI16
272 RCC.cr().write(|w| w.set_hsion(true));
273 while !RCC.cr().read().hsirdy() {}
274 }
275 ClockSrc::HSE32 => {
276 // Enable HSE32
277 RCC.cr().write(|w| {
278 w.set_hsebyppwr(true);
279 w.set_hseon(true);
280 });
281 while !RCC.cr().read().hserdy() {}
282 }
283 ClockSrc::MSI(range) => {
284 let cr = RCC.cr().read();
285 assert!(!cr.msion() || cr.msirdy());
286 RCC.cr().write(|w| {
287 w.set_msirgsel(true);
288 w.set_msirange(range.into());
289 w.set_msion(true);
290 });
291 while !RCC.cr().read().msirdy() {}
292 }
293 }
294
295 RCC.extcfgr().modify(|w| {
296 if config.shd_ahb_pre == AHBPrescaler::NotDivided {
297 w.set_shdhpre(0);
298 } else {
299 w.set_shdhpre(config.shd_ahb_pre.into());
300 }
301 });
302
303 RCC.cfgr().modify(|w| {
304 w.set_sw(sw.into());
305 if config.ahb_pre == AHBPrescaler::NotDivided {
306 w.set_hpre(0);
307 } else {
308 w.set_hpre(config.ahb_pre.into());
309 }
310 w.set_ppre1(config.apb1_pre.into());
311 w.set_ppre2(config.apb2_pre.into());
312 });
313
314 // TODO: switch voltage range
315
316 if config.enable_lsi {
317 let csr = RCC.csr().read();
318 if !csr.lsion() {
319 RCC.csr().modify(|w| w.set_lsion(true));
320 while !RCC.csr().read().lsirdy() {}
321 }
322 }
323
322 set_freqs(Clocks { 324 set_freqs(Clocks {
323 sys: Hertz(sys_clk), 325 sys: Hertz(sys_clk),
324 ahb1: Hertz(ahb_freq), 326 ahb1: Hertz(ahb_freq),
@@ -326,7 +328,7 @@ pub(crate) unsafe fn init(config: Config) {
326 ahb3: Hertz(shd_ahb_freq), 328 ahb3: Hertz(shd_ahb_freq),
327 apb1: Hertz(apb1_freq), 329 apb1: Hertz(apb1_freq),
328 apb2: Hertz(apb2_freq), 330 apb2: Hertz(apb2_freq),
329 apb3: Hertz(apb3_freq), 331 apb3: Hertz(shd_ahb_freq),
330 apb1_tim: Hertz(apb1_tim_freq), 332 apb1_tim: Hertz(apb1_tim_freq),
331 apb2_tim: Hertz(apb2_tim_freq), 333 apb2_tim: Hertz(apb2_tim_freq),
332 }); 334 });