1use crate::clocks::Stm32f4Clocks;
6use crate::rcc::{APBPrescaler, Rcc, RtcClockSource};
7use kernel::platform::chip::ClockInterface;
8
9pub struct PeripheralClock<'a> {
10 pub clock: PeripheralClockType,
11 clocks: &'a dyn Stm32f4Clocks,
12}
13
14pub enum PeripheralClockType {
16 AHB1(HCLK1),
17 AHB2(HCLK2),
18 AHB3(HCLK3),
19 APB1(PCLK1),
20 APB2(PCLK2),
21 RTC,
22 PWR,
23}
24
25pub enum HCLK1 {
27 DMA1,
28 DMA2,
29 GPIOH,
30 GPIOG,
31 GPIOF,
32 GPIOE,
33 GPIOD,
34 GPIOC,
35 GPIOB,
36 GPIOA,
37}
38
39pub enum HCLK3 {
41 FMC,
42}
43
44pub enum HCLK2 {
46 RNG,
47 OTGFS,
48}
49
50pub enum PCLK1 {
52 TIM2,
53 USART2,
54 USART3,
55 SPI3,
56 I2C1,
57 CAN1,
58 DAC,
59}
60
61pub enum PCLK2 {
63 USART1,
64 ADC1,
65 SYSCFG,
66}
67
68impl<'a> PeripheralClock<'a> {
69 pub const fn new(clock: PeripheralClockType, clocks: &'a dyn Stm32f4Clocks) -> Self {
70 Self { clock, clocks }
71 }
72
73 pub fn configure_rng_clock(&self) {
74 self.clocks.get_rcc().configure_rng_clock();
75 }
76
77 pub fn get_frequency(&self) -> u32 {
78 #[inline(always)]
79 fn tim_freq(rcc: &Rcc, hclk_freq: usize, prescaler: APBPrescaler) -> usize {
80 if !rcc.is_enabled_tim_pre() {
86 match prescaler {
87 APBPrescaler::DivideBy1 | APBPrescaler::DivideBy2 => hclk_freq,
88 _ => hclk_freq / usize::from(prescaler) * 2,
89 }
90 } else {
91 match prescaler {
92 APBPrescaler::DivideBy1 | APBPrescaler::DivideBy2 | APBPrescaler::DivideBy4 => {
93 hclk_freq
94 }
95 _ => hclk_freq / usize::from(prescaler) * 4,
96 }
97 }
98 }
99 let rcc = self.clocks.get_rcc();
100 let hclk_freq = self.clocks.get_ahb_frequency();
101 match self.clock {
102 PeripheralClockType::AHB1(_)
103 | PeripheralClockType::AHB2(_)
104 | PeripheralClockType::AHB3(_) => hclk_freq as u32,
105 PeripheralClockType::APB1(ref v) => {
106 let prescaler = rcc.get_apb1_prescaler();
107 match v {
108 PCLK1::TIM2 => tim_freq(rcc, hclk_freq, prescaler) as u32,
109 _ => (hclk_freq / usize::from(prescaler)) as u32,
110 }
111 }
112 PeripheralClockType::APB2(_) => {
113 let prescaler = rcc.get_apb2_prescaler();
114 (hclk_freq / usize::from(prescaler)) as u32
115 }
116 PeripheralClockType::RTC => todo!(),
118 PeripheralClockType::PWR => todo!(),
119 }
120 }
121}
122
123impl ClockInterface for PeripheralClock<'_> {
124 fn is_enabled(&self) -> bool {
125 let rcc = self.clocks.get_rcc();
126 match self.clock {
127 PeripheralClockType::AHB1(ref v) => match v {
128 HCLK1::DMA1 => rcc.is_enabled_dma1_clock(),
129 HCLK1::DMA2 => rcc.is_enabled_dma2_clock(),
130 HCLK1::GPIOH => rcc.is_enabled_gpioh_clock(),
131 HCLK1::GPIOG => rcc.is_enabled_gpiog_clock(),
132 HCLK1::GPIOF => rcc.is_enabled_gpiof_clock(),
133 HCLK1::GPIOE => rcc.is_enabled_gpioe_clock(),
134 HCLK1::GPIOD => rcc.is_enabled_gpiod_clock(),
135 HCLK1::GPIOC => rcc.is_enabled_gpioc_clock(),
136 HCLK1::GPIOB => rcc.is_enabled_gpiob_clock(),
137 HCLK1::GPIOA => rcc.is_enabled_gpioa_clock(),
138 },
139 PeripheralClockType::AHB2(ref v) => match v {
140 HCLK2::RNG => rcc.is_enabled_rng_clock(),
141 HCLK2::OTGFS => rcc.is_enabled_otgfs_clock(),
142 },
143 PeripheralClockType::AHB3(ref v) => match v {
144 HCLK3::FMC => rcc.is_enabled_fmc_clock(),
145 },
146 PeripheralClockType::APB1(ref v) => match v {
147 PCLK1::TIM2 => rcc.is_enabled_tim2_clock(),
148 PCLK1::USART2 => rcc.is_enabled_usart2_clock(),
149 PCLK1::USART3 => rcc.is_enabled_usart3_clock(),
150 PCLK1::I2C1 => rcc.is_enabled_i2c1_clock(),
151 PCLK1::SPI3 => rcc.is_enabled_spi3_clock(),
152 PCLK1::CAN1 => rcc.is_enabled_can1_clock(),
153 PCLK1::DAC => rcc.is_enabled_dac_clock(),
154 },
155 PeripheralClockType::APB2(ref v) => match v {
156 PCLK2::USART1 => rcc.is_enabled_usart1_clock(),
157 PCLK2::ADC1 => rcc.is_enabled_adc1_clock(),
158 PCLK2::SYSCFG => rcc.is_enabled_syscfg_clock(),
159 },
160 PeripheralClockType::RTC => rcc.is_enabled_rtc_clock(),
161 PeripheralClockType::PWR => rcc.is_enabled_pwr_clock(),
162 }
163 }
164
165 fn enable(&self) {
166 let rcc = self.clocks.get_rcc();
167 match self.clock {
168 PeripheralClockType::AHB1(ref v) => match v {
169 HCLK1::DMA1 => {
170 rcc.enable_dma1_clock();
171 }
172 HCLK1::DMA2 => {
173 rcc.enable_dma2_clock();
174 }
175 HCLK1::GPIOH => {
176 rcc.enable_gpioh_clock();
177 }
178 HCLK1::GPIOG => {
179 rcc.enable_gpiog_clock();
180 }
181 HCLK1::GPIOF => {
182 rcc.enable_gpiof_clock();
183 }
184 HCLK1::GPIOE => {
185 rcc.enable_gpioe_clock();
186 }
187 HCLK1::GPIOD => {
188 rcc.enable_gpiod_clock();
189 }
190 HCLK1::GPIOC => {
191 rcc.enable_gpioc_clock();
192 }
193 HCLK1::GPIOB => {
194 rcc.enable_gpiob_clock();
195 }
196 HCLK1::GPIOA => {
197 rcc.enable_gpioa_clock();
198 }
199 },
200 PeripheralClockType::AHB2(ref v) => match v {
201 HCLK2::RNG => {
202 rcc.enable_rng_clock();
203 }
204 HCLK2::OTGFS => {
205 rcc.enable_otgfs_clock();
206 }
207 },
208 PeripheralClockType::AHB3(ref v) => match v {
209 HCLK3::FMC => rcc.enable_fmc_clock(),
210 },
211 PeripheralClockType::APB1(ref v) => match v {
212 PCLK1::TIM2 => {
213 rcc.enable_tim2_clock();
214 }
215 PCLK1::USART2 => {
216 rcc.enable_usart2_clock();
217 }
218 PCLK1::USART3 => {
219 rcc.enable_usart3_clock();
220 }
221 PCLK1::I2C1 => {
222 rcc.enable_i2c1_clock();
223 }
224 PCLK1::SPI3 => {
225 rcc.enable_spi3_clock();
226 }
227 PCLK1::CAN1 => {
228 rcc.enable_can1_clock();
229 }
230 PCLK1::DAC => {
231 rcc.enable_dac_clock();
232 }
233 },
234 PeripheralClockType::APB2(ref v) => match v {
235 PCLK2::USART1 => {
236 rcc.enable_usart1_clock();
237 }
238 PCLK2::ADC1 => {
239 rcc.enable_adc1_clock();
240 }
241 PCLK2::SYSCFG => {
242 rcc.enable_syscfg_clock();
243 }
244 },
245 PeripheralClockType::RTC => rcc.enable_rtc_clock(RtcClockSource::LSI),
246 PeripheralClockType::PWR => rcc.enable_pwr_clock(),
247 }
248 }
249
250 fn disable(&self) {
251 let rcc = self.clocks.get_rcc();
252 match self.clock {
253 PeripheralClockType::AHB1(ref v) => match v {
254 HCLK1::DMA1 => {
255 rcc.disable_dma1_clock();
256 }
257 HCLK1::DMA2 => {
258 rcc.disable_dma2_clock();
259 }
260 HCLK1::GPIOH => {
261 rcc.disable_gpioh_clock();
262 }
263 HCLK1::GPIOG => {
264 rcc.disable_gpiog_clock();
265 }
266 HCLK1::GPIOF => {
267 rcc.disable_gpiof_clock();
268 }
269 HCLK1::GPIOE => {
270 rcc.disable_gpioe_clock();
271 }
272 HCLK1::GPIOD => {
273 rcc.disable_gpiod_clock();
274 }
275 HCLK1::GPIOC => {
276 rcc.disable_gpioc_clock();
277 }
278 HCLK1::GPIOB => {
279 rcc.disable_gpiob_clock();
280 }
281 HCLK1::GPIOA => {
282 rcc.disable_gpioa_clock();
283 }
284 },
285 PeripheralClockType::AHB2(ref v) => match v {
286 HCLK2::RNG => {
287 rcc.disable_rng_clock();
288 }
289 HCLK2::OTGFS => {
290 rcc.disable_otgfs_clock();
291 }
292 },
293 PeripheralClockType::AHB3(ref v) => match v {
294 HCLK3::FMC => rcc.disable_fmc_clock(),
295 },
296 PeripheralClockType::APB1(ref v) => match v {
297 PCLK1::TIM2 => {
298 rcc.disable_tim2_clock();
299 }
300 PCLK1::USART2 => {
301 rcc.disable_usart2_clock();
302 }
303 PCLK1::USART3 => {
304 rcc.disable_usart3_clock();
305 }
306 PCLK1::I2C1 => {
307 rcc.disable_i2c1_clock();
308 }
309 PCLK1::SPI3 => {
310 rcc.disable_spi3_clock();
311 }
312 PCLK1::CAN1 => {
313 rcc.disable_can1_clock();
314 }
315 PCLK1::DAC => {
316 rcc.disable_dac_clock();
317 }
318 },
319 PeripheralClockType::APB2(ref v) => match v {
320 PCLK2::USART1 => {
321 rcc.disable_usart1_clock();
322 }
323 PCLK2::ADC1 => {
324 rcc.disable_adc1_clock();
325 }
326 PCLK2::SYSCFG => {
327 rcc.disable_syscfg_clock();
328 }
329 },
330 PeripheralClockType::RTC => rcc.disable_rtc_clock(),
331 PeripheralClockType::PWR => rcc.disable_pwr_clock(),
332 }
333 }
334}