1 /**
2 ******************************************************************************
3 * @file stm32f2xx_ll_rcc.c
4 * @author MCD Application Team
5 * @brief RCC LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2017 STMicroelectronics.
10 * All rights reserved.
11 *
12 * This software is licensed under terms that can be found in the LICENSE file in
13 * the root directory of this software component.
14 * If no LICENSE file comes with this software, it is provided AS-IS.
15 ******************************************************************************
16 */
17
18 #if defined(USE_FULL_LL_DRIVER)
19
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32f2xx_ll_rcc.h"
22 #ifdef USE_FULL_ASSERT
23 #include "stm32_assert.h"
24 #else
25 #define assert_param(expr) ((void)0U)
26 #endif
27 /** @addtogroup STM32F2xx_LL_Driver
28 * @{
29 */
30
31 #if defined(RCC)
32
33 /** @addtogroup RCC_LL
34 * @{
35 */
36
37 /* Private types -------------------------------------------------------------*/
38 /* Private variables ---------------------------------------------------------*/
39 /* Private constants ---------------------------------------------------------*/
40 /* Private macros ------------------------------------------------------------*/
41 /** @addtogroup RCC_LL_Private_Macros
42 * @{
43 */
44 #define IS_LL_RCC_I2S_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2S1_CLKSOURCE))
45 /**
46 * @}
47 */
48
49 /* Private function prototypes -----------------------------------------------*/
50 /** @defgroup RCC_LL_Private_Functions RCC Private functions
51 * @{
52 */
53 uint32_t RCC_GetSystemClockFreq(void);
54 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
55 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
56 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
57 uint32_t RCC_PLL_GetFreqDomain_SYS(void);
58 uint32_t RCC_PLL_GetFreqDomain_48M(void);
59 uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void);
60 /**
61 * @}
62 */
63
64 /* Exported functions --------------------------------------------------------*/
65 /** @addtogroup RCC_LL_Exported_Functions
66 * @{
67 */
68
69 /** @addtogroup RCC_LL_EF_Init
70 * @{
71 */
72
73 /**
74 * @brief Reset the RCC clock configuration to the default reset state.
75 * @note The default reset state of the clock configuration is given below:
76 * - HSI ON and used as system clock source
77 * - HSE, PLL, PLLI2S OFF
78 * - AHB, APB1 and APB2 prescaler set to 1.
79 * - CSS, MCO OFF
80 * - All interrupts disabled
81 * @note This function doesn't modify the configuration of the
82 * - Peripheral clocks
83 * - LSI, LSE and RTC clocks
84 * @retval An ErrorStatus enumeration value:
85 * - SUCCESS: RCC registers are de-initialized
86 * - ERROR: not applicable
87 */
LL_RCC_DeInit(void)88 ErrorStatus LL_RCC_DeInit(void)
89 {
90 uint32_t vl_mask = 0U;
91
92 /* Set HSION bit */
93 LL_RCC_HSI_Enable();
94
95 /* Wait for HSI READY bit */
96 while(LL_RCC_HSI_IsReady() != 1U)
97 {}
98
99 /* Reset CFGR register */
100 LL_RCC_WriteReg(CFGR, 0x00000000U);
101
102 vl_mask = 0xFFFFFFFFU;
103
104 /* Reset HSEON, PLLSYSON bits */
105 CLEAR_BIT(vl_mask, (RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_PLLON | RCC_CR_CSSON));
106
107 /* Reset PLLI2SON bit */
108 CLEAR_BIT(vl_mask, RCC_CR_PLLI2SON);
109
110 /* Write new mask in CR register */
111 LL_RCC_WriteReg(CR, vl_mask);
112
113 /* Set HSITRIM bits to the reset value*/
114 LL_RCC_HSI_SetCalibTrimming(0x10U);
115
116 /* Wait for PLL READY bit to be reset */
117 while(LL_RCC_PLL_IsReady() != 0U)
118 {}
119
120 /* Wait for PLLI2S READY bit to be reset */
121 while(LL_RCC_PLLI2S_IsReady() != 0U)
122 {}
123
124 /* Reset PLLCFGR register */
125 LL_RCC_WriteReg(PLLCFGR, 0x24003010U);
126
127 /* Reset PLLI2SCFGR register */
128 LL_RCC_WriteReg(PLLI2SCFGR, 0x20003000U);
129
130 /* Disable all interrupts */
131 LL_RCC_WriteReg(CIR, 0x00000000U);
132
133 /* Clear reset flags */
134 LL_RCC_ClearResetFlags();
135
136 return SUCCESS;
137 }
138
139 /**
140 * @}
141 */
142
143 /** @addtogroup RCC_LL_EF_Get_Freq
144 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
145 * and different peripheral clocks available on the device.
146 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
147 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
148 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(***)
149 * or HSI_VALUE(**) multiplied/divided by the PLL factors.
150 * @note (**) HSI_VALUE is a constant defined in this file (default value
151 * 16 MHz) but the real value may vary depending on the variations
152 * in voltage and temperature.
153 * @note (***) HSE_VALUE is a constant defined in this file (default value
154 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
155 * frequency of the crystal used. Otherwise, this function may
156 * have wrong result.
157 * @note The result of this function could be incorrect when using fractional
158 * value for HSE crystal.
159 * @note This function can be used by the user application to compute the
160 * baud-rate for the communication peripherals or configure other parameters.
161 * @{
162 */
163
164 /**
165 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
166 * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
167 * must be called to update structure fields. Otherwise, any
168 * configuration based on this function will be incorrect.
169 * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
170 * @retval None
171 */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)172 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
173 {
174 /* Get SYSCLK frequency */
175 RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
176
177 /* HCLK clock frequency */
178 RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
179
180 /* PCLK1 clock frequency */
181 RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
182
183 /* PCLK2 clock frequency */
184 RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
185 }
186
187 /**
188 * @brief Return I2Sx clock frequency
189 * @param I2SxSource This parameter can be one of the following values:
190 * @arg @ref LL_RCC_I2S1_CLKSOURCE
191 * @retval I2S clock frequency (in Hz)
192 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready
193 */
LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)194 uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)
195 {
196 uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
197
198 /* Check parameter */
199 assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource));
200
201 if (I2SxSource == LL_RCC_I2S1_CLKSOURCE)
202 {
203 /* I2S1 CLK clock frequency */
204 switch (LL_RCC_GetI2SClockSource(I2SxSource))
205 {
206 case LL_RCC_I2S1_CLKSOURCE_PLLI2S: /* I2S1 Clock is PLLI2S */
207 if (LL_RCC_PLLI2S_IsReady())
208 {
209 i2s_frequency = RCC_PLLI2S_GetFreqDomain_I2S();
210 }
211 break;
212
213 case LL_RCC_I2S1_CLKSOURCE_PIN: /* I2S1 Clock is External clock */
214 default:
215 i2s_frequency = EXTERNAL_CLOCK_VALUE;
216 break;
217 }
218 }
219
220 return i2s_frequency;
221 }
222
223 /**
224 * @}
225 */
226
227 /**
228 * @}
229 */
230
231 /** @addtogroup RCC_LL_Private_Functions
232 * @{
233 */
234
235 /**
236 * @brief Return SYSTEM clock frequency
237 * @retval SYSTEM clock frequency (in Hz)
238 */
RCC_GetSystemClockFreq(void)239 uint32_t RCC_GetSystemClockFreq(void)
240 {
241 uint32_t frequency = 0U;
242
243 /* Get SYSCLK source -------------------------------------------------------*/
244 switch (LL_RCC_GetSysClkSource())
245 {
246 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
247 frequency = HSI_VALUE;
248 break;
249
250 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
251 frequency = HSE_VALUE;
252 break;
253
254 case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
255 frequency = RCC_PLL_GetFreqDomain_SYS();
256 break;
257
258 default:
259 frequency = HSI_VALUE;
260 break;
261 }
262
263 return frequency;
264 }
265
266 /**
267 * @brief Return HCLK clock frequency
268 * @param SYSCLK_Frequency SYSCLK clock frequency
269 * @retval HCLK clock frequency (in Hz)
270 */
RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)271 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
272 {
273 /* HCLK clock frequency */
274 return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
275 }
276
277 /**
278 * @brief Return PCLK1 clock frequency
279 * @param HCLK_Frequency HCLK clock frequency
280 * @retval PCLK1 clock frequency (in Hz)
281 */
RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)282 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
283 {
284 /* PCLK1 clock frequency */
285 return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
286 }
287
288 /**
289 * @brief Return PCLK2 clock frequency
290 * @param HCLK_Frequency HCLK clock frequency
291 * @retval PCLK2 clock frequency (in Hz)
292 */
RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)293 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
294 {
295 /* PCLK2 clock frequency */
296 return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
297 }
298
299 /**
300 * @brief Return PLL clock frequency used for system domain
301 * @retval PLL clock frequency (in Hz)
302 */
RCC_PLL_GetFreqDomain_SYS(void)303 uint32_t RCC_PLL_GetFreqDomain_SYS(void)
304 {
305 uint32_t pllinputfreq = 0U, pllsource = 0U;
306
307 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
308 */
309 pllsource = LL_RCC_PLL_GetMainSource();
310
311 switch (pllsource)
312 {
313 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
314 pllinputfreq = HSI_VALUE;
315 break;
316
317 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
318 pllinputfreq = HSE_VALUE;
319 break;
320
321 default:
322 pllinputfreq = HSI_VALUE;
323 break;
324 }
325 return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
326 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP());
327 }
328
329 /**
330 * @brief Return PLL clock frequency used for 48 MHz domain
331 * @retval PLL clock frequency (in Hz)
332 */
RCC_PLL_GetFreqDomain_48M(void)333 uint32_t RCC_PLL_GetFreqDomain_48M(void)
334 {
335 uint32_t pllinputfreq = 0U, pllsource = 0U;
336
337 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM ) * PLLN
338 48M Domain clock = PLL_VCO / PLLQ
339 */
340 pllsource = LL_RCC_PLL_GetMainSource();
341
342 switch (pllsource)
343 {
344 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
345 pllinputfreq = HSI_VALUE;
346 break;
347
348 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
349 pllinputfreq = HSE_VALUE;
350 break;
351
352 default:
353 pllinputfreq = HSI_VALUE;
354 break;
355 }
356 return __LL_RCC_CALC_PLLCLK_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
357 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
358 }
359
360 /**
361 * @brief Return PLLI2S clock frequency used for I2S domain
362 * @retval PLLI2S clock frequency (in Hz)
363 */
RCC_PLLI2S_GetFreqDomain_I2S(void)364 uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void)
365 {
366 uint32_t pllinputfreq = 0U, pllsource = 0U;
367
368 /* PLLI2S_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLI2SN
369 I2S Domain clock = PLLI2S_VCO / PLLI2SR
370 */
371 pllsource = LL_RCC_PLL_GetMainSource();
372
373 switch (pllsource)
374 {
375 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLI2S clock source */
376 pllinputfreq = HSE_VALUE;
377 break;
378
379 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLI2S clock source */
380 default:
381 pllinputfreq = HSI_VALUE;
382 break;
383 }
384 return __LL_RCC_CALC_PLLI2S_I2S_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
385 LL_RCC_PLLI2S_GetN(), LL_RCC_PLLI2S_GetR());
386 }
387
388 /**
389 * @}
390 */
391
392 /**
393 * @}
394 */
395
396 #endif /* defined(RCC) */
397
398 /**
399 * @}
400 */
401
402 #endif /* USE_FULL_LL_DRIVER */
403
404