stm32f4xx/
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::utilities::registers::interfaces::{ReadWriteable, Readable};
6use kernel::utilities::registers::{register_bitfields, ReadWrite};
7use kernel::utilities::StaticRef;
8
9/// Reset and clock control
10#[repr(C)]
11struct RccRegisters {
12    /// clock control register
13    cr: ReadWrite<u32, CR::Register>,
14    /// PLL configuration register
15    pllcfgr: ReadWrite<u32, PLLCFGR::Register>,
16    /// clock configuration register
17    cfgr: ReadWrite<u32, CFGR::Register>,
18    /// clock interrupt register
19    cir: ReadWrite<u32, CIR::Register>,
20    /// AHB1 peripheral reset register
21    ahb1rstr: ReadWrite<u32, AHB1RSTR::Register>,
22    /// AHB2 peripheral reset register
23    ahb2rstr: ReadWrite<u32, AHB2RSTR::Register>,
24    /// AHB3 peripheral reset register
25    ahb3rstr: ReadWrite<u32, AHB3RSTR::Register>,
26    _reserved0: [u8; 4],
27    /// APB1 peripheral reset register
28    apb1rstr: ReadWrite<u32, APB1RSTR::Register>,
29    /// APB2 peripheral reset register
30    apb2rstr: ReadWrite<u32, APB2RSTR::Register>,
31    _reserved1: [u8; 8],
32    /// AHB1 peripheral clock register
33    ahb1enr: ReadWrite<u32, AHB1ENR::Register>,
34    /// AHB2 peripheral clock enable register
35    ahb2enr: ReadWrite<u32, AHB2ENR::Register>,
36    /// AHB3 peripheral clock enable register
37    ahb3enr: ReadWrite<u32, AHB3ENR::Register>,
38    _reserved2: [u8; 4],
39    /// APB1 peripheral clock enable register
40    apb1enr: ReadWrite<u32, APB1ENR::Register>,
41    /// APB2 peripheral clock enable register
42    apb2enr: ReadWrite<u32, APB2ENR::Register>,
43    _reserved3: [u8; 8],
44    /// AHB1 peripheral clock enable in low power mode register
45    ahb1lpenr: ReadWrite<u32, AHB1LPENR::Register>,
46    /// AHB2 peripheral clock enable in low power mode register
47    ahb2lpenr: ReadWrite<u32, AHB2LPENR::Register>,
48    /// AHB3 peripheral clock enable in low power mode register
49    ahb3lpenr: ReadWrite<u32, AHB3LPENR::Register>,
50    _reserved4: [u8; 4],
51    /// APB1 peripheral clock enable in low power mode register
52    apb1lpenr: ReadWrite<u32, APB1LPENR::Register>,
53    /// APB2 peripheral clock enabled in low power mode register
54    apb2lpenr: ReadWrite<u32, APB2LPENR::Register>,
55    _reserved5: [u8; 8],
56    /// Backup domain control register
57    bdcr: ReadWrite<u32, BDCR::Register>,
58    /// clock control & status register
59    csr: ReadWrite<u32, CSR::Register>,
60    _reserved6: [u8; 8],
61    /// spread spectrum clock generation register
62    sscgr: ReadWrite<u32, SSCGR::Register>,
63    /// PLLI2S configuration register
64    plli2scfgr: ReadWrite<u32, PLLI2SCFGR::Register>,
65    /// PLL configuration register
66    pllsaicfgr: ReadWrite<u32, PLLSAICFGR::Register>,
67    /// Dedicated Clock Configuration Register
68    dckcfgr: ReadWrite<u32, DCKCFGR::Register>,
69    /// clocks gated enable register
70    ckgatenr: ReadWrite<u32, CKGATENR::Register>,
71    /// dedicated clocks configuration register 2
72    dckcfgr2: ReadWrite<u32, DCKCFGR2::Register>,
73}
74
75register_bitfields![u32,
76    CR [
77        /// PLLI2S clock ready flag
78        PLLI2SRDY OFFSET(27) NUMBITS(1) [],
79        /// PLLI2S enable
80        PLLI2SON OFFSET(26) NUMBITS(1) [],
81        /// Main PLL (PLL) clock ready flag
82        PLLRDY OFFSET(25) NUMBITS(1) [],
83        /// Main PLL (PLL) enable
84        PLLON OFFSET(24) NUMBITS(1) [],
85        /// Clock security system enable
86        CSSON OFFSET(19) NUMBITS(1) [],
87        /// HSE clock bypass
88        HSEBYP OFFSET(18) NUMBITS(1) [],
89        /// HSE clock ready flag
90        HSERDY OFFSET(17) NUMBITS(1) [],
91        /// HSE clock enable
92        HSEON OFFSET(16) NUMBITS(1) [],
93        /// Internal high-speed clock calibration
94        HSICAL OFFSET(8) NUMBITS(8) [],
95        /// Internal high-speed clock trimming
96        HSITRIM OFFSET(3) NUMBITS(5) [],
97        /// Internal high-speed clock ready flag
98        HSIRDY OFFSET(1) NUMBITS(1) [],
99        /// Internal high-speed clock enable
100        HSION OFFSET(0) NUMBITS(1) []
101    ],
102    PLLCFGR [
103        /// Main PLL (PLL) division factor for USB OTG FS, SDIO and random num
104        PLLQ OFFSET(24) NUMBITS(4) [],
105        /// Main PLL(PLL) and audio PLL (PLLI2S) entry clock source
106        PLLSRC OFFSET(22) NUMBITS(1) [
107            HSI = 0,
108            HSE = 1,
109        ],
110        /// Main PLL (PLL) division factor for main system clock
111        PLLP OFFSET(16) NUMBITS(2) [
112            DivideBy2 = 0b00,
113            DivideBy4 = 0b01,
114            DivideBy6 = 0b10,
115            DivideBy8 = 0b11,
116        ],
117        /// Main PLL (PLL) multiplication factor for VCO
118        PLLN OFFSET(6) NUMBITS(9) [],
119        /// Division factor for the main PLL (PLL) and audio PLL (PLLI2S) input
120        PLLM OFFSET(0) NUMBITS(6) []
121    ],
122    CFGR [
123        /// Microcontroller clock output 2
124        MCO2 OFFSET(30) NUMBITS(2) [],
125        /// MCO2 prescaler
126        MCO2PRE OFFSET(27) NUMBITS(3) [],
127        /// MCO1 prescaler
128        MCO1PRE OFFSET(24) NUMBITS(3) [],
129        /// I2S clock selection
130        I2SSRC OFFSET(23) NUMBITS(1) [],
131        /// Microcontroller clock output 1
132        MCO1 OFFSET(21) NUMBITS(2) [],
133        /// HSE division factor for RTC clock
134        RTCPRE OFFSET(16) NUMBITS(5) [],
135        /// APB high-speed prescaler (APB2)
136        PPRE2 OFFSET(13) NUMBITS(3) [],
137        /// APB Low speed prescaler (APB1)
138        PPRE1 OFFSET(10) NUMBITS(3) [],
139        /// AHB prescaler
140        HPRE OFFSET(4) NUMBITS(4) [],
141        /// System clock switch status
142        SWS OFFSET(2) NUMBITS(2) [],
143        /// System clock switch
144        SW OFFSET(0) NUMBITS(2) [
145            HSI = 0b00,
146            HSE = 0b01,
147            PLL = 0b10,
148        ]
149    ],
150    CIR [
151        /// Clock security system interrupt clear
152        CSSC OFFSET(23) NUMBITS(1) [],
153        /// PLLSAI Ready Interrupt Clear
154        PLLSAIRDYC OFFSET(22) NUMBITS(1) [],
155        /// PLLI2S ready interrupt clear
156        PLLI2SRDYC OFFSET(21) NUMBITS(1) [],
157        /// Main PLL(PLL) ready interrupt clear
158        PLLRDYC OFFSET(20) NUMBITS(1) [],
159        /// HSE ready interrupt clear
160        HSERDYC OFFSET(19) NUMBITS(1) [],
161        /// HSI ready interrupt clear
162        HSIRDYC OFFSET(18) NUMBITS(1) [],
163        /// LSE ready interrupt clear
164        LSERDYC OFFSET(17) NUMBITS(1) [],
165        /// LSI ready interrupt clear
166        LSIRDYC OFFSET(16) NUMBITS(1) [],
167        /// PLLSAI Ready Interrupt Enable
168        PLLSAIRDYIE OFFSET(14) NUMBITS(1) [],
169        /// PLLI2S ready interrupt enable
170        PLLI2SRDYIE OFFSET(13) NUMBITS(1) [],
171        /// Main PLL (PLL) ready interrupt enable
172        PLLRDYIE OFFSET(12) NUMBITS(1) [],
173        /// HSE ready interrupt enable
174        HSERDYIE OFFSET(11) NUMBITS(1) [],
175        /// HSI ready interrupt enable
176        HSIRDYIE OFFSET(10) NUMBITS(1) [],
177        /// LSE ready interrupt enable
178        LSERDYIE OFFSET(9) NUMBITS(1) [],
179        /// LSI ready interrupt enable
180        LSIRDYIE OFFSET(8) NUMBITS(1) [],
181        /// Clock security system interrupt flag
182        CSSF OFFSET(7) NUMBITS(1) [],
183        /// PLLSAI ready interrupt flag
184        PLLSAIRDYF OFFSET(6) NUMBITS(1) [],
185        /// PLLI2S ready interrupt flag
186        PLLI2SRDYF OFFSET(5) NUMBITS(1) [],
187        /// Main PLL (PLL) ready interrupt flag
188        PLLRDYF OFFSET(4) NUMBITS(1) [],
189        /// HSE ready interrupt flag
190        HSERDYF OFFSET(3) NUMBITS(1) [],
191        /// HSI ready interrupt flag
192        HSIRDYF OFFSET(2) NUMBITS(1) [],
193        /// LSE ready interrupt flag
194        LSERDYF OFFSET(1) NUMBITS(1) [],
195        /// LSI ready interrupt flag
196        LSIRDYF OFFSET(0) NUMBITS(1) []
197    ],
198    AHB1RSTR [
199        /// USB OTG HS module reset
200        OTGHSRST OFFSET(29) NUMBITS(1) [],
201        /// DMA2 reset
202        DMA2RST OFFSET(22) NUMBITS(1) [],
203        /// DMA2 reset
204        DMA1RST OFFSET(21) NUMBITS(1) [],
205        /// CRC reset
206        CRCRST OFFSET(12) NUMBITS(1) [],
207        /// IO port H reset
208        GPIOHRST OFFSET(7) NUMBITS(1) [],
209        /// IO port G reset
210        GPIOGRST OFFSET(6) NUMBITS(1) [],
211        /// IO port F reset
212        GPIOFRST OFFSET(5) NUMBITS(1) [],
213        /// IO port E reset
214        GPIOERST OFFSET(4) NUMBITS(1) [],
215        /// IO port D reset
216        GPIODRST OFFSET(3) NUMBITS(1) [],
217        /// IO port C reset
218        GPIOCRST OFFSET(2) NUMBITS(1) [],
219        /// IO port B reset
220        GPIOBRST OFFSET(1) NUMBITS(1) [],
221        /// IO port A reset
222        GPIOARST OFFSET(0) NUMBITS(1) []
223    ],
224    AHB2RSTR [
225        /// USB OTG FS module reset
226        OTGFSRST OFFSET(7) NUMBITS(1) [],
227        /// RNG module reset
228        RNGSRST OFFSET(6) NUMBITS(1) [],
229        /// Camera interface reset
230        DCMIRST OFFSET(0) NUMBITS(1) []
231    ],
232    AHB3RSTR [
233        /// Flexible memory controller module reset
234        FMCRST OFFSET(0) NUMBITS(1) [],
235        /// QUADSPI module reset
236        QSPIRST OFFSET(1) NUMBITS(1) []
237    ],
238    APB1RSTR [
239        /// TIM2 reset
240        TIM2RST OFFSET(0) NUMBITS(1) [],
241        /// TIM3 reset
242        TIM3RST OFFSET(1) NUMBITS(1) [],
243        /// TIM4 reset
244        TIM4RST OFFSET(2) NUMBITS(1) [],
245        /// TIM5 reset
246        TIM5RST OFFSET(3) NUMBITS(1) [],
247        /// TIM6 reset
248        TIM6RST OFFSET(4) NUMBITS(1) [],
249        /// TIM7 reset
250        TIM7RST OFFSET(5) NUMBITS(1) [],
251        /// TIM12 reset
252        TIM12RST OFFSET(6) NUMBITS(1) [],
253        /// TIM13 reset
254        TIM13RST OFFSET(7) NUMBITS(1) [],
255        /// TIM14 reset
256        TIM14RST OFFSET(8) NUMBITS(1) [],
257        /// Window watchdog reset
258        WWDGRST OFFSET(11) NUMBITS(1) [],
259        /// SPI 2 reset
260        SPI2RST OFFSET(14) NUMBITS(1) [],
261        /// SPI 3 reset
262        SPI3RST OFFSET(15) NUMBITS(1) [],
263        /// SPDIF-IN reset
264        SPDIFRST OFFSET(16) NUMBITS(1) [],
265        /// USART 2 reset
266        UART2RST OFFSET(17) NUMBITS(1) [],
267        /// USART 3 reset
268        UART3RST OFFSET(18) NUMBITS(1) [],
269        /// USART 4 reset
270        UART4RST OFFSET(19) NUMBITS(1) [],
271        /// USART 5 reset
272        UART5RST OFFSET(20) NUMBITS(1) [],
273        /// I2C 1 reset
274        I2C1RST OFFSET(21) NUMBITS(1) [],
275        /// I2C 2 reset
276        I2C2RST OFFSET(22) NUMBITS(1) [],
277        /// I2C3 reset
278        I2C3RST OFFSET(23) NUMBITS(1) [],
279        /// I2CFMP1 reset
280        I2CFMP1RST OFFSET(24) NUMBITS(1) [],
281        /// CAN1 reset
282        CAN1RST OFFSET(25) NUMBITS(1) [],
283        /// CAN2 reset
284        CAN2RST OFFSET(26) NUMBITS(1) [],
285        /// Power interface reset
286        PWRRST OFFSET(28) NUMBITS(1) [],
287        /// DAC reset
288        DACRST OFFSET(29) NUMBITS(1) []
289    ],
290    APB2RSTR [
291        /// TIM1 reset
292        TIM1RST OFFSET(0) NUMBITS(1) [],
293        /// TIM8 reset
294        TIM8RST OFFSET(1) NUMBITS(1) [],
295        /// USART1 reset
296        USART1RST OFFSET(4) NUMBITS(1) [],
297        /// USART6 reset
298        USART6RST OFFSET(5) NUMBITS(1) [],
299        /// ADC interface reset (common to all ADCs)
300        ADCRST OFFSET(8) NUMBITS(1) [],
301        /// SDIO reset
302        SDIORST OFFSET(11) NUMBITS(1) [],
303        /// SPI 1 reset
304        SPI1RST OFFSET(12) NUMBITS(1) [],
305        /// SPI4 reset
306        SPI4RST OFFSET(13) NUMBITS(1) [],
307        /// System configuration controller reset
308        SYSCFGRST OFFSET(14) NUMBITS(1) [],
309        /// TIM9 reset
310        TIM9RST OFFSET(16) NUMBITS(1) [],
311        /// TIM10 reset
312        TIM10RST OFFSET(17) NUMBITS(1) [],
313        /// TIM11 reset
314        TIM11RST OFFSET(18) NUMBITS(1) [],
315        /// SAI1 reset
316        SAI1RST OFFSET(22) NUMBITS(1) [],
317        /// SAI2 reset
318        SAI2RST OFFSET(23) NUMBITS(1) []
319    ],
320    AHB1ENR [
321        /// USB OTG HSULPI clock enable
322        OTGHSULPIEN OFFSET(30) NUMBITS(1) [],
323        /// USB OTG HS clock enable
324        OTGHSEN OFFSET(29) NUMBITS(1) [],
325        /// DMA2 clock enable
326        DMA2EN OFFSET(22) NUMBITS(1) [],
327        /// DMA1 clock enable
328        DMA1EN OFFSET(21) NUMBITS(1) [],
329        /// Backup SRAM interface clock enable
330        BKPSRAMEN OFFSET(18) NUMBITS(1) [],
331        /// CRC clock enable
332        CRCEN OFFSET(12) NUMBITS(1) [],
333        /// IO port H clock enable
334        GPIOHEN OFFSET(7) NUMBITS(1) [],
335        /// IO port G clock enable
336        GPIOGEN OFFSET(6) NUMBITS(1) [],
337        /// IO port F clock enable
338        GPIOFEN OFFSET(5) NUMBITS(1) [],
339        /// IO port E clock enable
340        GPIOEEN OFFSET(4) NUMBITS(1) [],
341        /// IO port D clock enable
342        GPIODEN OFFSET(3) NUMBITS(1) [],
343        /// IO port C clock enable
344        GPIOCEN OFFSET(2) NUMBITS(1) [],
345        /// IO port B clock enable
346        GPIOBEN OFFSET(1) NUMBITS(1) [],
347        /// IO port A clock enable
348        GPIOAEN OFFSET(0) NUMBITS(1) []
349    ],
350    AHB2ENR [
351        /// USB OTG FS clock enable
352        OTGFSEN OFFSET(7) NUMBITS(1) [],
353        /// RNG clock enable
354        RNGEN OFFSET(6) NUMBITS(1) [],
355        /// Camera interface enable
356        DCMIEN OFFSET(0) NUMBITS(1) []
357    ],
358    AHB3ENR [
359        /// Flexible memory controller module clock enable
360        FMCEN OFFSET(0) NUMBITS(1) [],
361        /// QUADSPI memory controller module clock enable
362        QSPIEN OFFSET(1) NUMBITS(1) []
363    ],
364    APB1ENR [
365        /// TIM2 clock enable
366        TIM2EN OFFSET(0) NUMBITS(1) [],
367        /// TIM3 clock enable
368        TIM3EN OFFSET(1) NUMBITS(1) [],
369        /// TIM4 clock enable
370        TIM4EN OFFSET(2) NUMBITS(1) [],
371        /// TIM5 clock enable
372        TIM5EN OFFSET(3) NUMBITS(1) [],
373        /// TIM6 clock enable
374        TIM6EN OFFSET(4) NUMBITS(1) [],
375        /// TIM7 clock enable
376        TIM7EN OFFSET(5) NUMBITS(1) [],
377        /// TIM12 clock enable
378        TIM12EN OFFSET(6) NUMBITS(1) [],
379        /// TIM13 clock enable
380        TIM13EN OFFSET(7) NUMBITS(1) [],
381        /// TIM14 clock enable
382        TIM14EN OFFSET(8) NUMBITS(1) [],
383        /// Window watchdog clock enable
384        WWDGEN OFFSET(11) NUMBITS(1) [],
385        /// SPI2 clock enable
386        SPI2EN OFFSET(14) NUMBITS(1) [],
387        /// SPI3 clock enable
388        SPI3EN OFFSET(15) NUMBITS(1) [],
389        /// SPDIF-IN clock enable
390        SPDIFEN OFFSET(16) NUMBITS(1) [],
391        /// USART 2 clock enable
392        USART2EN OFFSET(17) NUMBITS(1) [],
393        /// USART3 clock enable
394        USART3EN OFFSET(18) NUMBITS(1) [],
395        /// UART4 clock enable
396        UART4EN OFFSET(19) NUMBITS(1) [],
397        /// UART5 clock enable
398        UART5EN OFFSET(20) NUMBITS(1) [],
399        /// I2C1 clock enable
400        I2C1EN OFFSET(21) NUMBITS(1) [],
401        /// I2C2 clock enable
402        I2C2EN OFFSET(22) NUMBITS(1) [],
403        /// I2C3 clock enable
404        I2C3EN OFFSET(23) NUMBITS(1) [],
405        /// I2CFMP1 clock enable
406        I2CFMP1EN OFFSET(24) NUMBITS(1) [],
407        /// CAN 1 clock enable
408        CAN1EN OFFSET(25) NUMBITS(1) [],
409        /// CAN 2 clock enable
410        CAN2EN OFFSET(26) NUMBITS(1) [],
411        /// CEC interface clock enable
412        CEC OFFSET(27) NUMBITS(1) [],
413        /// Power interface clock enable
414        PWREN OFFSET(28) NUMBITS(1) [],
415        /// DAC interface clock enable
416        DACEN OFFSET(29) NUMBITS(1) []
417    ],
418    APB2ENR [
419        /// TIM1 clock enable
420        TIM1EN OFFSET(0) NUMBITS(1) [],
421        /// TIM8 clock enable
422        TIM8EN OFFSET(1) NUMBITS(1) [],
423        /// USART1 clock enable
424        USART1EN OFFSET(4) NUMBITS(1) [],
425        /// USART6 clock enable
426        USART6EN OFFSET(5) NUMBITS(1) [],
427        /// ADC1 clock enable
428        ADC1EN OFFSET(8) NUMBITS(1) [],
429        /// ADC2 clock enable
430        ADC2EN OFFSET(9) NUMBITS(1) [],
431        /// ADC3 clock enable
432        ADC3EN OFFSET(10) NUMBITS(1) [],
433        /// SDIO clock enable
434        SDIOEN OFFSET(11) NUMBITS(1) [],
435        /// SPI1 clock enable
436        SPI1EN OFFSET(12) NUMBITS(1) [],
437        /// SPI4 clock enable
438        SPI4ENR OFFSET(13) NUMBITS(1) [],
439        /// System configuration controller clock enable
440        SYSCFGEN OFFSET(14) NUMBITS(1) [],
441        /// TIM9 clock enable
442        TIM9EN OFFSET(16) NUMBITS(1) [],
443        /// TIM10 clock enable
444        TIM10EN OFFSET(17) NUMBITS(1) [],
445        /// TIM11 clock enable
446        TIM11EN OFFSET(18) NUMBITS(1) [],
447        /// SAI1 clock enable
448        SAI1EN OFFSET(22) NUMBITS(1) [],
449        /// SAI2 clock enable
450        SAI2EN OFFSET(23) NUMBITS(1) []
451    ],
452    AHB1LPENR [
453        /// IO port A clock enable during sleep mode
454        GPIOALPEN OFFSET(0) NUMBITS(1) [],
455        /// IO port B clock enable during Sleep mode
456        GPIOBLPEN OFFSET(1) NUMBITS(1) [],
457        /// IO port C clock enable during Sleep mode
458        GPIOCLPEN OFFSET(2) NUMBITS(1) [],
459        /// IO port D clock enable during Sleep mode
460        GPIODLPEN OFFSET(3) NUMBITS(1) [],
461        /// IO port E clock enable during Sleep mode
462        GPIOELPEN OFFSET(4) NUMBITS(1) [],
463        /// IO port F clock enable during Sleep mode
464        GPIOFLPEN OFFSET(5) NUMBITS(1) [],
465        /// IO port G clock enable during Sleep mode
466        GPIOGLPEN OFFSET(6) NUMBITS(1) [],
467        /// IO port H clock enable during Sleep mode
468        GPIOHLPEN OFFSET(7) NUMBITS(1) [],
469        /// CRC clock enable during Sleep mode
470        CRCLPEN OFFSET(12) NUMBITS(1) [],
471        /// Flash interface clock enable during Sleep mode
472        FLITFLPEN OFFSET(15) NUMBITS(1) [],
473        /// SRAM 1interface clock enable during Sleep mode
474        SRAM1LPEN OFFSET(16) NUMBITS(1) [],
475        /// SRAM 2 interface clock enable during Sleep mode
476        SRAM2LPEN OFFSET(17) NUMBITS(1) [],
477        /// Backup SRAM interface clock enable during Sleep mode
478        BKPSRAMLPEN OFFSET(18) NUMBITS(1) [],
479        /// DMA1 clock enable during Sleep mode
480        DMA1LPEN OFFSET(21) NUMBITS(1) [],
481        /// DMA2 clock enable during Sleep mode
482        DMA2LPEN OFFSET(22) NUMBITS(1) [],
483        /// USB OTG HS clock enable during Sleep mode
484        OTGHSLPEN OFFSET(29) NUMBITS(1) [],
485        /// USB OTG HS ULPI clock enable during Sleep mode
486        OTGHSULPILPEN OFFSET(30) NUMBITS(1) []
487    ],
488    AHB2LPENR [
489        /// USB OTG FS clock enable during Sleep mode
490        OTGFSLPEN OFFSET(7) NUMBITS(1) [],
491        /// RNG clock enable during Sleep mode
492        RNGLPEN OFFSET(6) NUMBITS(1) [],
493        /// Camera interface enable during Sleep mode
494        DCMILPEN OFFSET(0) NUMBITS(1) []
495    ],
496    AHB3LPENR [
497        /// Flexible memory controller module clock enable during Sleep mode
498        FMCLPEN OFFSET(0) NUMBITS(1) [],
499        /// QUADSPI memory controller module clock enable during Sleep mode
500        QSPILPEN OFFSET(1) NUMBITS(1) []
501    ],
502    APB1LPENR [
503        /// TIM2 clock enable during Sleep mode
504        TIM2LPEN OFFSET(0) NUMBITS(1) [],
505        /// TIM3 clock enable during Sleep mode
506        TIM3LPEN OFFSET(1) NUMBITS(1) [],
507        /// TIM4 clock enable during Sleep mode
508        TIM4LPEN OFFSET(2) NUMBITS(1) [],
509        /// TIM5 clock enable during Sleep mode
510        TIM5LPEN OFFSET(3) NUMBITS(1) [],
511        /// TIM6 clock enable during Sleep mode
512        TIM6LPEN OFFSET(4) NUMBITS(1) [],
513        /// TIM7 clock enable during Sleep mode
514        TIM7LPEN OFFSET(5) NUMBITS(1) [],
515        /// TIM12 clock enable during Sleep mode
516        TIM12LPEN OFFSET(6) NUMBITS(1) [],
517        /// TIM13 clock enable during Sleep mode
518        TIM13LPEN OFFSET(7) NUMBITS(1) [],
519        /// TIM14 clock enable during Sleep mode
520        TIM14LPEN OFFSET(8) NUMBITS(1) [],
521        /// Window watchdog clock enable during Sleep mode
522        WWDGLPEN OFFSET(11) NUMBITS(1) [],
523        /// SPI2 clock enable during Sleep mode
524        SPI2LPEN OFFSET(14) NUMBITS(1) [],
525        /// SPI3 clock enable during Sleep mode
526        SPI3LPEN OFFSET(15) NUMBITS(1) [],
527        /// SPDIF clock enable during Sleep mode
528        SPDIFLPEN OFFSET(16) NUMBITS(1) [],
529        /// USART2 clock enable during Sleep mode
530        USART2LPEN OFFSET(17) NUMBITS(1) [],
531        /// USART3 clock enable during Sleep mode
532        USART3LPEN OFFSET(18) NUMBITS(1) [],
533        /// UART4 clock enable during Sleep mode
534        UART4LPEN OFFSET(19) NUMBITS(1) [],
535        /// UART5 clock enable during Sleep mode
536        UART5LPEN OFFSET(20) NUMBITS(1) [],
537        /// I2C1 clock enable during Sleep mode
538        I2C1LPEN OFFSET(21) NUMBITS(1) [],
539        /// I2C2 clock enable during Sleep mode
540        I2C2LPEN OFFSET(22) NUMBITS(1) [],
541        /// I2C3 clock enable during Sleep mode
542        I2C3LPEN OFFSET(23) NUMBITS(1) [],
543        /// I2CFMP1 clock enable during Sleep mode
544        I2CFMP1LPEN OFFSET(24) NUMBITS(1) [],
545        /// CAN 1 clock enable during Sleep mode
546        CAN1LPEN OFFSET(25) NUMBITS(1) [],
547        /// CAN 2 clock enable during Sleep mode
548        CAN2LPEN OFFSET(26) NUMBITS(1) [],
549        /// CEC clock enable during Sleep mode
550        CECLPEN OFFSET(27) NUMBITS(1) [],
551        /// Power interface clock enable during Sleep mode
552        PWRLPEN OFFSET(28) NUMBITS(1) [],
553        /// DAC interface clock enable during Sleep mode
554        DACLPEN OFFSET(29) NUMBITS(1) []
555    ],
556    APB2LPENR [
557        /// TIM1 clock enable during Sleep mode
558        TIM1LPEN OFFSET(0) NUMBITS(1) [],
559        /// TIM8 clock enable during Sleep mode
560        TIM8LPEN OFFSET(1) NUMBITS(1) [],
561        /// USART1 clock enable during Sleep mode
562        USART1LPEN OFFSET(4) NUMBITS(1) [],
563        /// USART6 clock enable during Sleep mode
564        USART6LPEN OFFSET(5) NUMBITS(1) [],
565        /// ADC1 clock enable during Sleep mode
566        ADC1LPEN OFFSET(8) NUMBITS(1) [],
567        /// ADC2 clock enable during Sleep mode
568        ADC2LPEN OFFSET(9) NUMBITS(1) [],
569        /// ADC 3 clock enable during Sleep mode
570        ADC3LPEN OFFSET(10) NUMBITS(1) [],
571        /// SDIO clock enable during Sleep mode
572        SDIOLPEN OFFSET(11) NUMBITS(1) [],
573        /// SPI 1 clock enable during Sleep mode
574        SPI1LPEN OFFSET(12) NUMBITS(1) [],
575        /// SPI 4 clock enable during Sleep mode
576        SPI4LPEN OFFSET(13) NUMBITS(1) [],
577        /// System configuration controller clock enable during Sleep mode
578        SYSCFGLPEN OFFSET(14) NUMBITS(1) [],
579        /// TIM9 clock enable during sleep mode
580        TIM9LPEN OFFSET(16) NUMBITS(1) [],
581        /// TIM10 clock enable during Sleep mode
582        TIM10LPEN OFFSET(17) NUMBITS(1) [],
583        /// TIM11 clock enable during Sleep mode
584        TIM11LPEN OFFSET(18) NUMBITS(1) [],
585        /// SAI1 clock enable
586        SAI1LPEN OFFSET(22) NUMBITS(1) [],
587        /// SAI2 clock enable
588        SAI2LPEN OFFSET(23) NUMBITS(1) []
589    ],
590    BDCR [
591        /// Backup domain software reset
592        BDRST OFFSET(16) NUMBITS(1) [],
593        /// RTC clock enable
594        RTCEN OFFSET(15) NUMBITS(1) [],
595        /// RTC clock source selection
596        RTCSEL OFFSET(8) NUMBITS(2) [],
597        /// External low-speed oscillator mode
598        LSEMOD OFFSET(3) NUMBITS(1) [],
599        /// External low-speed oscillator bypass
600        LSEBYP OFFSET(2) NUMBITS(1) [],
601        /// External low-speed oscillator ready
602        LSERDY OFFSET(1) NUMBITS(1) [],
603        /// External low-speed oscillator enable
604        LSEON OFFSET(0) NUMBITS(1) []
605    ],
606    CSR [
607        /// Low-power reset flag
608        LPWRRSTF OFFSET(31) NUMBITS(1) [],
609        /// Window watchdog reset flag
610        WWDGRSTF OFFSET(30) NUMBITS(1) [],
611        /// Independent watchdog reset flag
612        WDGRSTF OFFSET(29) NUMBITS(1) [],
613        /// Software reset flag
614        SFTRSTF OFFSET(28) NUMBITS(1) [],
615        /// POR/PDR reset flag
616        PORRSTF OFFSET(27) NUMBITS(1) [],
617        /// PIN reset flag
618        PADRSTF OFFSET(26) NUMBITS(1) [],
619        /// BOR reset flag
620        BORRSTF OFFSET(25) NUMBITS(1) [],
621        /// Remove reset flag
622        RMVF OFFSET(24) NUMBITS(1) [],
623        /// Internal low-speed oscillator ready
624        LSIRDY OFFSET(1) NUMBITS(1) [],
625        /// Internal low-speed oscillator enable
626        LSION OFFSET(0) NUMBITS(1) []
627    ],
628    SSCGR [
629        /// Spread spectrum modulation enable
630        SSCGEN OFFSET(31) NUMBITS(1) [],
631        /// Spread Select
632        SPREADSEL OFFSET(30) NUMBITS(1) [],
633        /// Incrementation step
634        INCSTEP OFFSET(13) NUMBITS(15) [],
635        /// Modulation period
636        MODPER OFFSET(0) NUMBITS(13) []
637    ],
638    PLLI2SCFGR [
639        /// Division factor for audio PLL (PLLI2S) input clock
640        PLLI2SM OFFSET(0) NUMBITS(6) [],
641        /// PLLI2S multiplication factor for VCO
642        PLLI2SN OFFSET(6) NUMBITS(9) [],
643        /// PLLI2S division factor for SPDIF-IN clock
644        PLLI2SP OFFSET(16) NUMBITS(2) [],
645        /// PLLI2S division factor for SAI1 clock
646        PLLI2SQ OFFSET(24) NUMBITS(4) [],
647        /// PLLI2S division factor for I2S clocks
648        PLLI2SR OFFSET(28) NUMBITS(3) []
649    ],
650    PLLSAICFGR [
651        /// Division factor for audio PLLSAI input clock
652        PLLSAIM OFFSET(0) NUMBITS(6) [],
653        /// PLLSAI division factor for VCO
654        PLLSAIN OFFSET(6) NUMBITS(9) [],
655        /// PLLSAI division factor for 48 MHz clock
656        PLLSAIP OFFSET(16) NUMBITS(2) [],
657        /// PLLSAI division factor for SAIs clock
658        PLLSAIQ OFFSET(24) NUMBITS(4) []
659    ],
660    DCKCFGR [
661        /// PLLI2S division factor for SAIs clock
662        PLLI2SDIVQ OFFSET(0) NUMBITS(5) [],
663        /// PLLSAI division factor for SAIs clock
664        PLLSAIDIVQ OFFSET(8) NUMBITS(5) [],
665        /// SAI1 clock source selection
666        SAI1SRC OFFSET(20) NUMBITS(2) [],
667        /// SAI2 clock source selection
668        SAI2SRC OFFSET(22) NUMBITS(2) [],
669        /// Timers clocks prescalers selection
670        TIMPRE OFFSET(24) NUMBITS(1) [],
671        /// I2S APB1 clock source selection
672        I2S1SRC OFFSET(25) NUMBITS(2) [],
673        /// I2S APB2 clock source selection
674        I2S2SRC OFFSET(27) NUMBITS(2) []
675    ],
676    CKGATENR [
677        /// AHB to APB1 Bridge clock enable
678        AHB2APB1_CKEN OFFSET(0) NUMBITS(1) [],
679        /// AHB to APB2 Bridge clock enable
680        AHB2APB2_CKEN OFFSET(1) NUMBITS(1) [],
681        /// Cortex M4 ETM clock enable
682        CM4DBG_CKEN OFFSET(2) NUMBITS(1) [],
683        /// Spare clock enable
684        SPARE_CKEN OFFSET(3) NUMBITS(1) [],
685        /// SRQAM controller clock enable
686        SRAM_CKEN OFFSET(4) NUMBITS(1) [],
687        /// Flash Interface clock enable
688        FLITF_CKEN OFFSET(5) NUMBITS(1) [],
689        /// RCC clock enable
690        RCC_CKEN OFFSET(6) NUMBITS(1) []
691    ],
692    DCKCFGR2 [
693        /// I2C4 kernel clock source selection
694        FMPI2C1SEL OFFSET(22) NUMBITS(2) [],
695        /// HDMI CEC clock source selection
696        CECSEL OFFSET(26) NUMBITS(1) [],
697        /// SDIO/USBFS/HS clock selection
698        CK48MSEL OFFSET(27) NUMBITS(1) [],
699        /// SDIO clock selection
700        SDIOSEL OFFSET(28) NUMBITS(1) [],
701        /// SPDIF clock selection
702        SPDIFSEL OFFSET(29) NUMBITS(1) []
703    ]
704];
705
706const RCC_BASE: StaticRef<RccRegisters> =
707    unsafe { StaticRef::new(0x40023800 as *const RccRegisters) };
708
709// Default values when the hardware is reset. Uncomment if you need them.
710//pub(crate) const RESET_PLLM_VALUE: usize = PLLM::DivideBy16; // M = 16
711//pub(crate) const RESET_PLLP_VALUE: PLLP = PLLP::DivideBy2; // P = 2
712//pub(crate) const RESET_PLLQ_VALUE: PLLQ = PLLQ::DivideBy4; // Q = 4
713pub(crate) const RESET_PLLN_VALUE: usize = 0b011_000_000; // N = 192
714
715// Default PLL configuration. See Rcc::init_pll_clock() for more details.
716//
717// Choose PLLM::DivideBy8 for reduced PLL jitter or PLLM::DivideBy16 for default hardware
718// configuration
719pub(crate) const DEFAULT_PLLM_VALUE: PLLM = PLLM::DivideBy8;
720// DON'T CHANGE THIS VALUE
721pub(crate) const DEFAULT_PLLN_VALUE: usize = RESET_PLLN_VALUE;
722// Dynamically computing the default PLLP value based on the PLLM value
723pub(crate) const DEFAULT_PLLP_VALUE: PLLP = match DEFAULT_PLLM_VALUE {
724    PLLM::DivideBy16 => PLLP::DivideBy2,
725    PLLM::DivideBy8 => PLLP::DivideBy4,
726};
727// Dynamically computing the default PLLQ value based on the PLLM value
728pub(crate) const DEFAULT_PLLQ_VALUE: PLLQ = match DEFAULT_PLLM_VALUE {
729    PLLM::DivideBy16 => PLLQ::DivideBy4,
730    PLLM::DivideBy8 => PLLQ::DivideBy8,
731};
732
733pub struct Rcc {
734    registers: StaticRef<RccRegisters>,
735}
736
737pub enum RtcClockSource {
738    LSI,
739    LSE,
740    HSERTC,
741}
742
743impl Rcc {
744    pub fn new() -> Self {
745        let rcc = Self {
746            registers: RCC_BASE,
747        };
748        rcc.init();
749        rcc
750    }
751
752    // Some clocks need to be initialized before use
753    fn init(&self) {
754        self.init_pll_clock();
755    }
756
757    // Init the PLL clock. The default configuration:
758    // + if DEFAULT_PLLM_VALUE == PLLM::DivideBy8:
759    //   + 2MHz VCO input frequency for reduced PLL jitter: freq_VCO_input = freq_source / PLLM
760    //   + 384MHz VCO output frequency: freq_VCO_output = freq_VCO_input * PLLN
761    //   + 96MHz main output frequency: freq_PLL = freq_VCO_output / PLLP
762    //   + 48MHz PLL48CLK output frequency: freq_PLL48CLK = freq_VCO_output / PLLQ
763    // + if DEFAULT_PLLM_VALUE == PLLM::DivideBy16: (default hardware configuration)
764    //   + 1MHz VCO input frequency for reduced PLL jitter: freq_VCO_input = freq_source / PLLM
765    //   + 384MHz VCO output frequency: freq_VCO_output = freq_VCO_input * PLLN
766    //   + 96MHz main output frequency: freq_PLL = freq_VCO_output / PLLP
767    //   + 48MHz PLL48CLK output frequency: freq_PLL48CLK = freq_VCO_output / PLLQ
768    fn init_pll_clock(&self) {
769        self.set_pll_clocks_source(PllSource::HSI);
770        self.set_pll_clocks_m_divider(DEFAULT_PLLM_VALUE);
771        self.set_pll_clock_n_multiplier(DEFAULT_PLLN_VALUE);
772        self.set_pll_clock_p_divider(DEFAULT_PLLP_VALUE);
773        self.set_pll_clock_q_divider(DEFAULT_PLLQ_VALUE);
774    }
775
776    // Get the current system clock source
777    pub(crate) fn get_sys_clock_source(&self) -> SysClockSource {
778        match self.registers.cfgr.read(CFGR::SWS) {
779            0b00 => SysClockSource::HSI,
780            0b01 => SysClockSource::HSE,
781            _ => SysClockSource::PLL,
782            // Uncomment this when PPLLR support is added. Also change the above match arm to
783            // 0b10 => SysClockSource::PLL,
784            //_ => SysClockSource::PPLLR,
785        }
786    }
787
788    // Set the system clock source
789    // The source must be enabled
790    // NOTE: The flash latency also needs to be configured when changing the system clock frequency
791    pub(crate) fn set_sys_clock_source(&self, source: SysClockSource) {
792        self.registers.cfgr.modify(CFGR::SW.val(source as u32));
793    }
794
795    pub(crate) fn is_hsi_clock_system_clock(&self) -> bool {
796        let system_clock_source = self.get_sys_clock_source();
797        system_clock_source == SysClockSource::HSI
798            || system_clock_source == SysClockSource::PLL
799                && self.registers.pllcfgr.read(PLLCFGR::PLLSRC) == PllSource::HSI as u32
800    }
801
802    pub(crate) fn is_hse_clock_system_clock(&self) -> bool {
803        let system_clock_source = self.get_sys_clock_source();
804        system_clock_source == SysClockSource::HSE
805            || system_clock_source == SysClockSource::PLL
806                && self.registers.pllcfgr.read(PLLCFGR::PLLSRC) == PllSource::HSE as u32
807    }
808
809    /* HSI clock */
810    // The HSI clock must not be configured as the system clock, either directly or indirectly.
811    pub(crate) fn disable_hsi_clock(&self) {
812        self.registers.cr.modify(CR::HSION::CLEAR);
813    }
814
815    pub(crate) fn enable_hsi_clock(&self) {
816        self.registers.cr.modify(CR::HSION::SET);
817    }
818
819    pub(crate) fn is_enabled_hsi_clock(&self) -> bool {
820        self.registers.cr.is_set(CR::HSION)
821    }
822
823    // Indicates whether the HSI oscillator is stable
824    pub(crate) fn is_ready_hsi_clock(&self) -> bool {
825        self.registers.cr.is_set(CR::HSIRDY)
826    }
827
828    /* HSE clock */
829    pub(crate) fn disable_hse_clock(&self) {
830        self.registers.cr.modify(CR::HSEON::CLEAR);
831        self.registers.cr.modify(CR::HSEBYP::CLEAR);
832    }
833
834    pub(crate) fn enable_hse_clock_bypass(&self) {
835        self.registers.cr.modify(CR::HSEBYP::SET);
836    }
837
838    pub(crate) fn enable_hse_clock(&self) {
839        self.registers.cr.modify(CR::HSEON::SET);
840    }
841
842    pub(crate) fn is_enabled_hse_clock(&self) -> bool {
843        self.registers.cr.is_set(CR::HSEON)
844    }
845
846    // Indicates whether the HSE oscillator is stable
847    pub(crate) fn is_ready_hse_clock(&self) -> bool {
848        self.registers.cr.is_set(CR::HSERDY)
849    }
850
851    /* Main PLL clock*/
852
853    // The main PLL clock must not be configured as the system clock.
854    pub(crate) fn disable_pll_clock(&self) {
855        self.registers.cr.modify(CR::PLLON::CLEAR);
856    }
857
858    pub(crate) fn enable_pll_clock(&self) {
859        self.registers.cr.modify(CR::PLLON::SET);
860    }
861
862    pub(crate) fn is_enabled_pll_clock(&self) -> bool {
863        self.registers.cr.is_set(CR::PLLON)
864    }
865
866    // The PLL clock is locked when its signal is stable
867    pub(crate) fn is_locked_pll_clock(&self) -> bool {
868        self.registers.cr.is_set(CR::PLLRDY)
869    }
870
871    pub(crate) fn get_pll_clocks_source(&self) -> PllSource {
872        match self.registers.pllcfgr.read(PLLCFGR::PLLSRC) {
873            0b0 => PllSource::HSI,
874            _ => PllSource::HSE,
875        }
876    }
877
878    // This method must be called only when all PLL clocks are disabled
879    pub(crate) fn set_pll_clocks_source(&self, source: PllSource) {
880        self.registers
881            .pllcfgr
882            .modify(PLLCFGR::PLLSRC.val(source as u32));
883    }
884
885    pub(crate) fn get_pll_clocks_m_divider(&self) -> PLLM {
886        match self.registers.pllcfgr.read(PLLCFGR::PLLM) {
887            8 => PLLM::DivideBy8,
888            16 => PLLM::DivideBy16,
889            _ => panic!("Unexpected PLLM divider"),
890        }
891    }
892
893    // This method must be called only when all PLL clocks are disabled
894    pub(crate) fn set_pll_clocks_m_divider(&self, m: PLLM) {
895        self.registers.pllcfgr.modify(PLLCFGR::PLLM.val(m as u32));
896    }
897
898    pub(crate) fn get_pll_clock_n_multiplier(&self) -> usize {
899        self.registers.pllcfgr.read(PLLCFGR::PLLN) as usize
900    }
901
902    // This method must be called only if the main PLL clock is disabled
903    pub(crate) fn set_pll_clock_n_multiplier(&self, n: usize) {
904        self.registers.pllcfgr.modify(PLLCFGR::PLLN.val(n as u32));
905    }
906
907    pub(crate) fn get_pll_clock_p_divider(&self) -> PLLP {
908        match self.registers.pllcfgr.read(PLLCFGR::PLLP) {
909            0b00 => PLLP::DivideBy2,
910            0b01 => PLLP::DivideBy4,
911            0b10 => PLLP::DivideBy6,
912            _ => PLLP::DivideBy8,
913        }
914    }
915
916    // This method must be called only if the main PLL clock is disabled
917    pub(crate) fn set_pll_clock_p_divider(&self, p: PLLP) {
918        self.registers.pllcfgr.modify(PLLCFGR::PLLP.val(p as u32));
919    }
920
921    pub(crate) fn _get_pll_clock_q_divider(&self) -> PLLQ {
922        match self.registers.pllcfgr.read(PLLCFGR::PLLQ) {
923            3 => PLLQ::DivideBy3,
924            4 => PLLQ::DivideBy4,
925            5 => PLLQ::DivideBy5,
926            6 => PLLQ::DivideBy6,
927            7 => PLLQ::DivideBy7,
928            8 => PLLQ::DivideBy8,
929            9 => PLLQ::DivideBy9,
930            _ => panic!("Unexpected PLLQ divider"),
931        }
932    }
933
934    // This method must be called only if the main PLL clock is disabled
935    pub(crate) fn set_pll_clock_q_divider(&self, q: PLLQ) {
936        self.registers.pllcfgr.modify(PLLCFGR::PLLQ.val(q as u32));
937    }
938
939    /* AHB prescaler */
940
941    pub(crate) fn set_ahb_prescaler(&self, ahb_prescaler: AHBPrescaler) {
942        self.registers
943            .cfgr
944            .modify(CFGR::HPRE.val(ahb_prescaler as u32));
945    }
946
947    pub(crate) fn get_ahb_prescaler(&self) -> AHBPrescaler {
948        match self.registers.cfgr.read(CFGR::HPRE) {
949            0b1000 => AHBPrescaler::DivideBy2,
950            0b1001 => AHBPrescaler::DivideBy4,
951            0b1010 => AHBPrescaler::DivideBy8,
952            0b1011 => AHBPrescaler::DivideBy16,
953            0b1100 => AHBPrescaler::DivideBy64,
954            0b1101 => AHBPrescaler::DivideBy128,
955            0b1110 => AHBPrescaler::DivideBy256,
956            0b1111 => AHBPrescaler::DivideBy512,
957            _ => AHBPrescaler::DivideBy1,
958        }
959    }
960
961    /* APB1 prescaler */
962
963    pub(crate) fn set_apb1_prescaler(&self, apb1_prescaler: APBPrescaler) {
964        self.registers
965            .cfgr
966            .modify(CFGR::PPRE1.val(apb1_prescaler as u32));
967    }
968
969    pub(crate) fn get_apb1_prescaler(&self) -> APBPrescaler {
970        match self.registers.cfgr.read(CFGR::PPRE1) {
971            0b100 => APBPrescaler::DivideBy2,
972            0b101 => APBPrescaler::DivideBy4,
973            0b110 => APBPrescaler::DivideBy8,
974            0b111 => APBPrescaler::DivideBy16,
975            _ => APBPrescaler::DivideBy1, // 0b0xx means no division
976        }
977    }
978
979    /* APB2 prescaler */
980
981    pub(crate) fn set_apb2_prescaler(&self, apb2_prescaler: APBPrescaler) {
982        self.registers
983            .cfgr
984            .modify(CFGR::PPRE2.val(apb2_prescaler as u32));
985    }
986
987    pub(crate) fn get_apb2_prescaler(&self) -> APBPrescaler {
988        match self.registers.cfgr.read(CFGR::PPRE2) {
989            0b100 => APBPrescaler::DivideBy2,
990            0b101 => APBPrescaler::DivideBy4,
991            0b110 => APBPrescaler::DivideBy8,
992            0b111 => APBPrescaler::DivideBy16,
993            _ => APBPrescaler::DivideBy1, // 0b0xx means no division
994        }
995    }
996
997    pub(crate) fn set_mco1_clock_source(&self, source: MCO1Source) {
998        self.registers.cfgr.modify(CFGR::MCO1.val(source as u32));
999    }
1000
1001    pub(crate) fn get_mco1_clock_source(&self) -> MCO1Source {
1002        match self.registers.cfgr.read(CFGR::MCO1) {
1003            0b00 => MCO1Source::HSI,
1004            // When LSE or HSE are added, uncomment the following lines
1005            //0b01 => MCO1Source::LSE,
1006            0b10 => MCO1Source::HSE,
1007            // 0b11 corresponds to MCO1Source::PLL
1008            _ => MCO1Source::PLL,
1009        }
1010    }
1011
1012    pub(crate) fn set_mco1_clock_divider(&self, divider: MCO1Divider) {
1013        self.registers
1014            .cfgr
1015            .modify(CFGR::MCO1PRE.val(divider as u32));
1016    }
1017
1018    pub(crate) fn get_mco1_clock_divider(&self) -> MCO1Divider {
1019        match self.registers.cfgr.read(CFGR::MCO1PRE) {
1020            0b100 => MCO1Divider::DivideBy2,
1021            0b101 => MCO1Divider::DivideBy3,
1022            0b110 => MCO1Divider::DivideBy4,
1023            0b111 => MCO1Divider::DivideBy5,
1024            _ => MCO1Divider::DivideBy1,
1025        }
1026    }
1027
1028    pub(crate) fn configure_rng_clock(&self) {
1029        self.registers.pllcfgr.modify(PLLCFGR::PLLQ.val(2));
1030        self.registers.cr.modify(CR::PLLON::SET);
1031    }
1032
1033    // I2C1 clock
1034
1035    pub(crate) fn is_enabled_i2c1_clock(&self) -> bool {
1036        self.registers.apb1enr.is_set(APB1ENR::I2C1EN)
1037    }
1038
1039    pub(crate) fn enable_i2c1_clock(&self) {
1040        self.registers.apb1enr.modify(APB1ENR::I2C1EN::SET);
1041        self.registers.apb1rstr.modify(APB1RSTR::I2C1RST::SET);
1042        self.registers.apb1rstr.modify(APB1RSTR::I2C1RST::CLEAR);
1043    }
1044
1045    pub(crate) fn disable_i2c1_clock(&self) {
1046        self.registers.apb1enr.modify(APB1ENR::I2C1EN::CLEAR)
1047    }
1048
1049    // SPI3 clock
1050
1051    pub(crate) fn is_enabled_spi3_clock(&self) -> bool {
1052        self.registers.apb1enr.is_set(APB1ENR::SPI3EN)
1053    }
1054
1055    pub(crate) fn enable_spi3_clock(&self) {
1056        self.registers.apb1enr.modify(APB1ENR::SPI3EN::SET)
1057    }
1058
1059    pub(crate) fn disable_spi3_clock(&self) {
1060        self.registers.apb1enr.modify(APB1ENR::SPI3EN::CLEAR)
1061    }
1062
1063    // TIM2 clock
1064    pub(crate) fn is_enabled_tim_pre(&self) -> bool {
1065        self.registers.dckcfgr.is_set(DCKCFGR::TIMPRE)
1066    }
1067
1068    pub(crate) fn is_enabled_tim2_clock(&self) -> bool {
1069        self.registers.apb1enr.is_set(APB1ENR::TIM2EN)
1070    }
1071
1072    pub(crate) fn enable_tim2_clock(&self) {
1073        self.registers.apb1enr.modify(APB1ENR::TIM2EN::SET)
1074    }
1075
1076    pub(crate) fn disable_tim2_clock(&self) {
1077        self.registers.apb1enr.modify(APB1ENR::TIM2EN::CLEAR)
1078    }
1079
1080    // SYSCFG clock
1081
1082    pub(crate) fn is_enabled_syscfg_clock(&self) -> bool {
1083        self.registers.apb2enr.is_set(APB2ENR::SYSCFGEN)
1084    }
1085
1086    pub(crate) fn enable_syscfg_clock(&self) {
1087        self.registers.apb2enr.modify(APB2ENR::SYSCFGEN::SET)
1088    }
1089
1090    pub(crate) fn disable_syscfg_clock(&self) {
1091        self.registers.apb2enr.modify(APB2ENR::SYSCFGEN::CLEAR)
1092    }
1093
1094    // DMA1 clock
1095
1096    pub(crate) fn is_enabled_dma1_clock(&self) -> bool {
1097        self.registers.ahb1enr.is_set(AHB1ENR::DMA1EN)
1098    }
1099
1100    pub(crate) fn enable_dma1_clock(&self) {
1101        self.registers.ahb1enr.modify(AHB1ENR::DMA1EN::SET)
1102    }
1103
1104    pub(crate) fn disable_dma1_clock(&self) {
1105        self.registers.ahb1enr.modify(AHB1ENR::DMA1EN::CLEAR)
1106    }
1107
1108    // DMA2 clock
1109    pub(crate) fn is_enabled_dma2_clock(&self) -> bool {
1110        self.registers.ahb1enr.is_set(AHB1ENR::DMA2EN)
1111    }
1112
1113    pub(crate) fn enable_dma2_clock(&self) {
1114        self.registers.ahb1enr.modify(AHB1ENR::DMA2EN::SET)
1115    }
1116
1117    pub(crate) fn disable_dma2_clock(&self) {
1118        self.registers.ahb1enr.modify(AHB1ENR::DMA2EN::CLEAR)
1119    }
1120
1121    // GPIOH clock
1122
1123    pub(crate) fn is_enabled_gpioh_clock(&self) -> bool {
1124        self.registers.ahb1enr.is_set(AHB1ENR::GPIOHEN)
1125    }
1126
1127    pub(crate) fn enable_gpioh_clock(&self) {
1128        self.registers.ahb1enr.modify(AHB1ENR::GPIOHEN::SET)
1129    }
1130
1131    pub(crate) fn disable_gpioh_clock(&self) {
1132        self.registers.ahb1enr.modify(AHB1ENR::GPIOHEN::CLEAR)
1133    }
1134
1135    // GPIOG clock
1136
1137    pub(crate) fn is_enabled_gpiog_clock(&self) -> bool {
1138        self.registers.ahb1enr.is_set(AHB1ENR::GPIOGEN)
1139    }
1140
1141    pub(crate) fn enable_gpiog_clock(&self) {
1142        self.registers.ahb1enr.modify(AHB1ENR::GPIOGEN::SET)
1143    }
1144
1145    pub(crate) fn disable_gpiog_clock(&self) {
1146        self.registers.ahb1enr.modify(AHB1ENR::GPIOGEN::CLEAR)
1147    }
1148
1149    // GPIOF clock
1150
1151    pub(crate) fn is_enabled_gpiof_clock(&self) -> bool {
1152        self.registers.ahb1enr.is_set(AHB1ENR::GPIOFEN)
1153    }
1154
1155    pub(crate) fn enable_gpiof_clock(&self) {
1156        self.registers.ahb1enr.modify(AHB1ENR::GPIOFEN::SET)
1157    }
1158
1159    pub(crate) fn disable_gpiof_clock(&self) {
1160        self.registers.ahb1enr.modify(AHB1ENR::GPIOFEN::CLEAR)
1161    }
1162
1163    // GPIOE clock
1164
1165    pub(crate) fn is_enabled_gpioe_clock(&self) -> bool {
1166        self.registers.ahb1enr.is_set(AHB1ENR::GPIOEEN)
1167    }
1168
1169    pub(crate) fn enable_gpioe_clock(&self) {
1170        self.registers.ahb1enr.modify(AHB1ENR::GPIOEEN::SET)
1171    }
1172
1173    pub(crate) fn disable_gpioe_clock(&self) {
1174        self.registers.ahb1enr.modify(AHB1ENR::GPIOEEN::CLEAR)
1175    }
1176
1177    // GPIOD clock
1178
1179    pub(crate) fn is_enabled_gpiod_clock(&self) -> bool {
1180        self.registers.ahb1enr.is_set(AHB1ENR::GPIODEN)
1181    }
1182
1183    pub(crate) fn enable_gpiod_clock(&self) {
1184        self.registers.ahb1enr.modify(AHB1ENR::GPIODEN::SET)
1185    }
1186
1187    pub(crate) fn disable_gpiod_clock(&self) {
1188        self.registers.ahb1enr.modify(AHB1ENR::GPIODEN::CLEAR)
1189    }
1190
1191    // GPIOC clock
1192
1193    pub(crate) fn is_enabled_gpioc_clock(&self) -> bool {
1194        self.registers.ahb1enr.is_set(AHB1ENR::GPIOCEN)
1195    }
1196
1197    pub(crate) fn enable_gpioc_clock(&self) {
1198        self.registers.ahb1enr.modify(AHB1ENR::GPIOCEN::SET)
1199    }
1200
1201    pub(crate) fn disable_gpioc_clock(&self) {
1202        self.registers.ahb1enr.modify(AHB1ENR::GPIOCEN::CLEAR)
1203    }
1204
1205    // GPIOB clock
1206
1207    pub(crate) fn is_enabled_gpiob_clock(&self) -> bool {
1208        self.registers.ahb1enr.is_set(AHB1ENR::GPIOBEN)
1209    }
1210
1211    pub(crate) fn enable_gpiob_clock(&self) {
1212        self.registers.ahb1enr.modify(AHB1ENR::GPIOBEN::SET)
1213    }
1214
1215    pub(crate) fn disable_gpiob_clock(&self) {
1216        self.registers.ahb1enr.modify(AHB1ENR::GPIOBEN::CLEAR)
1217    }
1218
1219    // GPIOA clock
1220
1221    pub(crate) fn is_enabled_gpioa_clock(&self) -> bool {
1222        self.registers.ahb1enr.is_set(AHB1ENR::GPIOAEN)
1223    }
1224
1225    pub(crate) fn enable_gpioa_clock(&self) {
1226        self.registers.ahb1enr.modify(AHB1ENR::GPIOAEN::SET)
1227    }
1228
1229    pub(crate) fn disable_gpioa_clock(&self) {
1230        self.registers.ahb1enr.modify(AHB1ENR::GPIOAEN::CLEAR)
1231    }
1232
1233    // FMC
1234
1235    pub(crate) fn is_enabled_fmc_clock(&self) -> bool {
1236        self.registers.ahb3enr.is_set(AHB3ENR::FMCEN)
1237    }
1238
1239    pub(crate) fn enable_fmc_clock(&self) {
1240        self.registers.ahb3enr.modify(AHB3ENR::FMCEN::SET)
1241    }
1242
1243    pub(crate) fn disable_fmc_clock(&self) {
1244        self.registers.ahb3enr.modify(AHB3ENR::FMCEN::CLEAR)
1245    }
1246
1247    // USART1 clock
1248    pub(crate) fn is_enabled_usart1_clock(&self) -> bool {
1249        self.registers.apb2enr.is_set(APB2ENR::USART1EN)
1250    }
1251
1252    pub(crate) fn enable_usart1_clock(&self) {
1253        self.registers.apb2enr.modify(APB2ENR::USART1EN::SET)
1254    }
1255
1256    pub(crate) fn disable_usart1_clock(&self) {
1257        self.registers.apb2enr.modify(APB2ENR::USART1EN::CLEAR)
1258    }
1259
1260    // USART2 clock
1261
1262    pub(crate) fn is_enabled_usart2_clock(&self) -> bool {
1263        self.registers.apb1enr.is_set(APB1ENR::USART2EN)
1264    }
1265
1266    pub(crate) fn enable_usart2_clock(&self) {
1267        self.registers.apb1enr.modify(APB1ENR::USART2EN::SET)
1268    }
1269
1270    pub(crate) fn disable_usart2_clock(&self) {
1271        self.registers.apb1enr.modify(APB1ENR::USART2EN::CLEAR)
1272    }
1273
1274    // USART3 clock
1275
1276    pub(crate) fn is_enabled_usart3_clock(&self) -> bool {
1277        self.registers.apb1enr.is_set(APB1ENR::USART3EN)
1278    }
1279
1280    pub(crate) fn enable_usart3_clock(&self) {
1281        self.registers.apb1enr.modify(APB1ENR::USART3EN::SET)
1282    }
1283
1284    pub(crate) fn disable_usart3_clock(&self) {
1285        self.registers.apb1enr.modify(APB1ENR::USART3EN::CLEAR)
1286    }
1287
1288    // ADC1 clock
1289
1290    pub(crate) fn is_enabled_adc1_clock(&self) -> bool {
1291        self.registers.apb2enr.is_set(APB2ENR::ADC1EN)
1292    }
1293
1294    pub(crate) fn enable_adc1_clock(&self) {
1295        self.registers.apb2enr.modify(APB2ENR::ADC1EN::SET)
1296    }
1297
1298    pub(crate) fn disable_adc1_clock(&self) {
1299        self.registers.apb2enr.modify(APB2ENR::ADC1EN::CLEAR)
1300    }
1301
1302    // DAC clock
1303
1304    pub(crate) fn is_enabled_dac_clock(&self) -> bool {
1305        self.registers.apb1enr.is_set(APB1ENR::DACEN)
1306    }
1307
1308    pub(crate) fn enable_dac_clock(&self) {
1309        self.registers.apb1enr.modify(APB1ENR::DACEN::SET)
1310    }
1311
1312    pub(crate) fn disable_dac_clock(&self) {
1313        self.registers.apb1enr.modify(APB1ENR::DACEN::CLEAR)
1314    }
1315
1316    // RNG clock
1317
1318    pub(crate) fn is_enabled_rng_clock(&self) -> bool {
1319        self.registers.ahb2enr.is_set(AHB2ENR::RNGEN)
1320    }
1321
1322    pub(crate) fn enable_rng_clock(&self) {
1323        self.registers.ahb2enr.modify(AHB2ENR::RNGEN::SET);
1324    }
1325
1326    pub(crate) fn disable_rng_clock(&self) {
1327        self.registers.ahb2enr.modify(AHB2ENR::RNGEN::CLEAR);
1328    }
1329
1330    // OTGFS clock
1331
1332    pub(crate) fn is_enabled_otgfs_clock(&self) -> bool {
1333        self.registers.ahb2enr.is_set(AHB2ENR::OTGFSEN)
1334    }
1335
1336    pub(crate) fn enable_otgfs_clock(&self) {
1337        self.registers.ahb2enr.modify(AHB2ENR::OTGFSEN::SET);
1338    }
1339
1340    pub(crate) fn disable_otgfs_clock(&self) {
1341        self.registers.ahb2enr.modify(AHB2ENR::OTGFSEN::CLEAR);
1342    }
1343
1344    // CAN1 clock
1345
1346    pub(crate) fn is_enabled_can1_clock(&self) -> bool {
1347        self.registers.apb1enr.is_set(APB1ENR::CAN1EN)
1348    }
1349
1350    pub(crate) fn enable_can1_clock(&self) {
1351        self.registers.apb1rstr.modify(APB1RSTR::CAN1RST::SET);
1352        self.registers.apb1rstr.modify(APB1RSTR::CAN1RST::CLEAR);
1353        self.registers.apb1enr.modify(APB1ENR::CAN1EN::SET);
1354    }
1355
1356    pub(crate) fn disable_can1_clock(&self) {
1357        self.registers.apb1enr.modify(APB1ENR::CAN1EN::CLEAR);
1358    }
1359
1360    // RTC clock
1361    pub(crate) fn source_into_u32(source: RtcClockSource) -> u32 {
1362        match source {
1363            RtcClockSource::LSE => 1,
1364            RtcClockSource::LSI => 2,
1365            RtcClockSource::HSERTC => 3,
1366        }
1367    }
1368
1369    pub(crate) fn enable_lsi_clock(&self) {
1370        self.registers.csr.modify(CSR::LSION::SET);
1371    }
1372
1373    pub(crate) fn is_enabled_pwr_clock(&self) -> bool {
1374        self.registers.apb1enr.is_set(APB1ENR::PWREN)
1375    }
1376
1377    pub(crate) fn enable_pwr_clock(&self) {
1378        // Enable the power interface clock
1379        self.registers.apb1enr.modify(APB1ENR::PWREN::SET);
1380    }
1381
1382    pub(crate) fn disable_pwr_clock(&self) {
1383        self.registers.apb1enr.modify(APB1ENR::PWREN::CLEAR);
1384    }
1385
1386    pub(crate) fn is_enabled_rtc_clock(&self) -> bool {
1387        self.registers.bdcr.is_set(BDCR::RTCEN)
1388    }
1389
1390    pub(crate) fn enable_rtc_clock(&self, source: RtcClockSource) {
1391        // Enable LSI
1392        self.enable_lsi_clock();
1393        let mut counter = 1_000;
1394        while counter > 0 && !self.registers.csr.is_set(CSR::LSION) {
1395            counter -= 1;
1396        }
1397        if counter == 0 {
1398            panic!("Unable to activate lsi clock");
1399        }
1400
1401        // Select RTC clock source
1402        let source_num = Rcc::source_into_u32(source);
1403        self.registers.bdcr.modify(BDCR::RTCSEL.val(source_num));
1404
1405        // Enable RTC clock
1406        self.registers.bdcr.modify(BDCR::RTCEN::SET);
1407    }
1408
1409    pub(crate) fn disable_rtc_clock(&self) {
1410        self.registers.bdcr.modify(BDCR::RTCEN.val(1));
1411        self.registers.bdcr.modify(BDCR::RTCSEL.val(0));
1412    }
1413}
1414
1415#[derive(Copy, Clone, Debug, PartialEq)]
1416pub(crate) enum PLLP {
1417    DivideBy2 = 0b00,
1418    DivideBy4 = 0b01,
1419    DivideBy6 = 0b10,
1420    DivideBy8 = 0b11,
1421}
1422
1423impl From<PLLP> for usize {
1424    // (variant_value + 1) * 2 = X for X in DivideByX
1425    fn from(item: PLLP) -> Self {
1426        (item as usize + 1) << 1
1427    }
1428}
1429
1430// Theoretically, the PLLM value can range from 2 to 63. However, the current implementation was
1431// designed to support 1MHz frequency precision. In a future update, PLLM will become a usize.
1432#[allow(dead_code)]
1433pub(crate) enum PLLM {
1434    DivideBy8 = 8,
1435    DivideBy16 = 16,
1436}
1437
1438#[derive(Copy, Clone, Debug, PartialEq)]
1439// Due to the restricted values for PLLM, PLLQ 2/10-15 values are meaningless.
1440pub(crate) enum PLLQ {
1441    DivideBy3 = 3,
1442    DivideBy4,
1443    DivideBy5,
1444    DivideBy6,
1445    DivideBy7,
1446    DivideBy8,
1447    DivideBy9,
1448}
1449
1450/// Clock sources for the CPU
1451#[derive(Clone, Copy, PartialEq, Debug)]
1452pub enum SysClockSource {
1453    HSI = 0b00,
1454    HSE = 0b01,
1455    PLL = 0b10,
1456    // NOTE: not all STM32F4xx boards support this source.
1457    //PPLLR = 0b11, Uncomment this when support for PPLLR is added
1458}
1459
1460pub enum PllSource {
1461    HSI = 0b0,
1462    HSE = 0b1,
1463}
1464
1465pub enum MCO1Source {
1466    HSI = 0b00,
1467    //LSE = 0b01, // When support for LSE is added, uncomment this
1468    HSE = 0b10,
1469    PLL = 0b11,
1470}
1471
1472pub enum MCO1Divider {
1473    DivideBy1 = 0b000,
1474    DivideBy2 = 0b100,
1475    DivideBy3 = 0b101,
1476    DivideBy4 = 0b110,
1477    DivideBy5 = 0b111,
1478}
1479
1480/// HSE Mode
1481#[derive(PartialEq)]
1482pub enum HseMode {
1483    BYPASS,
1484    CRYSTAL,
1485}
1486
1487#[derive(Clone, Copy, PartialEq, Debug)]
1488pub enum AHBPrescaler {
1489    DivideBy1 = 0b0000,
1490    DivideBy2 = 0b1000,
1491    DivideBy4 = 0b1001,
1492    DivideBy8 = 0b1010,
1493    DivideBy16 = 0b1011,
1494    DivideBy64 = 0b1100,
1495    DivideBy128 = 0b1101,
1496    DivideBy256 = 0b1110,
1497    DivideBy512 = 0b1111,
1498}
1499
1500impl From<AHBPrescaler> for usize {
1501    fn from(item: AHBPrescaler) -> usize {
1502        match item {
1503            AHBPrescaler::DivideBy1 => 1,
1504            AHBPrescaler::DivideBy2 => 2,
1505            AHBPrescaler::DivideBy4 => 4,
1506            AHBPrescaler::DivideBy8 => 8,
1507            AHBPrescaler::DivideBy16 => 16,
1508            AHBPrescaler::DivideBy64 => 64,
1509            AHBPrescaler::DivideBy128 => 128,
1510            AHBPrescaler::DivideBy256 => 256,
1511            AHBPrescaler::DivideBy512 => 512,
1512        }
1513    }
1514}
1515
1516#[derive(Clone, Copy, PartialEq, Debug)]
1517pub enum APBPrescaler {
1518    DivideBy1 = 0b000, // No division
1519    DivideBy2 = 0b100,
1520    DivideBy4 = 0b101,
1521    DivideBy8 = 0b110,
1522    DivideBy16 = 0b111,
1523}
1524
1525impl From<APBPrescaler> for usize {
1526    fn from(item: APBPrescaler) -> Self {
1527        match item {
1528            APBPrescaler::DivideBy1 => 1,
1529            APBPrescaler::DivideBy2 => 2,
1530            APBPrescaler::DivideBy4 => 4,
1531            APBPrescaler::DivideBy8 => 8,
1532            APBPrescaler::DivideBy16 => 16,
1533        }
1534    }
1535}