1use core::cmp;
4
5use cast::u32;
6use crate::stm32::{rcc, RCC};
7
8use crate::flash::ACR;
9use crate::time::Hertz;
10
11pub trait RccExt {
13 fn constrain(self) -> Rcc;
15}
16
17impl RccExt for RCC {
18 fn constrain(self) -> Rcc {
19 Rcc {
20 ahb1: AHB1 { _0: () },
21 ahb2: AHB2 { _0: () },
22 ahb3: AHB3 { _0: () },
23 apb1r1: APB1R1 { _0: () },
24 apb1r2: APB1R2 { _0: () },
25 apb2: APB2 { _0: () },
26 bdcr: BDCR { _0: () },
27 csr: CSR { _0: () },
28 cfgr: CFGR {
29 hclk: None,
30 pclk1: None,
31 pclk2: None,
32 sysclk: None,
33 pllcfg: None,
34 },
35 }
36 }
37}
38
39pub struct Rcc {
41 pub ahb1: AHB1,
43 pub ahb2: AHB2,
45 pub ahb3: AHB3,
47 pub apb1r1: APB1R1,
49 pub apb1r2: APB1R2,
51 pub apb2: APB2,
53 pub cfgr: CFGR,
55 pub bdcr: BDCR,
57 pub csr: CSR,
59}
60
61pub struct CSR {
63 _0: (),
64}
65
66impl CSR {
67 #[allow(dead_code)]
69 pub(crate) fn csr(&mut self) -> &rcc::CSR {
70 unsafe { &(*RCC::ptr()).csr }
72 }
73}
74
75pub struct BDCR {
77 _0: (),
78}
79
80impl BDCR {
81 #[allow(dead_code)]
83 pub(crate) fn enr(&mut self) -> &rcc::BDCR {
84 unsafe { &(*RCC::ptr()).bdcr }
86 }
87}
88
89pub struct AHB1 {
91 _0: (),
92}
93
94impl AHB1 {
95 #[allow(dead_code)]
97 pub(crate) fn enr(&mut self) -> &rcc::AHB1ENR {
98 unsafe { &(*RCC::ptr()).ahb1enr }
100 }
101 #[allow(dead_code)]
103 pub(crate) fn rstr(&mut self) -> &rcc::AHB1RSTR {
104 unsafe { &(*RCC::ptr()).ahb1rstr }
106 }
107}
108
109pub struct AHB2 {
111 _0: (),
112}
113
114impl AHB2 {
115 pub(crate) fn enr(&mut self) -> &rcc::AHB2ENR {
116 unsafe { &(*RCC::ptr()).ahb2enr }
118 }
119
120 pub(crate) fn rstr(&mut self) -> &rcc::AHB2RSTR {
121 unsafe { &(*RCC::ptr()).ahb2rstr }
123 }
124}
125
126pub struct AHB3 {
128 _0: (),
129}
130
131impl AHB3 {
132 #[allow(dead_code)]
134 pub(crate) fn enr(&mut self) -> &rcc::AHB3ENR {
135 unsafe { &(*RCC::ptr()).ahb3enr }
137 }
138 #[allow(dead_code)]
140 pub(crate) fn rstr(&mut self) -> &rcc::AHB3RSTR {
141 unsafe { &(*RCC::ptr()).ahb3rstr }
143 }
144}
145
146pub struct APB1R1 {
148 _0: (),
149}
150
151impl APB1R1 {
152 pub(crate) fn enr(&mut self) -> &rcc::APB1ENR1 {
153 unsafe { &(*RCC::ptr()).apb1enr1 }
155 }
156
157 pub(crate) fn rstr(&mut self) -> &rcc::APB1RSTR1 {
158 unsafe { &(*RCC::ptr()).apb1rstr1 }
160 }
161}
162
163pub struct APB1R2 {
165 _0: (),
166}
167
168impl APB1R2 {
169 #[allow(dead_code)]
171 pub(crate) fn enr(&mut self) -> &rcc::APB1ENR2 {
172 unsafe { &(*RCC::ptr()).apb1enr2 }
174 }
175 #[allow(dead_code)]
177 pub(crate) fn rstr(&mut self) -> &rcc::APB1RSTR2 {
178 unsafe { &(*RCC::ptr()).apb1rstr2 }
180 }
181}
182
183pub struct APB2 {
185 _0: (),
186}
187
188impl APB2 {
189 pub(crate) fn enr(&mut self) -> &rcc::APB2ENR {
190 unsafe { &(*RCC::ptr()).apb2enr }
192 }
193
194 pub(crate) fn rstr(&mut self) -> &rcc::APB2RSTR {
195 unsafe { &(*RCC::ptr()).apb2rstr }
197 }
198}
199
200const HSI: u32 = 16_000_000; pub struct CFGR {
204 hclk: Option<u32>,
205 pclk1: Option<u32>,
206 pclk2: Option<u32>,
207 sysclk: Option<u32>,
208 pllcfg: Option<PllConfig>
209}
210
211impl CFGR {
212 pub fn hclk<F>(mut self, freq: F) -> Self
214 where
215 F: Into<Hertz>,
216 {
217 self.hclk = Some(freq.into().0);
218 self
219 }
220
221 pub fn pclk1<F>(mut self, freq: F) -> Self
223 where
224 F: Into<Hertz>,
225 {
226 self.pclk1 = Some(freq.into().0);
227 self
228 }
229
230 pub fn pclk2<F>(mut self, freq: F) -> Self
232 where
233 F: Into<Hertz>,
234 {
235 self.pclk2 = Some(freq.into().0);
236 self
237 }
238
239 pub fn sysclk<F>(mut self, freq: F) -> Self
241 where
242 F: Into<Hertz>,
243 {
244 self.sysclk = Some(freq.into().0);
245 self
246 }
247
248 pub fn sysclk_with_pll<F>(mut self, freq: F, cfg: PllConfig) -> Self
250 where
251 F: Into<Hertz>,
252 {
253 self.pllcfg = Some(cfg);
254 self.sysclk = Some(freq.into().0);
255 self
256 }
257
258 pub fn freeze(self, acr: &mut ACR) -> Clocks {
260
261 let pllconf = if self.pllcfg.is_none() {
262 let plln = (2 * self.sysclk.unwrap_or(HSI)) / HSI;
263 let plln = cmp::min(cmp::max(plln, 2), 16);
264 if plln == 2 {
265 None
266 } else {
267 let conf = PllConfig {
270 m: 0b0,
271 r: 0b0,
272 n: plln as u8
273 };
274 Some(conf)
275 }
276
277 } else {
278 let conf = self.pllcfg.unwrap();
279 Some(conf)
280 };
281
282 let sysclk = self.sysclk.unwrap_or(HSI);
283
284 assert!(sysclk <= 80_000_000);
285
286 let hpre_bits = self.hclk
287 .map(|hclk| match sysclk / hclk {
288 0 => unreachable!(),
289 1 => 0b0000,
290 2 => 0b1000,
291 3...5 => 0b1001,
292 6...11 => 0b1010,
293 12...39 => 0b1011,
294 40...95 => 0b1100,
295 96...191 => 0b1101,
296 192...383 => 0b1110,
297 _ => 0b1111,
298 })
299 .unwrap_or(0b0000);
300
301 let hclk = sysclk / (1 << (hpre_bits));
302
303 assert!(hclk <= sysclk);
304
305 let ppre1_bits = self.pclk1
306 .map(|pclk1| match hclk / pclk1 {
307 0 => unreachable!(),
308 1 => 0b000,
309 2 => 0b100,
310 3...5 => 0b101,
311 6...11 => 0b110,
312 _ => 0b111,
313 })
314 .unwrap_or(0b000);
315
316 let ppre1 = 1 << (ppre1_bits);
317 let pclk1 = hclk / u32(ppre1);
318
319 assert!(pclk1 <= sysclk);
320
321 let ppre2_bits = self.pclk2
322 .map(|pclk2| match hclk / pclk2 {
323 0 => unreachable!(),
324 1 => 0b000,
325 2 => 0b100,
326 3...5 => 0b101,
327 6...11 => 0b110,
328 _ => 0b111,
329 })
330 .unwrap_or(0b000);
331
332 let ppre2 = 1 << (ppre2_bits);
333 let pclk2 = hclk / u32(ppre2);
334
335 assert!(pclk2 <= sysclk);
336
337 unsafe {
339 acr.acr().write(|w| {
340 w.latency().bits(if sysclk <= 24_000_000 {
341 0b000
342 } else if sysclk <= 48_000_000 {
343 0b001
344 } else {
345 0b010
346 })
347 })
348 }
349
350 let rcc = unsafe { &*RCC::ptr() };
351 let sysclk_src_bits;
352 if let Some(pllconf) = pllconf {
353 sysclk_src_bits = 0b11;
355 rcc.cr.modify(|_, w| w.pllon().clear_bit());
356 while rcc.cr.read().pllrdy().bit_is_set() {}
357
358 let pllsrc_bits = 0b10; rcc.cr.write(|w| w.hsion().set_bit());
360 while rcc.cr.read().hsirdy().bit_is_clear() {}
361
362 rcc.pllcfgr
363 .modify(|_, w| unsafe {
364 w.pllsrc()
365 .bits(pllsrc_bits)
366 .pllm().bits(pllconf.m)
367 .pllr().bits(pllconf.r)
368 .plln().bits(pllconf.n)
369 });
370
371 rcc.cr.modify(|_, w| w.pllon().set_bit());
372
373 while rcc.cr.read().pllrdy().bit_is_clear() {}
374
375 rcc.pllcfgr.modify(|_, w| w.pllren().set_bit());
376
377 rcc.cfgr.modify(|_, w| unsafe {
379 w.ppre2()
380 .bits(ppre2_bits)
381 .ppre1()
382 .bits(ppre1_bits)
383 .hpre()
384 .bits(hpre_bits)
385 .sw()
386 .bits(sysclk_src_bits)
387 });
388 } else {
389 sysclk_src_bits = 0b01;
391
392 rcc.cr.write(|w| w.hsion().set_bit());
393 while rcc.cr.read().hsirdy().bit_is_clear() {}
394
395 rcc.cfgr.write(|w| unsafe {
397 w.ppre2()
398 .bits(ppre2_bits)
399 .ppre1()
400 .bits(ppre1_bits)
401 .hpre()
402 .bits(hpre_bits)
403 .sw()
404 .bits(sysclk_src_bits)
405 });
406 }
407
408 while rcc.cfgr.read().sws().bits() != sysclk_src_bits {}
409
410 rcc.csr.modify(|_, w| {
412 w.lsion().set_bit()
413 });
414 while rcc.csr.read().lsirdy().bit_is_clear() {}
416
417
418 Clocks {
419 hclk: Hertz(hclk),
420 pclk1: Hertz(pclk1),
421 pclk2: Hertz(pclk2),
422 ppre1,
423 ppre2,
424 sysclk: Hertz(sysclk),
425 }
426 }
427}
428
429#[derive(Clone, Copy)]
430pub struct PllConfig {
432 pub m: u8,
434 pub n: u8,
436 pub r: u8,
438}
439
440#[derive(Clone, Copy)]
444pub struct Clocks {
445 hclk: Hertz,
446 pclk1: Hertz,
447 pclk2: Hertz,
448 #[allow(dead_code)]
450 ppre1: u8,
451 ppre2: u8,
452 sysclk: Hertz,
453}
454
455impl Clocks {
456 pub fn hclk(&self) -> Hertz {
458 self.hclk
459 }
460
461 pub fn pclk1(&self) -> Hertz {
463 self.pclk1
464 }
465
466 pub fn pclk2(&self) -> Hertz {
468 self.pclk2
469 }
470
471 #[allow(dead_code)]
473 pub(crate) fn ppre1(&self) -> u8 {
474 self.ppre1
475 }
476 #[allow(dead_code)]
478 pub(crate) fn ppre2(&self) -> u8 {
479 self.ppre2
480 }
481
482 pub fn sysclk(&self) -> Hertz {
484 self.sysclk
485 }
486}