1 /**
2 ******************************************************************************
3 * @file stm32f1xx_ll_rcc.c
4 * @author MCD Application Team
5 * @brief RCC LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
10 * All rights reserved.</center></h2>
11 *
12 * This software component is licensed by ST under BSD 3-Clause license,
13 * the "License"; You may not use this file except in compliance with the
14 * License. You may obtain a copy of the License at:
15 * opensource.org/licenses/BSD-3-Clause
16 *
17 ******************************************************************************
18 */
19
20 #if defined(USE_FULL_LL_DRIVER)
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "stm32f1xx_ll_rcc.h"
24 #ifdef USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif /* USE_FULL_ASSERT */
29 /** @addtogroup STM32F1xx_LL_Driver
30 * @{
31 */
32
33 #if defined(RCC)
34
35 /** @defgroup RCC_LL RCC
36 * @{
37 */
38
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /* Private macros ------------------------------------------------------------*/
43 /** @addtogroup RCC_LL_Private_Macros
44 * @{
45 */
46 #if defined(RCC_PLLI2S_SUPPORT)
47 #define IS_LL_RCC_I2S_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2S2_CLKSOURCE) \
48 || ((__VALUE__) == LL_RCC_I2S3_CLKSOURCE))
49 #endif /* RCC_PLLI2S_SUPPORT */
50
51 #if defined(USB) || defined(USB_OTG_FS)
52 #define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USB_CLKSOURCE))
53 #endif /* USB */
54
55 #define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADC_CLKSOURCE))
56 /**
57 * @}
58 */
59
60 /* Private function prototypes -----------------------------------------------*/
61 /** @defgroup RCC_LL_Private_Functions RCC Private functions
62 * @{
63 */
64 uint32_t RCC_GetSystemClockFreq(void);
65 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
66 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
67 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
68 uint32_t RCC_PLL_GetFreqDomain_SYS(void);
69 #if defined(RCC_PLLI2S_SUPPORT)
70 uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void);
71 #endif /* RCC_PLLI2S_SUPPORT */
72 #if defined(RCC_PLL2_SUPPORT)
73 uint32_t RCC_PLL2_GetFreqClockFreq(void);
74 #endif /* RCC_PLL2_SUPPORT */
75 /**
76 * @}
77 */
78
79 /* Exported functions --------------------------------------------------------*/
80 /** @addtogroup RCC_LL_Exported_Functions
81 * @{
82 */
83
84 /** @addtogroup RCC_LL_EF_Init
85 * @{
86 */
87
88 /**
89 * @brief Reset the RCC clock configuration to the default reset state.
90 * @note The default reset state of the clock configuration is given below:
91 * - HSI ON and used as system clock source
92 * - HSE PLL, PLL2 & PLL3 are OFF
93 * - AHB, APB1 and APB2 prescaler set to 1.
94 * - CSS, MCO OFF
95 * - All interrupts disabled
96 * @note This function doesn't modify the configuration of the
97 * - Peripheral clocks
98 * - LSI, LSE and RTC clocks
99 * @retval An ErrorStatus enumeration value:
100 * - SUCCESS: RCC registers are de-initialized
101 * - ERROR: not applicable
102 */
LL_RCC_DeInit(void)103 ErrorStatus LL_RCC_DeInit(void)
104 {
105 /* Set HSION bit */
106 LL_RCC_HSI_Enable();
107
108 /* Wait for HSI READY bit */
109 while (LL_RCC_HSI_IsReady() != 1U)
110 {}
111
112 /* Configure HSI as system clock source */
113 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
114
115 /* Wait till clock switch is ready */
116 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
117 {}
118
119 /* Reset PLLON bit */
120 CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
121
122 /* Wait for PLL READY bit to be reset */
123 while (LL_RCC_PLL_IsReady() != 0U)
124 {}
125
126 /* Reset CFGR register */
127 LL_RCC_WriteReg(CFGR, 0x00000000U);
128
129 /* Reset HSEON, HSEBYP & CSSON bits */
130 CLEAR_BIT(RCC->CR, (RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSEBYP));
131
132 #if defined(RCC_CR_PLL2ON)
133 /* Reset PLL2ON bit */
134 CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
135 #endif /* RCC_CR_PLL2ON */
136
137 #if defined(RCC_CR_PLL3ON)
138 /* Reset PLL3ON bit */
139 CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
140 #endif /* RCC_CR_PLL3ON */
141
142 /* Set HSITRIM bits to the reset value */
143 LL_RCC_HSI_SetCalibTrimming(0x10U);
144
145 #if defined(RCC_CFGR2_PREDIV1)
146 /* Reset CFGR2 register */
147 LL_RCC_WriteReg(CFGR2, 0x00000000U);
148 #endif /* RCC_CFGR2_PREDIV1 */
149
150 /* Disable all interrupts */
151 LL_RCC_WriteReg(CIR, 0x00000000U);
152
153 /* Clear reset flags */
154 LL_RCC_ClearResetFlags();
155
156 return SUCCESS;
157 }
158
159 /**
160 * @}
161 */
162
163 /** @addtogroup RCC_LL_EF_Get_Freq
164 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
165 * and different peripheral clocks available on the device.
166 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
167 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
168 * @note If SYSCLK source is PLL, function returns values based on
169 * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
170 * @note (**) HSI_VALUE is a defined constant but the real value may vary
171 * depending on the variations in voltage and temperature.
172 * @note (***) HSE_VALUE is a defined constant, user has to ensure that
173 * HSE_VALUE is same as the real frequency of the crystal used.
174 * Otherwise, this function may have wrong result.
175 * @note The result of this function could be incorrect when using fractional
176 * value for HSE crystal.
177 * @note This function can be used by the user application to compute the
178 * baud-rate for the communication peripherals or configure other parameters.
179 * @{
180 */
181
182 /**
183 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
184 * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
185 * must be called to update structure fields. Otherwise, any
186 * configuration based on this function will be incorrect.
187 * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
188 * @retval None
189 */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)190 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
191 {
192 /* Get SYSCLK frequency */
193 RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
194
195 /* HCLK clock frequency */
196 RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
197
198 /* PCLK1 clock frequency */
199 RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
200
201 /* PCLK2 clock frequency */
202 RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
203 }
204
205 #if defined(RCC_CFGR2_I2S2SRC)
206 /**
207 * @brief Return I2Sx clock frequency
208 * @param I2SxSource This parameter can be one of the following values:
209 * @arg @ref LL_RCC_I2S2_CLKSOURCE
210 * @arg @ref LL_RCC_I2S3_CLKSOURCE
211 * @retval I2S clock frequency (in Hz)
212 */
LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)213 uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)
214 {
215 uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
216
217 /* Check parameter */
218 assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource));
219
220 /* I2S1CLK clock frequency */
221 switch (LL_RCC_GetI2SClockSource(I2SxSource))
222 {
223 case LL_RCC_I2S2_CLKSOURCE_SYSCLK: /*!< System clock selected as I2S clock source */
224 case LL_RCC_I2S3_CLKSOURCE_SYSCLK:
225 i2s_frequency = RCC_GetSystemClockFreq();
226 break;
227
228 case LL_RCC_I2S2_CLKSOURCE_PLLI2S_VCO: /*!< PLLI2S oscillator clock selected as I2S clock source */
229 case LL_RCC_I2S3_CLKSOURCE_PLLI2S_VCO:
230 default:
231 i2s_frequency = RCC_PLLI2S_GetFreqDomain_I2S() * 2U;
232 break;
233 }
234
235 return i2s_frequency;
236 }
237 #endif /* RCC_CFGR2_I2S2SRC */
238
239 #if defined(USB) || defined(USB_OTG_FS)
240 /**
241 * @brief Return USBx clock frequency
242 * @param USBxSource This parameter can be one of the following values:
243 * @arg @ref LL_RCC_USB_CLKSOURCE
244 * @retval USB clock frequency (in Hz)
245 * @arg @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI), HSE or PLL is not ready
246 */
LL_RCC_GetUSBClockFreq(uint32_t USBxSource)247 uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource)
248 {
249 uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
250
251 /* Check parameter */
252 assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource));
253
254 /* USBCLK clock frequency */
255 switch (LL_RCC_GetUSBClockSource(USBxSource))
256 {
257 #if defined(RCC_CFGR_USBPRE)
258 case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */
259 if (LL_RCC_PLL_IsReady())
260 {
261 usb_frequency = RCC_PLL_GetFreqDomain_SYS();
262 }
263 break;
264
265 case LL_RCC_USB_CLKSOURCE_PLL_DIV_1_5: /* PLL clock divided by 1.5 used as USB clock source */
266 default:
267 if (LL_RCC_PLL_IsReady())
268 {
269 usb_frequency = (RCC_PLL_GetFreqDomain_SYS() * 3U) / 2U;
270 }
271 break;
272 #endif /* RCC_CFGR_USBPRE */
273 #if defined(RCC_CFGR_OTGFSPRE)
274 /* USBCLK = PLLVCO/2
275 = (2 x PLLCLK) / 2
276 = PLLCLK */
277 case LL_RCC_USB_CLKSOURCE_PLL_DIV_2: /* PLL clock used as USB clock source */
278 if (LL_RCC_PLL_IsReady())
279 {
280 usb_frequency = RCC_PLL_GetFreqDomain_SYS();
281 }
282 break;
283
284 /* USBCLK = PLLVCO/3
285 = (2 x PLLCLK) / 3 */
286 case LL_RCC_USB_CLKSOURCE_PLL_DIV_3: /* PLL clock divided by 3 used as USB clock source */
287 default:
288 if (LL_RCC_PLL_IsReady())
289 {
290 usb_frequency = (RCC_PLL_GetFreqDomain_SYS() * 2U) / 3U;
291 }
292 break;
293 #endif /* RCC_CFGR_OTGFSPRE */
294 }
295
296 return usb_frequency;
297 }
298 #endif /* USB */
299
300 /**
301 * @brief Return ADCx clock frequency
302 * @param ADCxSource This parameter can be one of the following values:
303 * @arg @ref LL_RCC_ADC_CLKSOURCE
304 * @retval ADC clock frequency (in Hz)
305 */
LL_RCC_GetADCClockFreq(uint32_t ADCxSource)306 uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
307 {
308 uint32_t adc_prescaler = 0U;
309 uint32_t adc_frequency = 0U;
310
311 /* Check parameter */
312 assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
313
314 /* Get ADC prescaler */
315 adc_prescaler = LL_RCC_GetADCClockSource(ADCxSource);
316
317 /* ADC frequency = PCLK2 frequency / ADC prescaler (2, 4, 6 or 8) */
318 adc_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()))
319 / (((adc_prescaler >> POSITION_VAL(ADCxSource)) + 1U) * 2U);
320
321 return adc_frequency;
322 }
323
324 /**
325 * @}
326 */
327
328 /**
329 * @}
330 */
331
332 /** @addtogroup RCC_LL_Private_Functions
333 * @{
334 */
335
336 /**
337 * @brief Return SYSTEM clock frequency
338 * @retval SYSTEM clock frequency (in Hz)
339 */
RCC_GetSystemClockFreq(void)340 uint32_t RCC_GetSystemClockFreq(void)
341 {
342 uint32_t frequency = 0U;
343
344 /* Get SYSCLK source -------------------------------------------------------*/
345 switch (LL_RCC_GetSysClkSource())
346 {
347 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
348 frequency = HSI_VALUE;
349 break;
350
351 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
352 frequency = HSE_VALUE;
353 break;
354
355 case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
356 frequency = RCC_PLL_GetFreqDomain_SYS();
357 break;
358
359 default:
360 frequency = HSI_VALUE;
361 break;
362 }
363
364 return frequency;
365 }
366
367 /**
368 * @brief Return HCLK clock frequency
369 * @param SYSCLK_Frequency SYSCLK clock frequency
370 * @retval HCLK clock frequency (in Hz)
371 */
RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)372 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
373 {
374 /* HCLK clock frequency */
375 return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
376 }
377
378 /**
379 * @brief Return PCLK1 clock frequency
380 * @param HCLK_Frequency HCLK clock frequency
381 * @retval PCLK1 clock frequency (in Hz)
382 */
RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)383 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
384 {
385 /* PCLK1 clock frequency */
386 return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
387 }
388
389 /**
390 * @brief Return PCLK2 clock frequency
391 * @param HCLK_Frequency HCLK clock frequency
392 * @retval PCLK2 clock frequency (in Hz)
393 */
RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)394 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
395 {
396 /* PCLK2 clock frequency */
397 return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
398 }
399
400 /**
401 * @brief Return PLL clock frequency used for system domain
402 * @retval PLL clock frequency (in Hz)
403 */
RCC_PLL_GetFreqDomain_SYS(void)404 uint32_t RCC_PLL_GetFreqDomain_SYS(void)
405 {
406 uint32_t pllinputfreq = 0U, pllsource = 0U;
407
408 /* PLL_VCO = (HSE_VALUE, HSI_VALUE or PLL2 / PLL Predivider) * PLL Multiplicator */
409
410 /* Get PLL source */
411 pllsource = LL_RCC_PLL_GetMainSource();
412
413 switch (pllsource)
414 {
415 case LL_RCC_PLLSOURCE_HSI_DIV_2: /* HSI used as PLL clock source */
416 pllinputfreq = HSI_VALUE / 2U;
417 break;
418
419 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
420 pllinputfreq = HSE_VALUE / (LL_RCC_PLL_GetPrediv() + 1U);
421 break;
422
423 #if defined(RCC_PLL2_SUPPORT)
424 case LL_RCC_PLLSOURCE_PLL2: /* PLL2 used as PLL clock source */
425 pllinputfreq = RCC_PLL2_GetFreqClockFreq() / (LL_RCC_PLL_GetPrediv() + 1U);
426 break;
427 #endif /* RCC_PLL2_SUPPORT */
428
429 default:
430 pllinputfreq = HSI_VALUE / 2U;
431 break;
432 }
433 return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetMultiplicator());
434 }
435
436 #if defined(RCC_PLL2_SUPPORT)
437 /**
438 * @brief Return PLL clock frequency used for system domain
439 * @retval PLL clock frequency (in Hz)
440 */
RCC_PLL2_GetFreqClockFreq(void)441 uint32_t RCC_PLL2_GetFreqClockFreq(void)
442 {
443 return __LL_RCC_CALC_PLL2CLK_FREQ(HSE_VALUE, LL_RCC_PLL2_GetMultiplicator(), LL_RCC_HSE_GetPrediv2());
444 }
445 #endif /* RCC_PLL2_SUPPORT */
446
447 #if defined(RCC_PLLI2S_SUPPORT)
448 /**
449 * @brief Return PLL clock frequency used for system domain
450 * @retval PLL clock frequency (in Hz)
451 */
RCC_PLLI2S_GetFreqDomain_I2S(void)452 uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void)
453 {
454 return __LL_RCC_CALC_PLLI2SCLK_FREQ(HSE_VALUE, LL_RCC_PLLI2S_GetMultiplicator(), LL_RCC_HSE_GetPrediv2());
455 }
456 #endif /* RCC_PLLI2S_SUPPORT */
457
458 /**
459 * @}
460 */
461
462 /**
463 * @}
464 */
465
466 #endif /* defined(RCC) */
467
468 /**
469 * @}
470 */
471
472 #endif /* USE_FULL_LL_DRIVER */
473
474 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
475