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>&copy; 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