libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
rcc.c
Go to the documentation of this file.
1/** @defgroup rcc_file RCC peripheral API
2 *
3 * @ingroup peripheral_apis
4 *
5 * @section rcc_f4_api_ex Reset and Clock Control API.
6 *
7 * @brief <b>libopencm3 STM32F4xx Reset and Clock Control</b>
8 *
9 * @author @htmlonly &copy; @endhtmlonly 2013 Frantisek Burian <BuFran at seznam.cz>
10 *
11 * @date 18 Jun 2013
12 *
13 * This library supports the Reset and Clock Control System in the STM32 series
14 * of ARM Cortex Microcontrollers by ST Microelectronics.
15 *
16 * LGPL License Terms @ref lgpl_license
17 */
18
19/*
20 * This file is part of the libopencm3 project.
21 *
22 * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com>
23 * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
24 * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
25 *
26 * This library is free software: you can redistribute it and/or modify
27 * it under the terms of the GNU Lesser General Public License as published by
28 * the Free Software Foundation, either version 3 of the License, or
29 * (at your option) any later version.
30 *
31 * This library is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU Lesser General Public License for more details.
35 *
36 * You should have received a copy of the GNU Lesser General Public License
37 * along with this library. If not, see <http://www.gnu.org/licenses/>.
38 */
39
44
45/**@{*/
46
47/* Set the default clock frequencies after reset. */
48uint32_t rcc_ahb_frequency = 16000000;
49uint32_t rcc_apb1_frequency = 16000000;
50uint32_t rcc_apb2_frequency = 16000000;
51
53 { /* 84MHz */
54 .pllm = 16,
55 .plln = 336,
56 .pllp = 4,
57 .pllq = 7,
58 .pllr = 0,
59 .pll_source = RCC_CFGR_PLLSRC_HSI_CLK,
60 .hpre = RCC_CFGR_HPRE_NODIV,
61 .ppre1 = RCC_CFGR_PPRE_DIV2,
62 .ppre2 = RCC_CFGR_PPRE_NODIV,
63 .voltage_scale = PWR_SCALE1,
64 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
66 .ahb_frequency = 84000000,
67 .apb1_frequency = 42000000,
68 .apb2_frequency = 84000000,
69 },
70 { /* 96MHz */
71 .pllm = 8,
72 .plln = 96,
73 .pllp = 2,
74 .pllq = 4,
75 .pllr = 0,
76 .pll_source = RCC_CFGR_PLLSRC_HSI_CLK,
78 .ppre1 = RCC_CFGR_PPRE_DIV_2,
80 .voltage_scale = PWR_SCALE1,
82 .ahb_frequency = 96000000,
83 .apb1_frequency = 48000000,
84 .apb2_frequency = 96000000
85 },
86 { /* 168MHz */
87 .pllm = 16,
88 .plln = 336,
89 .pllp = 2,
90 .pllq = 7,
91 .pllr = 0,
92 .pll_source = RCC_CFGR_PLLSRC_HSI_CLK,
93 .hpre = RCC_CFGR_HPRE_NODIV,
94 .ppre1 = RCC_CFGR_PPRE_DIV4,
95 .ppre2 = RCC_CFGR_PPRE_DIV2,
96 .voltage_scale = PWR_SCALE1,
97 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
99 .ahb_frequency = 168000000,
100 .apb1_frequency = 42000000,
101 .apb2_frequency = 84000000,
102 },
103 { /* 180MHz */
104 .pllm = 16,
105 .plln = 360,
106 .pllp = 2,
107 .pllq = 8,
108 .pllr = 0,
109 .pll_source = RCC_CFGR_PLLSRC_HSI_CLK,
110 .hpre = RCC_CFGR_HPRE_NODIV,
111 .ppre1 = RCC_CFGR_PPRE_DIV4,
112 .ppre2 = RCC_CFGR_PPRE_DIV2,
113 .voltage_scale = PWR_SCALE1,
114 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
116 .ahb_frequency = 180000000,
117 .apb1_frequency = 45000000,
118 .apb2_frequency = 90000000,
119 },
120};
121
123 { /* 84MHz */
124 .pllm = 8,
125 .plln = 336,
126 .pllp = 4,
127 .pllq = 7,
128 .pllr = 0,
129 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
130 .hpre = RCC_CFGR_HPRE_NODIV,
131 .ppre1 = RCC_CFGR_PPRE_DIV2,
132 .ppre2 = RCC_CFGR_PPRE_NODIV,
133 .voltage_scale = PWR_SCALE1,
134 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
136 .ahb_frequency = 84000000,
137 .apb1_frequency = 42000000,
138 .apb2_frequency = 84000000,
139 },
140 { /* 96MHz */
141 .pllm = 4,
142 .plln = 96,
143 .pllp = 2,
144 .pllq = 4,
145 .pllr = 0,
146 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
148 .ppre1 = RCC_CFGR_PPRE_DIV_2,
149 .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
150 .voltage_scale = PWR_SCALE1,
152 .ahb_frequency = 96000000,
153 .apb1_frequency = 48000000,
154 .apb2_frequency = 96000000
155 },
156 { /* 168MHz */
157 .pllm = 8,
158 .plln = 336,
159 .pllp = 2,
160 .pllq = 7,
161 .pllr = 0,
162 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
163 .hpre = RCC_CFGR_HPRE_NODIV,
164 .ppre1 = RCC_CFGR_PPRE_DIV4,
165 .ppre2 = RCC_CFGR_PPRE_DIV2,
166 .voltage_scale = PWR_SCALE1,
167 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
169 .ahb_frequency = 168000000,
170 .apb1_frequency = 42000000,
171 .apb2_frequency = 84000000,
172 },
173 { /* 180MHz */
174 .pllm = 8,
175 .plln = 360,
176 .pllp = 2,
177 .pllq = 8,
178 .pllr = 0,
179 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
180 .hpre = RCC_CFGR_HPRE_NODIV,
181 .ppre1 = RCC_CFGR_PPRE_DIV4,
182 .ppre2 = RCC_CFGR_PPRE_DIV2,
183 .voltage_scale = PWR_SCALE1,
184 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
186 .ahb_frequency = 180000000,
187 .apb1_frequency = 45000000,
188 .apb2_frequency = 90000000,
189 },
190};
191
193 { /* 84MHz */
194 .pllm = 12,
195 .plln = 336,
196 .pllp = 4,
197 .pllq = 7,
198 .pllr = 0,
199 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
200 .hpre = RCC_CFGR_HPRE_NODIV,
201 .ppre1 = RCC_CFGR_PPRE_DIV2,
202 .ppre2 = RCC_CFGR_PPRE_NODIV,
203 .voltage_scale = PWR_SCALE1,
204 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
206 .ahb_frequency = 84000000,
207 .apb1_frequency = 42000000,
208 .apb2_frequency = 84000000,
209 },
210 { /* 96MHz */
211 .pllm = 6,
212 .plln = 96,
213 .pllp = 2,
214 .pllq = 4,
215 .pllr = 0,
216 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
218 .ppre1 = RCC_CFGR_PPRE_DIV_2,
219 .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
220 .voltage_scale = PWR_SCALE1,
222 .ahb_frequency = 96000000,
223 .apb1_frequency = 48000000,
224 .apb2_frequency = 96000000
225 },
226 { /* 168MHz */
227 .pllm = 12,
228 .plln = 336,
229 .pllp = 2,
230 .pllq = 7,
231 .pllr = 0,
232 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
233 .hpre = RCC_CFGR_HPRE_NODIV,
234 .ppre1 = RCC_CFGR_PPRE_DIV4,
235 .ppre2 = RCC_CFGR_PPRE_DIV2,
236 .voltage_scale = PWR_SCALE1,
237 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
239 .ahb_frequency = 168000000,
240 .apb1_frequency = 42000000,
241 .apb2_frequency = 84000000,
242 },
243 { /* 180MHz */
244 .pllm = 12,
245 .plln = 360,
246 .pllp = 2,
247 .pllq = 8,
248 .pllr = 0,
249 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
250 .hpre = RCC_CFGR_HPRE_NODIV,
251 .ppre1 = RCC_CFGR_PPRE_DIV4,
252 .ppre2 = RCC_CFGR_PPRE_DIV2,
253 .voltage_scale = PWR_SCALE1,
254 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
256 .ahb_frequency = 180000000,
257 .apb1_frequency = 45000000,
258 .apb2_frequency = 90000000,
259 },
260};
261
263 { /* 84MHz */
264 .pllm = 16,
265 .plln = 336,
266 .pllp = 4,
267 .pllq = 7,
268 .pllr = 0,
269 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
270 .hpre = RCC_CFGR_HPRE_NODIV,
271 .ppre1 = RCC_CFGR_PPRE_DIV2,
272 .ppre2 = RCC_CFGR_PPRE_NODIV,
273 .voltage_scale = PWR_SCALE1,
274 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
276 .ahb_frequency = 84000000,
277 .apb1_frequency = 42000000,
278 .apb2_frequency = 84000000,
279 },
280 { /* 96MHz */
281 .pllm = 8,
282 .plln = 96,
283 .pllp = 2,
284 .pllq = 4,
285 .pllr = 0,
286 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
288 .ppre1 = RCC_CFGR_PPRE_DIV_2,
289 .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
290 .voltage_scale = PWR_SCALE1,
292 .ahb_frequency = 96000000,
293 .apb1_frequency = 48000000,
294 .apb2_frequency = 96000000
295 },
296 { /* 168MHz */
297 .pllm = 16,
298 .plln = 336,
299 .pllp = 2,
300 .pllq = 7,
301 .pllr = 0,
302 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
303 .hpre = RCC_CFGR_HPRE_NODIV,
304 .ppre1 = RCC_CFGR_PPRE_DIV4,
305 .ppre2 = RCC_CFGR_PPRE_DIV2,
306 .voltage_scale = PWR_SCALE1,
307 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
309 .ahb_frequency = 168000000,
310 .apb1_frequency = 42000000,
311 .apb2_frequency = 84000000,
312 },
313 { /* 180MHz */
314 .pllm = 16,
315 .plln = 360,
316 .pllp = 2,
317 .pllq = 8,
318 .pllr = 0,
319 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
320 .hpre = RCC_CFGR_HPRE_NODIV,
321 .ppre1 = RCC_CFGR_PPRE_DIV4,
322 .ppre2 = RCC_CFGR_PPRE_DIV2,
323 .voltage_scale = PWR_SCALE1,
324 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
326 .ahb_frequency = 180000000,
327 .apb1_frequency = 45000000,
328 .apb2_frequency = 90000000,
329 },
330};
331
333 { /* 84MHz */
334 .pllm = 25,
335 .plln = 336,
336 .pllp = 4,
337 .pllq = 7,
338 .pllr = 0,
339 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
340 .hpre = RCC_CFGR_HPRE_NODIV,
341 .ppre1 = RCC_CFGR_PPRE_DIV2,
342 .ppre2 = RCC_CFGR_PPRE_NODIV,
343 .voltage_scale = PWR_SCALE1,
344 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
346 .ahb_frequency = 84000000,
347 .apb1_frequency = 42000000,
348 .apb2_frequency = 84000000,
349 },
350 { /* 96MHz */
351 .pllm = 25,
352 .plln = 192,
353 .pllp = 2,
354 .pllq = 4,
355 .pllr = 0,
356 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
358 .ppre1 = RCC_CFGR_PPRE_DIV_2,
359 .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
360 .voltage_scale = PWR_SCALE1,
362 .ahb_frequency = 96000000,
363 .apb1_frequency = 48000000,
364 .apb2_frequency = 96000000
365 },
366 { /* 168MHz */
367 .pllm = 25,
368 .plln = 336,
369 .pllp = 2,
370 .pllq = 7,
371 .pllr = 0,
372 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
373 .hpre = RCC_CFGR_HPRE_NODIV,
374 .ppre1 = RCC_CFGR_PPRE_DIV4,
375 .ppre2 = RCC_CFGR_PPRE_DIV2,
376 .voltage_scale = PWR_SCALE1,
377 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
379 .ahb_frequency = 168000000,
380 .apb1_frequency = 42000000,
381 .apb2_frequency = 84000000,
382 },
383 { /* 180MHz */
384 .pllm = 25,
385 .plln = 360,
386 .pllp = 2,
387 .pllq = 8,
388 .pllr = 0,
389 .pll_source = RCC_CFGR_PLLSRC_HSE_CLK,
390 .hpre = RCC_CFGR_HPRE_NODIV,
391 .ppre1 = RCC_CFGR_PPRE_DIV4,
392 .ppre2 = RCC_CFGR_PPRE_DIV2,
393 .voltage_scale = PWR_SCALE1,
394 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
396 .ahb_frequency = 180000000,
397 .apb1_frequency = 45000000,
398 .apb2_frequency = 90000000,
399 },
400};
401
403{
404 switch (osc) {
405 case RCC_PLL:
407 break;
408 case RCC_HSE:
410 break;
411 case RCC_HSI:
413 break;
414 case RCC_LSE:
416 break;
417 case RCC_LSI:
419 break;
420 case RCC_PLLSAI:
422 break;
423 case RCC_PLLI2S:
425 break;
426 }
427}
428
430{
431 switch (osc) {
432 case RCC_PLL:
434 break;
435 case RCC_HSE:
437 break;
438 case RCC_HSI:
440 break;
441 case RCC_LSE:
443 break;
444 case RCC_LSI:
446 break;
447 case RCC_PLLSAI:
449 break;
450 case RCC_PLLI2S:
452 break;
453 }
454}
455
457{
458 switch (osc) {
459 case RCC_PLL:
460 RCC_CIR &= ~RCC_CIR_PLLRDYIE;
461 break;
462 case RCC_HSE:
463 RCC_CIR &= ~RCC_CIR_HSERDYIE;
464 break;
465 case RCC_HSI:
466 RCC_CIR &= ~RCC_CIR_HSIRDYIE;
467 break;
468 case RCC_LSE:
469 RCC_CIR &= ~RCC_CIR_LSERDYIE;
470 break;
471 case RCC_LSI:
472 RCC_CIR &= ~RCC_CIR_LSIRDYIE;
473 break;
474 case RCC_PLLSAI:
475 RCC_CIR &= ~RCC_CIR_PLLSAIRDYIE;
476 break;
477 case RCC_PLLI2S:
478 RCC_CIR &= ~RCC_CIR_PLLI2SRDYIE;
479 break;
480 }
481}
482
484{
485 switch (osc) {
486 case RCC_PLL:
487 return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
488 case RCC_HSE:
489 return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
490 case RCC_HSI:
491 return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0);
492 case RCC_LSE:
493 return ((RCC_CIR & RCC_CIR_LSERDYF) != 0);
494 case RCC_LSI:
495 return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0);
496 case RCC_PLLSAI:
497 return ((RCC_CIR & RCC_CIR_PLLSAIRDYF) != 0);
498 case RCC_PLLI2S:
499 return ((RCC_CIR & RCC_CIR_PLLI2SRDYF) != 0);
500 }
501 return 0;
502}
503
505{
507}
508
510{
511 return ((RCC_CIR & RCC_CIR_CSSF) != 0);
512}
513
515{
516 switch (osc) {
517 case RCC_PLL:
518 return RCC_CR & RCC_CR_PLLRDY;
519 case RCC_HSE:
520 return RCC_CR & RCC_CR_HSERDY;
521 case RCC_HSI:
522 return RCC_CR & RCC_CR_HSIRDY;
523 case RCC_LSE:
524 return RCC_BDCR & RCC_BDCR_LSERDY;
525 case RCC_LSI:
526 return RCC_CSR & RCC_CSR_LSIRDY;
527 case RCC_PLLSAI:
528 return RCC_CR & RCC_CR_PLLSAIRDY;
529 case RCC_PLLI2S:
530 return RCC_CR & RCC_CR_PLLI2SRDY;
531 }
532 return false;
533}
534
536{
537 while (!rcc_is_osc_ready(osc));
538}
539
541{
542 switch (osc) {
543 case RCC_PLL:
546 break;
547 case RCC_HSE:
550 break;
551 case RCC_HSI:
554 break;
555 default:
556 /* Shouldn't be reached. */
557 break;
558 }
559}
560
561void rcc_osc_on(enum rcc_osc osc)
562{
563 switch (osc) {
564 case RCC_PLL:
566 break;
567 case RCC_HSE:
569 break;
570 case RCC_HSI:
572 break;
573 case RCC_LSE:
575 break;
576 case RCC_LSI:
578 break;
579 case RCC_PLLSAI:
581 break;
582 case RCC_PLLI2S:
584 break;
585 }
586}
587
588void rcc_osc_off(enum rcc_osc osc)
589{
590 switch (osc) {
591 case RCC_PLL:
592 RCC_CR &= ~RCC_CR_PLLON;
593 break;
594 case RCC_HSE:
595 RCC_CR &= ~RCC_CR_HSEON;
596 break;
597 case RCC_HSI:
598 RCC_CR &= ~RCC_CR_HSION;
599 break;
600 case RCC_LSE:
601 RCC_BDCR &= ~RCC_BDCR_LSEON;
602 break;
603 case RCC_LSI:
604 RCC_CSR &= ~RCC_CSR_LSION;
605 break;
606 case RCC_PLLSAI:
607 RCC_CR &= ~RCC_CR_PLLSAION;
608 break;
609 case RCC_PLLI2S:
610 RCC_CR &= ~RCC_CR_PLLI2SON;
611 break;
612 }
613}
614
616{
618}
619
621{
622 RCC_CR &= ~RCC_CR_CSSON;
623}
624
625/**
626 * Set the dividers for the PLLI2S clock outputs
627 * @param n valid range depends on target device, check your RefManual.
628 * @param r valid range is 2..7
629 */
630void rcc_plli2s_config(uint16_t n, uint8_t r)
631{
635}
636
637/**
638 * Set the dividers for the PLLSAI clock outputs
639 * divider p is only available on F4x9 parts, pass 0 for other parts.
640 * @param n valid range is 49..432
641 * @param p 0 if unused, @ref rcc_pllsaicfgr_pllsaip
642 * @param q valid range is 2..15
643 * @param r valid range is 2..7
644 * @sa rcc_pllsai_postscalers
645 */
646void rcc_pllsai_config(uint16_t n, uint16_t p, uint16_t q, uint16_t r)
647{
653}
654
655
656/**
657 * Set the dedicated dividers after the PLLSAI configuration.
658 *
659 * @param q dedicated PLLSAI divider, for either A or B
660 * @param r dedicated LCD-TFT divider, see LTDC
661 * @sa rcc_pllsai_config
662 */
663void rcc_pllsai_postscalers(uint8_t q, uint8_t r)
664{
665 uint32_t reg32 = RCC_DCKCFGR;
668 RCC_DCKCFGR = reg32 | ((q << RCC_DCKCFGR_PLLSAIDIVQ_SHIFT) |
670}
671
672
673void rcc_set_sysclk_source(uint32_t clk)
674{
675 uint32_t reg32;
676
677 reg32 = RCC_CFGR;
678 reg32 &= ~((1 << 1) | (1 << 0));
679 RCC_CFGR = (reg32 | clk);
680}
681
682void rcc_set_pll_source(uint32_t pllsrc)
683{
684 uint32_t reg32;
685
686 reg32 = RCC_PLLCFGR;
687 reg32 &= ~(1 << 22);
688 RCC_PLLCFGR = (reg32 | (pllsrc << 22));
689}
690
691void rcc_set_ppre2(uint32_t ppre2)
692{
693 uint32_t reg32;
694
695 reg32 = RCC_CFGR;
696 reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15));
697 RCC_CFGR = (reg32 | (ppre2 << 13));
698}
699
700void rcc_set_ppre1(uint32_t ppre1)
701{
702 uint32_t reg32;
703
704 reg32 = RCC_CFGR;
705 reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12));
706 RCC_CFGR = (reg32 | (ppre1 << 10));
707}
708
709void rcc_set_hpre(uint32_t hpre)
710{
711 uint32_t reg32;
712
713 reg32 = RCC_CFGR;
714 reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
715 RCC_CFGR = (reg32 | (hpre << 4));
716}
717
718void rcc_set_rtcpre(uint32_t rtcpre)
719{
720 uint32_t reg32;
721
722 reg32 = RCC_CFGR;
723 reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20));
724 RCC_CFGR = (reg32 | (rtcpre << 16));
725}
726
727/**
728 * Reconfigures the main PLL for a HSI source.
729 * Any reserved bits are kept at their reset values.
730 * @param pllm Divider for the main PLL input clock
731 * @param plln Main PLL multiplication factor for VCO
732 * @param pllp Main PLL divider for main system clock
733 * @param pllq Main PLL divider for USB OTG FS, SDMMC & RNG
734 * @param pllr Main PLL divider for DSI (for parts without DSI, provide 0 here)
735 */
736void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp,
737 uint32_t pllq, uint32_t pllr)
738{
739 /* Use reset value if not legal, for parts without pllr */
740 if (pllr < 2) {
741 pllr = 2;
742 }
743 RCC_PLLCFGR = 0 | /* HSI */
749}
750
751/**
752 * Reconfigures the main PLL for a HSE source.
753 * Any reserved bits are kept at their reset values.
754 * @param pllm Divider for the main PLL input clock
755 * @param plln Main PLL multiplication factor for VCO
756 * @param pllp Main PLL divider for main system clock
757 * @param pllq Main PLL divider for USB OTG FS, SDMMC & RNG
758 * @param pllr Main PLL divider for DSI (for parts without DSI, provide 0 here)
759 */
760void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp,
761 uint32_t pllq, uint32_t pllr)
762{
763 /* Use reset value if not legal, for parts without pllr */
764 if (pllr < 2) {
765 pllr = 2;
766 }
767 RCC_PLLCFGR = RCC_PLLCFGR_PLLSRC | /* HSE */
773}
774
776{
777 /* Return the clock source which is used as system clock. */
778 return (RCC_CFGR & 0x000c) >> 2;
779}
780
781/**
782 * Setup clocks to run from PLL.
783 *
784 * The arguments provide the pll source, multipliers, dividers, all that's
785 * needed to establish a system clock.
786 *
787 * @param clock clock information structure.
788 */
789void rcc_clock_setup_pll(const struct rcc_clock_scale *clock)
790{
791 /* Enable internal high-speed oscillator (HSI). */
794
795 /* Select HSI as SYSCLK source. */
797
798 /* Enable external high-speed oscillator (HSE). */
799 if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) {
802 }
803
804 /* Set the VOS scale mode */
807
808 /*
809 * Set prescalers for AHB, ADC, APB1, APB2.
810 * Do this before touching the PLL (TODO: why?).
811 */
812 rcc_set_hpre(clock->hpre);
813 rcc_set_ppre1(clock->ppre1);
814 rcc_set_ppre2(clock->ppre2);
815
816 /* Disable PLL oscillator before changing its configuration. */
818
819 /* Configure the PLL oscillator. */
820 if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) {
821 rcc_set_main_pll_hse(clock->pllm, clock->plln,
822 clock->pllp, clock->pllq, clock->pllr);
823 } else {
824 rcc_set_main_pll_hsi(clock->pllm, clock->plln,
825 clock->pllp, clock->pllq, clock->pllr);
826 }
827
828 /* Enable PLL oscillator and wait for it to stabilize. */
831
832 /* Configure flash settings. */
833 if (clock->flash_config & FLASH_ACR_DCEN) {
835 } else {
837 }
838 if (clock->flash_config & FLASH_ACR_ICEN) {
840 } else {
842 }
844
845 /* Select PLL as SYSCLK source. */
847
848 /* Wait for PLL clock to be selected. */
850
851 /* Set the peripheral clock frequencies used. */
855
856 /* Disable internal high-speed oscillator. */
857 if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) {
859 }
860}
861
862/**
863 * Setup clocks with the HSE.
864 *
865 * @deprecated replaced by rcc_clock_setup_pll as a drop in replacement.
866 * @see rcc_clock_setup_pll which supports HSI as well as HSE, using the same
867 * clock structures.
868 */
870{
871 rcc_clock_setup_pll(clock);
872}
873
874/*---------------------------------------------------------------------------*/
875/** @brief Get the peripheral clock speed for the USART at base specified.
876 * @param usart Base address of USART to get clock frequency for.
877 */
878uint32_t rcc_get_usart_clk_freq(uint32_t usart)
879{
880 /* Handle values with selectable clocks. */
881 if (usart == USART1_BASE || usart == USART6_BASE) {
882 return rcc_apb2_frequency;
883 } else {
884 return rcc_apb1_frequency;
885 }
886}
887
888/*---------------------------------------------------------------------------*/
889/** @brief Get the peripheral clock speed for the Timer at base specified.
890 * @param timer Base address of TIM to get clock frequency for.
891 */
892uint32_t rcc_get_timer_clk_freq(uint32_t timer)
893{
894 /* Handle APB1 timer clocks. */
895 if (timer >= TIM2_BASE && timer <= TIM14_BASE) {
898 : 2 * rcc_apb1_frequency;
899 } else {
902 : 2 * rcc_apb2_frequency;
903 }
904}
905
906/*---------------------------------------------------------------------------*/
907/** @brief Get the peripheral clock speed for the I2C device at base specified.
908 * @param i2c Base address of I2C to get clock frequency for.
909 */
910uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused)))
911{
912 return rcc_apb1_frequency;
913}
914
915/*---------------------------------------------------------------------------*/
916/** @brief Get the peripheral clock speed for the SPI device at base specified.
917 * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE).
918 */
919uint32_t rcc_get_spi_clk_freq(uint32_t spi) {
920 if (spi == SPI2_BASE || spi == SPI3_BASE) {
921 return rcc_apb1_frequency;
922 } else {
923 return rcc_apb2_frequency;
924 }
925}
926/**@}*/
#define FLASH_ACR_ICEN
#define FLASH_ACR_DCEN
void flash_icache_disable(void)
Disable the Instruction Cache.
void flash_icache_enable(void)
Enable the Instruction Cache.
void flash_dcache_disable(void)
Disable the data cache.
void flash_dcache_enable(void)
Enable the data cache.
void flash_set_ws(uint32_t ws)
Set the Number of Wait States.
#define FLASH_ACR_LATENCY_3WS
#define FLASH_ACR_LATENCY_5WS
#define FLASH_ACR_LATENCY_2WS
void pwr_set_vos_scale(enum pwr_vos_scale scale)
Definition: pwr.c:41
@ PWR_SCALE1
Definition: f4/pwr.h:80
#define RCC_BDCR_LSEON
Definition: f4/rcc.h:663
#define RCC_BDCR_LSERDY
Definition: f4/rcc.h:662
#define RCC_CFGR_HPRE_NODIV
Definition: f4/rcc.h:228
#define RCC_CFGR_PPRE_DIV2
Definition: f4/rcc.h:218
#define RCC_CFGR_PPRE_NODIV
Definition: f4/rcc.h:217
#define RCC_CFGR_PPRE_DIV4
Definition: f4/rcc.h:219
#define RCC_CFGR_HPRE_DIV_NONE
Definition: f4/rcc.h:264
#define RCC_CFGR_PPRE_DIV_NONE
Definition: f4/rcc.h:258
#define RCC_CFGR_PPRE_DIV_2
Definition: f4/rcc.h:259
#define RCC_CFGR_PLLSRC_HSI_CLK
Definition: f4/rcc.h:189
#define RCC_CFGR_PPRE1_MASK
Definition: f4/rcc.h:212
#define RCC_CFGR_PPRE2_SHIFT
Definition: f4/rcc.h:209
#define RCC_CFGR_PLLSRC_HSE_CLK
Definition: f4/rcc.h:190
#define RCC_CFGR_SWS_PLL
Definition: f4/rcc.h:244
#define RCC_CFGR_PPRE2_MASK
Definition: f4/rcc.h:210
#define RCC_CFGR_SWS_MASK
Definition: f4/rcc.h:241
#define RCC_CFGR_SWS_HSI
Definition: f4/rcc.h:242
#define RCC_CFGR_SW_PLL
Definition: f4/rcc.h:250
#define RCC_CFGR_SWS_SHIFT
Definition: f4/rcc.h:240
#define RCC_CFGR_SW_HSI
Definition: f4/rcc.h:248
#define RCC_CFGR_SWS_HSE
Definition: f4/rcc.h:243
#define RCC_CFGR_PPRE1_SHIFT
Definition: f4/rcc.h:211
#define RCC_CIR_PLLRDYF
Definition: f4/rcc.h:306
#define RCC_CIR_HSERDYF
Definition: f4/rcc.h:307
#define RCC_CIR_LSERDYC
Definition: f4/rcc.h:288
#define RCC_CIR_PLLRDYIE
Definition: f4/rcc.h:294
#define RCC_CIR_PLLI2SRDYIE
Definition: f4/rcc.h:293
#define RCC_CIR_PLLRDYC
Definition: f4/rcc.h:285
#define RCC_CIR_PLLSAIRDYF
Definition: f4/rcc.h:304
#define RCC_CIR_PLLSAIRDYC
Definition: f4/rcc.h:283
#define RCC_CIR_CSSC
Definition: f4/rcc.h:280
#define RCC_CIR_HSERDYIE
Definition: f4/rcc.h:295
#define RCC_CIR_LSERDYIE
Definition: f4/rcc.h:297
#define RCC_CIR_PLLI2SRDYC
Definition: f4/rcc.h:284
#define RCC_CIR_LSIRDYIE
Definition: f4/rcc.h:298
#define RCC_CIR_HSERDYC
Definition: f4/rcc.h:286
#define RCC_CIR_LSIRDYC
Definition: f4/rcc.h:289
#define RCC_CIR_LSERDYF
Definition: f4/rcc.h:309
#define RCC_CIR_HSIRDYIE
Definition: f4/rcc.h:296
#define RCC_CIR_LSIRDYF
Definition: f4/rcc.h:310
#define RCC_CIR_HSIRDYC
Definition: f4/rcc.h:287
#define RCC_CIR_PLLI2SRDYF
Definition: f4/rcc.h:305
#define RCC_CIR_HSIRDYF
Definition: f4/rcc.h:308
#define RCC_CIR_CSSF
Definition: f4/rcc.h:301
#define RCC_CIR_PLLSAIRDYIE
Definition: f4/rcc.h:292
#define RCC_CR_PLLI2SON
Definition: f4/rcc.h:128
#define RCC_CR_PLLI2SRDY
Definition: f4/rcc.h:127
#define RCC_CR_HSERDY
Definition: f4/rcc.h:133
#define RCC_CR_HSIRDY
Definition: f4/rcc.h:139
#define RCC_CR_PLLSAIRDY
Definition: f4/rcc.h:125
#define RCC_CR_CSSON
Definition: f4/rcc.h:131
#define RCC_CR_PLLON
Definition: f4/rcc.h:130
#define RCC_CR_HSEON
Definition: f4/rcc.h:134
#define RCC_CR_HSION
Definition: f4/rcc.h:140
#define RCC_CR_PLLRDY
Definition: f4/rcc.h:129
#define RCC_CR_PLLSAION
Definition: f4/rcc.h:126
#define RCC_CSR_LSION
Definition: f4/rcc.h:682
#define RCC_CSR_LSIRDY
Definition: f4/rcc.h:681
rcc_osc
Definition: f4/rcc.h:828
void rcc_periph_clock_enable(enum rcc_periph_clken clken)
Enable Peripheral Clock in running mode.
@ RCC_PWR
Definition: f4/rcc.h:900
@ RCC_HSI
Definition: f4/rcc.h:833
@ RCC_PLLSAI
Definition: f4/rcc.h:830
@ RCC_PLLI2S
Definition: f4/rcc.h:831
@ RCC_LSI
Definition: f4/rcc.h:835
@ RCC_PLL
Definition: f4/rcc.h:829
@ RCC_LSE
Definition: f4/rcc.h:834
@ RCC_HSE
Definition: f4/rcc.h:832
@ RCC_CLOCK_3V3_END
Definition: f4/rcc.h:802
int rcc_osc_ready_int_flag(enum rcc_osc osc)
Definition: rcc.c:483
void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock)
Setup clocks with the HSE.
Definition: rcc.c:869
int rcc_css_int_flag(void)
Definition: rcc.c:509
void rcc_osc_ready_int_clear(enum rcc_osc osc)
Definition: rcc.c:402
void rcc_wait_for_osc_ready(enum rcc_osc osc)
Wait for Oscillator Ready.
Definition: rcc.c:535
void rcc_css_disable(void)
Definition: rcc.c:620
bool rcc_is_osc_ready(enum rcc_osc osc)
Is the given oscillator ready?
Definition: rcc.c:514
uint32_t rcc_get_spi_clk_freq(uint32_t spi)
Get the peripheral clock speed for the SPI device at base specified.
Definition: rcc.c:919
void rcc_set_sysclk_source(uint32_t clk)
Definition: rcc.c:673
void rcc_pllsai_postscalers(uint8_t q, uint8_t r)
Set the dedicated dividers after the PLLSAI configuration.
Definition: rcc.c:663
uint32_t rcc_apb2_frequency
Definition: rcc.c:50
void rcc_set_pll_source(uint32_t pllsrc)
Definition: rcc.c:682
uint32_t rcc_get_timer_clk_freq(uint32_t timer)
Get the peripheral clock speed for the Timer at base specified.
Definition: rcc.c:892
uint32_t rcc_system_clock_source(void)
Definition: rcc.c:775
const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END]
Definition: rcc.c:122
void rcc_plli2s_config(uint16_t n, uint8_t r)
Set the dividers for the PLLI2S clock outputs.
Definition: rcc.c:630
uint32_t rcc_get_usart_clk_freq(uint32_t usart)
Get the peripheral clock speed for the USART at base specified.
Definition: rcc.c:878
const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END]
Definition: rcc.c:52
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock)
Setup clocks to run from PLL.
Definition: rcc.c:789
const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END]
Definition: rcc.c:192
void rcc_set_rtcpre(uint32_t rtcpre)
Definition: rcc.c:718
const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END]
Definition: rcc.c:332
void rcc_osc_ready_int_enable(enum rcc_osc osc)
Definition: rcc.c:429
void rcc_osc_ready_int_disable(enum rcc_osc osc)
Definition: rcc.c:456
void rcc_osc_on(enum rcc_osc osc)
Definition: rcc.c:561
uint32_t rcc_ahb_frequency
Definition: rcc.c:48
void rcc_osc_off(enum rcc_osc osc)
Definition: rcc.c:588
void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t pllq, uint32_t pllr)
Reconfigures the main PLL for a HSE source.
Definition: rcc.c:760
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c)
Get the peripheral clock speed for the I2C device at base specified.
Definition: rcc.c:910
uint32_t rcc_apb1_frequency
Definition: rcc.c:49
void rcc_wait_for_sysclk_status(enum rcc_osc osc)
Definition: rcc.c:540
void rcc_set_ppre1(uint32_t ppre1)
Definition: rcc.c:700
void rcc_css_int_clear(void)
Definition: rcc.c:504
void rcc_pllsai_config(uint16_t n, uint16_t p, uint16_t q, uint16_t r)
Set the dividers for the PLLSAI clock outputs divider p is only available on F4x9 parts,...
Definition: rcc.c:646
void rcc_set_ppre2(uint32_t ppre2)
Definition: rcc.c:691
void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t pllq, uint32_t pllr)
Reconfigures the main PLL for a HSI source.
Definition: rcc.c:736
void rcc_css_enable(void)
Definition: rcc.c:615
void rcc_set_hpre(uint32_t hpre)
Definition: rcc.c:709
const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END]
Definition: rcc.c:262
#define RCC_PLLCFGR_PLLN_SHIFT
Definition: f4/rcc.h:158
#define RCC_PLLCFGR_PLLR_MASK
Definition: f4/rcc.h:149
#define RCC_PLLCFGR_PLLP_MASK
Definition: f4/rcc.h:156
#define RCC_PLLCFGR_PLLN_MASK
Definition: f4/rcc.h:159
#define RCC_PLLCFGR_PLLSRC
Definition: f4/rcc.h:153
#define RCC_PLLCFGR_PLLR_SHIFT
Definition: f4/rcc.h:148
#define RCC_PLLCFGR_PLLQ_SHIFT
Definition: f4/rcc.h:151
#define RCC_PLLCFGR_PLLQ_MASK
Definition: f4/rcc.h:152
#define RCC_PLLCFGR_PLLM_SHIFT
Definition: f4/rcc.h:161
#define RCC_PLLCFGR_PLLP_SHIFT
Definition: f4/rcc.h:155
#define RCC_PLLCFGR_PLLM_MASK
Definition: f4/rcc.h:162
#define RCC_PLLSAICFGR_PLLSAIR_SHIFT
Definition: f4/rcc.h:720
#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT
Definition: f4/rcc.h:714
#define RCC_PLLSAICFGR_PLLSAIQ_SHIFT
Definition: f4/rcc.h:724
#define RCC_PLLSAICFGR_PLLSAIQ_MASK
Definition: f4/rcc.h:725
#define RCC_DCKCFGR_PLLSAIDIVR_MASK
Definition: f4/rcc.h:763
#define RCC_PLLSAICFGR_PLLSAIR_MASK
Definition: f4/rcc.h:721
#define RCC_PLLI2SCFGR_PLLI2SR_SHIFT
Definition: f4/rcc.h:708
#define RCC_PLLSAICFGR_PLLSAIP_SHIFT
Definition: f4/rcc.h:728
#define RCC_PLLSAICFGR_PLLSAIP_MASK
Definition: f4/rcc.h:729
#define RCC_PLLSAICFGR_PLLSAIN_SHIFT
Definition: f4/rcc.h:740
#define RCC_PLLSAICFGR_PLLSAIN_MASK
Definition: f4/rcc.h:741
#define RCC_DCKCFGR_PLLSAIDIVQ_MASK
Definition: f4/rcc.h:770
#define RCC_DCKCFGR_PLLSAIDIVR_SHIFT
Definition: f4/rcc.h:762
#define RCC_PLLI2SCFGR_PLLI2SN_MASK
Definition: f4/rcc.h:715
#define RCC_PLLI2SCFGR_PLLI2SR_MASK
Definition: f4/rcc.h:709
#define RCC_DCKCFGR_PLLSAIDIVQ_SHIFT
Definition: f4/rcc.h:769
#define RCC_CIR
Clock interrupt register.
Definition: f4/rcc.h:61
#define RCC_CR
Clock control register.
Definition: f4/rcc.h:55
#define RCC_PLLSAICFGR
PLLSAI configuration register.
Definition: f4/rcc.h:112
#define RCC_CSR
Clock control and status register.
Definition: f4/rcc.h:104
#define RCC_PLLI2SCFGR
PLLI2S configuration register.
Definition: f4/rcc.h:110
#define RCC_PLLCFGR
PLL Configuration register.
Definition: f4/rcc.h:57
#define RCC_CFGR
Clock Configuration register.
Definition: f4/rcc.h:59
#define RCC_BDCR
Backup Domain control register.
Definition: f4/rcc.h:102
#define RCC_DCKCFGR
Dedicated clocks configuration register.
Definition: f4/rcc.h:114
#define TIM2_BASE
#define USART1_BASE
#define TIM14_BASE
#define SPI2_BASE
#define USART6_BASE
#define SPI3_BASE
uint8_t ppre1
Definition: f4/rcc.h:814
uint8_t pllq
Definition: f4/rcc.h:809
uint8_t ppre2
Definition: f4/rcc.h:815
uint8_t pllp
Definition: f4/rcc.h:808
uint32_t apb1_frequency
Definition: f4/rcc.h:818
uint8_t pllm
Definition: f4/rcc.h:806
uint32_t ahb_frequency
Definition: f4/rcc.h:817
uint16_t plln
Definition: f4/rcc.h:807
enum pwr_vos_scale voltage_scale
Definition: f4/rcc.h:816
uint8_t pllr
Definition: f4/rcc.h:810
uint32_t flash_config
Definition: f4/rcc.h:812
uint8_t hpre
Definition: f4/rcc.h:813
uint32_t apb2_frequency
Definition: f4/rcc.h:819
uint8_t pll_source
Definition: f4/rcc.h:811