1 /**
2 ******************************************************************************
3 * @file stm32u0xx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extended RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extended peripheral:
8 * + Extended Peripheral Control functions
9 * + Extended Clock management functions
10 * + Extended Clock Recovery System Control functions
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2023 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 */
24
25 /* Includes ------------------------------------------------------------------*/
26 #include "stm32u0xx_hal.h"
27
28 /** @addtogroup STM32U0xx_HAL_Driver
29 * @{
30 */
31
32 /** @defgroup RCCEx RCCEx
33 * @brief RCC Extended HAL module driver
34 * @{
35 */
36
37 #ifdef HAL_RCC_MODULE_ENABLED
38
39 /* Private typedef -----------------------------------------------------------*/
40 /* Private defines -----------------------------------------------------------*/
41 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
42 * @{
43 */
44 #define __LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
45 #define LSCO_GPIO_PORT GPIOA
46 #define LSCO_PIN GPIO_PIN_2
47
48 /**
49 * @}
50 */
51
52 /* Private macros ------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
56 * @{
57 */
58 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource);
59
60 /**
61 * @}
62 */
63
64 /* Exported functions --------------------------------------------------------*/
65
66 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
67 * @{
68 */
69
70 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
71 * @brief Extended Peripheral Control functions
72 *
73 @verbatim
74 ===============================================================================
75 ##### Extended Peripheral Control functions #####
76 ===============================================================================
77 [..]
78 This subsection provides a set of functions allowing to control the RCC Clocks
79 frequencies.
80 [..]
81 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
82 select the RTC clock source; in this case the Backup domain will be reset in
83 order to modify the RTC Clock source, as consequence RTC registers (including
84 the backup registers) are set to their reset values.
85
86 @endverbatim
87 * @{
88 */
89 /**
90 * @brief Initialize the RCC extended peripherals clocks according to the specified
91 * parameters in the RCC_PeriphCLKInitTypeDef.
92 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
93 * contains a field PeriphClockSelection which can be a combination of the following values:
94 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
95 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
96 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
97 * @arg @ref RCC_PERIPHCLK_LPUART2 LPUART2 peripheral clock
98 * @arg @ref RCC_PERIPHCLK_LPUART3 LPUART3 peripheral clock
99 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
100 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
101 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
102 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
103 * @arg @ref RCC_PERIPHCLK_LPTIM3 LPTIM3 peripheral clock
104 * @arg @ref RCC_PERIPHCLK_TIM1 TIM1 peripheral clock
105 * @arg @ref RCC_PERIPHCLK_TIM15 TIM15 peripheral clock
106 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
107 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
108 *
109 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
110 * the RTC clock source: in this case the access to Backup domain is enabled.
111 *
112 * @retval HAL status
113 */
HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef * PeriphClkInit)114 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef *PeriphClkInit)
115 {
116 uint32_t tmpregister;
117 uint32_t tickstart;
118 HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
119 HAL_StatusTypeDef status = HAL_OK; /* Final status */
120
121 /* Check the parameters */
122 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
123
124 /*-------------------------- RTC clock source configuration ----------------------*/
125 if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
126 {
127 FlagStatus pwrclkchanged = RESET;
128
129 /* Check for RTC Parameters used to output RTCCLK */
130 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
131
132 /* Enable Power Clock */
133 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
134 {
135 __HAL_RCC_PWR_CLK_ENABLE();
136 pwrclkchanged = SET;
137 }
138
139 /* Enable write access to Backup domain */
140 SET_BIT(PWR->CR1, PWR_CR1_DBP);
141
142 /* Wait for Backup domain Write protection disable */
143 tickstart = HAL_GetTick();
144
145 while (READ_BIT(PWR->CR1, PWR_CR1_DBP) == 0U)
146 {
147 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
148 {
149 ret = HAL_TIMEOUT;
150 break;
151 }
152 }
153
154 if (ret == HAL_OK)
155 {
156 /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
157 tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
158
159 if ((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
160 {
161 /* Store the content of BDCR register before the reset of Backup Domain */
162 tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
163 /* RTC Clock selection can be changed only if the Backup Domain is reset */
164 __HAL_RCC_BACKUPRESET_FORCE();
165 __HAL_RCC_BACKUPRESET_RELEASE();
166 /* Restore the Content of BDCR register */
167 RCC->BDCR = tmpregister;
168 }
169
170 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
171 if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
172 {
173 /* Get Start Tick*/
174 tickstart = HAL_GetTick();
175
176 /* Wait till LSE is ready */
177 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
178 {
179 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
180 {
181 ret = HAL_TIMEOUT;
182 break;
183 }
184 }
185 }
186
187 if (ret == HAL_OK)
188 {
189 /* Apply new RTC clock source selection */
190 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
191 }
192 else
193 {
194 /* set overall return value */
195 status = ret;
196 }
197 }
198 else
199 {
200 /* set overall return value */
201 status = ret;
202 }
203
204 /* Restore clock configuration if changed */
205 if (pwrclkchanged == SET)
206 {
207 __HAL_RCC_PWR_CLK_DISABLE();
208 }
209 }
210
211 /*-------------------------- USART1 clock source configuration -------------------*/
212 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
213 {
214 /* Check the parameters */
215 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
216
217 /* Configure the USART1 clock source */
218 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
219 }
220
221 /*-------------------------- USART2 clock source configuration -------------------*/
222 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
223 {
224 /* Check the parameters */
225 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
226
227 /* Configure the USART2 clock source */
228 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
229 }
230
231 /*-------------------------- LPUART1 clock source configuration ------------------*/
232 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
233 {
234 /* Check the parameters */
235 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
236
237 /* Configure the LPUART1 clock source */
238 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
239 }
240
241 /*-------------------------- LPUART2 clock source configuration ------------------*/
242 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART2) == RCC_PERIPHCLK_LPUART2)
243 {
244 /* Check the parameters */
245 assert_param(IS_RCC_LPUART2CLKSOURCE(PeriphClkInit->Lpuart2ClockSelection));
246
247 /* Configure the LPUART2 clock source */
248 __HAL_RCC_LPUART2_CONFIG(PeriphClkInit->Lpuart2ClockSelection);
249 }
250 #if defined (LPUART3)
251 /*-------------------------- LPUART3 clock source configuration ------------------*/
252 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART3) == RCC_PERIPHCLK_LPUART3)
253 {
254 /* Check the parameters */
255 assert_param(IS_RCC_LPUART3CLKSOURCE(PeriphClkInit->Lpuart3ClockSelection));
256
257 /* Configure the LPUART3 clock source */
258 __HAL_RCC_LPUART3_CONFIG(PeriphClkInit->Lpuart3ClockSelection);
259 }
260 #endif /* LPUART3 */
261 /*-------------------------- I2C1 clock source configuration ---------------------*/
262 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
263 {
264 /* Check the parameters */
265 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
266
267 /* Configure the I2C1 clock source */
268 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
269 }
270
271 /*-------------------------- I2C3 clock source configuration ---------------------*/
272 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
273 {
274 /* Check the parameters */
275 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
276
277 /* Configure the I2C3 clock source */
278 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
279 }
280
281 /*----------------------- LPTIM1 clock source configuration -------------------*/
282 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
283 {
284 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
285 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
286 }
287
288 /*-------------------------- LPTIM2 clock source configuration -------------------*/
289 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
290 {
291 assert_param(IS_RCC_LPTIM2CLKSOURCE(PeriphClkInit->Lptim2ClockSelection));
292 __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
293 }
294 #if defined (LPTIM3)
295 /*----------------------- LPTIM3 clock source configuration -------------------*/
296 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM3) == (RCC_PERIPHCLK_LPTIM3))
297 {
298 assert_param(IS_RCC_LPTIM3CLKSOURCE(PeriphClkInit->Lptim3ClockSelection));
299 __HAL_RCC_LPTIM3_CONFIG(PeriphClkInit->Lptim3ClockSelection);
300 }
301 #endif /* LPTIM3 */
302 /*-------------------------- ADC clock source configuration ----------------*/
303 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
304 {
305 /* Check the parameters */
306 assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
307 if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLP)
308 {
309 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVP);
310 }
311 /* Configure the ADC1 clock source */
312 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
313 }
314 #if defined (USB_DRD_FS)
315 /*-------------------------- USB clock source configuration ----------------*/
316 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
317 {
318 /* Check the parameters */
319 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
320 if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLQ)
321 {
322 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
323 }
324 /* Configure the USB clock source */
325 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
326
327 }
328 #endif /* USB_DRD_FS */
329 /*-------------------------- RNG clock source configuration ----------------*/
330 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == RCC_PERIPHCLK_RNG)
331 {
332 /* Check the parameters */
333 assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
334 if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLQ)
335 {
336 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
337 }
338 /* Configure the RNG clock source */
339 __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
340
341 }
342 /*-------------------------- TIM1 clock source configuration ----------------*/
343 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM1) == RCC_PERIPHCLK_TIM1)
344 {
345
346 /* Check the parameters */
347 assert_param(IS_RCC_TIM1CLKSOURCE(PeriphClkInit->Tim1ClockSelection));
348 if (PeriphClkInit->Tim1ClockSelection == RCC_TIM1CLKSOURCE_PLLQ)
349 {
350 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
351 }
352 /* Configure the TIM1 clock source */
353 __HAL_RCC_TIM1_CONFIG(PeriphClkInit->Tim1ClockSelection);
354
355 }
356 /*-------------------------- TIM15 clock source configuration ----------------*/
357 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM15) == RCC_PERIPHCLK_TIM15)
358 {
359 /* Check the parameters */
360 assert_param(IS_RCC_TIM15CLKSOURCE(PeriphClkInit->Tim15ClockSelection));
361 if (PeriphClkInit->Tim15ClockSelection == RCC_TIM15CLKSOURCE_PLLQ)
362 {
363 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
364 }
365 /* Configure the TIM1 clock source */
366 __HAL_RCC_TIM15_CONFIG(PeriphClkInit->Tim15ClockSelection);
367
368 }
369
370 return status;
371 }
372 /**
373 * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
374 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
375 * returns the configuration information for the Extended Peripherals
376 * clocks(USART1, USART2, LPUART1, LPUART2, LPUART3, I2C1, I2C2, I2C3, I2C4, LPTIM1,
377 * LPTIM2, LPTIM3, USB, TIM1, LCD, SPI1, SPI2, SPI3, RTC, RNG, ADC, DAC, IWDG).
378 * @retval None
379 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)380 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
381 {
382 /* Set all possible values for the extended clock type parameter------------*/
383 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \
384 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_LPUART2 | RCC_PERIPHCLK_I2C1 | \
385 RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \
386 RCC_PERIPHCLK_TIM1 | RCC_PERIPHCLK_TIM15 | RCC_PERIPHCLK_RNG | \
387 RCC_PERIPHCLK_ADC ;
388
389 #if defined(LPUART3)
390 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART3;
391 #endif /* LPUART3*/
392 #if defined(LPTIM3)
393 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM3;
394 #endif /* LPTIM3 */
395 #if defined(USB_DRD_FS)
396 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
397 #endif /* USB_DRD_FS */
398 /* Get the RTC clock source ---------------------------------------------*/
399 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
400
401 /* Get the USART1 clock source ---------------------------------------------*/
402 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
403
404 /* Get the USART2 clock source ---------------------------------------------*/
405 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
406
407 /* Get the LPUART1 clock source --------------------------------------------*/
408 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
409
410 /* Get the LPUART2 clock source --------------------------------------------*/
411 PeriphClkInit->Lpuart2ClockSelection = __HAL_RCC_GET_LPUART2_SOURCE();
412
413 #if defined (LPUART3)
414 /* Get the LPUART3 clock source --------------------------------------------*/
415 PeriphClkInit->Lpuart3ClockSelection = __HAL_RCC_GET_LPUART3_SOURCE();
416 #endif /* LPUART3 */
417
418 /* Get the I2C1 clock source -----------------------------------------------*/
419 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
420
421 /* Get the I2C3 clock source -----------------------------------------------*/
422 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
423
424 /* Get the LPTIM1 clock source ---------------------------------------------*/
425 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
426
427 /* Get the LPTIM2 clock source ---------------------------------------------*/
428 PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE();
429
430 #if defined (LPTIM3)
431 /* Get the LPTIM3 clock source ---------------------------------------------*/
432 PeriphClkInit->Lptim3ClockSelection = __HAL_RCC_GET_LPTIM3_SOURCE();
433 #endif /* LPTIM3 */
434
435 /* Get the ADC clock source -----------------------------------------------*/
436 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
437
438 /* Get the TIM1 clock source -----------------------------------------------*/
439 PeriphClkInit->Tim1ClockSelection = __HAL_RCC_GET_TIM1_SOURCE();
440
441 /* Get the TIM15 clock source -----------------------------------------------*/
442 PeriphClkInit->Tim15ClockSelection = __HAL_RCC_GET_TIM15_SOURCE();
443
444 #if defined (USB_DRD_FS)
445 /* Get the USB clock source -------------------------------------------------*/
446 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
447 #endif /* USB_DRD_FS */
448
449 /* Get the RNG clock source -------------------------------------------------*/
450 PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE();
451
452 }
453
454 /**
455 * @brief Return the peripheral clock frequency for peripherals with clock source from PLLSAIs
456 * @note Return 0 if peripheral clock identifier not managed by this API
457 * @param PeriphClk Peripheral clock identifier
458 * This parameter can be one of the following values:
459 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
460 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
461 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
462 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
463 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
464 * @arg @ref RCC_PERIPHCLK_LPTIM3 LPTIM3 peripheral clock
465 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
466 * @arg @ref RCC_PERIPHCLK_LPUART2 LPUART2 peripheral clock
467 * @arg @ref RCC_PERIPHCLK_LPUART3 LPUART3 peripheral clock
468 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
469 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
470 * @arg @ref RCC_PERIPHCLK_USART3 USART3 peripheral clock
471 * @arg @ref RCC_PERIPHCLK_USART4 USART4 peripheral clock
472 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
473 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock (only for devices with RNG)
474 * @arg @ref RCC_PERIPHCLK_TIM1 TIM1 peripheral clock (only for devices with TIM1)
475 * @arg @ref RCC_PERIPHCLK_TIM15 TIM15 peripheral clock (only for devices with TIM15)
476 * @retval Frequency in Hz
477 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)478 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
479 {
480 uint32_t frequency = 0U;
481 uint32_t srcclk; /* no init needed */
482 PLL_ClocksTypeDef pll_freq;
483 uint32_t msirange;
484 /* Check the parameters */
485 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
486
487 if (PeriphClk == RCC_PERIPHCLK_RTC)
488 {
489 /* Get the current RCC_PERIPHCLK_RTC source */
490 srcclk = __HAL_RCC_GET_RTC_SOURCE();
491
492 switch (srcclk)
493 {
494 case RCC_RTCCLKSOURCE_LSE:
495 /* Check if LSE is ready */
496 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
497 {
498 frequency = LSE_VALUE;
499 }
500 break;
501 case RCC_RTCCLKSOURCE_LSI:
502 /* Check if LSI is ready */
503 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
504 {
505 #if defined(RCC_CSR_LSIPREDIV)
506 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
507 {
508 frequency = LSI_VALUE / 128U;
509 }
510 else
511 #endif /* RCC_CSR_LSIPREDIV */
512 {
513 frequency = LSI_VALUE;
514 }
515 }
516 break;
517 case RCC_RTCCLKSOURCE_HSE:
518 /* Check if HSE is ready */
519 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
520 {
521 frequency = HSE_VALUE / 32U;
522 }
523 break;
524 default:
525 /* No clock source, frequency default init at 0 */
526 break;
527 }
528 }
529 else
530 {
531 /* Other external peripheral clock source than RTC */
532 switch (PeriphClk)
533 {
534 case RCC_PERIPHCLK_USART1:
535 {
536 /* Get the current USART1 source */
537 srcclk = __HAL_RCC_GET_USART1_SOURCE();
538
539 switch (srcclk)
540 {
541 case RCC_USART1CLKSOURCE_PCLK1:
542 frequency = HAL_RCC_GetPCLK1Freq();
543 break;
544 case RCC_USART1CLKSOURCE_SYSCLK:
545 frequency = HAL_RCC_GetSysClockFreq();
546 break;
547 case RCC_USART1CLKSOURCE_HSI:
548 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
549 {
550 frequency = HSI_VALUE;
551 }
552 break;
553 case RCC_USART1CLKSOURCE_LSE:
554 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
555 {
556 frequency = LSE_VALUE;
557 }
558 break;
559 default:
560 /* No clock source, frequency default init at 0 */
561 break;
562 }
563
564 break;
565 }
566
567 case RCC_PERIPHCLK_USART2:
568 {
569 /* Get the current USART2 source */
570 srcclk = __HAL_RCC_GET_USART2_SOURCE();
571
572 switch (srcclk)
573 {
574 case RCC_USART2CLKSOURCE_PCLK1:
575 frequency = HAL_RCC_GetPCLK1Freq();
576 break;
577 case RCC_USART2CLKSOURCE_SYSCLK:
578 frequency = HAL_RCC_GetSysClockFreq();
579 break;
580 case RCC_USART2CLKSOURCE_HSI:
581 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
582 {
583 frequency = HSI_VALUE;
584 }
585 break;
586 case RCC_USART2CLKSOURCE_LSE:
587 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
588 {
589 frequency = LSE_VALUE;
590 }
591 break;
592 default:
593 /* No clock source, frequency default init at 0 */
594 break;
595 }
596
597 break;
598 }
599
600 /* USART3 and USART4 source */
601 case RCC_PERIPHCLK_USART3:
602 case RCC_PERIPHCLK_USART4:
603 {
604 frequency = HAL_RCC_GetPCLK1Freq();
605 break;
606 }
607
608 case RCC_PERIPHCLK_LPUART1:
609 {
610 /* Get the current LPUART1 source */
611 srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
612
613 switch (srcclk)
614 {
615 case RCC_LPUART1CLKSOURCE_PCLK1:
616 frequency = HAL_RCC_GetPCLK1Freq();
617 break;
618 case RCC_LPUART1CLKSOURCE_SYSCLK:
619 frequency = HAL_RCC_GetSysClockFreq();
620 break;
621 case RCC_LPUART1CLKSOURCE_HSI:
622 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
623 {
624 frequency = HSI_VALUE;
625 }
626 break;
627 case RCC_LPUART1CLKSOURCE_LSE:
628 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
629 {
630 frequency = LSE_VALUE;
631 }
632 break;
633 default:
634 /* No clock source, frequency default init at 0 */
635 break;
636 }
637 break;
638 }
639 case RCC_PERIPHCLK_LPUART2:
640 {
641 /* Get the current LPUART2 source */
642 srcclk = __HAL_RCC_GET_LPUART2_SOURCE();
643
644 switch (srcclk)
645 {
646 case RCC_LPUART2CLKSOURCE_PCLK1:
647 frequency = HAL_RCC_GetPCLK1Freq();
648 break;
649 case RCC_LPUART2CLKSOURCE_SYSCLK:
650 frequency = HAL_RCC_GetSysClockFreq();
651 break;
652 case RCC_LPUART2CLKSOURCE_HSI:
653 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
654 {
655 frequency = HSI_VALUE;
656 }
657 break;
658 case RCC_LPUART2CLKSOURCE_LSE:
659 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
660 {
661 frequency = LSE_VALUE;
662 }
663 break;
664 default:
665 /* No clock source, frequency default init at 0 */
666 break;
667 }
668 break;
669 }
670 #if defined(LPUART3)
671 case RCC_PERIPHCLK_LPUART3:
672 {
673 /* Get the current LPUART3 source */
674 srcclk = __HAL_RCC_GET_LPUART3_SOURCE();
675
676 switch (srcclk)
677 {
678 case RCC_LPUART3CLKSOURCE_PCLK1:
679 frequency = HAL_RCC_GetPCLK1Freq();
680 break;
681 case RCC_LPUART3CLKSOURCE_SYSCLK:
682 frequency = HAL_RCC_GetSysClockFreq();
683 break;
684 case RCC_LPUART3CLKSOURCE_HSI:
685 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
686 {
687 frequency = HSI_VALUE;
688 }
689 break;
690 case RCC_LPUART3CLKSOURCE_LSE:
691 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
692 {
693 frequency = LSE_VALUE;
694 }
695 break;
696 default:
697 /* No clock source, frequency default init at 0 */
698 break;
699 }
700 break;
701 }
702 #endif /* LPUART3 */
703 case RCC_PERIPHCLK_ADC:
704 {
705 srcclk = __HAL_RCC_GET_ADC_SOURCE();
706
707 switch (srcclk)
708 {
709 case RCC_ADCCLKSOURCE_SYSCLK:
710 frequency = HAL_RCC_GetSysClockFreq();
711 break;
712 case RCC_ADCCLKSOURCE_HSI:
713 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
714 {
715 frequency = HSI_VALUE;
716 }
717 else
718 {
719 frequency = 0U;
720 }
721 break;
722 case RCC_ADCCLKSOURCE_PLLP:
723 HAL_RCCEx_GetPLLClockFreq(&pll_freq);
724 frequency = pll_freq.PLL_P_Frequency;
725 break;
726
727 default:
728 /* No clock source, frequency default init at 0 */
729 break;
730 }
731 break;
732 }
733
734 case RCC_PERIPHCLK_I2C1:
735 {
736 /* Get the current I2C1 source */
737 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
738
739 switch (srcclk)
740 {
741 case RCC_I2C1CLKSOURCE_PCLK1:
742 frequency = HAL_RCC_GetPCLK1Freq();
743 break;
744 case RCC_I2C1CLKSOURCE_SYSCLK:
745 frequency = HAL_RCC_GetSysClockFreq();
746 break;
747 case RCC_I2C1CLKSOURCE_HSI:
748 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
749 {
750 frequency = HSI_VALUE;
751 }
752 break;
753 default:
754 /* No clock source, frequency default init at 0 */
755 break;
756 }
757
758 break;
759 }
760
761 case RCC_PERIPHCLK_I2C3:
762 {
763 /* Get the current I2C3 source */
764 srcclk = __HAL_RCC_GET_I2C3_SOURCE();
765
766 switch (srcclk)
767 {
768 case RCC_I2C3CLKSOURCE_PCLK1:
769 frequency = HAL_RCC_GetPCLK1Freq();
770 break;
771 case RCC_I2C3CLKSOURCE_SYSCLK:
772 frequency = HAL_RCC_GetSysClockFreq();
773 break;
774 case RCC_I2C3CLKSOURCE_HSI:
775 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
776 {
777 frequency = HSI_VALUE;
778 }
779 break;
780 default:
781 /* No clock source, frequency default init at 0 */
782 break;
783 }
784
785 break;
786 }
787
788 case RCC_PERIPHCLK_LPTIM1:
789 {
790 /* Get the current LPTIM1 source */
791 srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
792
793 switch (srcclk)
794 {
795 case RCC_LPTIM1CLKSOURCE_PCLK1:
796 frequency = HAL_RCC_GetPCLK1Freq();
797 break;
798 case RCC_LPTIM1CLKSOURCE_LSI:
799 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
800 {
801 #if defined(RCC_CSR_LSIPREDIV)
802 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
803 {
804 frequency = LSI_VALUE / 128U;
805 }
806 else
807 #endif /* RCC_CSR_LSIPREDIV */
808 {
809 frequency = LSI_VALUE;
810 }
811 }
812 break;
813 case RCC_LPTIM1CLKSOURCE_HSI:
814 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
815 {
816 frequency = HSI_VALUE;
817 }
818 break;
819 case RCC_LPTIM1CLKSOURCE_LSE:
820 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
821 {
822 frequency = LSE_VALUE;
823 }
824 break;
825 default:
826 /* No clock source, frequency default init at 0 */
827 break;
828 }
829
830 break;
831 }
832
833 case RCC_PERIPHCLK_LPTIM2:
834 {
835 /* Get the current LPTIM2 source */
836 srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
837
838 switch (srcclk)
839 {
840 case RCC_LPTIM2CLKSOURCE_PCLK1:
841 frequency = HAL_RCC_GetPCLK1Freq();
842 break;
843 case RCC_LPTIM2CLKSOURCE_LSI:
844 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
845 {
846 #if defined(RCC_CSR_LSIPREDIV)
847 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
848 {
849 frequency = LSI_VALUE / 128U;
850 }
851 else
852 #endif /* RCC_CSR_LSIPREDIV */
853 {
854 frequency = LSI_VALUE;
855 }
856 }
857 break;
858 case RCC_LPTIM2CLKSOURCE_HSI:
859 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
860 {
861 frequency = HSI_VALUE;
862 }
863 break;
864 case RCC_LPTIM2CLKSOURCE_LSE:
865 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
866 {
867 frequency = LSE_VALUE;
868 }
869 break;
870 default:
871 /* No clock source, frequency default init at 0 */
872 break;
873 }
874 break;
875 }
876 #if defined (LPTIM3)
877 case RCC_PERIPHCLK_LPTIM3:
878 {
879 /* Get the current LPTIM3 source */
880 srcclk = __HAL_RCC_GET_LPTIM3_SOURCE();
881
882 switch (srcclk)
883 {
884 case RCC_LPTIM3CLKSOURCE_PCLK1:
885 frequency = HAL_RCC_GetPCLK1Freq();
886 break;
887 case RCC_LPTIM3CLKSOURCE_LSI:
888 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
889 {
890 #if defined(RCC_CSR_LSIPREDIV)
891 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
892 {
893 frequency = LSI_VALUE / 128U;
894 }
895 else
896 #endif /* RCC_CSR_LSIPREDIV */
897 {
898 frequency = LSI_VALUE;
899 }
900 }
901 break;
902 case RCC_LPTIM3CLKSOURCE_HSI:
903 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
904 {
905 frequency = HSI_VALUE;
906 }
907 break;
908 case RCC_LPTIM3CLKSOURCE_LSE:
909 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
910 {
911 frequency = LSE_VALUE;
912 }
913 break;
914 default:
915 /* No clock source, frequency default init at 0 */
916 break;
917 }
918
919 break;
920 }
921 #endif /* LPTIM3 */
922 case RCC_PERIPHCLK_TIM1:
923 {
924 /* Get the current TIM1 source */
925 srcclk = __HAL_RCC_GET_TIM1_SOURCE();
926 switch (srcclk)
927 {
928 case RCC_TIM1CLKSOURCE_PCLK1:
929 if ((READ_BIT(RCC->CFGR, RCC_CFGR_PPRE) == RCC_HCLK_DIV1))
930 {
931 frequency = HAL_RCC_GetPCLK1Freq();
932 }
933 else
934 {
935 frequency = (HAL_RCC_GetPCLK1Freq() * 2U);
936 }
937 break;
938 case RCC_TIM1CLKSOURCE_PLLQ:
939 HAL_RCCEx_GetPLLClockFreq(&pll_freq);
940 frequency = pll_freq.PLL_Q_Frequency;
941 break;
942 default:
943 /* No clock source, frequency default init at 0 */
944 break;
945 }
946 break;
947 }
948 case RCC_PERIPHCLK_TIM15:
949 {
950 /* Get the current TIM15 source */
951 srcclk = __HAL_RCC_GET_TIM15_SOURCE();
952 switch (srcclk)
953 {
954 case RCC_TIM15CLKSOURCE_PCLK1:
955 if ((READ_BIT(RCC->CFGR, RCC_CFGR_PPRE) == RCC_HCLK_DIV1))
956 {
957 frequency = HAL_RCC_GetPCLK1Freq();
958 }
959 else
960 {
961 frequency = (HAL_RCC_GetPCLK1Freq() * 2U);
962 }
963 break;
964 case RCC_TIM15CLKSOURCE_PLLQ:
965 HAL_RCCEx_GetPLLClockFreq(&pll_freq);
966 frequency = pll_freq.PLL_Q_Frequency;
967 break;
968 default:
969 /* No clock source, frequency default init at 0 */
970 break;
971 }
972 break;
973 }
974 #if defined (USB_DRD_FS)
975 case RCC_PERIPHCLK_USB:
976 {
977 /* Get the current USB source */
978 srcclk = __HAL_RCC_GET_USB_SOURCE();
979 switch (srcclk)
980 {
981 case RCC_USBCLKSOURCE_HSI48:
982 frequency = HSI48_VALUE;
983 break;
984 case RCC_USBCLKSOURCE_MSI:
985 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
986 {
987 msirange = (__HAL_RCC_GET_MSI_RANGE() >> 4U);
988 if (msirange > 11U)
989 {
990 msirange = 11U;
991 }
992 frequency = MSIRangeTable[msirange];
993 }
994 break;
995 case RCC_USBCLKSOURCE_PLLQ:
996 HAL_RCCEx_GetPLLClockFreq(&pll_freq);
997 frequency = pll_freq.PLL_Q_Frequency;
998 break;
999 /* Clock not enabled for USB */
1000 case RCC_USBCLKSOURCE_NONE:
1001 frequency = 0U;
1002 break;
1003 default:
1004 /* No clock source, frequency default init at 0 */
1005 break;
1006 }
1007 break;
1008 }
1009 #endif /* USB_DRD_FS */
1010 case RCC_PERIPHCLK_RNG:
1011 {
1012 /* Get the current RNG source */
1013 srcclk = __HAL_RCC_GET_RNG_SOURCE();
1014 switch (srcclk)
1015 {
1016 case RCC_RNGCLKSOURCE_HSI48:
1017 frequency = HSI48_VALUE;
1018 break;
1019 case RCC_RNGCLKSOURCE_MSI:
1020 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
1021 {
1022 msirange = (__HAL_RCC_GET_MSI_RANGE() >> 4U);
1023 if (msirange > 11U)
1024 {
1025 msirange = 11U;
1026 }
1027 frequency = MSIRangeTable[msirange];
1028 }
1029 break;
1030 case RCC_RNGCLKSOURCE_PLLQ:
1031 HAL_RCCEx_GetPLLClockFreq(&pll_freq);
1032 frequency = pll_freq.PLL_Q_Frequency;
1033 break;
1034 /* Clock not enabled for RNG */
1035 case RCC_RNGCLKSOURCE_NONE:
1036 frequency = 0U;
1037 break;
1038 default:
1039 /* No clock source, frequency default init at 0 */
1040 break;
1041 }
1042 break;
1043 }
1044 default:
1045 break;
1046 }
1047 }
1048 return (frequency);
1049 }
1050
1051 /**
1052 * @brief Returns the PLL clock frequencies :PLL_P_Frequency,PLL_R_Frequency and PLL_Q_Frequency
1053 * @note The PLL clock frequencies computed by this function is not the real
1054 * frequency in the chip. It is calculated based on the predefined
1055 * constant and the selected clock source:
1056 * @note The function returns values based on HSE_VALUE, HSI_VALUE or MSI Value multiplied/divided by the PLL factors
1057 * @note This function can be used by the user application to compute the
1058 * baud-rate for the communication peripherals or configure other parameters.
1059 *
1060 * @note Each time PLLCLK changes, this function must be called to update the
1061 * right PLLCLK value. Otherwise, any configuration based on this function will be incorrect.
1062 * @param PLL_Clocks structure.
1063 * @retval None
1064 */
1065
HAL_RCCEx_GetPLLClockFreq(PLL_ClocksTypeDef * PLL_Clocks)1066 void HAL_RCCEx_GetPLLClockFreq(PLL_ClocksTypeDef *PLL_Clocks)
1067 {
1068 uint32_t pllsource;
1069 uint32_t pllm;
1070 uint32_t plln;
1071 uint32_t pllvco;
1072 uint32_t msirange;
1073
1074 plln = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1075 pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1076 pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1077 msirange = (__HAL_RCC_GET_MSI_RANGE() >> 4U);
1078 if (msirange > 11U)
1079 {
1080 msirange = 11U;
1081 }
1082 switch (pllsource)
1083 {
1084
1085 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1086 pllvco = (HSI_VALUE / pllm) * plln;
1087 break;
1088
1089 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
1090 pllvco = ((MSIRangeTable[msirange] / pllm) * plln);
1091 break;
1092
1093 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1094 pllvco = (HSE_VALUE / pllm) * plln;
1095 break;
1096
1097 default:
1098 pllvco = ((MSIRangeTable[msirange] / pllm) * plln);
1099 break;
1100 }
1101
1102 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_DIVP) != 0U)
1103 {
1104 PLL_Clocks->PLL_P_Frequency = (uint32_t)(pllvco / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) \
1105 >> RCC_PLLCFGR_PLLP_Pos) + 1U));
1106 }
1107 else
1108 {
1109 PLL_Clocks->PLL_P_Frequency = 0;
1110 }
1111
1112 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_DIVQ) != 0U)
1113 {
1114 PLL_Clocks->PLL_Q_Frequency = (uint32_t)(pllvco / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) \
1115 >> RCC_PLLCFGR_PLLQ_Pos) + 1U));
1116 }
1117 else
1118 {
1119 PLL_Clocks->PLL_Q_Frequency = 0;
1120 }
1121
1122 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_DIVR) != 0U)
1123 {
1124 PLL_Clocks->PLL_R_Frequency = (uint32_t)(pllvco / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) \
1125 >> RCC_PLLCFGR_PLLR_Pos) + 1U));
1126 }
1127 else
1128 {
1129 PLL_Clocks->PLL_R_Frequency = 0;
1130 }
1131 }
1132
1133 /**
1134 * @brief Enable PLL.
1135 * @param PLLInit pointer to an RCC_PLLInitTypeDef structure that
1136 * contains the configuration information for the PLL
1137 * @retval HAL status
1138 */
HAL_RCCEx_EnablePLL(RCC_PLLInitTypeDef * PLLInit)1139 HAL_StatusTypeDef HAL_RCCEx_EnablePLL(RCC_PLLInitTypeDef *PLLInit)
1140 {
1141 uint32_t tickstart;
1142 HAL_StatusTypeDef status = HAL_OK;
1143
1144 /* check for PLL Parameters used to output PLLCLK */
1145 assert_param(IS_RCC_PLLSOURCE(PLLInit->PLLSource));
1146 assert_param(IS_RCC_PLL_DIVM_VALUE(PLLInit->PLLM));
1147 assert_param(IS_RCC_PLL_MULN_VALUE(PLLInit->PLLN));
1148 assert_param(IS_RCC_PLL_DIVP_VALUE(PLLInit->PLLP));
1149 assert_param(IS_RCC_PLL_DIVQ_VALUE(PLLInit->PLLQ));
1150 assert_param(IS_RCC_PLL_DIVR_VALUE(PLLInit->PLLR));
1151 assert_param(IS_RCC_PLLCLOCKOUT_VALUE(PLLInit->PLLClockOut));
1152
1153 /* Disable the PLL */
1154 __HAL_RCC_PLL_DISABLE();
1155
1156 /* Get Start Tick*/
1157 tickstart = HAL_GetTick();
1158
1159 /* Wait till PLL is ready to be updated */
1160 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1161 {
1162 if ((HAL_GetTick() - tickstart) > 2U) /* PLL_TIMEOUT_VALUE) */
1163 {
1164 status = HAL_TIMEOUT;
1165 break;
1166 }
1167 }
1168
1169 if (status == HAL_OK)
1170 {
1171 /* Make sure PLLSource is ready */
1172 status = RCCEx_PLLSource_Enable(PLLInit->PLLSource);
1173
1174 if (status == HAL_OK)
1175 {
1176 /* Configure the PLL clock source, multiplication factor N, */
1177 /* and division factors M, P, Q and R */
1178 __HAL_RCC_PLL_CONFIG(PLLInit->PLLSource, PLLInit->PLLM, PLLInit->PLLN,
1179 PLLInit->PLLP, PLLInit->PLLQ, PLLInit->PLLR);
1180
1181 /* Configure the PLL Clock output(s) */
1182 __HAL_RCC_PLLCLKOUT_ENABLE(PLLInit->PLLClockOut);
1183
1184 /* Enable the PLL again by setting PLLON to 1*/
1185 __HAL_RCC_PLL_ENABLE();
1186
1187 /* Get Start Tick*/
1188 tickstart = HAL_GetTick();
1189
1190 /* Wait till PLL is ready */
1191 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1192 {
1193 if ((HAL_GetTick() - tickstart) > 2U) /* PLL_TIMEOUT_VALUE) */
1194 {
1195 status = HAL_TIMEOUT;
1196 break;
1197 }
1198 }
1199 }
1200 }
1201
1202 return status;
1203 }
1204
1205 /**
1206 * @brief Disable PLL.
1207 * @retval HAL status
1208 */
HAL_RCCEx_DisablePLL(void)1209 HAL_StatusTypeDef HAL_RCCEx_DisablePLL(void)
1210 {
1211 uint32_t tickstart;
1212 HAL_StatusTypeDef status = HAL_OK;
1213
1214 /* Disable the PLL */
1215 __HAL_RCC_PLL_DISABLE();
1216
1217 /* Get Start Tick*/
1218 tickstart = HAL_GetTick();
1219
1220 /* Wait till PLL is ready */
1221 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1222 {
1223 if ((HAL_GetTick() - tickstart) > 2U) /* PLL_TIMEOUT_VALUE) */
1224 {
1225 status = HAL_TIMEOUT;
1226 break;
1227 }
1228 }
1229
1230 /* To save power disable the PLL Source, FRACN and Clock outputs */
1231 CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLSRC);
1232
1233 return status;
1234 }
1235
1236 /**
1237 * @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
1238 * @param WakeUpClk Wakeup clock
1239 * This parameter can be one of the following values:
1240 * @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI oscillator selection
1241 * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection
1242 * @note This function shall not be called after the Clock Security System on HSE has been
1243 * enabled.
1244 * @retval None
1245 */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)1246 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
1247 {
1248 assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
1249
1250 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
1251 }
1252
1253 /**
1254 * @brief Configure the MSI range after standby mode.
1255 * @note After Standby its frequency can be selected between 3 possible values (1, 3.072 or 4 MHz).
1256 * @param MSIRange MSI range
1257 * This parameter can be one of the following values:
1258 * @arg @ref RCC_MSIRANGE_4 Range 4 around 4 MHz (reset value)
1259 * @arg @ref RCC_MSIRANGE_5 Range 5 around 2 MHz
1260 * @arg @ref RCC_MSIRANGE_6 Range 6 around 1.5 MHz
1261 * @arg @ref RCC_MSIRANGE_7 Range 7 around 1 MHz
1262 * @retval None
1263 */
HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)1264 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
1265 {
1266 assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
1267
1268 __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
1269 }
1270
1271 /**
1272 * @brief Enable the PLL-mode of the MSI.
1273 * @note Prior to enable the PLL-mode of the MSI for automatic hardware
1274 * calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
1275 * @retval None
1276 */
HAL_RCCEx_EnableMSIPLLMode(void)1277 void HAL_RCCEx_EnableMSIPLLMode(void)
1278 {
1279 SET_BIT(RCC->CR, RCC_CR_MSIPLLEN);
1280 }
1281
1282 /**
1283 * @brief Disable the PLL-mode of the MSI.
1284 * @note PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
1285 * @retval None
1286 */
HAL_RCCEx_DisableMSIPLLMode(void)1287 void HAL_RCCEx_DisableMSIPLLMode(void)
1288 {
1289 CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN);
1290 }
1291
1292 /**
1293 * @brief Enables the LSE Clock Security System.
1294 * @retval None
1295 */
HAL_RCCEx_EnableLSECSS(void)1296 void HAL_RCCEx_EnableLSECSS(void)
1297 {
1298 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1299 }
1300
1301 /**
1302 * @brief Disables the LSE Clock Security System.
1303 * @note Once enabled this bit cannot be disabled, except after an LSE failure detection
1304 * (LSECSSD=1). In that case the software MUST disable the LSECSSON bit.
1305 * Reset by power on reset and RTC software reset (RTCRST bit).
1306 * @retval None
1307 */
HAL_RCCEx_DisableLSECSS(void)1308 void HAL_RCCEx_DisableLSECSS(void)
1309 {
1310 /* Disable LSE CSS */
1311 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1312 }
1313
1314 /**
1315 * @brief Enable the LSE Clock Security System IT & corresponding EXTI line.
1316 * @note LSE Clock Security System IT is mapped on RTC EXTI line 27
1317 * @retval None
1318 */
HAL_RCCEx_EnableLSECSS_IT(void)1319 void HAL_RCCEx_EnableLSECSS_IT(void)
1320 {
1321 /* Enable LSE CSS */
1322 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1323 /* Enable LSE CSS IT */
1324 __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
1325 /* Enable IT on EXTI Line 27 */
1326 __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
1327 __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
1328 }
1329
1330 /**
1331 * @brief Handle the RCC LSE Clock Security System interrupt request.
1332 * @retval None
1333 */
HAL_RCCEx_LSECSS_IRQHandler(void)1334 void HAL_RCCEx_LSECSS_IRQHandler(void)
1335 {
1336 /* Check RCC LSE CSSF flag */
1337 if (__HAL_RCC_GET_IT(RCC_IT_LSECSS))
1338 {
1339 /* RCC LSE Clock Security System interrupt user callback */
1340 HAL_RCCEx_LSECSS_Callback();
1341
1342 /* Clear RCC LSE CSS pending bit */
1343 __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
1344 }
1345 }
1346
1347 /**
1348 * @brief RCCEx LSE Clock Security System interrupt callback.
1349 * @retval none
1350 */
HAL_RCCEx_LSECSS_Callback(void)1351 __weak void HAL_RCCEx_LSECSS_Callback(void)
1352 {
1353 /* NOTE : This function should not be modified, when the callback is needed,
1354 the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
1355 */
1356 }
1357
1358 /**
1359 * @brief Select the Low Speed clock source to output on LSCO pin (PA2).
1360 * @param LSCOSource specifies the Low Speed clock source to output.
1361 * This parameter can be one of the following values:
1362 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
1363 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
1364 * @retval None
1365 */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1366 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1367 {
1368 GPIO_InitTypeDef GPIO_InitStruct = {0};
1369 FlagStatus pwrclkchanged = RESET;
1370 FlagStatus backupchanged = RESET;
1371
1372 /* Check the parameters */
1373 assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1374
1375 /* LSCO Pin Clock Enable */
1376 __LSCO_CLK_ENABLE();
1377 #if defined (LSCO_PIN)
1378 /* Configure the LSCO pin in analog mode */
1379 GPIO_InitStruct.Pin = LSCO_PIN;
1380 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
1381 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1382 GPIO_InitStruct.Pull = GPIO_NOPULL;
1383 HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
1384 #endif /* LSCO_PIN */
1385 /* Update LSCOSEL clock source in Backup Domain control register */
1386 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1387 {
1388 __HAL_RCC_PWR_CLK_ENABLE();
1389 pwrclkchanged = SET;
1390 }
1391 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1392 {
1393 HAL_PWR_EnableBkUpAccess();
1394 backupchanged = SET;
1395 }
1396
1397 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
1398
1399 if (backupchanged == SET)
1400 {
1401 HAL_PWR_DisableBkUpAccess();
1402 }
1403 if (pwrclkchanged == SET)
1404 {
1405 __HAL_RCC_PWR_CLK_DISABLE();
1406 }
1407 }
1408
1409 /**
1410 * @brief Disable the Low Speed clock output.
1411 * @retval None
1412 */
HAL_RCCEx_DisableLSCO(void)1413 void HAL_RCCEx_DisableLSCO(void)
1414 {
1415 FlagStatus pwrclkchanged = RESET;
1416 FlagStatus backupchanged = RESET;
1417
1418 /* Update LSCOEN bit in Backup Domain control register */
1419 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1420 {
1421 __HAL_RCC_PWR_CLK_ENABLE();
1422 pwrclkchanged = SET;
1423 }
1424 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1425 {
1426 /* Enable access to the backup domain */
1427 HAL_PWR_EnableBkUpAccess();
1428 backupchanged = SET;
1429 }
1430
1431 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
1432
1433 /* Restore previous configuration */
1434 if (backupchanged == SET)
1435 {
1436 /* Disable access to the backup domain */
1437 HAL_PWR_DisableBkUpAccess();
1438 }
1439 if (pwrclkchanged == SET)
1440 {
1441 __HAL_RCC_PWR_CLK_DISABLE();
1442 }
1443 }
1444
1445 /**
1446 * @}
1447 */
1448
1449 #if defined(CRS)
1450
1451 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
1452 * @brief Extended Clock Recovery System Control functions
1453 *
1454 @verbatim
1455 ===============================================================================
1456 ##### Extended Clock Recovery System Control functions #####
1457 ===============================================================================
1458 [..]
1459 For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
1460
1461 (#) In System clock config, HSI48 needs to be enabled
1462
1463 (#) Enable CRS clock in IP MSP init which will use CRS functions
1464
1465 (#) Call CRS functions as follows:
1466 (##) Prepare synchronization configuration necessary for HSI48 calibration
1467 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
1468 and also HSI48 oscillator smooth trimming.
1469 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
1470 directly reload value with target and synchronization frequencies values
1471 (##) Call function HAL_RCCEx_CRSConfig which
1472 (+++) Resets CRS registers to their default values.
1473 (+++) Configures CRS registers with synchronization configuration
1474 (+++) Enables automatic calibration and frequency error counter feature
1475 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
1476 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
1477 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
1478 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
1479 should be used as SYNC signal.
1480
1481 (##) A polling function is provided to wait for complete synchronization
1482 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
1483 (+++) According to CRS status, user can decide to adjust again the calibration or continue
1484 application if synchronization is OK
1485
1486 (#) User can retrieve information related to synchronization in calling function
1487 HAL_RCCEx_CRSGetSynchronizationInfo()
1488
1489 (#) Regarding synchronization status and synchronization information, user can try a new calibration
1490 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
1491 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
1492 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
1493 incremented), while when it is detected during the upcounting phase it means that the actual frequency
1494 is higher (and that the TRIM value should be decremented).
1495
1496 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
1497 through CRS Handler (CRS_IRQn/CRS_IRQHandler)
1498 (++) Call function HAL_RCCEx_CRSConfig()
1499 (++) Enable CRS_IRQn (thanks to NVIC functions)
1500 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
1501 (++) Implement CRS status management in the following user callbacks called from
1502 HAL_RCCEx_CRS_IRQHandler():
1503 (+++) HAL_RCCEx_CRS_SyncOkCallback()
1504 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
1505 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
1506 (+++) HAL_RCCEx_CRS_ErrorCallback()
1507
1508 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
1509 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
1510
1511 @endverbatim
1512 * @{
1513 */
1514
1515 /**
1516 * @brief Start automatic synchronization for polling mode
1517 * @param pInit Pointer on RCC_CRSInitTypeDef structure
1518 * @retval None
1519 */
HAL_RCCEx_CRSConfig(const RCC_CRSInitTypeDef * const pInit)1520 void HAL_RCCEx_CRSConfig(const RCC_CRSInitTypeDef *const pInit)
1521 {
1522 uint32_t value; /* no init needed */
1523
1524 /* Check the parameters */
1525 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
1526 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
1527 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
1528 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
1529 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
1530 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
1531
1532 /* CONFIGURATION */
1533
1534 /* Before configuration, reset CRS registers to their default values*/
1535 __HAL_RCC_CRS_FORCE_RESET();
1536 __HAL_RCC_CRS_RELEASE_RESET();
1537
1538 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
1539 /* Set the SYNCSRC[1:0] bits according to Source value */
1540 /* Set the SYNCSPOL bit according to Polarity value */
1541 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
1542 /* Set the RELOAD[15:0] bits according to ReloadValue value */
1543 value |= pInit->ReloadValue;
1544 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
1545 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
1546 WRITE_REG(CRS->CFGR, value);
1547
1548 /* Adjust HSI48 oscillator smooth trimming */
1549 /* Set the TRIM[6:0] bits according to RCC_CRS_HSI48CalibrationValue value */
1550 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
1551
1552 /* START AUTOMATIC SYNCHRONIZATION*/
1553
1554 /* Enable Automatic trimming & Frequency error counter */
1555 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
1556 }
1557
1558 /**
1559 * @brief Generate the software synchronization event
1560 * @retval None
1561 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)1562 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
1563 {
1564 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
1565 }
1566
1567 /**
1568 * @brief Return synchronization info
1569 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
1570 * @retval None
1571 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)1572 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
1573 {
1574 /* Check the parameter */
1575 assert_param(pSynchroInfo != (void *)NULL);
1576
1577 /* Get the reload value */
1578 pSynchroInfo->ReloadValue = (READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
1579
1580 /* Get HSI48 oscillator smooth trimming */
1581 pSynchroInfo->HSI48CalibrationValue = (READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
1582
1583 /* Get Frequency error capture */
1584 pSynchroInfo->FreqErrorCapture = (READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
1585
1586 /* Get Frequency error direction */
1587 pSynchroInfo->FreqErrorDirection = (READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
1588 }
1589
1590 /**
1591 * @brief Wait for CRS Synchronization status.
1592 * @param Timeout Duration of the timeout
1593 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
1594 * frequency.
1595 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
1596 * @retval Combination of Synchronization status
1597 * This parameter can be a combination of the following values:
1598 * @arg @ref RCC_CRS_TIMEOUT
1599 * @arg @ref RCC_CRS_SYNCOK
1600 * @arg @ref RCC_CRS_SYNCWARN
1601 * @arg @ref RCC_CRS_SYNCERR
1602 * @arg @ref RCC_CRS_SYNCMISS
1603 * @arg @ref RCC_CRS_TRIMOVF
1604 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)1605 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1606 {
1607 uint32_t crsstatus = RCC_CRS_NONE;
1608 uint32_t tickstart;
1609
1610 /* Get timeout */
1611 tickstart = HAL_GetTick();
1612
1613 /* Wait for CRS flag or timeout detection */
1614 do
1615 {
1616 if (Timeout != HAL_MAX_DELAY)
1617 {
1618 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1619 {
1620 crsstatus = RCC_CRS_TIMEOUT;
1621 }
1622 }
1623 /* Check CRS SYNCOK flag */
1624 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1625 {
1626 /* CRS SYNC event OK */
1627 crsstatus |= RCC_CRS_SYNCOK;
1628
1629 /* Clear CRS SYNC event OK bit */
1630 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1631 }
1632
1633 /* Check CRS SYNCWARN flag */
1634 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1635 {
1636 /* CRS SYNC warning */
1637 crsstatus |= RCC_CRS_SYNCWARN;
1638
1639 /* Clear CRS SYNCWARN bit */
1640 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1641 }
1642
1643 /* Check CRS TRIM overflow flag */
1644 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1645 {
1646 /* CRS SYNC Error */
1647 crsstatus |= RCC_CRS_TRIMOVF;
1648
1649 /* Clear CRS Error bit */
1650 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1651 }
1652
1653 /* Check CRS Error flag */
1654 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1655 {
1656 /* CRS SYNC Error */
1657 crsstatus |= RCC_CRS_SYNCERR;
1658
1659 /* Clear CRS Error bit */
1660 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1661 }
1662
1663 /* Check CRS SYNC Missed flag */
1664 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1665 {
1666 /* CRS SYNC Missed */
1667 crsstatus |= RCC_CRS_SYNCMISS;
1668
1669 /* Clear CRS SYNC Missed bit */
1670 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1671 }
1672
1673 /* Check CRS Expected SYNC flag */
1674 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1675 {
1676 /* frequency error counter reached a zero value */
1677 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1678 }
1679 } while (RCC_CRS_NONE == crsstatus);
1680
1681 return crsstatus;
1682 }
1683
1684 /**
1685 * @brief Handle the Clock Recovery System interrupt request.
1686 * @retval None
1687 */
HAL_RCCEx_CRS_IRQHandler(void)1688 void HAL_RCCEx_CRS_IRQHandler(void)
1689 {
1690 uint32_t crserror = RCC_CRS_NONE;
1691 /* Get current IT flags and IT sources values */
1692 uint32_t itflags = READ_REG(CRS->ISR);
1693 uint32_t itsources = READ_REG(CRS->CR);
1694
1695 /* Check CRS SYNCOK flag */
1696 if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
1697 {
1698 /* Clear CRS SYNC event OK flag */
1699 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
1700
1701 /* user callback */
1702 HAL_RCCEx_CRS_SyncOkCallback();
1703 }
1704 /* Check CRS SYNCWARN flag */
1705 else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
1706 {
1707 /* Clear CRS SYNCWARN flag */
1708 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
1709
1710 /* user callback */
1711 HAL_RCCEx_CRS_SyncWarnCallback();
1712 }
1713 /* Check CRS Expected SYNC flag */
1714 else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
1715 {
1716 /* frequency error counter reached a zero value */
1717 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
1718
1719 /* user callback */
1720 HAL_RCCEx_CRS_ExpectedSyncCallback();
1721 }
1722 /* Check CRS Error flags */
1723 else
1724 {
1725 if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
1726 {
1727 if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
1728 {
1729 crserror |= RCC_CRS_SYNCERR;
1730 }
1731 if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
1732 {
1733 crserror |= RCC_CRS_SYNCMISS;
1734 }
1735 if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
1736 {
1737 crserror |= RCC_CRS_TRIMOVF;
1738 }
1739
1740 /* Clear CRS Error flags */
1741 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
1742
1743 /* user error callback */
1744 HAL_RCCEx_CRS_ErrorCallback(crserror);
1745 }
1746 }
1747 }
1748
1749 /**
1750 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
1751 * @retval none
1752 */
HAL_RCCEx_CRS_SyncOkCallback(void)1753 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1754 {
1755 /* NOTE : This function should not be modified, when the callback is needed,
1756 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1757 */
1758 }
1759
1760 /**
1761 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
1762 * @retval none
1763 */
HAL_RCCEx_CRS_SyncWarnCallback(void)1764 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1765 {
1766 /* NOTE : This function should not be modified, when the callback is needed,
1767 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1768 */
1769 }
1770
1771 /**
1772 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
1773 * @retval none
1774 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1775 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1776 {
1777 /* NOTE : This function should not be modified, when the callback is needed,
1778 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1779 */
1780 }
1781
1782 /**
1783 * @brief RCCEx Clock Recovery System Error interrupt callback.
1784 * @param Error Combination of Error status.
1785 * This parameter can be a combination of the following values:
1786 * @arg @ref RCC_CRS_SYNCERR
1787 * @arg @ref RCC_CRS_SYNCMISS
1788 * @arg @ref RCC_CRS_TRIMOVF
1789 * @retval none
1790 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1791 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1792 {
1793 /* Prevent unused argument(s) compilation warning */
1794 UNUSED(Error);
1795
1796 /* NOTE : This function should not be modified, when the callback is needed,
1797 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1798 */
1799 }
1800
1801 /**
1802 * @}
1803 */
1804
1805 #endif /* CRS */
1806
1807 /** @addtogroup RCCEx_Private_Functions
1808 * @{
1809 */
1810
RCCEx_PLLSource_Enable(uint32_t PllSource)1811 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource)
1812 {
1813 uint32_t tickstart;
1814 HAL_StatusTypeDef status = HAL_OK;
1815
1816 switch (PllSource)
1817 {
1818 case RCC_PLLSOURCE_MSI:
1819 /* Check whether MSI in not ready and enable it */
1820 if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1821 {
1822 /* Enable the Internal Multi Speed oscillator (MSI). */
1823 __HAL_RCC_MSI_ENABLE();
1824
1825 /* Get timeout */
1826 tickstart = HAL_GetTick();
1827
1828 /* Wait till MSI is ready */
1829 while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1830 {
1831 if ((HAL_GetTick() - tickstart) > RCC_MSI_TIMEOUT_VALUE)
1832 {
1833 status = HAL_TIMEOUT;
1834 break;
1835 }
1836 }
1837 }
1838 break;
1839
1840 case RCC_PLLSOURCE_HSI:
1841 /* Check whether HSI in not ready and enable it */
1842 if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1843 {
1844 /* Enable the Internal High Speed oscillator (HSI). */
1845 __HAL_RCC_HSI_ENABLE();
1846
1847 /* Get timeout */
1848 tickstart = HAL_GetTick();
1849
1850 /* Wait till MSI is ready */
1851 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1852 {
1853 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
1854 {
1855 status = HAL_TIMEOUT;
1856 break;
1857 }
1858 }
1859 }
1860 break;
1861
1862 case RCC_PLLSOURCE_HSE:
1863 /* Check whether HSE in not ready and enable it */
1864 if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1865 {
1866 /* Enable the External High Speed oscillator (HSE). */
1867 SET_BIT(RCC->CR, RCC_CR_HSEON);
1868
1869 /* Get Start Tick*/
1870 tickstart = HAL_GetTick();
1871
1872 /* Wait till HSE is ready */
1873 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1874 {
1875 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
1876 {
1877 status = HAL_TIMEOUT;
1878 break;
1879 }
1880 }
1881 }
1882 break;
1883
1884 default:
1885 status = HAL_ERROR;
1886 break;
1887 }
1888
1889 return status;
1890 }
1891
1892 /**
1893 * @}
1894 */
1895
1896 /**
1897 * @}
1898 */
1899
1900 /**
1901 * @}
1902 */
1903
1904 #endif /* HAL_RCC_MODULE_ENABLED */
1905
1906 /**
1907 * @}
1908 */
1909
1910 /**
1911 * @}
1912 */
1913