1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_ll_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 20223 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 "stm32wbaxx_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 STM32WBAxx_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 #if defined(USART2)
45 #define IS_LL_RCC_USART2_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_USART2_CLKSOURCE)
46 #else
47 #define IS_LL_RCC_USART2_CLKSOURCE(__VALUE__) (0)
48 #endif
49 
50 #define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \
51                                                || IS_LL_RCC_USART2_CLKSOURCE(__VALUE__))
52 
53 #if defined(I2C1)
54 #define IS_LL_RCC_I2C1_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_I2C1_CLKSOURCE)
55 #else
56 #define IS_LL_RCC_I2C1_CLKSOURCE(__VALUE__) (0)
57 #endif
58 
59 #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C3_CLKSOURCE) \
60                                              || IS_LL_RCC_I2C1_CLKSOURCE(__VALUE__))
61 
62 #if defined(SPI1)
63 #define IS_LL_RCC_SPI1_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_SPI1_CLKSOURCE)
64 #else
65 #define IS_LL_RCC_SPI1_CLKSOURCE(__VALUE__) (0)
66 #endif
67 
68 #define IS_LL_RCC_SPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SPI3_CLKSOURCE) \
69                                              || IS_LL_RCC_SPI1_CLKSOURCE(__VALUE__))
70 
71 #if defined(LPTIM2)
72 #define IS_LL_RCC_LPTIM2_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_LPTIM2_CLKSOURCE)
73 #else
74 #define IS_LL_RCC_LPTIM2_CLKSOURCE(__VALUE__) (0)
75 #endif
76 
77 #define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) \
78                                                || IS_LL_RCC_LPTIM2_CLKSOURCE(__VALUE__))
79 
80 #define IS_LL_RCC_LPUART_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_LPUART1_CLKSOURCE)
81 
82 #if defined(SAI1)
83 #define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__)    ((__VALUE__) == LL_RCC_SAI1_CLKSOURCE)
84 #endif /* SAI1 */
85 
86 #define IS_LL_RCC_RNG_CLKSOURCE(__VALUE__)    ((__VALUE__) == LL_RCC_RNG_CLKSOURCE)
87 
88 #define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__)    ((__VALUE__) == LL_RCC_ADC_CLKSOURCE)
89 
90 /**
91   * @}
92   */
93 
94 /* Private function prototypes -----------------------------------------------*/
95 /** @defgroup RCC_LL_Private_Functions RCC Private functions
96   * @{
97   */
98 uint32_t RCC_GetSystemClockFreq(void);
99 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
100 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
101 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
102 uint32_t RCC_GetPCLK7ClockFreq(uint32_t HCLK_Frequency);
103 uint32_t RCC_PLL1R_GetFreqDomain(void);
104 uint32_t RCC_PLL1P_GetFreqDomain(void);
105 uint32_t RCC_PLL1Q_GetFreqDomain(void);
106 /**
107   * @}
108   */
109 
110 /* Exported functions --------------------------------------------------------*/
111 /** @addtogroup RCC_LL_Exported_Functions
112   * @{
113   */
114 
115 /** @addtogroup RCC_LL_EF_Init
116   * @{
117   */
118 
119 /**
120   * @brief  Reset the RCC clock configuration to the default reset state.
121   * @note   The default reset state of the clock configuration is given below:
122   *         - MSI  ON and used as system clock source
123   *         - HSE, HSI, PLL1, PLL2 and PLL3 OFF
124   *         - AHB, APB1, APB2 and APB3 prescaler set to 1.
125   *         - CSS, MCO OFF
126   *         - All interrupts disabled
127   * @note   This function doesn't modify the configuration of the
128   *         - Peripheral clocks
129   *         - LSI, LSE and RTC clocks
130   * @retval An ErrorStatus enumeration value:
131   *          - SUCCESS: RCC registers are de-initialized
132   *          - ERROR: not applicable
133   */
LL_RCC_DeInit(void)134 ErrorStatus LL_RCC_DeInit(void)
135 {
136   uint32_t vl_mask;
137 
138   /* Set HSION bit */
139   LL_RCC_HSI_Enable();
140 
141   /* Insure HSIRDY bit is set */
142   while (LL_RCC_HSI_IsReady() == 0U)
143   {
144   }
145 
146   /* Set HSITRIM bits to the reset value*/
147   LL_RCC_HSI_SetCalibTrimming(0x20U);
148 
149   /* Reset CFGR register */
150   LL_RCC_WriteReg(CFGR1, 0x00000000U);
151   LL_RCC_WriteReg(CFGR2, 0x00000000U);
152 
153   while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
154   {
155   }
156 
157   /* Read CR register */
158   vl_mask = LL_RCC_ReadReg(CR);
159 
160   /* Reset HSION, HSIKERON, HSEON and PLL1ON bits */
161   CLEAR_BIT(vl_mask, (RCC_CR_HSION | RCC_CR_HSIKERON  | RCC_CR_HSEON | RCC_CR_PLL1ON));
162 
163   /* Write new mask in CR register */
164   LL_RCC_WriteReg(CR, vl_mask);
165 
166   /* Wait for PLL1RDY, PLL2RDY and PLL3RDY bits to be reset */
167   while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
168   {
169   }
170 
171   /* Reset PLL1CFGR register */
172   LL_RCC_WriteReg(PLL1CFGR, 0x0U);
173 
174   /* Reset PLL1DIVR register */
175   LL_RCC_WriteReg(PLL1DIVR, 0x01010280U);
176 
177   /* Disable all interrupts */
178   LL_RCC_WriteReg(CIER, 0x00000000U);
179 
180   /* Clear all interrupt flags */
181 #if defined(RCC_LSI2_SUPPORT)
182   vl_mask = RCC_CICR_LSI1RDYC | RCC_CICR_LSI2RDYC | RCC_CICR_LSERDYC  | RCC_CICR_HSIRDYC | \
183             RCC_CICR_HSERDYC  | RCC_CICR_PLL1RDYC | RCC_CICR_HSECSSC;
184 #else
185   vl_mask = RCC_CICR_LSI1RDYC |                     RCC_CICR_LSERDYC  | RCC_CICR_HSIRDYC | \
186             RCC_CICR_HSERDYC  | RCC_CICR_PLL1RDYC | RCC_CICR_HSECSSC;
187 #endif
188   LL_RCC_WriteReg(CICR, vl_mask);
189 
190   /* Clear reset flags */
191   LL_RCC_ClearResetFlags();
192 
193 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
194   /* Reset secure configuration */
195   LL_RCC_ConfigSecure(LL_RCC_ALL_NSEC);
196 #endif /* __ARM_FEATURE_CMSE && (__ARM_FEATURE_CMSE == 3U) */
197 
198   return SUCCESS;
199 }
200 
201 /**
202   * @}
203   */
204 
205 /** @addtogroup RCC_LL_EF_Get_Freq
206   * @brief  Return the frequencies of different on chip clocks;  System, AHB, APB1 and APB2 buses clocks
207   *         and different peripheral clocks available on the device.
208   * @note   If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
209   * @note   If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
210   * @note   If SYSCLK source is PLL1, function returns values based on HSE_VALUE(***)
211   *         or HSI_VALUE(**) multiplied/divided by the PLL1 factors.
212   * @note   (**) HSI_VALUE is a constant defined in this file (default value
213   *              16 MHz) but the real value may vary depending on the variations
214   *              in voltage and temperature.
215   * @note   (***) HSE_VALUE is a constant defined in this file (default value
216   *               32 MHz), user has to ensure that HSE_VALUE is same as the real
217   *               frequency of the crystal used. Otherwise, this function may
218   *               have wrong result.
219   * @note   The result of this function could be incorrect when using fractional
220   *         value for HSE crystal.
221   * @note   This function can be used by the user application to compute the
222   *         baud-rate for the communication peripherals or configure other parameters.
223   * @{
224   */
225 
226 /**
227   * @brief  Return the frequencies of different on chip clocks;  System, AHB, APB1 and APB2 buses clocks
228   * @note   Each time SYSCLK, HCLK and/or PCLK1, PCLK2 and/or PCLK7 clock changes, this function
229   *         must be called to update structure fields. Otherwise, any
230   *         configuration based on this function will be incorrect.
231   * @param  RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
232   * @retval None
233   */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)234 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
235 {
236   /* Get SYSCLK frequency */
237   RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
238 
239   /* HCLK clock frequency */
240   RCC_Clocks->HCLK_Frequency   = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
241 
242   /* PCLK1 clock frequency */
243   RCC_Clocks->PCLK1_Frequency  = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
244 
245   /* PCLK2 clock frequency */
246   RCC_Clocks->PCLK2_Frequency  = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
247 
248   /* PCLK7 clock frequency */
249   RCC_Clocks->PCLK7_Frequency  = RCC_GetPCLK7ClockFreq(RCC_Clocks->HCLK_Frequency);
250 }
251 
252 /**
253   * @brief  Return USARTx clock frequency
254   * @param  USARTxSource This parameter can be one of the following values:
255   *         @arg @ref LL_RCC_USART1_CLKSOURCE
256   *         @arg @ref LL_RCC_USART2_CLKSOURCE
257   * @retval USART clock frequency (in Hz)
258   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
259   */
LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)260 uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)
261 {
262   uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
263 
264   /* Check parameter */
265   assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource));
266 
267   if (USARTxSource == LL_RCC_USART1_CLKSOURCE)
268   {
269     /* USART1CLK clock frequency */
270     switch (LL_RCC_GetUSARTClockSource(USARTxSource))
271     {
272       case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
273         usart_frequency = RCC_GetSystemClockFreq();
274         break;
275 
276       case LL_RCC_USART1_CLKSOURCE_HSI:    /* USART1 Clock is HSI Osc. */
277         if (LL_RCC_HSI_IsReady() != 0U)
278         {
279           usart_frequency = HSI_VALUE;
280         }
281         break;
282 
283       case LL_RCC_USART1_CLKSOURCE_LSE:    /* USART1 Clock is LSE Osc. */
284         if (LL_RCC_LSE_IsReady() != 0U)
285         {
286           usart_frequency = LSE_VALUE;
287         }
288         break;
289 
290       case LL_RCC_USART1_CLKSOURCE_PCLK2:  /* USART1 Clock is PCLK2 */
291         usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
292         break;
293 
294       default:
295         /* unreachable code */
296         break;
297     }
298   }
299 #if defined(USART2)
300   else if (USARTxSource == LL_RCC_USART2_CLKSOURCE)
301   {
302     /* USART2CLK clock frequency */
303     switch (LL_RCC_GetUSARTClockSource(USARTxSource))
304     {
305       case LL_RCC_USART2_CLKSOURCE_SYSCLK: /* USART2 Clock is System Clock */
306         usart_frequency = RCC_GetSystemClockFreq();
307         break;
308 
309       case LL_RCC_USART2_CLKSOURCE_HSI:    /* USART2 Clock is HSI Osc. */
310         if (LL_RCC_HSI_IsReady() != 0U)
311         {
312           usart_frequency = HSI_VALUE;
313         }
314         break;
315 
316       case LL_RCC_USART2_CLKSOURCE_LSE:    /* USART2 Clock is LSE Osc. */
317         if (LL_RCC_LSE_IsReady() != 0U)
318         {
319           usart_frequency = LSE_VALUE;
320         }
321         break;
322 
323       case LL_RCC_USART2_CLKSOURCE_PCLK1:  /* USART2 Clock is PCLK1 */
324         usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
325         break;
326 
327       default:
328         /* unreachable code */
329         break;
330     }
331   }
332 #endif /* USART2 */
333   else
334   {
335     /* nothing to do */
336   }
337 
338   return usart_frequency;
339 }
340 
341 /**
342   * @brief  Return SPIx clock frequency
343   * @param  SPIxSource This parameter can be one of the following values:
344   *         @arg @ref LL_RCC_SPI1_CLKSOURCE
345   *         @arg @ref LL_RCC_SPI3_CLKSOURCE
346   * @retval SPI clock frequency (in Hz)
347   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI) is not ready
348   */
LL_RCC_GetSPIClockFreq(uint32_t SPIxSource)349 uint32_t LL_RCC_GetSPIClockFreq(uint32_t SPIxSource)
350 {
351   uint32_t SPI_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
352 
353   /* Check parameter */
354   assert_param(IS_LL_RCC_SPI_CLKSOURCE(SPIxSource));
355 
356   if (SPIxSource == LL_RCC_SPI3_CLKSOURCE)
357   {
358     /* SPI3 CLK clock frequency */
359     switch (LL_RCC_GetSPIClockSource(SPIxSource))
360     {
361       case LL_RCC_SPI3_CLKSOURCE_SYSCLK: /* SPI3 Clock is System Clock */
362         SPI_frequency = RCC_GetSystemClockFreq();
363         break;
364 
365       case LL_RCC_SPI3_CLKSOURCE_HSI:    /* SPI3 Clock is HSI Osc. */
366         if (LL_RCC_HSI_IsReady() != 0U)
367         {
368           SPI_frequency = HSI_VALUE;
369         }
370         break;
371 
372       case LL_RCC_SPI3_CLKSOURCE_PCLK7:   /* SPI3 Clock is PCLK7 */
373         SPI_frequency = RCC_GetPCLK7ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
374         break;
375 
376       default:
377         /* unreachable code */
378         break;
379     }
380   }
381 #if defined(SPI1)
382   else if (SPIxSource == LL_RCC_SPI1_CLKSOURCE)
383   {
384     /* SPI1 CLK clock frequency */
385     switch (LL_RCC_GetSPIClockSource(SPIxSource))
386     {
387       case LL_RCC_SPI1_CLKSOURCE_SYSCLK: /* SPI1 Clock is System Clock */
388         SPI_frequency = RCC_GetSystemClockFreq();
389         break;
390 
391       case LL_RCC_SPI1_CLKSOURCE_HSI:    /* SPI1 Clock is HSI Osc. */
392         if (LL_RCC_HSI_IsReady() != 0U)
393         {
394           SPI_frequency = HSI_VALUE;
395         }
396         break;
397 
398       case LL_RCC_SPI1_CLKSOURCE_PCLK2:  /* SPI1 Clock is PCLK2 */
399         SPI_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
400         break;
401 
402       default:
403         /* unreachable code */
404         break;
405     }
406   }
407 #endif /* SPI1 */
408   else
409   {
410     /* nothing to do */
411   }
412 
413   return SPI_frequency;
414 }
415 
416 /**
417   * @brief  Return I2Cx clock frequency
418   * @param  I2CxSource This parameter can be one of the following values:
419   *         @arg @ref LL_RCC_I2C1_CLKSOURCE
420   *         @arg @ref LL_RCC_I2C3_CLKSOURCE
421   * @retval I2C clock frequency (in Hz)
422   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI) is not ready
423   */
LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)424 uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)
425 {
426   uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
427 
428   /* Check parameter */
429   assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource));
430 
431   if (I2CxSource == LL_RCC_I2C3_CLKSOURCE)
432   {
433     /* I2C3 CLK clock frequency */
434     switch (LL_RCC_GetI2CClockSource(I2CxSource))
435     {
436       case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */
437         i2c_frequency = RCC_GetSystemClockFreq();
438         break;
439 
440       case LL_RCC_I2C3_CLKSOURCE_HSI:    /* I2C3 Clock is HSI Osc. */
441         if (LL_RCC_HSI_IsReady() != 0U)
442         {
443           i2c_frequency = HSI_VALUE;
444         }
445         break;
446 
447       case LL_RCC_I2C3_CLKSOURCE_PCLK7:  /* I2C3 Clock is PCLK7 */
448         i2c_frequency = RCC_GetPCLK7ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
449         break;
450 
451       default:
452         /* unreachable code */
453         break;
454     }
455   }
456 #if defined(I2C1)
457   else if (I2CxSource == LL_RCC_I2C1_CLKSOURCE)
458   {
459     /* I2C1 CLK clock frequency */
460     switch (LL_RCC_GetI2CClockSource(I2CxSource))
461     {
462       case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
463         i2c_frequency = RCC_GetSystemClockFreq();
464         break;
465 
466       case LL_RCC_I2C1_CLKSOURCE_HSI:    /* I2C1 Clock is HSI Osc. */
467         if (LL_RCC_HSI_IsReady() != 0U)
468         {
469           i2c_frequency = HSI_VALUE;
470         }
471         break;
472 
473       case LL_RCC_I2C1_CLKSOURCE_PCLK1:  /* I2C1 Clock is PCLK1 */
474         i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
475         break;
476 
477       default:
478         /* unreachable code */
479         break;
480     }
481   }
482 #endif /* I2C1 */
483   else
484   {
485     /* nothing to do */
486   }
487 
488   return i2c_frequency;
489 }
490 
491 /**
492   * @brief  Return LPUARTx clock frequency
493   * @param  LPUARTxSource This parameter can be one of the following values:
494   *         @arg @ref LL_RCC_LPUART1_CLKSOURCE
495   * @retval LPUART clock frequency (in Hz)
496   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
497   */
LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)498 uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)
499 {
500   uint32_t lpuart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
501 
502   /* Check parameter */
503   assert_param(IS_LL_RCC_LPUART_CLKSOURCE(LPUARTxSource));
504 
505   /* LPUART1CLK clock frequency */
506   switch (LL_RCC_GetLPUARTClockSource(LPUARTxSource))
507   {
508     case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */
509       lpuart_frequency = RCC_GetSystemClockFreq();
510       break;
511 
512     case LL_RCC_LPUART1_CLKSOURCE_HSI:    /* LPUART1 Clock is HSI Osc. */
513       if (LL_RCC_HSI_IsReady() != 0U)
514       {
515         lpuart_frequency = HSI_VALUE;
516       }
517       break;
518 
519     case LL_RCC_LPUART1_CLKSOURCE_LSE:    /* LPUART1 Clock is LSE Osc. */
520       if (LL_RCC_LSE_IsReady() != 0U)
521       {
522         lpuart_frequency = LSE_VALUE;
523       }
524       break;
525 
526     case LL_RCC_LPUART1_CLKSOURCE_PCLK7:  /* LPUART1 Clock is PCLK7 */
527       lpuart_frequency = RCC_GetPCLK7ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
528       break;
529 
530     default:
531       /* unreachable code */
532       break;
533   }
534 
535   return lpuart_frequency;
536 }
537 
538 /**
539   * @brief  Return LPTIMx clock frequency
540   * @param  LPTIMxSource This parameter can be one of the following values:
541   *         @arg @ref LL_RCC_LPTIM1_CLKSOURCE
542   *         @arg @ref LL_RCC_LPTIM2_CLKSOURCE
543   * @retval LPTIM clock frequency (in Hz)
544   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI, LSI or LSE) is not ready
545   */
LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource)546 uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource)
547 {
548   uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
549 
550   /* Check parameter */
551   assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMxSource));
552 
553   if (LPTIMxSource == LL_RCC_LPTIM1_CLKSOURCE)
554   {
555     /* LPTIM1CLK clock frequency */
556     switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
557     {
558       case LL_RCC_LPTIM1_CLKSOURCE_LSI:    /* LPTIM1 Clock is LSI Osc. */
559 #if defined(RCC_LSI2_SUPPORT)
560         if ((RCC->BDCR1& (RCC_BDCR1_LSI1ON | RCC_BDCR1_LSI2ON)) != 0U)
561 #else
562         if (LL_RCC_LSI1_IsReady() != 0U)
563 #endif
564         {
565           lptim_frequency = LSI_VALUE;
566         }
567         break;
568 
569       case LL_RCC_LPTIM1_CLKSOURCE_HSI:    /* LPTIM1 Clock is HSI Osc. */
570         if (LL_RCC_HSI_IsReady() != 0U)
571         {
572           lptim_frequency = HSI_VALUE;
573         }
574         break;
575 
576       case LL_RCC_LPTIM1_CLKSOURCE_LSE:    /* LPTIM1 Clock is LSE Osc. */
577         if (LL_RCC_LSE_IsReady() != 0U)
578         {
579           lptim_frequency = LSE_VALUE;
580         }
581         break;
582 
583       case LL_RCC_LPTIM1_CLKSOURCE_PCLK7:  /* LPTIM1 Clock is PCLK7 */
584         lptim_frequency = RCC_GetPCLK7ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
585         break;
586 
587       default:
588         /* unreachable code */
589         break;
590     }
591   }
592 #if defined(LPTIM2)
593   else if (LPTIMxSource == LL_RCC_LPTIM2_CLKSOURCE)
594   {
595     /* LPTIM2CLK clock frequency */
596     switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
597     {
598       case LL_RCC_LPTIM2_CLKSOURCE_LSI:    /* LPTIM2 Clock is LSI Osc. */
599 #if defined(RCC_LSI2_SUPPORT)
600         if ((RCC->BDCR1& (RCC_BDCR1_LSI1ON | RCC_BDCR1_LSI2ON)) != 0U)
601 #else
602         if (LL_RCC_LSI1_IsReady() != 0U)
603 #endif
604         {
605           lptim_frequency = LSI_VALUE;
606         }
607         break;
608 
609       case LL_RCC_LPTIM2_CLKSOURCE_HSI:    /* LPTIM2 Clock is HSI Osc. */
610         if (LL_RCC_HSI_IsReady() != 0U)
611         {
612           lptim_frequency = HSI_VALUE;
613         }
614         break;
615 
616       case LL_RCC_LPTIM2_CLKSOURCE_LSE:    /* LPTIM2 Clock is LSE Osc. */
617         if (LL_RCC_LSE_IsReady() != 0U)
618         {
619           lptim_frequency = LSE_VALUE;
620         }
621         break;
622 
623       case LL_RCC_LPTIM2_CLKSOURCE_PCLK1:  /* LPTIM2 Clock is PCLK1 */
624         lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
625         break;
626 
627       default:
628         /* unreachable code */
629         break;
630     }
631   }
632 #endif /* LPTIM2 */
633   else
634   {
635     /* nothing to do */
636   }
637 
638   return lptim_frequency;
639 }
640 
641 #if defined(SAI1)
642 /**
643   * @brief  Return SAIx clock frequency
644   * @param  SAIxSource This parameter can be one of the following values:
645   *         @arg @ref LL_RCC_SAI1_CLKSOURCE
646   * @retval SAI clock frequency (in Hz)
647   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that PLL1 is not ready
648   */
LL_RCC_GetSAIClockFreq(uint32_t SAIxSource)649 uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource)
650 {
651   uint32_t sai_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
652 
653   /* Check parameter */
654   assert_param(IS_LL_RCC_SAI_CLKSOURCE(SAIxSource));
655 
656   if (SAIxSource == LL_RCC_SAI1_CLKSOURCE)
657   {
658     /* SAI1CLK clock frequency */
659     switch (LL_RCC_GetSAIClockSource(SAIxSource))
660     {
661       case LL_RCC_SAI1_CLKSOURCE_PLL1P:        /* PLL1P clock used as SAI1 clock source */
662         if (LL_RCC_PLL1_IsReady() != 0U)
663         {
664           if (LL_RCC_PLL1_IsEnabledDomain_PLL1P() != 0U)
665           {
666             sai_frequency = RCC_PLL1P_GetFreqDomain();
667           }
668         }
669         break;
670 
671       case LL_RCC_SAI1_CLKSOURCE_PLL1Q:        /* PLL1Q clock used as SAI1 clock source */
672         if (LL_RCC_PLL1_IsReady() != 0U)
673         {
674           if (LL_RCC_PLL1_IsEnabledDomain_PLL1Q() != 0U)
675           {
676             sai_frequency = RCC_PLL1Q_GetFreqDomain();
677           }
678         }
679         break;
680 
681       case LL_RCC_SAI1_CLKSOURCE_SYSCLK:        /* System clock used as SAI1 clock source */
682         sai_frequency = RCC_GetSystemClockFreq();
683         break;
684 
685       case LL_RCC_SAI1_CLKSOURCE_PIN:         /* External input clock used as SAI1 clock source */
686         sai_frequency = EXTERNAL_SAI1_CLOCK_VALUE;
687         break;
688 
689       case LL_RCC_SAI1_CLKSOURCE_HSI:        /* SAI Clock is HSI Osc. */
690         if (LL_RCC_HSI_IsReady() != 0U)
691         {
692           sai_frequency = HSI_VALUE;
693         }
694         break;
695 
696       default:
697         /* unreachable code */
698         break;
699     }
700   }
701   else
702   {
703     /* nothing to do */
704   }
705 
706   return sai_frequency;
707 }
708 #endif /* SAI1 */
709 
710 /**
711   * @brief  Return RNGx clock frequency
712   * @param  RNGxSource This parameter can be one of the following values:
713   *         @arg @ref LL_RCC_RNG_CLKSOURCE
714   * @retval RNG clock frequency (in Hz)
715   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI or HSI48) or PLL1 is not ready
716   */
LL_RCC_GetRNGClockFreq(uint32_t RNGxSource)717 uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource)
718 {
719   uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
720 
721   /* Check parameter */
722   assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource));
723 
724   /* RNGCLK clock frequency */
725   switch (LL_RCC_GetRNGClockSource(RNGxSource))
726   {
727     case LL_RCC_RNG_CLKSOURCE_HSI:            /* HSI clock used as RNG clock source */
728       if (LL_RCC_HSI_IsReady() != 0U)
729       {
730         rng_frequency = HSI_VALUE;
731       }
732       break;
733 
734     case LL_RCC_RNG_CLKSOURCE_LSI:            /* LSI clock used as RNG clock source */
735 #if defined(RCC_LSI2_SUPPORT)
736       if ((RCC->BDCR1& (RCC_BDCR1_LSI1ON | RCC_BDCR1_LSI2ON)) != 0U)
737 #else
738       if (LL_RCC_LSI1_IsReady() != 0U)
739 #endif
740       {
741         rng_frequency = LSI_VALUE;
742       }
743       break;
744 
745     case LL_RCC_RNG_CLKSOURCE_LSE:            /* LSE clock used as RNG clock source */
746       if (LL_RCC_LSE_IsReady() != 0U)
747       {
748         rng_frequency = LSE_VALUE;
749       }
750       break;
751 
752     case LL_RCC_RNG_CLKSOURCE_PLL1Q_DIV2:     /* PLL1Q/2 clock used as RNG clock source */
753       if (LL_RCC_PLL1_IsReady() != 0U)
754       {
755         if (LL_RCC_PLL1_IsEnabledDomain_PLL1Q() != 0U)
756         {
757           rng_frequency = RCC_PLL1Q_GetFreqDomain()/2U;
758         }
759       }
760       break;
761     default:
762       /* unreachable code */
763       break;
764 
765   }
766 
767   return rng_frequency;
768 }
769 
770 /**
771   * @brief  Return ADCx clock frequency
772   * @param  ADCxSource This parameter can be one of the following values:
773   *         @arg @ref LL_RCC_ADC_CLKSOURCE
774   * @retval ADC clock frequency (in Hz)
775   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSE / HSI) or PLL1 is not ready
776   */
LL_RCC_GetADCClockFreq(uint32_t ADCxSource)777 uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
778 {
779   uint32_t adc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
780 
781   /* Check parameter */
782   assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
783 
784   /* ADCCLK clock frequency */
785   switch (LL_RCC_GetADCClockSource(ADCxSource))
786   {
787     case LL_RCC_ADC_CLKSOURCE_HCLK:         /* ADC Clock is SYSCLK */
788       adc_frequency = RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq());
789       break;
790 
791     case LL_RCC_ADC_CLKSOURCE_SYSCLK:       /* SYSCLK clock used as ADC clock source */
792       adc_frequency = RCC_GetSystemClockFreq();
793       break;
794 
795     case LL_RCC_ADC_CLKSOURCE_PLL1P:        /* PLL1P clock used as ADC clock source */
796       if (LL_RCC_PLL1_IsReady() != 0U)
797       {
798         if (LL_RCC_PLL1_IsEnabledDomain_PLL1P() != 0U)
799         {
800           adc_frequency = RCC_PLL1P_GetFreqDomain();
801         }
802       }
803       break;
804 
805     case LL_RCC_ADC_CLKSOURCE_HSI:          /*HSI clock used as ADC clock source */
806       if (LL_RCC_HSI_IsReady() != 0U)
807       {
808         adc_frequency = HSI_VALUE;
809       }
810       break;
811 
812     case LL_RCC_ADC_CLKSOURCE_HSE:           /*HSE clock used as ADC clock source */
813       if (LL_RCC_HSE_IsReady() != 0U)
814       {
815         adc_frequency = HSE_VALUE;
816       }
817       break;
818 
819     default:
820       /* unreachable code */
821       break;
822   }
823 
824   return adc_frequency;
825 }
826 
827 
828 
829 /**
830   * @}
831   */
832 
833 /**
834   * @}
835   */
836 
837 /** @addtogroup RCC_LL_Private_Functions
838   * @{
839   */
840 
841 /**
842   * @brief  Return SYSTEM clock frequency
843   * @retval SYSTEM clock frequency (in Hz)
844   */
RCC_GetSystemClockFreq(void)845 uint32_t RCC_GetSystemClockFreq(void)
846 {
847   uint32_t frequency;
848 
849   /* Get SYSCLK source -------------------------------------------------------*/
850   switch (LL_RCC_GetSysClkSource())
851   {
852     case LL_RCC_SYS_CLKSOURCE_STATUS_HSI:   /* HSI used as system clock  source */
853       frequency = HSI_VALUE;
854       break;
855 
856     case LL_RCC_SYS_CLKSOURCE_STATUS_HSE:   /* HSE used as system clock  source */
857       frequency = HSE_VALUE;
858       break;
859 
860     case LL_RCC_SYS_CLKSOURCE_STATUS_PLL1R:  /* PLL1 used as system clock  source */
861       frequency = RCC_PLL1R_GetFreqDomain();
862       break;
863 
864     default:
865       frequency = HSI_VALUE;
866       break;
867   }
868 
869   return frequency;
870 }
871 
872 /**
873   * @brief  Return HCLK clock frequency
874   * @param  SYSCLK_Frequency SYSCLK clock frequency
875   * @retval HCLK clock frequency (in Hz)
876   */
RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)877 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
878 {
879   /* HCLK clock frequency */
880   return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
881 }
882 
883 /**
884   * @brief  Return PCLK1 clock frequency
885   * @param  HCLK_Frequency HCLK clock frequency
886   * @retval PCLK1 clock frequency (in Hz)
887   */
RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)888 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
889 {
890   /* PCLK1 clock frequency */
891   return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
892 }
893 
894 /**
895   * @brief  Return PCLK2 clock frequency
896   * @param  HCLK_Frequency HCLK clock frequency
897   * @retval PCLK2 clock frequency (in Hz)
898   */
RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)899 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
900 {
901   /* PCLK2 clock frequency */
902   return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
903 }
904 
905 
906 /**
907   * @brief  Return PCLK7 clock frequency
908   * @param  HCLK_Frequency HCLK clock frequency
909   * @retval PCLK7 clock frequency (in Hz)
910   */
RCC_GetPCLK7ClockFreq(uint32_t HCLK_Frequency)911 uint32_t RCC_GetPCLK7ClockFreq(uint32_t HCLK_Frequency)
912 {
913   /* PCLK7 clock frequency */
914   return __LL_RCC_CALC_PCLK7_FREQ(HCLK_Frequency, LL_RCC_GetAPB7Prescaler());
915 }
916 
917 /**
918   * @brief  Return PLL1R clock frequency used for system domain
919   * @retval PLL1R clock frequency (in Hz)
920   */
RCC_PLL1R_GetFreqDomain(void)921 uint32_t RCC_PLL1R_GetFreqDomain(void)
922 {
923   uint32_t pllinputfreq, pllsource;
924 
925   /* PLL_VCO = (HSE_VALUE or HSI_VALUE/ PLLM) * PLLN
926      SYSCLK = PLL_VCO / PLLR
927     */
928   pllsource = LL_RCC_PLL1_GetMainSource();
929 
930   switch (pllsource)
931   {
932     case LL_RCC_PLL1SOURCE_HSI:  /* HSI used as PLL1 clock source */
933       pllinputfreq = HSI_VALUE;
934       break;
935 
936     case LL_RCC_PLL1SOURCE_HSE:  /* HSE used as PLL1 clock source */
937       pllinputfreq = HSE_VALUE;
938       break;
939 
940     default:
941       pllinputfreq = HSI_VALUE;
942       break;
943   }
944   return __LL_RCC_CALC_PLL1RCLK_FREQ(pllinputfreq, LL_RCC_PLL1_GetDivider(),
945                                      LL_RCC_PLL1_GetN(), LL_RCC_PLL1_GetR());
946 }
947 /**
948   * @brief  Return PLL1P clock frequency used for ADC and SAI domains
949   * @retval PLL1P clock frequency (in Hz)
950   */
RCC_PLL1P_GetFreqDomain(void)951 uint32_t RCC_PLL1P_GetFreqDomain(void)
952 {
953   uint32_t pll1inputfreq, pll1outputfreq, pll1source;
954   uint32_t pll1n, pll1pdiv;
955 
956   /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
957      Domain clock = PLL_VCO / PLL1P
958     */
959   pll1source = LL_RCC_PLL1_GetMainSource();
960 
961   switch (pll1source)
962   {
963     case LL_RCC_PLL1SOURCE_HSI:  /* HSI used as PLL1 clock source */
964       pll1inputfreq = HSI_VALUE;
965       break;
966 
967     case LL_RCC_PLL1SOURCE_HSE:  /* HSE used as PLL1 clock source */
968       pll1inputfreq = HSE_VALUE;
969       break;
970 
971     default:
972       pll1inputfreq = HSI_VALUE;
973       break;
974   }
975 
976   pll1n = LL_RCC_PLL1_GetN();
977   pll1pdiv = LL_RCC_PLL1_GetP();
978   if ((pll1n >= 8U) && (pll1pdiv >= 2U))
979   {
980     pll1outputfreq = __LL_RCC_CALC_PLL1PCLK_FREQ(pll1inputfreq, LL_RCC_PLL1_GetDivider(),
981                                                  pll1n, pll1pdiv);
982   }
983   else
984   {
985     pll1outputfreq = 0;  /* Invalid PLL1N or PLL1PDIV value */
986   }
987   return pll1outputfreq;
988 }
989 
990 /**
991   * @brief  Return PLL1Q clock frequency used for RNG and SAI domains
992   * @retval PLL1Q clock frequency (in Hz)
993   */
RCC_PLL1Q_GetFreqDomain(void)994 uint32_t RCC_PLL1Q_GetFreqDomain(void)
995 {
996   uint32_t pll1inputfreq, pll1source;
997 
998   /* PLL1_VCO = (HSE_VALUE or HSI_VALUE / PLL1M) * PLL1N
999      Domain clock = PLL1_VCO / PLL1Q
1000     */
1001   pll1source = LL_RCC_PLL1_GetMainSource();
1002 
1003   switch (pll1source)
1004   {
1005     case LL_RCC_PLL1SOURCE_HSI:  /* HSI used as PLL1 clock source */
1006       pll1inputfreq = HSI_VALUE;
1007       break;
1008 
1009     case LL_RCC_PLL1SOURCE_HSE:  /* HSE used as PLL1 clock source */
1010       pll1inputfreq = HSE_VALUE;
1011       break;
1012 
1013     default:
1014       pll1inputfreq = HSI_VALUE;
1015       break;
1016   }
1017   return __LL_RCC_CALC_PLL1QCLK_FREQ(pll1inputfreq, LL_RCC_PLL1_GetDivider(),
1018                                      LL_RCC_PLL1_GetN(), LL_RCC_PLL1_GetQ());
1019 }
1020 
1021 /**
1022   * @}
1023   */
1024 
1025 /**
1026   * @}
1027   */
1028 
1029 #endif /* defined(RCC) */
1030 
1031 /**
1032   * @}
1033   */
1034 
1035 #endif /* USE_FULL_LL_DRIVER */
1036 
1037