stm32f303xc/
rcc.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use kernel::platform::chip::ClockInterface;
6use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
7use kernel::utilities::registers::{register_bitfields, ReadWrite};
8use kernel::utilities::StaticRef;
9
10/// Reset and clock control
11#[repr(C)]
12struct RccRegisters {
13    /// clock control register
14    cr: ReadWrite<u32, CR::Register>,
15    /// clock configuration register
16    cfgr: ReadWrite<u32, CFGR::Register>,
17    /// clock interrupt register
18    cir: ReadWrite<u32, CIR::Register>,
19    /// APB2 peripheral reset register
20    apb2rstr: ReadWrite<u32, APB2RSTR::Register>,
21    /// APB1 peripheral reset register
22    apb1rstr: ReadWrite<u32, APB1RSTR::Register>,
23    /// AHB peripheral clock register
24    ahbenr: ReadWrite<u32, AHBENR::Register>,
25    /// APB2 peripheral clock enable register
26    apb2enr: ReadWrite<u32, APB2ENR::Register>,
27    /// APB1 peripheral clock enable register
28    apb1enr: ReadWrite<u32, APB1ENR::Register>,
29    /// Backup domain control register
30    bdcr: ReadWrite<u32, BDCR::Register>,
31    /// clock control & status register
32    csr: ReadWrite<u32, CSR::Register>,
33    /// AHB peripheral reset register
34    ahbrstr: ReadWrite<u32, AHBRSTR::Register>,
35    /// clocks configuration register 2
36    cfgr2: ReadWrite<u32, CFGR2::Register>,
37    /// clocks configuration register 3
38    cfgr3: ReadWrite<u32, CFGR3::Register>,
39}
40
41register_bitfields![u32,
42    CR [
43        /// Main PLL (PLL) clock ready flag
44        PLLRDY OFFSET(25) NUMBITS(1) [],
45        /// Main PLL (PLL) enable
46        PLLON OFFSET(24) NUMBITS(1) [],
47        /// Clock security system enable
48        CSSON OFFSET(19) NUMBITS(1) [],
49        /// HSE clock bypass
50        HSEBYP OFFSET(18) NUMBITS(1) [],
51        /// HSE clock ready flag
52        HSERDY OFFSET(17) NUMBITS(1) [],
53        /// HSE clock enable
54        HSEON OFFSET(16) NUMBITS(1) [],
55        /// Internal high-speed clock calibration
56        HSICAL OFFSET(8) NUMBITS(8) [],
57        /// Internal high-speed clock trimming
58        HSITRIM OFFSET(3) NUMBITS(5) [],
59        /// Internal high-speed clock ready flag
60        HSIRDY OFFSET(1) NUMBITS(1) [],
61        /// Internal high-speed clock enable
62        HSION OFFSET(0) NUMBITS(1) []
63    ],
64    CFGR [
65        /// Do not divide PLL to MCO
66        PLLNODIV OFFSET(31) NUMBITS(1) [],
67        /// MCO prescaler
68        MCOPRE OFFSET(28) NUMBITS(3) [],
69        /// Microcontorller clock output flag
70        MCOF OFFSET(28) NUMBITS(1) [],
71        /// Microcontroller clock output
72        MCO OFFSET(24) NUMBITS(3) [],
73        /// I2S clock selection
74        I2SSRC OFFSET(23) NUMBITS(1) [], //stm32f303vct6 specific
75        /// USB prescaler
76        USBPRE OFFSET(22) NUMBITS(1) [],
77        /// PLL multiplication factor
78        PLLMUL OFFSET(18) NUMBITS(4) [],
79        /// HSE divider for PLL input clock
80        PLLXTPRE OFFSET(17) NUMBITS(1) [],
81        /// PLL entry clock source
82        PLLSRC OFFSET(16) NUMBITS(1) [], //stm32f303vct6 specific
83        /// APB high-speed prescaler (APB2)
84        PPRE2 OFFSET(11) NUMBITS(3) [],
85        /// APB Low speed prescaler (APB1)
86        PPRE1 OFFSET(8) NUMBITS(3) [],
87        /// AHB prescaler
88        HPRE OFFSET(4) NUMBITS(4) [],
89        /// System clock switch status
90        SWS1 OFFSET(3) NUMBITS(1) [],
91        /// System clock switch status
92        SWS0 OFFSET(2) NUMBITS(1) [],
93        /// System clock switch
94        SW1 OFFSET(1) NUMBITS(1) [],
95        /// System clock switch
96        SW0 OFFSET(0) NUMBITS(1) []
97    ],
98    CIR [
99        /// Clock security system interrupt clear
100        CSSC OFFSET(23) NUMBITS(1) [],
101        /// Main PLL(PLL) ready interrupt clear
102        PLLRDYC OFFSET(20) NUMBITS(1) [],
103        /// HSE ready interrupt clear
104        HSERDYC OFFSET(19) NUMBITS(1) [],
105        /// HSI ready interrupt clear
106        HSIRDYC OFFSET(18) NUMBITS(1) [],
107        /// LSE ready interrupt clear
108        LSERDYC OFFSET(17) NUMBITS(1) [],
109        /// LSI ready interrupt clear
110        LSIRDYC OFFSET(16) NUMBITS(1) [],
111        /// Main PLL (PLL) ready interrupt enable
112        PLLRDYIE OFFSET(12) NUMBITS(1) [],
113        /// HSE ready interrupt enable
114        HSERDYIE OFFSET(11) NUMBITS(1) [],
115        /// HSI ready interrupt enable
116        HSIRDYIE OFFSET(10) NUMBITS(1) [],
117        /// LSE ready interrupt enable
118        LSERDYIE OFFSET(9) NUMBITS(1) [],
119        /// LSI ready interrupt enable
120        LSIRDYIE OFFSET(8) NUMBITS(1) [],
121        /// Clock security system interrupt flag
122        CSSF OFFSET(7) NUMBITS(1) [],
123        /// PLLSAI ready interrupt flag
124        PLLSAIRDYF OFFSET(6) NUMBITS(1) [],
125        /// PLLI2S ready interrupt flag
126        PLLI2SRDYF OFFSET(5) NUMBITS(1) [],
127        /// Main PLL (PLL) ready interrupt flag
128        PLLRDYF OFFSET(4) NUMBITS(1) [],
129        /// HSE ready interrupt flag
130        HSERDYF OFFSET(3) NUMBITS(1) [],
131        /// HSI ready interrupt flag
132        HSIRDYF OFFSET(2) NUMBITS(1) [],
133        /// LSE ready interrupt flag
134        LSERDYF OFFSET(1) NUMBITS(1) [],
135        /// LSI ready interrupt flag
136        LSIRDYF OFFSET(0) NUMBITS(1) []
137    ],
138    APB2RSTR [
139        /// TIM20 reset
140        TIM20RST OFFSET(20) NUMBITS(1) [],
141        /// TIM17 reset
142        TIM17RST OFFSET(18) NUMBITS(1) [],
143        /// TIM16 reset
144        TIM16RST OFFSET(17) NUMBITS(1) [],
145        /// TIM15 reset
146        TIM15RST OFFSET(16) NUMBITS(1) [],
147        /// SPI4 reset
148        SPI4RST OFFSET(15) NUMBITS(1) [],
149        /// USART1 reset
150        USART1RST OFFSET(14) NUMBITS(1) [],
151        /// TIM8 reset
152        TIM8RST OFFSET(13) NUMBITS(1) [],
153        /// SPI 1 reset
154        SPI1RST OFFSET(12) NUMBITS(1) [],
155        /// TIM1 reset
156        TIM1RST OFFSET(11) NUMBITS(1) [],
157        /// SYSCFG, Comparators and operational amplifiers reset
158        SYSCFGRST OFFSET(0) NUMBITS(1) []
159    ],
160    APB1RSTR [
161        /// TIM2 reset
162        TIM2RST OFFSET(0) NUMBITS(1) [],
163        /// TIM3 reset
164        TIM3RST OFFSET(1) NUMBITS(1) [],
165        /// TIM4 reset
166        TIM4RST OFFSET(2) NUMBITS(1) [],
167        /// TIM6 reset
168        TIM6RST OFFSET(4) NUMBITS(1) [],
169        /// TIM7 reset
170        TIM7RST OFFSET(5) NUMBITS(1) [],
171        /// Window watchdog reset
172        WWDGRST OFFSET(11) NUMBITS(1) [],
173        /// SPI 2 reset
174        SPI2RST OFFSET(14) NUMBITS(1) [],
175        /// SPI 3 reset
176        SPI3RST OFFSET(15) NUMBITS(1) [],
177        /// USART 2 reset
178        UART2RST OFFSET(17) NUMBITS(1) [],
179        /// USART 3 reset
180        UART3RST OFFSET(18) NUMBITS(1) [],
181        /// USART 4 reset
182        UART4RST OFFSET(19) NUMBITS(1) [],
183        /// USART 5 reset
184        UART5RST OFFSET(20) NUMBITS(1) [],
185        /// I2C 1 reset
186        I2C1RST OFFSET(21) NUMBITS(1) [],
187        /// I2C 2 reset
188        I2C2RST OFFSET(22) NUMBITS(1) [],
189        /// USB reset
190        USBRST OFFSET(23) NUMBITS(1) [],
191        /// CAN reset
192        CANRST OFFSET(25) NUMBITS(1) [],
193        /// DAC2 reset
194        DAC2RST OFFSET(26) NUMBITS(1) [],
195        /// Power interface reset
196        PWRRST OFFSET(28) NUMBITS(1) [],
197        /// DAC1 reset
198        DAC1RST OFFSET(29) NUMBITS(1) [],
199        /// I2C 3 reset
200        I2C3RST OFFSET(30) NUMBITS(1) []
201    ],
202    AHBENR [
203        /// ADC3 and ADC4 enable
204        ADC34EN OFFSET(29) NUMBITS(1) [], //stm32f303vct6 specific
205        /// ADC1 and ADC2 enable
206        ADC12EN OFFSET(28) NUMBITS(1) [],
207        /// Touch sensing controller clock enable
208        TSCEN OFFSET(24) NUMBITS(1) [],
209        /// IO port F clock enable
210        IOPFEN OFFSET(22) NUMBITS(1) [],
211        /// IO port E clock enable
212        IOPEEN OFFSET(21) NUMBITS(1) [],
213        /// IO port D clock enable
214        IOPDEN OFFSET(20) NUMBITS(1) [],
215        /// IO port C clock enable
216        IOPCEN OFFSET(19) NUMBITS(1) [],
217        /// IO port B clock enable
218        IOPBEN OFFSET(18) NUMBITS(1) [],
219        /// IO port A clock enable
220        IOPAEN OFFSET(17) NUMBITS(1) [],
221        /// CRC clock enable
222        CRCEN OFFSET(6) NUMBITS(1) [],
223        /// FLITF clock enable
224        FLITFEN OFFSET(4) NUMBITS(1) [],
225        /// SRAM interface clock enable
226        SRAMEN OFFSET(2) NUMBITS(1) [],
227        /// DMA2 clock enable
228        DMA2EN OFFSET(1) NUMBITS(1) [], //stm32f303vct6 specific
229        /// DMA1 clock enable
230        DMA1EN OFFSET(0) NUMBITS(1) []
231    ],
232    APB2ENR [
233        /// TIM20 clock enable
234        TIM20EN OFFSET(20) NUMBITS(1) [],
235        /// TIM17 clock enable
236        TIM17EN OFFSET(18) NUMBITS(1) [],
237        /// TIM16 clock enable
238        TIM16EN OFFSET(17) NUMBITS(1) [],
239        /// TIM15 clock enable
240        TIM15EN OFFSET(16) NUMBITS(1) [],
241        /// SPI4 clock enable
242        SPI4EN OFFSET(15) NUMBITS(1) [],
243        /// USART1 clock enable
244        USART1EN OFFSET(14) NUMBITS(1) [],
245        /// TIM8 clock enable
246        TIM8EN OFFSET(13) NUMBITS(1) [],
247        /// SPI1 clock enable
248        SPI1EN OFFSET(12) NUMBITS(1) [],
249        /// TIM1 clock enable
250        TIM1EN OFFSET(11) NUMBITS(1) [],
251        /// SYSCFG clock enable
252        SYSCFGEN OFFSET(0) NUMBITS(1) []
253    ],
254    APB1ENR [
255        /// TIM2 clock enable
256        TIM2EN OFFSET(0) NUMBITS(1) [],
257        /// TIM3 clock enable
258        TIM3EN OFFSET(1) NUMBITS(1) [],
259        /// TIM4 clock enable
260        TIM4EN OFFSET(2) NUMBITS(1) [],
261        /// TIM6 clock enable
262        TIM6EN OFFSET(4) NUMBITS(1) [],
263        /// TIM7 clock enable
264        TIM7EN OFFSET(5) NUMBITS(1) [],
265        /// Window watchdog clock enable
266        WWDGEN OFFSET(11) NUMBITS(1) [],
267        /// SPI2 clock enable
268        SPI2EN OFFSET(14) NUMBITS(1) [],
269        /// SPI3 clock enable
270        SPI3EN OFFSET(15) NUMBITS(1) [],
271        /// USART 2 clock enable
272        USART2EN OFFSET(17) NUMBITS(1) [],
273        /// USART3 clock enable
274        USART3EN OFFSET(18) NUMBITS(1) [],
275        /// UART4 clock enable
276        UART4EN OFFSET(19) NUMBITS(1) [],
277        /// UART5 clock enable
278        UART5EN OFFSET(20) NUMBITS(1) [],
279        /// I2C1 clock enable
280        I2C1EN OFFSET(21) NUMBITS(1) [],
281        /// I2C2 clock enable
282        I2C2EN OFFSET(22) NUMBITS(1) [],
283        /// USB clock enable
284        USBEN OFFSET(23) NUMBITS(1) [], //stm32f303vct6 specific
285        /// I2CFMP1 clock enable
286        I2CFMP1EN OFFSET(24) NUMBITS(1) [],
287        /// CAN clock enable
288        CANEN OFFSET(25) NUMBITS(1) [],
289        /// DAC 2 clock enable
290        DAC2EN OFFSET(26) NUMBITS(1) [],
291        /// Power interface clock enable
292        PWREN OFFSET(28) NUMBITS(1) [],
293        /// DAC 1 clock enable
294        DAC1EN OFFSET(29) NUMBITS(1) [],
295        /// I2C 3 interface clock enable
296        I2C3EN OFFSET(30) NUMBITS(1) []
297    ],
298    BDCR [
299        /// Backup domain software reset
300        BDRST OFFSET(16) NUMBITS(1) [],
301        /// RTC clock enable
302        RTCEN OFFSET(15) NUMBITS(1) [],
303        /// RTC clock source selection
304        RTCSEL OFFSET(8) NUMBITS(2) [],
305        /// External low-speed oscillator mode
306        LSEDRV OFFSET(3) NUMBITS(2) [],
307        /// External low-speed oscillator bypass
308        LSEBYP OFFSET(2) NUMBITS(1) [],
309        /// External low-speed oscillator ready
310        LSERDY OFFSET(1) NUMBITS(1) [],
311        /// External low-speed oscillator enable
312        LSEON OFFSET(0) NUMBITS(1) []
313    ],
314    CSR [
315        /// Low-power reset flag
316        LPWRRSTF OFFSET(31) NUMBITS(1) [],
317        /// Window watchdog reset flag
318        WWDGRSTF OFFSET(30) NUMBITS(1) [],
319        /// Independent watchdog reset flag
320        IWDGRSTF OFFSET(29) NUMBITS(1) [],
321        /// Software reset flag
322        SFTRSTF OFFSET(28) NUMBITS(1) [],
323        /// POR/PDR reset flag
324        PORRSTF OFFSET(27) NUMBITS(1) [],
325        /// PIN reset flag
326        PINRSTF OFFSET(26) NUMBITS(1) [],
327        /// Option byte loader reset flag
328        OBLRSTF OFFSET(25) NUMBITS(1) [],
329        /// Remove reset flag
330        RMVF OFFSET(24) NUMBITS(1) [],
331        /// Reset flag of the 1.8 V domain
332        V18PWRRSTF OFFSET(23) NUMBITS(1) [],
333        /// Internal low-speed oscillator ready
334        LSIRDY OFFSET(1) NUMBITS(1) [],
335        /// Internal low-speed oscillator enable
336        LSION OFFSET(0) NUMBITS(1) []
337    ],
338    AHBRSTR [
339        /// ADC3 and ADC4
340        ADC34RST OFFSET(29) NUMBITS(1) [], //stm32f303vct6 specific
341        /// ADC1 and ADC2 reset
342        ADC12RST OFFSET(28) NUMBITS(1) [],
343        /// Touch sensing controller reset
344        TSCRST OFFSET(24) NUMBITS(1) [],
345        /// IO port F reset
346        IOPFRST OFFSET(22) NUMBITS(1) [],
347        /// IO port E reset
348        IOPERST OFFSET(21) NUMBITS(1) [],
349        /// IO port D reset
350        IOPDRST OFFSET(20) NUMBITS(1) [],
351        /// IO port C reset
352        IOPCRST OFFSET(19) NUMBITS(1) [],
353        /// IO port B reset
354        IOPBRST OFFSET(18) NUMBITS(1) [],
355        /// IO port A reset
356        IOPARST OFFSET(17) NUMBITS(1) []
357    ],
358    CFGR2 [
359        /// ADC34 prescaler
360        ADC34PRES OFFSET(9) NUMBITS(5) [], //stm32f303vct6 specific
361        /// ADC12 prescaler
362        ADC12PRES OFFSET(4) NUMBITS(5) [],
363        /// PREDIV division factor
364        PREDIV OFFSET(0) NUMBITS(4) []
365    ],
366    CFGR3 [
367        /// USART5 clock source selection
368        USART5SW OFFSET(22) NUMBITS(2) [], //stm32f303vct6 specific
369        /// USART4 clock source selection
370        USART4SW OFFSET(20) NUMBITS(2) [], //stm32f303vct6 specific
371        /// USART2 clock source selection
372        USART2SW OFFSET(16) NUMBITS(2) [],
373        /// Timer8 clock source selection
374        TIM8SW OFFSET(9) NUMBITS(1) [], //stm32f303vct6 specific
375        /// Timer1 clock source selection
376        TIM1SW OFFSET(8) NUMBITS(1) [],
377        /// I2C2 clock source selection
378        I2C2SW OFFSET(5) NUMBITS(1) [], //stm32f303vct6 specific
379        /// I2C1 clock source selection
380        I2C1SW OFFSET(4) NUMBITS(1) [],
381        /// USART1 clock source selection
382        USART1SW OFFSET(0) NUMBITS(2) []
383    ]
384];
385
386const RCC_BASE: StaticRef<RccRegisters> =
387    unsafe { StaticRef::new(0x40021000 as *const RccRegisters) };
388
389pub struct Rcc {
390    registers: StaticRef<RccRegisters>,
391}
392
393impl Rcc {
394    pub const fn new() -> Rcc {
395        Rcc {
396            registers: RCC_BASE,
397        }
398    }
399
400    // TIM2 clock
401
402    fn is_enabled_tim2_clock(&self) -> bool {
403        self.registers.apb1enr.is_set(APB1ENR::TIM2EN)
404    }
405
406    fn enable_tim2_clock(&self) {
407        self.registers.apb1enr.modify(APB1ENR::TIM2EN::SET)
408    }
409
410    fn disable_tim2_clock(&self) {
411        self.registers.apb1enr.modify(APB1ENR::TIM2EN::CLEAR)
412    }
413
414    // SYSCFG clock
415
416    fn is_enabled_syscfg_clock(&self) -> bool {
417        self.registers.apb2enr.is_set(APB2ENR::SYSCFGEN)
418    }
419
420    fn enable_syscfg_clock(&self) {
421        self.registers.apb2enr.modify(APB2ENR::SYSCFGEN::SET)
422    }
423
424    fn disable_syscfg_clock(&self) {
425        self.registers.apb2enr.modify(APB2ENR::SYSCFGEN::CLEAR)
426    }
427
428    // DMA1 clock
429
430    fn is_enabled_dma1_clock(&self) -> bool {
431        self.registers.ahbenr.is_set(AHBENR::DMA1EN)
432    }
433
434    fn enable_dma1_clock(&self) {
435        self.registers.ahbenr.modify(AHBENR::DMA1EN::SET)
436    }
437
438    fn disable_dma1_clock(&self) {
439        self.registers.ahbenr.modify(AHBENR::DMA1EN::CLEAR)
440    }
441
442    // GPIOF clock
443
444    fn is_enabled_gpiof_clock(&self) -> bool {
445        self.registers.ahbenr.is_set(AHBENR::IOPFEN)
446    }
447
448    fn enable_gpiof_clock(&self) {
449        self.registers.ahbenr.modify(AHBENR::IOPFEN::SET)
450    }
451
452    fn disable_gpiof_clock(&self) {
453        self.registers.ahbenr.modify(AHBENR::IOPFEN::CLEAR)
454    }
455
456    // GPIOE clock
457
458    fn is_enabled_gpioe_clock(&self) -> bool {
459        self.registers.ahbenr.is_set(AHBENR::IOPEEN)
460    }
461
462    fn enable_gpioe_clock(&self) {
463        self.registers.ahbenr.modify(AHBENR::IOPEEN::SET)
464    }
465
466    fn disable_gpioe_clock(&self) {
467        self.registers.ahbenr.modify(AHBENR::IOPEEN::CLEAR)
468    }
469
470    // GPIOD clock
471
472    fn is_enabled_gpiod_clock(&self) -> bool {
473        self.registers.ahbenr.is_set(AHBENR::IOPDEN)
474    }
475
476    fn enable_gpiod_clock(&self) {
477        self.registers.ahbenr.modify(AHBENR::IOPDEN::SET)
478    }
479
480    fn disable_gpiod_clock(&self) {
481        self.registers.ahbenr.modify(AHBENR::IOPDEN::CLEAR)
482    }
483
484    // GPIOC clock
485
486    fn is_enabled_gpioc_clock(&self) -> bool {
487        self.registers.ahbenr.is_set(AHBENR::IOPCEN)
488    }
489
490    fn enable_gpioc_clock(&self) {
491        self.registers.ahbenr.modify(AHBENR::IOPCEN::SET)
492    }
493
494    fn disable_gpioc_clock(&self) {
495        self.registers.ahbenr.modify(AHBENR::IOPCEN::CLEAR)
496    }
497
498    // GPIOB clock
499
500    fn is_enabled_gpiob_clock(&self) -> bool {
501        self.registers.ahbenr.is_set(AHBENR::IOPBEN)
502    }
503
504    fn enable_gpiob_clock(&self) {
505        self.registers.ahbenr.modify(AHBENR::IOPBEN::SET)
506    }
507
508    fn disable_gpiob_clock(&self) {
509        self.registers.ahbenr.modify(AHBENR::IOPBEN::CLEAR)
510    }
511
512    // GPIOA clock
513
514    fn is_enabled_gpioa_clock(&self) -> bool {
515        self.registers.ahbenr.is_set(AHBENR::IOPAEN)
516    }
517
518    fn enable_gpioa_clock(&self) {
519        self.registers.ahbenr.modify(AHBENR::IOPAEN::SET)
520    }
521
522    fn disable_gpioa_clock(&self) {
523        self.registers.ahbenr.modify(AHBENR::IOPAEN::CLEAR)
524    }
525
526    // USART1 clock
527
528    fn is_enabled_usart1_clock(&self) -> bool {
529        self.registers.apb2enr.is_set(APB2ENR::USART1EN)
530    }
531
532    fn enable_usart1_clock(&self) {
533        self.registers.apb2enr.modify(APB2ENR::USART1EN::SET)
534    }
535
536    fn disable_usart1_clock(&self) {
537        self.registers.apb2enr.modify(APB2ENR::USART1EN::CLEAR)
538    }
539
540    // USART2 clock
541
542    fn is_enabled_usart2_clock(&self) -> bool {
543        self.registers.apb1enr.is_set(APB1ENR::USART2EN)
544    }
545
546    fn enable_usart2_clock(&self) {
547        self.registers.apb1enr.modify(APB1ENR::USART2EN::SET)
548    }
549
550    fn disable_usart2_clock(&self) {
551        self.registers.apb1enr.modify(APB1ENR::USART2EN::CLEAR)
552    }
553
554    // USART3 clock
555
556    fn is_enabled_usart3_clock(&self) -> bool {
557        self.registers.apb1enr.is_set(APB1ENR::USART3EN)
558    }
559
560    fn enable_usart3_clock(&self) {
561        self.registers.apb1enr.modify(APB1ENR::USART3EN::SET)
562    }
563
564    fn disable_usart3_clock(&self) {
565        self.registers.apb1enr.modify(APB1ENR::USART3EN::CLEAR)
566    }
567
568    // SPI1 clock
569
570    fn is_enabled_spi1_clock(&self) -> bool {
571        self.registers.apb2enr.is_set(APB2ENR::SPI1EN)
572    }
573
574    fn enable_spi1_clock(&self) {
575        self.registers.apb2enr.modify(APB2ENR::SPI1EN::SET)
576    }
577
578    fn disable_spi1_clock(&self) {
579        self.registers.apb2enr.modify(APB2ENR::SPI1EN::CLEAR)
580    }
581
582    // I2C1 clock
583
584    fn is_enabled_i2c1_clock(&self) -> bool {
585        self.registers.apb1enr.is_set(APB1ENR::I2C1EN)
586    }
587
588    fn enable_i2c1_clock(&self) {
589        self.registers.apb1enr.modify(APB1ENR::I2C1EN::SET)
590    }
591
592    fn disable_i2c1_clock(&self) {
593        self.registers.apb1enr.modify(APB1ENR::I2C1EN::CLEAR)
594    }
595
596    fn reset_i2c1(&self) {
597        self.registers.apb1rstr.modify(APB1RSTR::I2C1RST::SET);
598        self.registers.apb1rstr.modify(APB1RSTR::I2C1RST::CLEAR);
599    }
600
601    // ADC12 clock
602
603    fn is_enabled_adc12_clock(&self) -> bool {
604        self.registers.ahbenr.is_set(AHBENR::ADC12EN)
605    }
606
607    fn enable_adc12_clock(&self) {
608        self.registers.cfgr.modify(CFGR::HPRE.val(0b0000));
609        self.registers.cfgr2.modify(CFGR2::ADC12PRES.val(0b10111));
610        self.registers.ahbenr.modify(AHBENR::ADC12EN::SET);
611    }
612
613    fn disable_adc12_clock(&self) {
614        self.registers.ahbenr.modify(AHBENR::ADC12EN::CLEAR);
615    }
616
617    // ADC34 clock
618    fn is_enabled_adc34_clock(&self) -> bool {
619        self.registers.ahbenr.is_set(AHBENR::ADC34EN)
620    }
621
622    fn enable_adc34_clock(&self) {
623        self.registers.ahbenr.modify(AHBENR::ADC34EN::SET);
624    }
625
626    fn disable_adc34_clock(&self) {
627        self.registers.ahbenr.modify(AHBENR::ADC34EN::CLEAR);
628    }
629
630    // WWDG clock
631
632    fn is_enabled_wwdg_clock(&self) -> bool {
633        self.registers.apb1enr.is_set(APB1ENR::WWDGEN)
634    }
635
636    fn enable_wwdg_clock(&self) {
637        self.registers.apb1enr.modify(APB1ENR::WWDGEN::SET);
638    }
639
640    fn disable_wwdg_clock(&self) {
641        self.registers.apb1enr.modify(APB1ENR::WWDGEN::CLEAR);
642    }
643}
644
645/// Clock sources for CPU
646pub enum CPUClock {
647    HSE,
648    HSI,
649    PLLCLK,
650}
651
652pub struct PeripheralClock<'a> {
653    pub clock: PeripheralClockType,
654    rcc: &'a Rcc,
655}
656
657/// Bus + Clock name for the peripherals
658///
659/// Not yet implemented clocks:
660///
661/// AHB2(HCLK2)
662/// AHB3(HCLK3)
663/// APB1(PCLK1),
664/// APB2(PCLK2),
665pub enum PeripheralClockType {
666    AHB(HCLK),
667    APB2(PCLK2),
668    APB1(PCLK1),
669}
670
671/// Peripherals clocked by HCLK1
672pub enum HCLK {
673    ADC1,
674    ADC2,
675    ADC3,
676    ADC4,
677    DMA1,
678    GPIOF,
679    GPIOE,
680    GPIOD,
681    GPIOC,
682    GPIOB,
683    GPIOA,
684}
685
686/// Peripherals clocked by PCLK1
687pub enum PCLK1 {
688    TIM2,
689    USART2,
690    USART3,
691    I2C1,
692    WWDG,
693    // I2C2,
694    // SPI3,
695}
696
697/// Peripherals clocked by PCLK2
698pub enum PCLK2 {
699    SYSCFG,
700    USART1,
701    SPI1,
702}
703
704impl<'a> PeripheralClock<'a> {
705    pub const fn new(clock: PeripheralClockType, rcc: &'a Rcc) -> Self {
706        Self { clock, rcc }
707    }
708}
709
710impl ClockInterface for PeripheralClock<'_> {
711    fn is_enabled(&self) -> bool {
712        match self.clock {
713            PeripheralClockType::AHB(ref v) => match v {
714                HCLK::ADC1 | HCLK::ADC2 => self.rcc.is_enabled_adc12_clock(),
715                HCLK::ADC3 | HCLK::ADC4 => self.rcc.is_enabled_adc34_clock(),
716                HCLK::DMA1 => self.rcc.is_enabled_dma1_clock(),
717                HCLK::GPIOF => self.rcc.is_enabled_gpiof_clock(),
718                HCLK::GPIOE => self.rcc.is_enabled_gpioe_clock(),
719                HCLK::GPIOD => self.rcc.is_enabled_gpiod_clock(),
720                HCLK::GPIOC => self.rcc.is_enabled_gpioc_clock(),
721                HCLK::GPIOB => self.rcc.is_enabled_gpiob_clock(),
722                HCLK::GPIOA => self.rcc.is_enabled_gpioa_clock(),
723            },
724            PeripheralClockType::APB1(ref v) => match v {
725                PCLK1::TIM2 => self.rcc.is_enabled_tim2_clock(),
726                PCLK1::USART2 => self.rcc.is_enabled_usart2_clock(),
727                PCLK1::USART3 => self.rcc.is_enabled_usart3_clock(),
728                PCLK1::I2C1 => self.rcc.is_enabled_i2c1_clock(),
729                PCLK1::WWDG => self.rcc.is_enabled_wwdg_clock(),
730            },
731            PeripheralClockType::APB2(ref v) => match v {
732                PCLK2::SPI1 => self.rcc.is_enabled_spi1_clock(),
733                PCLK2::SYSCFG => self.rcc.is_enabled_syscfg_clock(),
734                PCLK2::USART1 => self.rcc.is_enabled_usart1_clock(),
735            },
736        }
737    }
738
739    fn enable(&self) {
740        match self.clock {
741            PeripheralClockType::AHB(ref v) => match v {
742                HCLK::ADC1 | HCLK::ADC2 => {
743                    self.rcc.enable_adc12_clock();
744                }
745                HCLK::ADC3 | HCLK::ADC4 => {
746                    self.rcc.enable_adc34_clock();
747                }
748                HCLK::DMA1 => {
749                    self.rcc.enable_dma1_clock();
750                }
751                HCLK::GPIOF => {
752                    self.rcc.enable_gpiof_clock();
753                }
754                HCLK::GPIOE => {
755                    self.rcc.enable_gpioe_clock();
756                }
757                HCLK::GPIOD => {
758                    self.rcc.enable_gpiod_clock();
759                }
760                HCLK::GPIOC => {
761                    self.rcc.enable_gpioc_clock();
762                }
763                HCLK::GPIOB => {
764                    self.rcc.enable_gpiob_clock();
765                }
766                HCLK::GPIOA => {
767                    self.rcc.enable_gpioa_clock();
768                }
769            },
770            PeripheralClockType::APB1(ref v) => match v {
771                PCLK1::TIM2 => {
772                    self.rcc.enable_tim2_clock();
773                }
774                PCLK1::USART2 => {
775                    self.rcc.enable_usart2_clock();
776                }
777                PCLK1::USART3 => {
778                    self.rcc.enable_usart3_clock();
779                }
780                PCLK1::I2C1 => {
781                    self.rcc.enable_i2c1_clock();
782                    self.rcc.reset_i2c1();
783                }
784                PCLK1::WWDG => {
785                    self.rcc.enable_wwdg_clock();
786                }
787            },
788            PeripheralClockType::APB2(ref v) => match v {
789                PCLK2::SYSCFG => {
790                    self.rcc.enable_syscfg_clock();
791                }
792                PCLK2::USART1 => {
793                    self.rcc.enable_usart1_clock();
794                }
795                PCLK2::SPI1 => {
796                    self.rcc.enable_spi1_clock();
797                }
798            },
799        }
800    }
801
802    fn disable(&self) {
803        match self.clock {
804            PeripheralClockType::AHB(ref v) => match v {
805                HCLK::ADC1 | HCLK::ADC2 => {
806                    self.rcc.disable_adc12_clock();
807                }
808                HCLK::ADC3 | HCLK::ADC4 => {
809                    self.rcc.disable_adc34_clock();
810                }
811                HCLK::DMA1 => {
812                    self.rcc.disable_dma1_clock();
813                }
814                HCLK::GPIOF => {
815                    self.rcc.disable_gpiof_clock();
816                }
817                HCLK::GPIOE => {
818                    self.rcc.disable_gpioe_clock();
819                }
820                HCLK::GPIOD => {
821                    self.rcc.disable_gpiod_clock();
822                }
823                HCLK::GPIOC => {
824                    self.rcc.disable_gpioc_clock();
825                }
826                HCLK::GPIOB => {
827                    self.rcc.disable_gpiob_clock();
828                }
829                HCLK::GPIOA => {
830                    self.rcc.disable_gpioa_clock();
831                }
832            },
833            PeripheralClockType::APB1(ref v) => match v {
834                PCLK1::TIM2 => {
835                    self.rcc.disable_tim2_clock();
836                }
837                PCLK1::USART2 => {
838                    self.rcc.disable_usart2_clock();
839                }
840                PCLK1::USART3 => {
841                    self.rcc.disable_usart3_clock();
842                }
843                PCLK1::I2C1 => {
844                    self.rcc.disable_i2c1_clock();
845                }
846                PCLK1::WWDG => {
847                    self.rcc.disable_wwdg_clock();
848                }
849            },
850            PeripheralClockType::APB2(ref v) => match v {
851                PCLK2::SYSCFG => {
852                    self.rcc.disable_syscfg_clock();
853                }
854                PCLK2::USART1 => {
855                    self.rcc.disable_usart1_clock();
856                }
857                PCLK2::SPI1 => {
858                    self.rcc.disable_spi1_clock();
859                }
860            },
861        }
862    }
863}