1 /**
2 ******************************************************************************
3 * @file stm32l1xx_ll_rcc.c
4 * @author MCD Application Team
5 * @brief RCC LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright(c) 2017 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 #if defined(USE_FULL_LL_DRIVER)
20
21 /* Includes ------------------------------------------------------------------*/
22 #include "stm32l1xx_ll_rcc.h"
23 /** @addtogroup STM32L1xx_LL_Driver
24 * @{
25 */
26
27 #if defined(RCC)
28
29 /** @defgroup RCC_LL RCC
30 * @{
31 */
32
33 /* Private types -------------------------------------------------------------*/
34 /* Private variables ---------------------------------------------------------*/
35
36 /* Private constants ---------------------------------------------------------*/
37 /* Private macros ------------------------------------------------------------*/
38 /* Private function prototypes -----------------------------------------------*/
39 /** @defgroup RCC_LL_Private_Functions RCC Private functions
40 * @{
41 */
42 static uint32_t RCC_GetSystemClockFreq(void);
43 static uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
44 static uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
45 static uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
46 static uint32_t RCC_PLL_GetFreqDomain_SYS(void);
47 /**
48 * @}
49 */
50
51
52 /* Exported functions --------------------------------------------------------*/
53 /** @addtogroup RCC_LL_Exported_Functions
54 * @{
55 */
56
57 /** @addtogroup RCC_LL_EF_Init
58 * @{
59 */
60
61 /**
62 * @brief Reset the RCC clock configuration to the default reset state.
63 * @note The default reset state of the clock configuration is given below:
64 * - MSI ON and used as system clock source
65 * - HSE, HSI and PLL OFF
66 * - AHB, APB1 and APB2 prescaler set to 1.
67 * - CSS, MCO OFF
68 * - All interrupts disabled
69 * @note This function doesn't modify the configuration of the
70 * - Peripheral clocks
71 * - LSI, LSE and RTC clocks
72 * @retval An ErrorStatus enumeration value:
73 * - SUCCESS: RCC registers are de-initialized
74 * - ERROR: not applicable
75 */
LL_RCC_DeInit(void)76 ErrorStatus LL_RCC_DeInit(void)
77 {
78 __IO uint32_t vl_mask;
79
80 /* Set MSION bit */
81 LL_RCC_MSI_Enable();
82
83 /* Insure MSIRDY bit is set before writing default MSIRANGE value */
84 while (LL_RCC_MSI_IsReady() == 0U)
85 {
86 __NOP();
87 }
88
89 /* Set MSIRANGE default value */
90 LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5);
91 /* Set MSITRIM bits to the reset value*/
92 LL_RCC_MSI_SetCalibTrimming(0U);
93
94 /* Set HSITRIM bits to the reset value*/
95 LL_RCC_HSI_SetCalibTrimming(0x10U);
96
97 /* Reset SW, HPRE, PPRE and MCOSEL bits */
98 vl_mask = 0xFFFFFFFFU;
99 CLEAR_BIT(vl_mask, (RCC_CFGR_SW | RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2 | RCC_CFGR_MCOSEL));
100 LL_RCC_WriteReg(CFGR, vl_mask);
101
102 /* Read CR register */
103 vl_mask = LL_RCC_ReadReg(CR);
104
105 /* Reset HSION, HSEON, CSSON, PLLON bits */
106 CLEAR_BIT(vl_mask, (RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSION));
107 LL_RCC_WriteReg(CR, vl_mask);
108
109 /* Reset HSEBYP bit */
110 LL_RCC_HSE_DisableBypass();
111
112 /* Insure PLL is disabled before to reset PLLSRC/PLLMUL/PLLDIV in CFGR register */
113 while(LL_RCC_PLL_IsReady() != 0U) {};
114
115 /* Reset CFGR register */
116 LL_RCC_WriteReg(CFGR, 0x00000000U);
117
118 /* Disable all interrupts */
119 LL_RCC_WriteReg(CIR, 0x00000000U);
120
121 /* Clear pending flags */
122 #if defined(RCC_LSECSS_SUPPORT)
123 vl_mask = (LL_RCC_CIR_LSIRDYC | LL_RCC_CIR_LSERDYC | LL_RCC_CIR_HSIRDYC | LL_RCC_CIR_HSERDYC | \
124 LL_RCC_CIR_PLLRDYC | LL_RCC_CIR_MSIRDYC | LL_RCC_CIR_LSECSSC | LL_RCC_CIR_CSSC);
125 #else
126 vl_mask = (LL_RCC_CIR_LSIRDYC | LL_RCC_CIR_LSERDYC | LL_RCC_CIR_HSIRDYC | LL_RCC_CIR_HSERDYC | \
127 LL_RCC_CIR_PLLRDYC | LL_RCC_CIR_MSIRDYC | LL_RCC_CIR_CSSC);
128 #endif /* RCC_LSECSS_SUPPORT */
129 LL_RCC_WriteReg(CIR, vl_mask);
130
131 /* Clear reset flags */
132 LL_RCC_ClearResetFlags();
133
134 return SUCCESS;
135 }
136
137 /**
138 * @}
139 */
140
141 /** @addtogroup RCC_LL_EF_Get_Freq
142 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
143 * and different peripheral clocks available on the device.
144 * @note If SYSCLK source is MSI, function returns values based on MSI clock(*)
145 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
146 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
147 * @note If SYSCLK source is PLL, function returns values based on
148 * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
149 * @note (*) MSI clock depends on the selected MSI range but the real value
150 * may vary depending on the variations in voltage and temperature.
151 * @note (**) HSI_VALUE is a defined constant but the real value may vary
152 * depending on the variations in voltage and temperature.
153 * @note (***) HSE_VALUE is a defined constant, user has to ensure that
154 * HSE_VALUE is same as the real frequency of the crystal used.
155 * Otherwise, this function may have wrong result.
156 * @note The result of this function could be incorrect when using fractional
157 * value for HSE crystal.
158 * @note This function can be used by the user application to compute the
159 * baud-rate for the communication peripherals or configure other parameters.
160 * @{
161 */
162
163 /**
164 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
165 * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
166 * must be called to update structure fields. Otherwise, any
167 * configuration based on this function will be incorrect.
168 * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
169 * @retval None
170 */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)171 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
172 {
173 /* Get SYSCLK frequency */
174 RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
175
176 /* HCLK clock frequency */
177 RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
178
179 /* PCLK1 clock frequency */
180 RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
181
182 /* PCLK2 clock frequency */
183 RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
184 }
185
186 /**
187 * @}
188 */
189
190 /**
191 * @}
192 */
193
194 /** @addtogroup RCC_LL_Private_Functions
195 * @{
196 */
197
198 /**
199 * @brief Return SYSTEM clock frequency
200 * @retval SYSTEM clock frequency (in Hz)
201 */
RCC_GetSystemClockFreq(void)202 static uint32_t RCC_GetSystemClockFreq(void)
203 {
204 uint32_t frequency;
205
206 /* Get SYSCLK source -------------------------------------------------------*/
207 switch (LL_RCC_GetSysClkSource())
208 {
209 case LL_RCC_SYS_CLKSOURCE_STATUS_MSI: /* MSI used as system clock source */
210 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
211 break;
212
213 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
214 frequency = HSI_VALUE;
215 break;
216
217 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
218 frequency = HSE_VALUE;
219 break;
220
221 case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
222 frequency = RCC_PLL_GetFreqDomain_SYS();
223 break;
224
225 default:
226 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
227 break;
228 }
229
230 return frequency;
231 }
232
233 /**
234 * @brief Return HCLK clock frequency
235 * @param SYSCLK_Frequency SYSCLK clock frequency
236 * @retval HCLK clock frequency (in Hz)
237 */
RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)238 static uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
239 {
240 /* HCLK clock frequency */
241 return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
242 }
243
244 /**
245 * @brief Return PCLK1 clock frequency
246 * @param HCLK_Frequency HCLK clock frequency
247 * @retval PCLK1 clock frequency (in Hz)
248 */
RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)249 static uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
250 {
251 /* PCLK1 clock frequency */
252 return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
253 }
254
255 /**
256 * @brief Return PCLK2 clock frequency
257 * @param HCLK_Frequency HCLK clock frequency
258 * @retval PCLK2 clock frequency (in Hz)
259 */
RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)260 static uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
261 {
262 /* PCLK2 clock frequency */
263 return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
264 }
265
266 /**
267 * @brief Return PLL clock frequency used for system domain
268 * @retval PLL clock frequency (in Hz)
269 */
RCC_PLL_GetFreqDomain_SYS(void)270 static uint32_t RCC_PLL_GetFreqDomain_SYS(void)
271 {
272 uint32_t pllsource, pllinputfreq;
273
274 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL divider) * PLL Multiplicator */
275
276 /* Get PLL source */
277 pllsource = LL_RCC_PLL_GetMainSource();
278
279 switch (pllsource)
280 {
281 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
282 pllinputfreq = HSI_VALUE;
283 break;
284
285 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
286 pllinputfreq = HSE_VALUE;
287 break;
288
289 default:
290 pllinputfreq = HSI_VALUE;
291 break;
292 }
293 return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetMultiplicator(), LL_RCC_PLL_GetDivider());
294 }
295 /**
296 * @}
297 */
298
299 /**
300 * @}
301 */
302
303 #endif /* defined(RCC) */
304
305 /**
306 * @}
307 */
308
309 #endif /* USE_FULL_LL_DRIVER */
310
311 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
312