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