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_f2_api_ex Reset and Clock Control API.
6 *
7 * @brief <b>libopencm3 STM32F2xx 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
43
44/**@{*/
45
46/* Set the default clock frequencies after reset. */
47uint32_t rcc_ahb_frequency = 16000000;
48uint32_t rcc_apb1_frequency = 16000000;
49uint32_t rcc_apb2_frequency = 16000000;
50
52 { /* 120MHz */
53 .pllm = 8,
54 .plln = 240,
55 .pllp = 2,
56 .pllq = 5,
57 .hpre = RCC_CFGR_HPRE_NODIV,
58 .ppre1 = RCC_CFGR_PPRE_DIV4,
59 .ppre2 = RCC_CFGR_PPRE_DIV2,
60 .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
62 .apb1_frequency = 30000000,
63 .apb2_frequency = 60000000,
64 },
65};
66
68{
69 switch (osc) {
70 case RCC_PLL:
72 break;
73 case RCC_HSE:
75 break;
76 case RCC_HSI:
78 break;
79 case RCC_LSE:
81 break;
82 case RCC_LSI:
84 break;
85 }
86}
87
89{
90 switch (osc) {
91 case RCC_PLL:
93 break;
94 case RCC_HSE:
96 break;
97 case RCC_HSI:
99 break;
100 case RCC_LSE:
102 break;
103 case RCC_LSI:
105 break;
106 }
107}
108
110{
111 switch (osc) {
112 case RCC_PLL:
113 RCC_CIR &= ~RCC_CIR_PLLRDYIE;
114 break;
115 case RCC_HSE:
116 RCC_CIR &= ~RCC_CIR_HSERDYIE;
117 break;
118 case RCC_HSI:
119 RCC_CIR &= ~RCC_CIR_HSIRDYIE;
120 break;
121 case RCC_LSE:
122 RCC_CIR &= ~RCC_CIR_LSERDYIE;
123 break;
124 case RCC_LSI:
125 RCC_CIR &= ~RCC_CIR_LSIRDYIE;
126 break;
127 }
128}
129
131{
132 switch (osc) {
133 case RCC_PLL:
134 return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
135 break;
136 case RCC_HSE:
137 return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
138 break;
139 case RCC_HSI:
140 return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0);
141 break;
142 case RCC_LSE:
143 return ((RCC_CIR & RCC_CIR_LSERDYF) != 0);
144 break;
145 case RCC_LSI:
146 return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0);
147 break;
148 }
149
151}
152
154{
156}
157
159{
160 return ((RCC_CIR & RCC_CIR_CSSF) != 0);
161}
162
164{
165 switch (osc) {
166 case RCC_PLL:
167 return RCC_CR & RCC_CR_PLLRDY;
168 case RCC_HSE:
169 return RCC_CR & RCC_CR_HSERDY;
170 case RCC_HSI:
171 return RCC_CR & RCC_CR_HSIRDY;
172 case RCC_LSE:
173 return RCC_BDCR & RCC_BDCR_LSERDY;
174 case RCC_LSI:
175 return RCC_CSR & RCC_CSR_LSIRDY;
176 }
177 return false;
178}
179
181{
182 while (!rcc_is_osc_ready(osc));
183}
184
186{
187 switch (osc) {
188 case RCC_PLL:
191 break;
192 case RCC_HSE:
195 break;
196 case RCC_HSI:
199 break;
200 default:
201 /* Shouldn't be reached. */
202 break;
203 }
204}
205
206void rcc_osc_on(enum rcc_osc osc)
207{
208 switch (osc) {
209 case RCC_PLL:
211 break;
212 case RCC_HSE:
214 break;
215 case RCC_HSI:
217 break;
218 case RCC_LSE:
220 break;
221 case RCC_LSI:
223 break;
224 }
225}
226
227void rcc_osc_off(enum rcc_osc osc)
228{
229 switch (osc) {
230 case RCC_PLL:
231 RCC_CR &= ~RCC_CR_PLLON;
232 break;
233 case RCC_HSE:
234 RCC_CR &= ~RCC_CR_HSEON;
235 break;
236 case RCC_HSI:
237 RCC_CR &= ~RCC_CR_HSION;
238 break;
239 case RCC_LSE:
240 RCC_BDCR &= ~RCC_BDCR_LSEON;
241 break;
242 case RCC_LSI:
243 RCC_CSR &= ~RCC_CSR_LSION;
244 break;
245 }
246}
247
249{
251}
252
254{
255 RCC_CR &= ~RCC_CR_CSSON;
256}
257
258void rcc_set_sysclk_source(uint32_t clk)
259{
260 uint32_t reg32;
261
262 reg32 = RCC_CFGR;
263 reg32 &= ~((1 << 1) | (1 << 0));
264 RCC_CFGR = (reg32 | clk);
265}
266
267void rcc_set_pll_source(uint32_t pllsrc)
268{
269 uint32_t reg32;
270
271 reg32 = RCC_PLLCFGR;
272 reg32 &= ~(1 << 22);
273 RCC_PLLCFGR = (reg32 | (pllsrc << 22));
274}
275
276void rcc_set_ppre2(uint32_t ppre2)
277{
278 uint32_t reg32;
279
280 reg32 = RCC_CFGR;
281 reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15));
282 RCC_CFGR = (reg32 | (ppre2 << 13));
283}
284
285void rcc_set_ppre1(uint32_t ppre1)
286{
287 uint32_t reg32;
288
289 reg32 = RCC_CFGR;
290 reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12));
291 RCC_CFGR = (reg32 | (ppre1 << 10));
292}
293
294void rcc_set_hpre(uint32_t hpre)
295{
296 uint32_t reg32;
297
298 reg32 = RCC_CFGR;
299 reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
300 RCC_CFGR = (reg32 | (hpre << 4));
301}
302
303void rcc_set_rtcpre(uint32_t rtcpre)
304{
305 uint32_t reg32;
306
307 reg32 = RCC_CFGR;
308 reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20));
309 RCC_CFGR = (reg32 | (rtcpre << 16));
310}
311
312void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp,
313 uint32_t pllq)
314{
317 (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) |
319}
320
321void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp,
322 uint32_t pllq)
323{
326 (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) |
329}
330
332{
333 /* Return the clock source which is used as system clock. */
334 return (RCC_CFGR & 0x000c) >> 2;
335}
336
338{
339 /* Enable internal high-speed oscillator. */
342
343 /* Select HSI as SYSCLK source. */
345
346 /* Enable external high-speed oscillator 8MHz. */
349
350 /*
351 * Set prescalers for AHB, ADC, APB1, APB2.
352 * Do this before touching the PLL (TODO: why?).
353 */
354 rcc_set_hpre(clock->hpre);
355 rcc_set_ppre1(clock->ppre1);
356 rcc_set_ppre2(clock->ppre2);
357
358 /* Disable PLL oscillator before changing its configuration. */
360
361 /* Configure the PLL oscillator. */
362 rcc_set_main_pll_hse(clock->pllm, clock->plln,
363 clock->pllp, clock->pllq);
364
365 /* Enable PLL oscillator and wait for it to stabilize. */
368
369 /* Configure flash settings. */
371
372 /* Select PLL as SYSCLK source. */
374
375 /* Wait for PLL clock to be selected. */
377
378 /* Set the peripheral clock frequencies used. */
381}
382
384{
385 /* Set the backup domain software reset. */
387
388 /* Clear the backup domain software reset. */
389 RCC_BDCR &= ~RCC_BDCR_BDRST;
390}
391
392
393/*---------------------------------------------------------------------------*/
394/** @brief Get the peripheral clock speed for the USART at base specified.
395 * @param usart Base address of USART to get clock frequency for.
396 */
397uint32_t rcc_get_usart_clk_freq(uint32_t usart)
398{
399 if (usart == USART1_BASE || usart == USART6_BASE) {
400 return rcc_apb2_frequency;
401 } else {
402 return rcc_apb1_frequency;
403 }
404}
405
406/*---------------------------------------------------------------------------*/
407/** @brief Get the peripheral clock speed for the Timer at base specified.
408 * @param timer Base address of TIM to get clock frequency for.
409 */
410uint32_t rcc_get_timer_clk_freq(uint32_t timer)
411{
412 /* Handle APB1 timer clocks. */
413 if (timer >= TIM2_BASE && timer <= TIM14_BASE) {
416 : 2 * rcc_apb1_frequency;
417 } else {
420 : 2 * rcc_apb2_frequency;
421 }
422}
423
424/*---------------------------------------------------------------------------*/
425/** @brief Get the peripheral clock speed for the I2C device at base specified.
426 * @param i2c Base address of I2C to get clock frequency for.
427 */
428uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused)))
429{
430 return rcc_apb1_frequency;
431}
432
433/*---------------------------------------------------------------------------*/
434/** @brief Get the peripheral clock speed for the SPI device at base specified.
435 * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE).
436 */
437uint32_t rcc_get_spi_clk_freq(uint32_t spi) {
438 if (spi == SPI1_BASE) {
439 return rcc_apb2_frequency;
440 } else {
441 return rcc_apb1_frequency;
442 }
443}
444/**@}*/
#define cm3_assert_not_reached()
Check if unreachable code is reached.
Definition: assert.h:102
#define FLASH_ACR_ICEN
#define FLASH_ACR_DCEN
void flash_set_ws(uint32_t ws)
Set the Number of Wait States.
#define FLASH_ACR_LATENCY_3WS
#define RCC_CFGR_HPRE_NODIV
Definition: f2/rcc.h:164
#define RCC_CFGR_PPRE_DIV2
Definition: f2/rcc.h:154
#define RCC_CFGR_PPRE_DIV4
Definition: f2/rcc.h:155
#define RCC_CFGR_PPRE_DIV_NONE
Definition: f2/rcc.h:193
#define RCC_BDCR_LSEON
Definition: f2/rcc.h:534
#define RCC_PLLCFGR_PLLN_SHIFT
Definition: f2/rcc.h:106
#define RCC_CIR_PLLRDYF
Definition: f2/rcc.h:236
#define RCC_CIR
Definition: f2/rcc.h:51
#define RCC_CIR_HSERDYF
Definition: f2/rcc.h:237
#define RCC_CFGR_PPRE1_MASK
Definition: f2/rcc.h:148
#define RCC_CIR_LSERDYC
Definition: f2/rcc.h:220
#define RCC_CFGR_PPRE2_SHIFT
Definition: f2/rcc.h:145
#define RCC_CIR_PLLRDYIE
Definition: f2/rcc.h:225
#define RCC_CIR_PLLRDYC
Definition: f2/rcc.h:217
#define RCC_BDCR_BDRST
Definition: f2/rcc.h:529
#define RCC_CFGR_SWS_PLL
Definition: f2/rcc.h:180
#define RCC_CR
Definition: f2/rcc.h:48
#define RCC_CFGR_PPRE2_MASK
Definition: f2/rcc.h:146
#define RCC_CFGR_SWS_MASK
Definition: f2/rcc.h:177
#define RCC_CIR_CSSC
Definition: f2/rcc.h:213
#define RCC_CIR_HSERDYIE
Definition: f2/rcc.h:226
#define RCC_CFGR_SWS_HSI
Definition: f2/rcc.h:178
rcc_osc
Definition: f2/rcc.h:597
#define RCC_CIR_LSERDYIE
Definition: f2/rcc.h:228
#define RCC_CSR
Definition: f2/rcc.h:77
#define RCC_CSR_LSION
Definition: f2/rcc.h:550
#define RCC_PLLCFGR
Definition: f2/rcc.h:49
#define RCC_CR_HSERDY
Definition: f2/rcc.h:91
#define RCC_CIR_LSIRDYIE
Definition: f2/rcc.h:229
#define RCC_CFGR_SW_PLL
Definition: f2/rcc.h:186
#define RCC_CFGR
Definition: f2/rcc.h:50
#define RCC_PLLCFGR_PLLSRC
Definition: f2/rcc.h:102
#define RCC_CIR_HSERDYC
Definition: f2/rcc.h:218
#define RCC_CIR_LSIRDYC
Definition: f2/rcc.h:221
#define RCC_CR_HSIRDY
Definition: f2/rcc.h:95
#define RCC_CFGR_SWS_SHIFT
Definition: f2/rcc.h:176
#define RCC_BDCR_LSERDY
Definition: f2/rcc.h:533
#define RCC_CSR_LSIRDY
Definition: f2/rcc.h:549
#define RCC_BDCR
Definition: f2/rcc.h:76
#define RCC_CIR_LSERDYF
Definition: f2/rcc.h:239
#define RCC_PLLCFGR_PLLQ_SHIFT
Definition: f2/rcc.h:101
#define RCC_CIR_HSIRDYIE
Definition: f2/rcc.h:227
#define RCC_CIR_LSIRDYF
Definition: f2/rcc.h:240
#define RCC_CFGR_SW_HSI
Definition: f2/rcc.h:184
#define RCC_CR_CSSON
Definition: f2/rcc.h:89
#define RCC_CR_PLLON
Definition: f2/rcc.h:88
#define RCC_CIR_HSIRDYC
Definition: f2/rcc.h:219
#define RCC_CIR_HSIRDYF
Definition: f2/rcc.h:238
#define RCC_CIR_CSSF
Definition: f2/rcc.h:232
#define RCC_PLLCFGR_PLLM_SHIFT
Definition: f2/rcc.h:108
#define RCC_CR_HSEON
Definition: f2/rcc.h:92
#define RCC_CFGR_SWS_HSE
Definition: f2/rcc.h:179
#define RCC_PLLCFGR_PLLP_SHIFT
Definition: f2/rcc.h:104
#define RCC_CR_HSION
Definition: f2/rcc.h:96
#define RCC_CR_PLLRDY
Definition: f2/rcc.h:87
#define RCC_CFGR_PPRE1_SHIFT
Definition: f2/rcc.h:147
@ RCC_HSI
Definition: f2/rcc.h:600
@ RCC_LSI
Definition: f2/rcc.h:602
@ RCC_PLL
Definition: f2/rcc.h:598
@ RCC_LSE
Definition: f2/rcc.h:601
@ RCC_HSE
Definition: f2/rcc.h:599
@ RCC_CLOCK_3V3_END
Definition: f2/rcc.h:579
int rcc_osc_ready_int_flag(enum rcc_osc osc)
Definition: rcc.c:130
void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock)
Definition: rcc.c:337
int rcc_css_int_flag(void)
Definition: rcc.c:158
void rcc_osc_ready_int_clear(enum rcc_osc osc)
Definition: rcc.c:67
void rcc_wait_for_osc_ready(enum rcc_osc osc)
Wait for Oscillator Ready.
Definition: rcc.c:180
void rcc_css_disable(void)
Definition: rcc.c:253
bool rcc_is_osc_ready(enum rcc_osc osc)
Is the given oscillator ready?
Definition: rcc.c:163
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:437
void rcc_set_sysclk_source(uint32_t clk)
Definition: rcc.c:258
uint32_t rcc_apb2_frequency
Definition: rcc.c:49
void rcc_set_pll_source(uint32_t pllsrc)
Definition: rcc.c:267
uint32_t rcc_get_timer_clk_freq(uint32_t timer)
Get the peripheral clock speed for the Timer at base specified.
Definition: rcc.c:410
uint32_t rcc_system_clock_source(void)
Definition: rcc.c:331
const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END]
Definition: rcc.c:51
uint32_t rcc_get_usart_clk_freq(uint32_t usart)
Get the peripheral clock speed for the USART at base specified.
Definition: rcc.c:397
void rcc_set_rtcpre(uint32_t rtcpre)
Definition: rcc.c:303
void rcc_osc_ready_int_enable(enum rcc_osc osc)
Definition: rcc.c:88
void rcc_osc_ready_int_disable(enum rcc_osc osc)
Definition: rcc.c:109
void rcc_osc_on(enum rcc_osc osc)
Definition: rcc.c:206
uint32_t rcc_ahb_frequency
Definition: rcc.c:47
void rcc_osc_off(enum rcc_osc osc)
Definition: rcc.c:227
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:428
void rcc_backupdomain_reset(void)
Definition: rcc.c:383
uint32_t rcc_apb1_frequency
Definition: rcc.c:48
void rcc_wait_for_sysclk_status(enum rcc_osc osc)
Definition: rcc.c:185
void rcc_set_ppre1(uint32_t ppre1)
Definition: rcc.c:285
void rcc_css_int_clear(void)
Definition: rcc.c:153
void rcc_set_ppre2(uint32_t ppre2)
Definition: rcc.c:276
void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t pllq)
Definition: rcc.c:321
void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t pllq)
Definition: rcc.c:312
void rcc_css_enable(void)
Definition: rcc.c:248
void rcc_set_hpre(uint32_t hpre)
Definition: rcc.c:294
#define TIM2_BASE
#define SPI1_BASE
#define USART1_BASE
#define TIM14_BASE
#define USART6_BASE
uint8_t ppre1
Definition: f2/rcc.h:589
uint8_t pllq
Definition: f2/rcc.h:586
uint8_t ppre2
Definition: f2/rcc.h:590
uint8_t pllp
Definition: f2/rcc.h:585
uint32_t apb1_frequency
Definition: f2/rcc.h:591
uint8_t pllm
Definition: f2/rcc.h:583
uint16_t plln
Definition: f2/rcc.h:584
uint32_t flash_config
Definition: f2/rcc.h:587
uint8_t hpre
Definition: f2/rcc.h:588
uint32_t apb2_frequency
Definition: f2/rcc.h:592