1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_ll_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2024 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 "stm32wb0x_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 
28 /** @addtogroup STM32WB0x_LL_Driver
29   * @{
30   */
31 
32 #if defined(RCC)
33 
34 /** @addtogroup RCC_LL
35   * @{
36   */
37 
38 /* Private types -------------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 /* Private constants ---------------------------------------------------------*/
41 /* Private macros ------------------------------------------------------------*/
42 /** @addtogroup RCC_LL_Private_Macros
43   * @{
44   */
45 
46 #if defined(RCC_CFGR_LPUCLKSEL)
47 #define IS_LL_RCC_LPUART_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_LPUART1_CLKSOURCE)
48 #endif /* RCC_CFGR_LPUCLKSEL */
49 
50 /**
51   * @}
52   */
53 
54 /* Private function prototypes -----------------------------------------------*/
55 /** @defgroup RCC_LL_Private_Functions RCC Private functions
56   * @{
57   */
58 static uint32_t RCC_GetSystemClockFreq(void);
59 
60 /**
61   * @}
62   */
63 
64 
65 /* Exported functions --------------------------------------------------------*/
66 /** @addtogroup RCC_LL_Exported_Functions
67   * @{
68   */
69 
70 /** @addtogroup RCC_LL_EF_Init
71   * @{
72   */
73 
74 /**
75   * @brief  Reset the RCC clock  to the default reset state.
76   * @note   The default reset state of the clock configuration is given below:
77   *         - HSI ON and used as system clock source
78   *         - HSE and PLL Source OFF
79   *         - All interrupts disabled
80   * @note   This function doesn't modify the configuration of the
81   *         - Peripheral clocks
82   *         - LSI, LSE
83   * @retval An ErrorStatus enumeration value:
84   *          - SUCCESS: RCC registers are de-initialized
85   *          - ERROR: not applicable
86   */
LL_RCC_DeInit(void)87 ErrorStatus LL_RCC_DeInit(void)
88 {
89   uint32_t vl_mask;
90 
91   /* Disable all the HS clock source */
92   LL_RCC_HSE_Disable();
93   LL_RCC_RC64MPLL_Disable();
94 
95   /* Set the System Clock prescaler to reset state */
96   LL_RCC_SetRC64MPLLPrescaler(LL_RCC_RC64MPLL_DIV_4);
97 
98   /* Wait for PLL READY bit to be reset */
99   while (LL_RCC_RC64MPLL_IsReady() != 0U)
100   {}
101 
102   /* Insure HSIRDY bit is set */
103   while (LL_RCC_HSI_IsReady() == 0U)
104   {}
105 
106   /* Disable all interrupts */
107   LL_RCC_WriteReg(CIER, 0x00000000U);
108 
109   /* Clear all interrupt flags */
110   vl_mask = RCC_CIFR_LSIRDYF | RCC_CIFR_LSERDYF | RCC_CIFR_HSIRDYF | RCC_CIFR_HSERDYF | RCC_CIFR_HSIPLLRDYF;
111   LL_RCC_WriteReg(CIFR, vl_mask);
112 
113   /* Clear reset flags */
114   LL_RCC_ClearResetFlags();
115 
116   return SUCCESS;
117 }
118 
119 /**
120   * @}
121   */
122 
123 /** @addtogroup RCC_LL_EF_Get_Freq
124   * @brief  Return the frequency of the system clock device.
125   * @note   If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
126   * @note   If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
127   * @note   (**) HSI_VALUE is a constant defined in this file (default value
128   *              64 MHz) but the real value may vary depending on the variations
129   *              in voltage and temperature.
130   * @note   (***) HSE_VALUE is a constant defined in this file (default value
131   *               32 MHz). The HSE_VALUE value is divided from a 64 MHz PLL to return
132   *               frequency of the crystal used.
133   * @{
134   */
135 
136 /**
137   * @brief  Return the frequency of the system clock.
138   * @param  RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
139   * @retval None
140   */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)141 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
142 {
143   /* Get SYSCLK frequency */
144   RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
145 }
146 
147 /**
148   * @brief  Return SMPS clock frequency
149   * @note   This function is only applicable when CPU runs.
150   * @retval SMPS clock frequency (in Hz)
151   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that the peripheral has a wrong ANADIV prescaler setup
152   */
LL_RCC_GetSMPSClockFreq(void)153 uint32_t LL_RCC_GetSMPSClockFreq(void)
154 {
155   uint32_t smps_frequency;
156   uint32_t smps_prescaler;
157 
158   smps_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
159 
160   smps_prescaler = LL_RCC_GetSMPSPrescaler();
161   if (smps_prescaler == LL_RCC_SMPS_DIV_2)
162   {
163     smps_frequency = 32000000 / 4;
164   }
165   else
166   {
167     smps_frequency = 32000000 / 8;
168   }
169 
170   return smps_frequency;
171 }
172 
173 #if defined(RCC_CFGR_LPUCLKSEL)
174 /**
175   * @brief  Return LPUARTx clock frequency
176   * @param  LPUARTxSource This parameter can be one of the following values:
177   *         @arg @ref LL_RCC_LPUART1_CLKSOURCE
178   * @retval LPUART clock frequency (in Hz)
179   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (CLK_16M or LSE) is not ready
180   */
LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)181 uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)
182 {
183   uint32_t lpuart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
184 
185   /* Check parameter */
186   assert_param(IS_LL_RCC_LPUART_CLKSOURCE(LPUARTxSource));
187 
188   /* LPUART1CLK clock frequency */
189   if (LPUARTxSource == LL_RCC_LPUART1_CLKSOURCE)
190   {
191     switch (LL_RCC_GetLPUARTClockSource())
192     {
193       case LL_RCC_LPUCLKSEL_CLKLSE: /* LPUART1 Clock is LSE Osc. */
194         if (LL_RCC_LSE_IsReady() == 1U)
195         {
196           lpuart_frequency = LSE_VALUE;
197         }
198         break;
199 
200       case LL_RCC_LPUCLKSEL_CLK16M: /* LPUART1 Clock is CLK_16M */
201         lpuart_frequency = 16000000U;
202         break;
203 
204       default:
205         break;
206     }
207   }
208 
209   return lpuart_frequency;
210 }
211 #endif /* RCC_CFGR_LPUCLKSEL */
212 
213 /**
214   * @}
215   */
216 
217 /**
218   * @}
219   */
220 
221 /** @addtogroup RCC_LL_Private_Functions
222   * @{
223   */
224 
225 /**
226   * @brief  Return SYSTEM clock (SYSCLK) frequency
227   * @retval SYSTEM clock frequency (in Hz)
228   */
RCC_GetSystemClockFreq(void)229 static uint32_t RCC_GetSystemClockFreq(void)
230 {
231   uint32_t frequency;
232   uint32_t smps_prescaler=0;
233 
234   frequency = RC64MPLL_VALUE;
235 
236   if (LL_RCC_DIRECT_HSE_IsEnabled())
237   {
238     frequency = HSE_VALUE;
239 
240 #if defined(RCC_CFGR_CLKSYSDIV_STATUS)
241     switch (LL_RCC_GetCLKSYSPrescalerStatus())
242 #else
243     switch (LL_RCC_GetRC64MPLLPrescaler())
244 #endif
245     {
246       case LL_RCC_DIRECT_HSE_DIV_1:
247         smps_prescaler = 1;
248         break;
249       case LL_RCC_DIRECT_HSE_DIV_2:
250         smps_prescaler = 2;
251         break;
252       case LL_RCC_DIRECT_HSE_DIV_4:
253         smps_prescaler = 4;
254         break;
255       case LL_RCC_DIRECT_HSE_DIV_8:
256         smps_prescaler = 8;
257         break;
258       case LL_RCC_DIRECT_HSE_DIV_16:
259         smps_prescaler = 16;
260         break;
261       case LL_RCC_DIRECT_HSE_DIV_32:
262         smps_prescaler = 32;
263         break;
264     }
265   }
266   else
267   {
268     frequency = RC64MPLL_VALUE;
269 
270 #if defined(RCC_CFGR_CLKSYSDIV_STATUS)
271     switch (LL_RCC_GetCLKSYSPrescalerStatus())
272 #else
273     switch (LL_RCC_GetRC64MPLLPrescaler())
274 #endif
275     {
276       case LL_RCC_RC64MPLL_DIV_1:
277         smps_prescaler = 1;
278         break;
279       case LL_RCC_RC64MPLL_DIV_2:
280         smps_prescaler = 2;
281         break;
282       case LL_RCC_RC64MPLL_DIV_4:
283         smps_prescaler = 4;
284         break;
285       case LL_RCC_RC64MPLL_DIV_8:
286         smps_prescaler = 8;
287         break;
288       case LL_RCC_RC64MPLL_DIV_16:
289         smps_prescaler = 16;
290         break;
291       case LL_RCC_RC64MPLL_DIV_32:
292         smps_prescaler = 32;
293         break;
294       case LL_RCC_RC64MPLL_DIV_64:
295         smps_prescaler = 64;
296         break;
297     }
298   }
299 
300   return (uint32_t)(frequency / smps_prescaler);
301 }
302 /**
303   * @}
304   */
305 
306 /**
307   * @}
308   */
309 
310 #endif /* defined(RCC) */
311 
312 /**
313   * @}
314   */
315 
316 #endif /* USE_FULL_LL_DRIVER */
317