1use core::cmp;
4
5use cast::u32;
6use stm32f30x::{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 ahb: AHB { _0: () },
21 apb1: APB1 { _0: () },
22 apb2: APB2 { _0: () },
23 cfgr: CFGR {
24 hclk: None,
25 pclk1: None,
26 pclk2: None,
27 sysclk: None,
28 },
29 }
30 }
31}
32
33pub struct Rcc {
35 pub ahb: AHB,
37 pub apb1: APB1,
39 pub apb2: APB2,
41 pub cfgr: CFGR,
43}
44
45pub struct AHB {
47 _0: (),
48}
49
50impl AHB {
51 pub(crate) fn enr(&mut self) -> &rcc::AHBENR {
52 unsafe { &(*RCC::ptr()).ahbenr }
54 }
55
56 pub(crate) fn rstr(&mut self) -> &rcc::AHBRSTR {
57 unsafe { &(*RCC::ptr()).ahbrstr }
59 }
60}
61
62pub struct APB1 {
64 _0: (),
65}
66
67impl APB1 {
68 pub(crate) fn enr(&mut self) -> &rcc::APB1ENR {
69 unsafe { &(*RCC::ptr()).apb1enr }
71 }
72
73 pub(crate) fn rstr(&mut self) -> &rcc::APB1RSTR {
74 unsafe { &(*RCC::ptr()).apb1rstr }
76 }
77}
78
79pub struct APB2 {
81 _0: (),
82}
83
84impl APB2 {
85 pub(crate) fn enr(&mut self) -> &rcc::APB2ENR {
86 unsafe { &(*RCC::ptr()).apb2enr }
88 }
89
90 pub(crate) fn rstr(&mut self) -> &rcc::APB2RSTR {
91 unsafe { &(*RCC::ptr()).apb2rstr }
93 }
94}
95
96const HSI: u32 = 8_000_000; pub struct CFGR {
100 hclk: Option<u32>,
101 pclk1: Option<u32>,
102 pclk2: Option<u32>,
103 sysclk: Option<u32>,
104}
105
106impl CFGR {
107 pub fn hclk<F>(mut self, freq: F) -> Self
109 where
110 F: Into<Hertz>,
111 {
112 self.hclk = Some(freq.into().0);
113 self
114 }
115
116 pub fn pclk1<F>(mut self, freq: F) -> Self
118 where
119 F: Into<Hertz>,
120 {
121 self.pclk1 = Some(freq.into().0);
122 self
123 }
124
125 pub fn pclk2<F>(mut self, freq: F) -> Self
127 where
128 F: Into<Hertz>,
129 {
130 self.pclk2 = Some(freq.into().0);
131 self
132 }
133
134 pub fn sysclk<F>(mut self, freq: F) -> Self
136 where
137 F: Into<Hertz>,
138 {
139 self.sysclk = Some(freq.into().0);
140 self
141 }
142
143 pub fn freeze(self, acr: &mut ACR) -> Clocks {
145 let pllmul = (2 * self.sysclk.unwrap_or(HSI)) / HSI;
146 let pllmul = cmp::min(cmp::max(pllmul, 2), 16);
147 let pllmul_bits = if pllmul == 2 {
148 None
149 } else {
150 Some(pllmul as u8 - 2)
151 };
152
153 let sysclk = pllmul * HSI / 2;
154
155 assert!(sysclk <= 72_000_000);
156
157 let hpre_bits = self.hclk
158 .map(|hclk| match sysclk / hclk {
159 0 => unreachable!(),
160 1 => 0b0111,
161 2 => 0b1000,
162 3...5 => 0b1001,
163 6...11 => 0b1010,
164 12...39 => 0b1011,
165 40...95 => 0b1100,
166 96...191 => 0b1101,
167 192...383 => 0b1110,
168 _ => 0b1111,
169 })
170 .unwrap_or(0b0111);
171
172 let hclk = sysclk / (1 << (hpre_bits - 0b0111));
173
174 assert!(hclk <= 72_000_000);
175
176 let ppre1_bits = self.pclk1
177 .map(|pclk1| match hclk / pclk1 {
178 0 => unreachable!(),
179 1 => 0b011,
180 2 => 0b100,
181 3...5 => 0b101,
182 6...11 => 0b110,
183 _ => 0b111,
184 })
185 .unwrap_or(0b011);
186
187 let ppre1 = 1 << (ppre1_bits - 0b011);
188 let pclk1 = hclk / u32(ppre1);
189
190 assert!(pclk1 <= 36_000_000);
191
192 let ppre2_bits = self.pclk2
193 .map(|pclk2| match hclk / pclk2 {
194 0 => unreachable!(),
195 1 => 0b011,
196 2 => 0b100,
197 3...5 => 0b101,
198 6...11 => 0b110,
199 _ => 0b111,
200 })
201 .unwrap_or(0b011);
202
203 let ppre2 = 1 << (ppre2_bits - 0b011);
204 let pclk2 = hclk / u32(ppre2);
205
206 assert!(pclk2 <= 72_000_000);
207
208 unsafe {
210 acr.acr().write(|w| {
211 w.latency().bits(if sysclk <= 24_000_000 {
212 0b000
213 } else if sysclk <= 48_000_000 {
214 0b001
215 } else {
216 0b010
217 })
218 })
219 }
220
221 let rcc = unsafe { &*RCC::ptr() };
222 if let Some(pllmul_bits) = pllmul_bits {
223 rcc.cfgr.write(|w| unsafe { w.pllmul().bits(pllmul_bits) });
226
227 rcc.cr.write(|w| w.pllon().set_bit());
228
229 while rcc.cr.read().pllrdy().bit_is_clear() {}
230
231 rcc.cfgr.modify(|_, w| unsafe {
233 w.ppre2()
234 .bits(ppre2_bits)
235 .ppre1()
236 .bits(ppre1_bits)
237 .hpre()
238 .bits(hpre_bits)
239 .sw()
240 .bits(0b10)
241 });
242 } else {
243 rcc.cfgr.write(|w| unsafe {
247 w.ppre2()
248 .bits(ppre2_bits)
249 .ppre1()
250 .bits(ppre1_bits)
251 .hpre()
252 .bits(hpre_bits)
253 .sw()
254 .bits(0b00)
255 });
256 }
257
258 Clocks {
259 hclk: Hertz(hclk),
260 pclk1: Hertz(pclk1),
261 pclk2: Hertz(pclk2),
262 ppre1,
263 ppre2,
264 sysclk: Hertz(sysclk),
265 }
266 }
267}
268
269#[derive(Clone, Copy)]
273pub struct Clocks {
274 hclk: Hertz,
275 pclk1: Hertz,
276 pclk2: Hertz,
277 ppre1: u8,
278 #[allow(dead_code)]
280 ppre2: u8,
281 sysclk: Hertz,
282}
283
284impl Clocks {
285 pub fn hclk(&self) -> Hertz {
287 self.hclk
288 }
289
290 pub fn pclk1(&self) -> Hertz {
292 self.pclk1
293 }
294
295 pub fn pclk2(&self) -> Hertz {
297 self.pclk2
298 }
299
300 pub(crate) fn ppre1(&self) -> u8 {
301 self.ppre1
302 }
303
304 #[allow(dead_code)]
306 pub(crate) fn ppre2(&self) -> u8 {
307 self.ppre2
308 }
309
310 pub fn sysclk(&self) -> Hertz {
312 self.sysclk
313 }
314}