1 /**
2 ******************************************************************************
3 * @file stm32c0xx_ll_rcc.c
4 * @author MCD Application Team
5 * @brief RCC LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2022 STMicroelectronics.
10 * All rights reserved.
11 *
12 * This software is licensed under terms that can be found in the LICENSE file
13 * in 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 "stm32c0xx_ll_rcc.h"
22 #ifdef USE_FULL_ASSERT
23 #include "stm32_assert.h"
24 #else
25 #define assert_param(expr) ((void)0U)
26 #endif /* USE_FULL_ASSERT */
27 /** @addtogroup STM32C0xx_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
45 #define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_USART1_CLKSOURCE)
46 #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_I2C1_CLKSOURCE)
47 #define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_ADC_CLKSOURCE)
48 #define IS_LL_RCC_I2S_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_I2S1_CLKSOURCE)
49 #if defined (USB_DRD_FS)
50 #define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_USB_CLKSOURCE)
51 #endif /* USB_DRD_FS */
52
53 /**
54 * @}
55 */
56
57 /* Private function prototypes -----------------------------------------------*/
58 /** @defgroup RCC_LL_Private_Functions RCC Private functions
59 * @{
60 */
61 uint32_t RCC_GetSystemClockFreq(void);
62 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
63 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
64 /**
65 * @}
66 */
67
68
69 /* Exported functions --------------------------------------------------------*/
70 /** @addtogroup RCC_LL_Exported_Functions
71 * @{
72 */
73
74 /** @addtogroup RCC_LL_EF_Init
75 * @{
76 */
77
78 /**
79 * @brief Reset the RCC clock configuration to the default reset state.
80 * @note The default reset state of the clock configuration is given below:
81 * - HSI ON and used as system clock source
82 * - HSE OFF
83 * - AHB and APB1 prescaler set to 1.
84 * - CSS, MCO OFF
85 * - All interrupts disabled
86 * @note This function does not modify the configuration of the
87 * - Peripheral clocks
88 * - LSI, LSE and RTC clocks
89 * @retval An ErrorStatus enumeration value:
90 * - SUCCESS: RCC registers are de-initialized
91 * - ERROR: not applicable
92 */
LL_RCC_DeInit(void)93 ErrorStatus LL_RCC_DeInit(void)
94 {
95 /* Set HSION bit and wait for HSI READY bit */
96 LL_RCC_HSI_Enable();
97 while (LL_RCC_HSI_IsReady() != 1U)
98 {}
99
100 /* Set HSITRIM bits to reset value*/
101 LL_RCC_HSI_SetCalibTrimming(0x40U);
102
103 /* Reset CFGR register */
104 LL_RCC_WriteReg(CFGR, 0x00000000U);
105
106 /* Reset whole CR register but HSI in 2 steps in case HSEBYP is set */
107 LL_RCC_WriteReg(CR, RCC_CR_HSION);
108 while (LL_RCC_HSE_IsReady() != 0U)
109 {}
110 LL_RCC_WriteReg(CR, RCC_CR_HSION);
111
112 /* Disable all interrupts */
113 LL_RCC_WriteReg(CIER, 0x00000000U);
114
115 /* Clear all interrupts flags */
116 LL_RCC_WriteReg(CICR, 0xFFFFFFFFU);
117
118 return SUCCESS;
119 }
120
121 /**
122 * @}
123 */
124
125 /** @addtogroup RCC_LL_EF_Get_Freq
126 * @brief Return the frequencies of different on chip clocks; System, AHB and APB1 buses clocks
127 * and different peripheral clocks available on the device.
128 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE divided by HSI division factor(**)
129 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
130 * @note (**) HSI_VALUE is a constant defined in this file (default value
131 * 48 MHz) but the real value may vary depending on the variations
132 * in voltage and temperature.
133 * @note (***) HSE_VALUE is a constant defined in this file (default value
134 * 48 MHz), user has to ensure that HSE_VALUE is same as the real
135 * frequency of the crystal used. Otherwise, this function may
136 * have wrong result.
137 * @note The result of this function could be incorrect when using fractional
138 * value for HSE crystal.
139 * @note This function can be used by the user application to compute the
140 * baud-rate for the communication peripherals or configure other parameters.
141 * @{
142 */
143
144 /**
145 * @brief Return the frequencies of different on chip clocks; System, AHB and APB1 buses clocks
146 * @note Each time SYSCLK, HCLK and/or PCLK1 clock changes, this function
147 * must be called to update structure fields. Otherwise, any
148 * configuration based on this function will be incorrect.
149 * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
150 * @retval None
151 */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)152 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
153 {
154 /* Get SYSCLK frequency */
155 RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
156
157 /* HCLK clock frequency */
158 RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
159
160 /* PCLK1 clock frequency */
161 RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
162 }
163
164 /**
165 * @brief Return USARTx clock frequency
166 * @param USARTxSource This parameter can be one of the following values:
167 * @arg @ref LL_RCC_USART1_CLKSOURCE
168 * @retval USART clock frequency (in Hz)
169 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
170 */
LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)171 uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)
172 {
173 uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
174
175 /* Check parameter */
176 assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource));
177
178 if (USARTxSource == LL_RCC_USART1_CLKSOURCE)
179 {
180 /* USART1CLK clock frequency */
181 switch (LL_RCC_GetUSARTClockSource(USARTxSource))
182 {
183 case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
184 usart_frequency = RCC_GetSystemClockFreq();
185 break;
186
187 case LL_RCC_USART1_CLKSOURCE_HSIKER: /* USART1 Clock is HSI Kernel */
188 if (LL_RCC_HSI_IsReady() == 1U)
189 {
190 usart_frequency = (HSI_VALUE / ((LL_RCC_HSIKER_GetDivider() >> RCC_CR_HSIKERDIV_Pos) + 1U));
191 }
192 break;
193
194 case LL_RCC_USART1_CLKSOURCE_LSE: /* USART1 Clock is LSE Osc. */
195 if (LL_RCC_LSE_IsReady() == 1U)
196 {
197 usart_frequency = LSE_VALUE;
198 }
199 break;
200
201 case LL_RCC_USART1_CLKSOURCE_PCLK1: /* USART1 Clock is PCLK1 */
202 default:
203 usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
204 break;
205 }
206 }
207 else
208 {
209 }
210 return usart_frequency;
211 }
212
213 /**
214 * @brief Return I2Cx clock frequency
215 * @param I2CxSource This parameter can be one of the following values:
216 * @arg @ref LL_RCC_I2C1_CLKSOURCE
217 * @arg @ref LL_RCC_I2C2_CLKSOURCE (*)
218 * @retval I2C clock frequency (in Hz)
219 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that HSI oscillator is not ready
220 * @note (*) peripheral not available on all devices
221 */
LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)222 uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)
223 {
224 uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
225
226 /* Check parameter */
227 assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource));
228
229 if (I2CxSource == LL_RCC_I2C1_CLKSOURCE)
230 {
231 /* I2C1 CLK clock frequency */
232 switch (LL_RCC_GetI2CClockSource(I2CxSource))
233 {
234 case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
235 i2c_frequency = RCC_GetSystemClockFreq();
236 break;
237
238 case LL_RCC_I2C1_CLKSOURCE_HSIKER: /* I2C1 Clock is HSI Kernel */
239 if (LL_RCC_HSI_IsReady() == 1U)
240 {
241 i2c_frequency = (HSI_VALUE / ((LL_RCC_HSIKER_GetDivider() >> RCC_CR_HSIKERDIV_Pos) + 1U));
242 }
243 break;
244
245 case LL_RCC_I2C1_CLKSOURCE_PCLK1: /* I2C1 Clock is PCLK1 */
246 default:
247 i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
248 break;
249 }
250 }
251 #if defined(I2C2)
252 else if (I2CxSource == LL_RCC_I2C2_CLKSOURCE)
253 {
254 /* I2C2 CLK clock frequency */
255 switch (LL_RCC_GetI2CClockSource(I2CxSource))
256 {
257 case LL_RCC_I2C2_CLKSOURCE_SYSCLK: /* I2C2 Clock is System Clock */
258 i2c_frequency = RCC_GetSystemClockFreq();
259 break;
260
261 case LL_RCC_I2C2_CLKSOURCE_HSIKER: /* I2C2 Clock is HSI Kernel */
262 if (LL_RCC_HSI_IsReady() == 1U)
263 {
264 i2c_frequency = (HSI_VALUE / ((LL_RCC_HSIKER_GetDivider() >> RCC_CR_HSIKERDIV_Pos) + 1U));
265 }
266 break;
267
268 case LL_RCC_I2C2_CLKSOURCE_PCLK1: /* I2C2 Clock is PCLK1 */
269 default:
270 i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
271 break;
272 }
273 }
274 #endif /* I2C2 */
275
276 return i2c_frequency;
277 }
278
279 /**
280 * @brief Return I2Sx clock frequency
281 * @param I2SxSource This parameter can be one of the following values:
282 * @arg @ref LL_RCC_I2S1_CLKSOURCE
283 * @retval I2S clock frequency (in Hz)
284 * @arg @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready
285 */
LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)286 uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)
287 {
288 uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
289
290 /* Check parameter */
291 assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource));
292
293 if (I2SxSource == LL_RCC_I2S1_CLKSOURCE)
294 {
295 /* I2S1 CLK clock frequency */
296 switch (LL_RCC_GetI2SClockSource(I2SxSource))
297 {
298 case LL_RCC_I2S1_CLKSOURCE_HSIKER: /* I2S1 Clock is HSI Kernel */
299 if (LL_RCC_HSI_IsReady() == 1U)
300 {
301 i2s_frequency = (HSI_VALUE / ((LL_RCC_HSIKER_GetDivider() >> RCC_CR_HSIKERDIV_Pos) + 1U));
302 }
303 break;
304
305 case LL_RCC_I2S1_CLKSOURCE_PIN: /* I2S1 Clock is External clock */
306 i2s_frequency = EXTERNAL_CLOCK_VALUE;
307 break;
308
309 case LL_RCC_I2S1_CLKSOURCE_SYSCLK: /* I2S1 Clock is System Clock */
310 default:
311 i2s_frequency = RCC_GetSystemClockFreq();
312 break;
313 }
314 }
315
316 return i2s_frequency;
317 }
318
319 /**
320 * @brief Return ADCx clock frequency
321 * @param ADCxSource This parameter can be one of the following values:
322 * @arg @ref LL_RCC_ADC_CLKSOURCE
323 * @retval ADC clock frequency (in Hz)
324 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI) is not ready
325 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
326 */
LL_RCC_GetADCClockFreq(uint32_t ADCxSource)327 uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
328 {
329 uint32_t adc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
330
331 /* Check parameter */
332 assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
333
334 /* ADCCLK clock frequency */
335 switch (LL_RCC_GetADCClockSource(ADCxSource))
336 {
337 case LL_RCC_ADC_CLKSOURCE_SYSCLK: /* SYSCLK clock used as ADC clock source */
338 adc_frequency = RCC_GetSystemClockFreq();
339 break;
340 case LL_RCC_ADC_CLKSOURCE_HSIKER : /* HSI clock Kernel used as ADC clock source */
341 if (LL_RCC_HSI_IsReady() == 1U)
342 {
343 adc_frequency = (HSI_VALUE / ((LL_RCC_HSIKER_GetDivider() >> RCC_CR_HSIKERDIV_Pos) + 1U));
344 }
345 break;
346 default:
347 adc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
348 break;
349 }
350
351 return adc_frequency;
352 }
353
354 /**
355 * @brief Return RTC clock frequency
356 * @retval RTC clock frequency (in Hz)
357 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillators (LSI, LSE or HSE) are not ready
358 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
359 */
LL_RCC_GetRTCClockFreq(void)360 uint32_t LL_RCC_GetRTCClockFreq(void)
361 {
362 uint32_t rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
363
364 /* RTCCLK clock frequency */
365 switch (LL_RCC_GetRTCClockSource())
366 {
367 case LL_RCC_RTC_CLKSOURCE_LSE: /* LSE clock used as RTC clock source */
368 if (LL_RCC_LSE_IsReady() == 1U)
369 {
370 rtc_frequency = LSE_VALUE;
371 }
372 break;
373
374 case LL_RCC_RTC_CLKSOURCE_LSI: /* LSI clock used as RTC clock source */
375 if (LL_RCC_LSI_IsReady() == 1U)
376 {
377 rtc_frequency = LSI_VALUE;
378 }
379 break;
380
381 case LL_RCC_RTC_CLKSOURCE_HSE_DIV32: /* HSE clock used as ADC clock source */
382 rtc_frequency = HSE_VALUE / 32U;
383 break;
384
385 case LL_RCC_RTC_CLKSOURCE_NONE: /* No clock used as RTC clock source */
386 default:
387 rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
388 break;
389 }
390
391 return rtc_frequency;
392 }
393
394 #if defined(USB_DRD_FS)
395 /**
396 * @brief Return USBx clock frequency
397 * @param USBxSource This parameter can be one of the following values:
398 * @arg @ref LL_RCC_USB_CLKSOURCE
399 * @retval USB clock frequency (in Hz)
400 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI48) is not ready
401 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
402 */
LL_RCC_GetUSBClockFreq(uint32_t USBxSource)403 uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource)
404 {
405 uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
406
407 /* Check parameter */
408 assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource));
409
410 /* USBCLK clock frequency */
411 switch (LL_RCC_GetUSBClockSource(USBxSource))
412 {
413 #if defined(RCC_HSI48_SUPPORT)
414 case LL_RCC_USB_CLKSOURCE_HSI48: /* HSI48 used as USB clock source */
415 if (LL_RCC_HSI48_IsReady() != 0U)
416 {
417 usb_frequency = HSI48_VALUE;
418 }
419 break;
420 #endif /* RCC_HSI48_SUPPORT */
421
422 case LL_RCC_USB_CLKSOURCE_HSE: /* HSE used as USB clock source */
423 if (LL_RCC_HSE_IsReady() != 0U)
424 {
425 usb_frequency = HSE_VALUE;
426 }
427 break;
428
429 default:
430 usb_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
431 break;
432 }
433
434 return usb_frequency;
435 }
436 #endif /* USB_DRD_FS */
437
438 /**
439 * @}
440 */
441
442 /**
443 * @}
444 */
445
446 /** @addtogroup RCC_LL_Private_Functions
447 * @{
448 */
449
450 /**
451 * @brief Return SYSTEM clock frequency
452 * @retval SYSTEM clock frequency (in Hz)
453 */
RCC_GetSystemClockFreq(void)454 uint32_t RCC_GetSystemClockFreq(void)
455 {
456 uint32_t frequency;
457 uint32_t hsidiv;
458 #if defined(RCC_CR_SYSDIV)
459 uint32_t sysdiv = (uint32_t)(((RCC->CR & RCC_CR_SYSDIV) >> RCC_CR_SYSDIV_Pos) + 1U);
460 #endif /* RCC_CR_SYSDIV */
461
462 /* Get SYSCLK source -------------------------------------------------------*/
463 switch (LL_RCC_GetSysClkSource())
464 {
465 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
466 frequency = HSE_VALUE;
467 break;
468
469 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
470 hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
471 frequency = (HSI_VALUE / hsidiv);
472 break;
473
474 case LL_RCC_SYS_CLKSOURCE_STATUS_LSE: /* LSE used as system clock source */
475 frequency = LSE_VALUE;
476 break;
477
478 case LL_RCC_SYS_CLKSOURCE_STATUS_LSI: /* LSI used as system clock source */
479 frequency = LSI_VALUE;
480 break;
481
482 #if defined(RCC_HSI48_SUPPORT)
483 case LL_RCC_SYS_CLKSOURCE_STATUS_HSIUSB48: /* HSIUSB48 used as system clock source */
484 frequency = HSI48_VALUE;
485 break;
486 #endif /* RCC_HSI48_SUPPORT */
487
488 default:
489 hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
490 frequency = (HSI_VALUE / hsidiv);
491 break;
492 }
493 #if defined(RCC_CR_SYSDIV)
494 frequency = frequency / sysdiv;
495 #endif /* RCC_CR_SYSDIV */
496
497 return frequency;
498 }
499
500 /**
501 * @brief Return HCLK clock frequency
502 * @param SYSCLK_Frequency SYSCLK clock frequency
503 * @retval HCLK clock frequency (in Hz)
504 */
RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)505 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
506 {
507 /* HCLK clock frequency */
508 return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
509 }
510
511 /**
512 * @brief Return PCLK1 clock frequency
513 * @param HCLK_Frequency HCLK clock frequency
514 * @retval PCLK1 clock frequency (in Hz)
515 */
RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)516 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
517 {
518 /* PCLK1 clock frequency */
519 return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
520 }
521
522 /**
523 * @}
524 */
525
526 /**
527 * @}
528 */
529
530 #endif /* defined(RCC) */
531
532 /**
533 * @}
534 */
535
536 #endif /* USE_FULL_LL_DRIVER */
537