1use core::cmp;
4
5use cast::u32;
6use stm32f429::{rcc, RCC};
7
8use flash::ACR;
9use 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 apb1: APB1 { _0: () },
24 apb2: APB2 { _0: () },
25 cfgr: CFGR {
26 hclk: None,
27 pclk1: None,
28 pclk2: None,
29 sysclk: None,
30 },
31 }
32 }
33}
34
35pub struct Rcc {
37 pub ahb1: AHB1,
39 pub ahb2: AHB2,
41 pub ahb3: AHB3,
43 pub apb1: APB1,
45 pub apb2: APB2,
47 pub cfgr: CFGR,
49}
50
51pub struct AHB1 {
53 _0: (),
54}
55
56#[allow(unused)]
57impl AHB1 {
58 pub(crate) fn enr(&mut self) -> &rcc::AHB1ENR {
59 unsafe { &(*RCC::ptr()).ahb1enr }
61 }
62
63 pub(crate) fn rstr(&mut self) -> &rcc::AHB1RSTR {
64 unsafe { &(*RCC::ptr()).ahb1rstr }
66 }
67}
68
69pub struct AHB2 {
71 _0: (),
72}
73
74#[allow(unused)]
75impl AHB2 {
76 pub(crate) fn enr(&mut self) -> &rcc::AHB2ENR {
77 unsafe { &(*RCC::ptr()).ahb2enr }
79 }
80
81 pub(crate) fn rstr(&mut self) -> &rcc::AHB2RSTR {
82 unsafe { &(*RCC::ptr()).ahb2rstr }
84 }
85}
86
87pub struct AHB3 {
89 _0: (),
90}
91
92#[allow(unused)]
93impl AHB3 {
94 pub(crate) fn enr(&mut self) -> &rcc::AHB3ENR {
95 unsafe { &(*RCC::ptr()).ahb3enr }
97 }
98
99 pub(crate) fn rstr(&mut self) -> &rcc::AHB3RSTR {
100 unsafe { &(*RCC::ptr()).ahb3rstr }
102 }
103}
104
105pub struct APB1 {
107 _0: (),
108}
109
110impl APB1 {
111 pub(crate) fn enr(&mut self) -> &rcc::APB1ENR {
112 unsafe { &(*RCC::ptr()).apb1enr }
114 }
115
116 pub(crate) fn rstr(&mut self) -> &rcc::APB1RSTR {
117 unsafe { &(*RCC::ptr()).apb1rstr }
119 }
120}
121
122pub struct APB2 {
124 _0: (),
125}
126
127#[allow(unused)]
128impl APB2 {
129 pub(crate) fn enr(&mut self) -> &rcc::APB2ENR {
130 unsafe { &(*RCC::ptr()).apb2enr }
132 }
133
134 pub(crate) fn rstr(&mut self) -> &rcc::APB2RSTR {
135 unsafe { &(*RCC::ptr()).apb2rstr }
137 }
138}
139
140const HSI: u32 = 16_000_000; #[derive(Debug)]
144pub struct CFGR {
145 hclk: Option<u32>,
146 pclk1: Option<u32>,
147 pclk2: Option<u32>,
148 sysclk: Option<u32>,
149}
150
151impl CFGR {
152 pub fn hclk<F>(mut self, freq: F) -> Self
154 where
155 F: Into<Hertz>,
156 {
157 self.hclk = Some(freq.into().0);
158 self
159 }
160
161 pub fn pclk1<F>(mut self, freq: F) -> Self
163 where
164 F: Into<Hertz>,
165 {
166 self.pclk1 = Some(freq.into().0);
167 self
168 }
169
170 pub fn pclk2<F>(mut self, freq: F) -> Self
172 where
173 F: Into<Hertz>,
174 {
175 self.pclk2 = Some(freq.into().0);
176 self
177 }
178
179 pub fn sysclk<F>(mut self, freq: F) -> Self
181 where
182 F: Into<Hertz>,
183 {
184 self.sysclk = Some(freq.into().0);
185 self
186 }
187
188 pub fn freeze(self, acr: &mut ACR) -> Clocks {
190 let pllmul = (2 * self.sysclk.unwrap_or(HSI)) / HSI;
191 let pllmul = cmp::min(cmp::max(pllmul, 2), 16);
192 let pllmul_bits = if pllmul == 2 {
193 None
194 } else {
195 Some(pllmul as u8 - 2)
196 };
197
198 let sysclk = pllmul * HSI / 2;
199
200 assert!(sysclk <= 72_000_000);
201
202 let hpre_bits = self.hclk
204 .map(|hclk| match sysclk / hclk {
205 0 => unreachable!(),
206 1 => 0b0111, 2 => 0b1000,
208 3...5 => 0b1001,
209 6...11 => 0b1010,
210 12...39 => 0b1011,
211 40...95 => 0b1100,
212 96...191 => 0b1101,
213 192...383 => 0b1110,
214 _ => 0b1111,
215 })
216 .unwrap_or(0b0111); let hclk = sysclk / (1 << (hpre_bits - 0b0111));
219
220 assert!(hclk <= 72_000_000);
221
222 let ppre1_bits = self.pclk1
223 .map(|pclk1| match hclk / pclk1 {
224 0 => unreachable!(),
225 1 => 0b011,
226 2 => 0b100,
227 3...5 => 0b101,
228 6...11 => 0b110,
229 _ => 0b111,
230 })
231 .unwrap_or(0b011);
232
233 let ppre1 = 1 << (ppre1_bits - 0b011);
234 let pclk1 = hclk / u32(ppre1);
235
236 assert!(pclk1 <= 45_000_000);
238
239 let ppre2_bits = self.pclk2
240 .map(|pclk2| match hclk / pclk2 {
241 0 => unreachable!(),
242 1 => 0b011,
243 2 => 0b100,
244 3...5 => 0b101,
245 6...11 => 0b110,
246 _ => 0b111,
247 })
248 .unwrap_or(0b011);
249
250 let ppre2 = 1 << (ppre2_bits - 0b011);
251 let pclk2 = hclk / u32(ppre2);
252
253 assert!(pclk2 <= 90_000_000);
255
256 acr.acr().write(|w| {
258 w.latency().bits(if sysclk <= 24_000_000 {
259 0b000
260 } else if sysclk <= 48_000_000 {
261 0b001
262 } else {
263 0b010
264 })
265 });
266
267 let rcc = unsafe { &*RCC::ptr() };
268 if let Some(pllmul_bits) = pllmul_bits {
269 rcc.cfgr.modify(|_, w| w.hpre().bits(pllmul_bits));
271
272 rcc.cr.write(|w| w.pllon().set_bit());
274 while rcc.cr.read().pllrdy().bit_is_clear() {}
276
277 rcc.cfgr.modify(|_, w| unsafe {
279 w
280 .ppre2()
282 .bits(ppre2_bits)
283 .ppre1()
285 .bits(ppre1_bits)
286 .hpre()
288 .bits(hpre_bits)
289 .sw()
291 .bits(0b10)
293 });
294 } else {
295 rcc.cfgr.write(|w| unsafe {
299 w.ppre2()
300 .bits(ppre2_bits)
301 .ppre1()
302 .bits(ppre1_bits)
303 .hpre()
304 .bits(hpre_bits)
305 .sw()
306 .bits(0b00)
307 });
308 }
309
310 Clocks {
311 hclk: Hertz(hclk),
312 pclk1: Hertz(pclk1),
313 pclk2: Hertz(pclk2),
314 ppre1,
315 ppre2,
316 sysclk: Hertz(sysclk),
317 }
318 }
319}
320
321#[derive(Clone, Copy, Debug)]
325pub struct Clocks {
326 hclk: Hertz,
327 pclk1: Hertz,
328 pclk2: Hertz,
329 ppre1: u8,
330 #[allow(dead_code)] ppre2: u8,
332 sysclk: Hertz,
333}
334
335impl Clocks {
336 pub fn hclk(&self) -> Hertz {
338 self.hclk
339 }
340
341 pub fn pclk1(&self) -> Hertz {
343 self.pclk1
344 }
345
346 pub fn pclk2(&self) -> Hertz {
348 self.pclk2
349 }
350
351 pub(crate) fn ppre1(&self) -> u8 {
352 self.ppre1
353 }
354
355 #[allow(dead_code)]
357 pub(crate) fn ppre2(&self) -> u8 {
358 self.ppre2
359 }
360
361 pub fn sysclk(&self) -> Hertz {
363 self.sysclk
364 }
365}