1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_hal_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Reset and Clock Control (RCC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2019 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                       ##### RCC specific features #####
24   ==============================================================================
25     [..]
26       After reset the device is running from Multiple Speed Internal oscillator
27       (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
28       and I-Cache are disabled, and all peripherals are off except internal
29       SRAM, Flash and JTAG.
30 
31       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) buses:
32           all peripherals mapped on these buses are running at MSI speed.
33       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
34       (+) All GPIOs are in analog mode, except the JTAG pins which
35           are assigned to be used for debug purpose.
36 
37     [..]
38       Once the device started from reset, the user application has to:
39       (+) Configure the clock source to be used to drive the System clock
40           (if the application needs higher frequency/performance)
41       (+) Configure the System clock frequency and Flash settings
42       (+) Configure the AHB and APB buses prescalers
43       (+) Enable the clock for the peripheral(s) to be used
44       (+) Configure the clock source(s) for peripherals which clocks are not
45           derived from the System clock (SAI1, RTC, ADC, USB/RNG, USART1, LPUART1, LPTIMx, I2Cx, SMPS)
46 
47   @endverbatim
48   ******************************************************************************
49   */
50 
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32wbxx_hal.h"
53 
54 /** @addtogroup STM32WBxx_HAL_Driver
55   * @{
56   */
57 
58 /** @defgroup RCC RCC
59   * @brief RCC HAL module driver
60   * @{
61   */
62 
63 #ifdef HAL_RCC_MODULE_ENABLED
64 
65 /* Private typedef -----------------------------------------------------------*/
66 /* Private define ------------------------------------------------------------*/
67 /** @defgroup RCC_Private_Constants RCC Private Constants
68   * @{
69   */
70 #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
71 #define HSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
72 #define MSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
73 #define LSI1_TIMEOUT_VALUE         (2U)    /* 2 ms (minimum Tick + 1)   */
74 #define LSI2_TIMEOUT_VALUE         (3U)    /* to be adjusted with DS    */
75 #define HSI48_TIMEOUT_VALUE        (2U)    /* 2 ms (minimum Tick + 1)   */
76 #define PLL_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
77 #if defined(SAI1)
78 #define PLLSAI1_TIMEOUT_VALUE      (2U)    /* 2 ms (minimum Tick + 1)   */
79 #endif /* SAI1 */
80 #define PRESCALER_TIMEOUT_VALUE    (2U)    /* 2 ms (minimum Tick + 1)   */
81 #define LATENCY_TIMEOUT_VALUE      (2U)    /* 2 ms (minimum Tick + 1)   */
82 #define CLOCKSWITCH_TIMEOUT_VALUE  (5000U) /* 5 s                       */
83 
84 #define PLLSOURCE_NONE             (0U)
85 #define MEGA_HZ                    (1000000U) /* Division factor to convert Hz in Mhz */
86 /**
87   * @}
88   */
89 
90 /* Private macro -------------------------------------------------------------*/
91 /** @defgroup RCC_Private_Macros RCC Private Macros
92   * @{
93   */
94 
95 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__)   ((__RCC_MCOx__) & GPIO_PIN_MASK)
96 
97 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__)    (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
98 
99 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
100 
101 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__)  (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
102 
103 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
104   (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (uint32_t)(__HAL_RCC_PLLSOURCE__)))
105 
106 #define __COUNTOF(_A_)   (sizeof(_A_) / sizeof(*(_A_)))
107 /**
108   * @}
109   */
110 
111 /* Private variables ---------------------------------------------------------*/
112 /** @defgroup RCC_Private_Variables RCC Private Variables
113   * @{
114   */
115 
116 
117 /**
118   * @}
119   */
120 
121 /* Private function prototypes -----------------------------------------------*/
122 /** @defgroup RCC_Private_Functions RCC Private Functions
123   * @{
124   */
125 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range);
126 static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage);
127 /**
128   * @}
129   */
130 
131 /* Exported functions --------------------------------------------------------*/
132 
133 /** @defgroup RCC_Exported_Functions RCC Exported Functions
134   * @{
135   */
136 
137 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
138   *  @brief    Initialization and Configuration functions
139   *
140   @verbatim
141  ===============================================================================
142            ##### Initialization and de-initialization functions #####
143  ===============================================================================
144     [..]
145       This section provides functions allowing to configure the internal and external oscillators
146       (HSE, HSI, LSE, MSI, LSI1, LSI2, PLL, CSS and MCO) and the System buses clocks (SYSCLK, HCLK1, HCLK2, HCLK4, PCLK1
147        and PCLK2).
148 
149     [..] Internal/external clock and PLL configuration
150          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
151              the PLL as System clock source.
152 
153          (+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
154              It can be used to generate the clock for the USB FS (48 MHz).
155              The number of flash wait states is automatically adjusted when MSI range is updated with
156              HAL_RCC_OscConfig() and the MSI is used as System clock source.
157 
158          (+) LSI1/LSI2 (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
159              clock source.
160 
161          (+) HSE (high-speed external): 32 MHz crystal oscillator used directly or
162              through the PLL as System clock source. Can be used also optionally as RTC clock source.
163 
164          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source
165              or the RF system Auto-wakeup from Stop and Standby modes.
166 
167          (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
168            (++) The first output is used to generate the high speed system clock (up to 64MHz).
169            (++) The second output is used to generate the clock for the USB FS (48 MHz),
170                 the random analog generator (<=48 MHz)
171            (++) The third output is used to generate an accurate clock to achieve
172                 high-quality audio performance on SAI interface.
173 
174          (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
175            (++) The first output is used to generate SAR ADC clock.
176            (++) The second output is used to generate the clock for the USB FS (48 MHz),
177                 the random analog generator (<=48 MHz).
178            (++) The Third output is used to generate an accurate clock to achieve
179                 high-quality audio performance on SAI interface.
180 
181 
182          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
183             (HSE used directly or through PLL as System clock source), the System clock
184              is automatically switched to MSI or the HSI oscillator (depending on the
185              STOPWUCK configuration) and an interrupt is generated if enabled.
186              The interrupt is linked to the CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector.
187 
188          (+) LSECSS: once enabled, if a LSE clock failure occurs, the LSE
189              clock is no longer supplied to the RTC but no hardware action is made to the registers. If the
190              MSI was in PLL-mode, this mode is disabled.
191              In Standby mode a wakeup is generated. In other modes an interrupt can be sent to wakeup
192              the software
193 
194          (+) MCO (microcontroller clock output): used to output MSI, LSI1, LSI2, HSI, LSE, HSE (before and
195              after stabilization), SYSCLK, HSI48 or main PLL clock (through a configurable prescaler)
196              on PA8, PB6 & PA15 pins.
197 
198     [..] System, AHB and APB buses clocks configuration
199          (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
200              HSE and main PLL.
201              The AHB clock (HCLK1) is derived from System clock through configurable
202              prescaler and used to clock the CPU, memory and peripherals mapped
203              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
204              from AHB clock through configurable prescalers and used to clock
205              the peripherals mapped on these buses. You can use
206              HAL_RCC_GetSysClockFreq() function to retrieve the frequencies of these clocks.
207              The AHB4 clock (HCLK4) is derived from System clock through configurable
208              prescaler and used to clock the FLASH
209 
210          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
211 
212            (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSYS) or
213                 from an external clock mapped on the SAI_CKIN pin.
214                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
215            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
216                 divided by 32.
217                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
218                 to configure this clock.
219            (+@) USB FS and RNG: USB FS requires a frequency equal to 48 MHz
220                 to work correctly, while RNG peripherals requires a frequency
221                 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
222                 through PLLQ divider. You have to enable the peripheral clock and use
223                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
224            (+@) IWDG clock which is always the LSI clock.
225 
226 
227          (+) The maximum frequency of the SYSCLK, HCLK1, HCLK4, PCLK1 and PCLK2 is 64 MHz.
228              The maximum frequency of the HCLK2 is 32 MHz.
229              The clock source frequency should be adapted depending on the device voltage range
230              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
231 
232   @endverbatim
233 
234            Table 1. HCLK4 clock frequency.
235            +-------------------------------------------------------+
236            | Latency         |    HCLK4 clock frequency (MHz)      |
237            |                 |-------------------------------------|
238            |                 | voltage range 1  | voltage range 2  |
239            |                 |      1.2 V       |     1.0 V        |
240            |-----------------|------------------|------------------|
241            |0WS(1 CPU cycles)|   HCLK4 <= 18    |   HCLK4 <= 6     |
242            |-----------------|------------------|------------------|
243            |1WS(2 CPU cycles)|   HCLK4 <= 36    |   HCLK4 <= 12    |
244            |-----------------|------------------|------------------|
245            |2WS(3 CPU cycles)|   HCLK4 <= 54    |   HCLK4 <= 16    |
246            |-----------------|------------------|------------------|
247            |3WS(4 CPU cycles)|   HCLK4 <= 64    |   HCLK4 <= n.a.  |
248            |-----------------|------------------|------------------|
249 
250   * @{
251   */
252 
253 /**
254   * @brief  Reset the RCC clock configuration to the default reset state.
255   * @note   The default reset state of the clock configuration is given below:
256   *           - MSI ON and used as system clock source
257   *           - HSE, HSI, PLL, PLLSAI1
258   *           - HCLK1, HCLK2, HCLK4, PCLK1 and PCLK2 prescalers set to 1.
259   *           - CSS, MCO OFF
260   *           - All interrupts disabled
261   * @note   This function doesn't modify the configuration of the
262   *           - Peripheral clocks
263   *           - LSI, LSE and RTC clocks
264   * @retval HAL status
265   */
HAL_RCC_DeInit(void)266 HAL_StatusTypeDef HAL_RCC_DeInit(void)
267 {
268   uint32_t tickstart;
269 
270   /* Get Start Tick*/
271   tickstart = HAL_GetTick();
272 
273   /* MSI PLL OFF */
274   LL_RCC_MSI_DisablePLLMode();
275 
276   /* Set MSION bit */
277   LL_RCC_MSI_Enable();
278 
279   /* Wait till MSI is ready */
280   while (LL_RCC_MSI_IsReady() == 0U)
281   {
282     if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
283     {
284       return HAL_TIMEOUT;
285     }
286   }
287 
288   /* Set MSIRANGE default value */
289   LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6);
290 
291   /* Set MSITRIM bits to the reset value*/
292   LL_RCC_MSI_SetCalibTrimming(0);
293 
294   /* Set HSITRIM bits to the reset value*/
295   LL_RCC_HSI_SetCalibTrimming(0x40U);
296 
297   /* Get Start Tick*/
298   tickstart = HAL_GetTick();
299 
300   /* Reset CFGR register (MSI is selected as system clock source) */
301   CLEAR_REG(RCC->CFGR);
302 
303   /* Wait till MSI is ready */
304   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
305   {
306     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
307     {
308       return HAL_TIMEOUT;
309     }
310   }
311 
312   /* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLON, PLLSAI11ON, HSEPRE bits */
313 #if defined(SAI1)
314   CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON |
315             RCC_CR_PLLSAI1ON);
316 #else
317   CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON);
318 #endif /* SAI1 */
319 
320   /* Get Start Tick*/
321   tickstart = HAL_GetTick();
322 
323   /* Wait till PLL is ready */
324   while (LL_RCC_PLL_IsReady() != 0U)
325   {
326     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
327     {
328       return HAL_TIMEOUT;
329     }
330   }
331 
332   /* once PLL is OFF, reset PLLCFGR register to default value */
333   WRITE_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLP_1 | RCC_PLLCFGR_PLLN_0);
334 
335 #if defined(SAI1)
336   /* Get Start Tick*/
337   tickstart = HAL_GetTick();
338 
339   /* Wait till PLL is ready */
340   while (LL_RCC_PLLSAI1_IsReady() != 0U)
341   {
342     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
343     {
344       return HAL_TIMEOUT;
345     }
346   }
347   /* once PLLSAI1 is OFF, reset PLLSAI1CFGR register to default value */
348   WRITE_REG(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLR_0 | RCC_PLLSAI1CFGR_PLLQ_0 |
349             RCC_PLLSAI1CFGR_PLLP_1 | RCC_PLLSAI1CFGR_PLLN_0);
350 #endif /* SAI1 */
351 
352   /* Disable all interrupts */
353   CLEAR_REG(RCC->CIER);
354 
355   /* Clear all interrupt flags */
356   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
357 
358   /* EXTCFGR reset*/
359   LL_RCC_WriteReg(EXTCFGR, 0x00030000U);
360 
361   /* Update the SystemCoreClock global variable */
362   SystemCoreClock = MSI_VALUE;
363 
364   /* Adapt Systick interrupt period */
365   if (HAL_InitTick(uwTickPrio) != HAL_OK)
366   {
367     return HAL_ERROR;
368   }
369   else
370   {
371     return HAL_OK;
372   }
373 }
374 
375 /**
376   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
377   *         @ref RCC_OscInitTypeDef.
378   * @param  RCC_OscInitStruct  pointer to a @ref RCC_OscInitTypeDef structure that
379   *         contains the configuration information for the RCC Oscillators.
380   * @note   The PLL is not disabled when used as system clock.
381   * @note   The PLL source is not updated when used as PLLSAI1 clock source.
382   * @retval HAL status
383   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)384 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
385 {
386   uint32_t tickstart;
387 
388   /* Check Null pointer */
389   if (RCC_OscInitStruct == NULL)
390   {
391     return HAL_ERROR;
392   }
393 
394   /* Check the parameters */
395   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
396 
397   /*----------------------------- MSI Configuration --------------------------*/
398   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
399   {
400     /* Check the parameters */
401     assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
402     assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
403     assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
404 
405     /* When the MSI is used as system clock it will not be disabled */
406     const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
407     const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
408     if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI) ||
409         ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_MSI)))
410     {
411       if (RCC_OscInitStruct->MSIState == RCC_MSI_OFF)
412       {
413         return HAL_ERROR;
414       }
415       /* Otherwise, just the calibration and MSI range change are allowed */
416       else
417       {
418         /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
419            must be correctly programmed according to the frequency of the AHB4 clock
420            and the supply voltage of the device. */
421         if (RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
422         {
423           /* First increase number of wait states update if necessary */
424           if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
425           {
426             return HAL_ERROR;
427           }
428 
429           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
430           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
431           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
432           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
433         }
434         else
435         {
436           /* Else, keep current flash latency while decreasing applies */
437           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
438           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
439           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
440           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
441 
442           /* Decrease number of wait states update if necessary */
443           if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
444           {
445             return HAL_ERROR;
446           }
447         }
448 
449         /* Update the SystemCoreClock global variable */
450         SystemCoreClock = HAL_RCC_GetHCLKFreq();
451 
452         if (HAL_InitTick(uwTickPrio) != HAL_OK)
453         {
454           return HAL_ERROR;
455         }
456       }
457     }
458     else
459     {
460       /* Check the MSI State */
461       if (RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
462       {
463         /* Enable the Internal High Speed oscillator (MSI). */
464         __HAL_RCC_MSI_ENABLE();
465 
466         /* Get timeout */
467         tickstart = HAL_GetTick();
468 
469         /* Wait till MSI is ready */
470         while (LL_RCC_MSI_IsReady() == 0U)
471         {
472           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
473           {
474             return HAL_TIMEOUT;
475           }
476         }
477 
478         /* Selects the Multiple Speed oscillator (MSI) clock range .*/
479         __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
480         /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
481         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
482 
483       }
484       else
485       {
486         /* Disable the Internal High Speed oscillator (MSI). */
487         __HAL_RCC_MSI_DISABLE();
488 
489         /* Get timeout */
490         tickstart = HAL_GetTick();
491 
492         /* Wait till MSI is disabled */
493         while (LL_RCC_MSI_IsReady() != 0U)
494         {
495           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
496           {
497             return HAL_TIMEOUT;
498           }
499         }
500       }
501     }
502   }
503 
504   /*------------------------------- HSE Configuration ------------------------*/
505   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
506   {
507     /* Check the parameters */
508     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
509 
510     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
511     const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
512     const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
513     if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
514         ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_HSE)))
515     {
516       if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
517       {
518         return HAL_ERROR;
519       }
520     }
521     else
522     {
523       /* Set the new HSE configuration ---------------------------------------*/
524       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
525 
526       /* Check the HSE State */
527       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
528       {
529         /* Get Start Tick*/
530         tickstart = HAL_GetTick();
531 
532         /* Wait till HSE is ready */
533         while (LL_RCC_HSE_IsReady() == 0U)
534         {
535           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
536           {
537             return HAL_TIMEOUT;
538           }
539         }
540       }
541       else
542       {
543         /* Get Start Tick*/
544         tickstart = HAL_GetTick();
545 
546         /* Wait till HSE is disabled */
547         while (LL_RCC_HSE_IsReady() != 0U)
548         {
549           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
550           {
551             return HAL_TIMEOUT;
552           }
553         }
554       }
555     }
556   }
557 
558   /*----------------------------- HSI Configuration --------------------------*/
559   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
560   {
561     /* Check the parameters */
562     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
563     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
564 
565     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
566     const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
567     const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
568     if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
569         ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_HSI)))
570     {
571       /* When HSI is used as system clock it will not be disabled */
572       if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
573       {
574         return HAL_ERROR;
575       }
576       /* Otherwise, just the calibration is allowed */
577       else
578       {
579         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
580         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
581       }
582     }
583     else
584     {
585       /* Check the HSI State */
586       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
587       {
588         /* Enable the Internal High Speed oscillator (HSI). */
589         __HAL_RCC_HSI_ENABLE();
590 
591         /* Get Start Tick*/
592         tickstart = HAL_GetTick();
593 
594         /* Wait till HSI is ready */
595         while (LL_RCC_HSI_IsReady() == 0U)
596         {
597           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
598           {
599             return HAL_TIMEOUT;
600           }
601         }
602 
603         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
604         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
605       }
606       else
607       {
608         /* Disable the Internal High Speed oscillator (HSI). */
609         __HAL_RCC_HSI_DISABLE();
610 
611         /* Get Start Tick*/
612         tickstart = HAL_GetTick();
613 
614         /* Wait till HSI is disabled */
615         while (LL_RCC_HSI_IsReady() != 0U)
616         {
617           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
618           {
619             return HAL_TIMEOUT;
620           }
621         }
622       }
623     }
624   }
625   /*------------------------------ LSI Configuration (LSI1 or LSI2) -------------------------*/
626 
627   if ((((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI1) == RCC_OSCILLATORTYPE_LSI1) || \
628       (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI2) == RCC_OSCILLATORTYPE_LSI2))
629   {
630     /* Check the parameters */
631     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
632 
633     /* Check the LSI State */
634     if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
635     {
636       /*------------------------------ LSI2 selected by default (when Switch ON) -------------------------*/
637       if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI2) == RCC_OSCILLATORTYPE_LSI2)
638       {
639         assert_param(IS_RCC_LSI2_CALIBRATION_VALUE(RCC_OscInitStruct->LSI2CalibrationValue));
640 
641         /* 1. Check LSI1 state and enable if required */
642         if (LL_RCC_LSI1_IsReady() == 0U)
643         {
644           /* This is required to enable LSI1 before enabling LSI2 */
645           __HAL_RCC_LSI1_ENABLE();
646 
647           /* Get Start Tick*/
648           tickstart = HAL_GetTick();
649 
650           /* Wait till LSI1 is ready */
651           while (LL_RCC_LSI1_IsReady() == 0U)
652           {
653             if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
654             {
655               return HAL_TIMEOUT;
656             }
657           }
658         }
659 
660         /* 2. Enable the Internal Low Speed oscillator (LSI2) and set trimming value */
661         __HAL_RCC_LSI2_ENABLE();
662 
663         /* Get Start Tick*/
664         tickstart = HAL_GetTick();
665 
666         /* Wait till LSI2 is ready */
667         while (LL_RCC_LSI2_IsReady() == 0U)
668         {
669           if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE)
670           {
671             return HAL_TIMEOUT;
672           }
673         }
674         /* Adjusts the Internal Low Spee oscillator (LSI2) calibration value */
675         __HAL_RCC_LSI2_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->LSI2CalibrationValue);
676 
677         /* 3. Disable LSI1 */
678 
679         /* LSI1 was initially not enable, require to disable it */
680         __HAL_RCC_LSI1_DISABLE();
681 
682         /* Get Start Tick*/
683         tickstart = HAL_GetTick();
684 
685         /* Wait till LSI1 is disabled */
686         while (LL_RCC_LSI1_IsReady() != 0U)
687         {
688           if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
689           {
690             return HAL_TIMEOUT;
691           }
692         }
693       }
694       else
695       {
696         /*------------------------------ LSI1 selected (only if LSI2 OFF)-------------------------*/
697 
698         /* 1. Enable the Internal Low Speed oscillator (LSI1). */
699         __HAL_RCC_LSI1_ENABLE();
700 
701         /* Get Start Tick*/
702         tickstart = HAL_GetTick();
703 
704         /* Wait till LSI1 is ready */
705         while (LL_RCC_LSI1_IsReady() == 0U)
706         {
707           if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
708           {
709             return HAL_TIMEOUT;
710           }
711         }
712         /*2. Switch OFF LSI2*/
713 
714         /* Disable the Internal Low Speed oscillator (LSI2). */
715         __HAL_RCC_LSI2_DISABLE();
716 
717         /* Wait till LSI2 is disabled */
718         while (LL_RCC_LSI2_IsReady() != 0U)
719         {
720           if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE)
721           {
722             return HAL_TIMEOUT;
723           }
724         }
725       }
726     }
727     else
728     {
729 
730       /* Disable the Internal Low Speed oscillator (LSI2). */
731       __HAL_RCC_LSI2_DISABLE();
732 
733       /* Get Start Tick*/
734       tickstart = HAL_GetTick();
735 
736       /* Wait till LSI2 is disabled */
737       while (LL_RCC_LSI2_IsReady() != 0U)
738       {
739         if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE)
740         {
741           return HAL_TIMEOUT;
742         }
743       }
744 
745       /* Disable the Internal Low Speed oscillator (LSI1). */
746       __HAL_RCC_LSI1_DISABLE();
747 
748       /* Get Start Tick*/
749       tickstart = HAL_GetTick();
750 
751       /* Wait till LSI1 is disabled */
752       while (LL_RCC_LSI1_IsReady() != 0U)
753       {
754         if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
755         {
756           return HAL_TIMEOUT;
757         }
758       }
759     }
760   }
761 
762   /*------------------------------ LSE Configuration -------------------------*/
763   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
764   {
765     /* Check the parameters */
766     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
767 
768     /* Update LSE configuration in Backup Domain control register    */
769     /* Requires to enable write access to Backup Domain of necessary */
770 
771     if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
772     {
773       /* Enable write access to Backup domain */
774       HAL_PWR_EnableBkUpAccess();
775 
776       /* Wait for Backup domain Write protection disable */
777       tickstart = HAL_GetTick();
778 
779       while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
780       {
781         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
782         {
783           return HAL_TIMEOUT;
784         }
785       }
786     }
787 
788     /* Set the new LSE configuration -----------------------------------------*/
789     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
790 
791     /* Check the LSE State */
792     if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
793     {
794       /* Get Start Tick*/
795       tickstart = HAL_GetTick();
796 
797       /* Wait till LSE is ready */
798       while (LL_RCC_LSE_IsReady() == 0U)
799       {
800         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
801         {
802           return HAL_TIMEOUT;
803         }
804       }
805     }
806     else
807     {
808       /* Get Start Tick*/
809       tickstart = HAL_GetTick();
810 
811       /* Wait till LSE is disabled */
812       while (LL_RCC_LSE_IsReady() != 0U)
813       {
814         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
815         {
816           return HAL_TIMEOUT;
817         }
818       }
819     }
820 
821   }
822 #if defined(RCC_HSI48_SUPPORT)
823   /*------------------------------ HSI48 Configuration -----------------------*/
824   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
825   {
826     /* Check the parameters */
827     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
828 
829     /* Check the HSI State */
830     if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
831     {
832       /* Enable the Internal Low Speed oscillator (HSI48). */
833       __HAL_RCC_HSI48_ENABLE();
834 
835       /* Get Start Tick*/
836       tickstart = HAL_GetTick();
837 
838       /* Wait till HSI48 is ready */
839       while (LL_RCC_HSI48_IsReady() == 0U)
840       {
841         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
842         {
843           return HAL_TIMEOUT;
844         }
845       }
846     }
847     else
848     {
849       /* Disable the Internal Low Speed oscillator (HSI48). */
850       __HAL_RCC_HSI48_DISABLE();
851 
852       /* Get Start Tick*/
853       tickstart = HAL_GetTick();
854 
855       /* Wait till HSI48 is disabled */
856       while (LL_RCC_HSI48_IsReady() != 0U)
857       {
858         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
859         {
860           return HAL_TIMEOUT;
861         }
862       }
863     }
864   }
865 #endif /* RCC_HSI48_SUPPORT */
866   /*-------------------------------- PLL Configuration -----------------------*/
867   /* Check the parameters */
868   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
869 
870   if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
871   {
872     const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
873     const uint32_t temp_pllconfig = RCC->PLLCFGR;
874 
875     /* PLL On ? */
876     if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
877     {
878       /* Check the parameters */
879       assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
880       assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
881       assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
882       assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
883       assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
884       assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
885 
886       /* Do nothing if PLL configuration is unchanged */
887       if ((READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
888           (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||
889           ((READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos) != RCC_OscInitStruct->PLL.PLLN) ||
890           (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) ||
891           (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ) ||
892           (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLR) != RCC_OscInitStruct->PLL.PLLR))
893       {
894         /* Check if the PLL is used as system clock or not */
895         if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
896         {
897 #if defined(SAI1)
898           /* Check if main PLL can be updated */
899           /* Not possible if the source is shared by other enabled PLLSAIx */
900           if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U)
901 
902           {
903             return HAL_ERROR;
904           }
905           else
906 #endif /* SAI1 */
907           {
908             /* Disable the main PLL. */
909             __HAL_RCC_PLL_DISABLE();
910 
911             /* Get Start Tick*/
912             tickstart = HAL_GetTick();
913 
914             /* Wait till PLL is ready */
915             while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
916             {
917               if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
918               {
919                 return HAL_TIMEOUT;
920               }
921             }
922 
923             /* Configure the main PLL clock source, multiplication and division factors. */
924             __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
925                                  RCC_OscInitStruct->PLL.PLLM,
926                                  RCC_OscInitStruct->PLL.PLLN,
927                                  RCC_OscInitStruct->PLL.PLLP,
928                                  RCC_OscInitStruct->PLL.PLLQ,
929                                  RCC_OscInitStruct->PLL.PLLR);
930 
931             /* Enable the main PLL. */
932             __HAL_RCC_PLL_ENABLE();
933 
934             /* Enable PLL System Clock output. */
935             __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
936 
937             /* Get Start Tick*/
938             tickstart = HAL_GetTick();
939 
940             /* Wait till PLL is ready */
941             while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
942             {
943               if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
944               {
945                 return HAL_TIMEOUT;
946               }
947             }
948           }
949         }
950         else
951         {
952           /* PLL is already used as System core clock */
953           return HAL_ERROR;
954         }
955       }
956       else
957       {
958         /* PLL configuration is unchanged */
959         /* Re-enable PLL if it was disabled (ie. low power mode) */
960         if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
961         {
962           /* Enable the main PLL. */
963           __HAL_RCC_PLL_ENABLE();
964 
965           /* Enable PLL System Clock output. */
966           __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
967 
968           /* Get Start Tick*/
969           tickstart = HAL_GetTick();
970 
971           /* Wait till PLL is ready */
972           while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
973           {
974             if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
975             {
976               return HAL_TIMEOUT;
977             }
978           }
979         }
980       }
981     }
982     else
983     {
984       /* Check that PLL is not used as system clock or not */
985       if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
986       {
987         /* Disable the main PLL. */
988         __HAL_RCC_PLL_DISABLE();
989 
990         /* Get Start Tick*/
991         tickstart = HAL_GetTick();
992 
993         /* Wait till PLL is disabled */
994         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
995         {
996           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
997           {
998             return HAL_TIMEOUT;
999           }
1000         }
1001 
1002         /* Disable the PLL source and outputs to save power when PLL is off */
1003 #if defined(SAI1) && defined(USB)
1004         CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLREN));
1005 #else
1006         CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLREN));
1007 #endif /* SAI1 && USB */
1008       }
1009       else
1010       {
1011         /* PLL is already used as System core clock */
1012         return HAL_ERROR;
1013       }
1014     }
1015   }
1016   return HAL_OK;
1017 }
1018 
1019 
1020 /**
1021   * @brief  Initialize the CPU, AHB and APB buses clocks according to the specified
1022   *         parameters in the RCC_ClkInitStruct.
1023   * @param  RCC_ClkInitStruct  pointer to a @ref RCC_ClkInitTypeDef structure that
1024   *         contains the configuration information for the RCC peripheral.
1025   * @param  FLatency  FLASH Latency
1026   *          This parameter can be one of the following values:
1027   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
1028   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
1029   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycle
1030   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycle
1031   *
1032   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1033   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
1034   *
1035   * @note   The MSI is used by default as system clock source after
1036   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
1037   *         the MSI frequency is set to its default value 4 MHz.
1038   *
1039   * @note   The HSI can be selected as system clock source after
1040   *         from STOP modes or in case of failure of the HSE used directly or indirectly
1041   *         as system clock (if the Clock Security System CSS is enabled).
1042   *
1043   * @note   A switch from one clock source to another occurs only if the target
1044   *         clock source is ready (clock stable after startup delay or PLL locked).
1045   *         If a clock source which is not yet ready is selected, the switch will
1046   *         occur when the clock source is ready.
1047   *
1048   * @note   You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
1049   *         currently used as system clock source.
1050   *
1051   * @note   Depending on the device voltage range, the software has to set correctly
1052   *         HPRE[3:0] bits to ensure that HCLK1 not exceed the maximum allowed frequency
1053   *         (for more details refer to section above "Initialization/de-initialization functions")
1054   * @retval None
1055   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)1056 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
1057 {
1058   uint32_t tickstart;
1059 
1060   /* Check Null pointer */
1061   if (RCC_ClkInitStruct == NULL)
1062   {
1063     return HAL_ERROR;
1064   }
1065 
1066   /* Check the parameters */
1067   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
1068   assert_param(IS_FLASH_LATENCY(FLatency));
1069 
1070   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1071     must be correctly programmed according to the frequency of the FLASH clock
1072     (HCLK4) and the supply voltage of the device. */
1073 
1074   /* Increasing the number of wait states because of higher CPU frequency */
1075   if (FLatency > __HAL_FLASH_GET_LATENCY())
1076   {
1077     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1078     __HAL_FLASH_SET_LATENCY(FLatency);
1079 
1080     /* Get Start Tick*/
1081     tickstart = HAL_GetTick();
1082 
1083     /* Check that the new number of wait states is taken into account to access the Flash
1084        memory by reading the FLASH_ACR register */
1085     while (__HAL_FLASH_GET_LATENCY() != FLatency)
1086     {
1087       if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
1088       {
1089         return HAL_TIMEOUT;
1090       }
1091     }
1092   }
1093 
1094   /*-------------------------- HCLK1 Configuration --------------------------*/
1095   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1096   {
1097     assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLKDivider));
1098     LL_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLKDivider);
1099 
1100     /* HCLK1 prescaler flag when value applied */
1101     tickstart = HAL_GetTick();
1102     while (LL_RCC_IsActiveFlag_HPRE() == 0U)
1103     {
1104       if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1105       {
1106         return HAL_TIMEOUT;
1107       }
1108     }
1109   }
1110 
1111   /*-------------------------- HCLK2 Configuration --------------------------*/
1112   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK2) == RCC_CLOCKTYPE_HCLK2)
1113   {
1114     assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK2Divider));
1115     LL_C2_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLK2Divider);
1116 
1117     /* HCLK2 prescaler flag when value applied */
1118     tickstart = HAL_GetTick();
1119     while (LL_RCC_IsActiveFlag_C2HPRE() == 0U)
1120     {
1121       if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1122       {
1123         return HAL_TIMEOUT;
1124       }
1125     }
1126   }
1127   /*-------------------------- HCLK4 Configuration --------------------------*/
1128   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK4) == RCC_CLOCKTYPE_HCLK4)
1129   {
1130     assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK4Divider));
1131     LL_RCC_SetAHB4Prescaler(RCC_ClkInitStruct->AHBCLK4Divider);
1132 
1133     /* AHB shared prescaler flag when value applied */
1134     tickstart = HAL_GetTick();
1135     while (LL_RCC_IsActiveFlag_SHDHPRE() == 0U)
1136     {
1137       if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1138       {
1139         return HAL_TIMEOUT;
1140       }
1141     }
1142   }
1143 
1144   /*-------------------------- PCLK1 Configuration ---------------------------*/
1145   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1146   {
1147     assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB1CLKDivider));
1148     LL_RCC_SetAPB1Prescaler(RCC_ClkInitStruct->APB1CLKDivider);
1149 
1150     /* APB1 prescaler flag when value applied */
1151     tickstart = HAL_GetTick();
1152     while (LL_RCC_IsActiveFlag_PPRE1() == 0U)
1153     {
1154       if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1155       {
1156         return HAL_TIMEOUT;
1157       }
1158     }
1159   }
1160 
1161   /*-------------------------- PCLK2 Configuration ---------------------------*/
1162   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1163   {
1164     assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB2CLKDivider));
1165     LL_RCC_SetAPB2Prescaler((RCC_ClkInitStruct->APB2CLKDivider) << 3U);
1166 
1167     /* APB2 prescaler flag when value applied */
1168     tickstart = HAL_GetTick();
1169     while (LL_RCC_IsActiveFlag_PPRE2() == 0U)
1170     {
1171       if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1172       {
1173         return HAL_TIMEOUT;
1174       }
1175     }
1176   }
1177 
1178   /*------------------------- SYSCLK Configuration ---------------------------*/
1179   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1180   {
1181     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1182 
1183     /* HSE is selected as System Clock Source */
1184     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1185     {
1186       /* Check the HSE ready flag */
1187       if (LL_RCC_HSE_IsReady() == 0U)
1188       {
1189         return HAL_ERROR;
1190       }
1191     }
1192     /* PLL is selected as System Clock Source */
1193     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1194     {
1195       /* Check the PLL ready flag */
1196       if (LL_RCC_PLL_IsReady() == 0U)
1197       {
1198         return HAL_ERROR;
1199       }
1200     }
1201     /* MSI is selected as System Clock Source */
1202     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1203     {
1204       /* Check the MSI ready flag */
1205       if (LL_RCC_MSI_IsReady() == 0U)
1206       {
1207         return HAL_ERROR;
1208       }
1209     }
1210     /* HSI is selected as System Clock Source */
1211     else
1212     {
1213       /* Check the HSI ready flag */
1214       if (LL_RCC_HSI_IsReady() == 0U)
1215       {
1216         return HAL_ERROR;
1217       }
1218 
1219     }
1220 
1221     /* apply system clock switch */
1222     LL_RCC_SetSysClkSource(RCC_ClkInitStruct->SYSCLKSource);
1223 
1224     /* Get Start Tick*/
1225     tickstart = HAL_GetTick();
1226 
1227     /* check system clock source switch status */
1228     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1229     {
1230       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1231       {
1232         return HAL_TIMEOUT;
1233       }
1234     }
1235   }
1236 
1237   /* Decreasing the number of wait states because of lower CPU frequency */
1238   if (FLatency < __HAL_FLASH_GET_LATENCY())
1239   {
1240     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1241     __HAL_FLASH_SET_LATENCY(FLatency);
1242 
1243     /* Get Start Tick*/
1244     tickstart = HAL_GetTick();
1245 
1246     /* Check that the new number of wait states is taken into account to access the Flash
1247     memory by reading the FLASH_ACR register */
1248     while (__HAL_FLASH_GET_LATENCY() != FLatency)
1249     {
1250       if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
1251       {
1252         return HAL_TIMEOUT;
1253       }
1254     }
1255   }
1256 
1257   /*---------------------------------------------------------------------------*/
1258 
1259   /* Update the SystemCoreClock global variable */
1260   SystemCoreClock = HAL_RCC_GetHCLKFreq();
1261 
1262   /* Configure the source of time base considering new system clocks settings*/
1263   return HAL_InitTick(HAL_GetTickPrio());
1264 }
1265 
1266 /**
1267   * @}
1268   */
1269 
1270 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1271   *  @brief   RCC clocks control functions
1272   *
1273 @verbatim
1274  ===============================================================================
1275                       ##### Peripheral Control functions #####
1276  ===============================================================================
1277     [..]
1278     This subsection provides a set of functions allowing to:
1279 
1280     (+) Output clock to MCO pin.
1281     (+) Retrieve current clock frequencies.
1282     (+) Enable the Clock Security System.
1283 
1284 @endverbatim
1285   * @{
1286   */
1287 
1288 /**
1289   * @brief  Select the clock source to output on MCO1 pin(PA8) or MCO2 pin (PB6) or MCO3 pin (PA15).
1290   * @note   PA8, PB6 or PA15 should be configured in alternate function mode.
1291   * @param  RCC_MCOx  specifies the output direction for the clock source.
1292   *            @arg @ref RCC_MCO1_PA8  Clock source to output on MCO1 pin(PA8)
1293   *            @arg @ref RCC_MCO2_PB6  Clock source to output on MCO2 pin(PB6)
1294   *            @arg @ref RCC_MCO3_PA15  Clock source to output on MCO3 pin(PA15)
1295   * @param  RCC_MCOSource  specifies the clock source to output.
1296   *          This parameter can be one of the following values:
1297   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
1298   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system clock selected as MCO source
1299   *            @arg @ref RCC_MCO1SOURCE_MSI    MSI clock selected as MCO source
1300   *            @arg @ref RCC_MCO1SOURCE_HSI    HSI clock selected as MCO source
1301   *            @arg @ref RCC_MCO1SOURCE_HSE    HSE clock selected as MCO source
1302   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
1303   *            @arg @ref RCC_MCO1SOURCE_LSI1   LSI1 clock selected as MCO source
1304   *            @arg @ref RCC_MCO1SOURCE_LSI2   LSI2 clock selected as MCO source
1305   *            @arg @ref RCC_MCO1SOURCE_LSE    LSE clock selected as MCO source
1306   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
1307   *            @arg @ref RCC_MCO1SOURCE_HSE_BEFORE_STAB  HSE clock before stabilization selected as MCO source
1308   * @param  RCC_MCODiv  specifies the MCO prescaler.
1309   *          This parameter can be one of the following values:
1310   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
1311   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
1312   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
1313   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
1314   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
1315   * @retval None
1316   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1317 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1318 {
1319   GPIO_InitTypeDef gpio_initstruct;
1320   uint32_t mcoindex;
1321   uint32_t mco_gpio_index;
1322   GPIO_TypeDef *mco_gpio_port;
1323 
1324   /* Check the parameters */
1325   assert_param(IS_RCC_MCO(RCC_MCOx));
1326 
1327   /* Common GPIO init parameters */
1328   gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
1329   gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
1330   gpio_initstruct.Pull      = GPIO_NOPULL;
1331 
1332   /* Get MCOx selection */
1333   mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
1334 
1335   /* Get MCOx GPIO Port */
1336   mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1337 
1338   /* MCOx Clock Enable */
1339   mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1340   SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index));
1341 
1342   /* Configure the MCOx pin in alternate function mode */
1343   gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1344   gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1345   HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
1346 
1347   if (mcoindex == RCC_MCO1_INDEX)
1348   {
1349     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1350     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1351     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1352     LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
1353   }
1354   else if (mcoindex == RCC_MCO2_INDEX)
1355   {
1356     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1357     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
1358     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1359     LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
1360   }
1361 #if defined(RCC_MCO3_SUPPORT)
1362   else if (mcoindex == RCC_MCO3_INDEX)
1363   {
1364     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1365     assert_param(IS_RCC_MCO3SOURCE(RCC_MCOSource));
1366     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1367     LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
1368   }
1369 #endif /* RCC_MCO3_SUPPORT */
1370   else
1371   {}
1372 }
1373 
1374 /**
1375   * @brief  Return the SYSCLK frequency.
1376   *
1377   * @note   The system computed by this function is not the real
1378   *         frequency in the chip. It is calculated based on the predefined
1379   *         constant and the selected clock source:
1380   * @note     If SYSCLK source is MSI, function returns values based on MSI range
1381   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1382   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1383   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1384   *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1385   * @note     (*) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
1386   *               16 MHz) but the real value may vary depending on the variations
1387   *               in voltage and temperature.
1388   * @note     (**) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
1389   *                32 MHz), user has to ensure that HSE_VALUE is same as the real
1390   *                frequency of the crystal used. Otherwise, this function may
1391   *                have wrong result.
1392   *
1393   * @note   The result of this function could be not correct when using fractional
1394   *         value for HSE crystal.
1395   *
1396   * @note   This function can be used by the user application to compute the
1397   *         baudrate for the communication peripherals or configure other parameters.
1398   *
1399   * @note   Each time SYSCLK changes, this function must be called to update the
1400   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1401   *
1402   *
1403   * @retval SYSCLK frequency
1404   */
HAL_RCC_GetSysClockFreq(void)1405 uint32_t HAL_RCC_GetSysClockFreq(void)
1406 {
1407   uint32_t pllsource;
1408   uint32_t sysclockfreq;
1409   uint32_t pllinputfreq;
1410   const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
1411 
1412   if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI)
1413   {
1414     /* Retrieve MSI frequency range in HZ*/
1415     /* MSI used as system clock source */
1416     sysclockfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
1417   }
1418   else if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI)
1419   {
1420     /* HSI used as system clock source */
1421     sysclockfreq = HSI_VALUE;
1422   }
1423   else if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE)
1424   {
1425     /* HSE used as system clock source */
1426     if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
1427     {
1428       sysclockfreq = HSE_VALUE / 2U;
1429     }
1430     else
1431     {
1432       sysclockfreq = HSE_VALUE;
1433     }
1434   }
1435   else
1436   {
1437     /* PLL used as system clock  source */
1438     pllsource = LL_RCC_PLL_GetMainSource();
1439     switch (pllsource)
1440     {
1441       case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1442         pllinputfreq = HSI_VALUE;
1443         break;
1444       case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1445         if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
1446         {
1447           pllinputfreq = HSE_VALUE / 2U;
1448         }
1449         else
1450         {
1451           pllinputfreq = HSE_VALUE;
1452         }
1453         break;
1454       case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1455       default:
1456         pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
1457         break;
1458     }
1459     sysclockfreq = __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), LL_RCC_PLL_GetN(),
1460                                              LL_RCC_PLL_GetR());
1461   }
1462 
1463   return sysclockfreq;
1464 }
1465 
1466 /**
1467   * @brief  Return the HCLK frequency.
1468   * @retval HCLK frequency in Hz
1469   */
HAL_RCC_GetHCLKFreq(void)1470 uint32_t HAL_RCC_GetHCLKFreq(void)
1471 {
1472   /* Get SysClock and Compute HCLK1 frequency ---------------------------*/
1473   return ((uint32_t)(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler())));
1474 }
1475 
1476 /**
1477   * @brief  Return the HCLK2 frequency.
1478   * @retval HCLK2 frequency in Hz
1479   */
HAL_RCC_GetHCLK2Freq(void)1480 uint32_t HAL_RCC_GetHCLK2Freq(void)
1481 {
1482   /* Get SysClock and Compute HCLK2 frequency ---------------------------*/
1483   return ((uint32_t)(__LL_RCC_CALC_HCLK2_FREQ(HAL_RCC_GetSysClockFreq(), LL_C2_RCC_GetAHBPrescaler())));
1484 }
1485 
1486 /**
1487   * @brief  Return the HCLK4 frequency.
1488   * @retval HCLK4 frequency in Hz
1489   */
HAL_RCC_GetHCLK4Freq(void)1490 uint32_t HAL_RCC_GetHCLK4Freq(void)
1491 {
1492   /* Get SysClock and Compute AHB4 frequency ---------------------------*/
1493   return ((uint32_t)(__LL_RCC_CALC_HCLK4_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHB4Prescaler())));
1494 }
1495 
1496 /**
1497   * @brief  Return the PCLK1 frequency.
1498   * @note   Each time PCLK1 changes, this function must be called to update the
1499   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1500   * @retval PCLK1 frequency in Hz
1501   */
HAL_RCC_GetPCLK1Freq(void)1502 uint32_t HAL_RCC_GetPCLK1Freq(void)
1503 {
1504   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1505   return ((uint32_t)(__LL_RCC_CALC_PCLK1_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB1Prescaler())));
1506 }
1507 
1508 /**
1509   * @brief  Return the PCLK2 frequency.
1510   * @note   Each time PCLK2 changes, this function must be called to update the
1511   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1512   * @retval PCLK2 frequency in Hz
1513   */
HAL_RCC_GetPCLK2Freq(void)1514 uint32_t HAL_RCC_GetPCLK2Freq(void)
1515 {
1516   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1517   return ((uint32_t)(__LL_RCC_CALC_PCLK2_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB2Prescaler())));
1518 }
1519 
1520 /**
1521   * @brief  Configure the RCC_OscInitStruct according to the internal
1522   *         RCC configuration registers.
1523   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1524   *         will be configured.
1525   * @retval None
1526   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1527 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1528 {
1529   uint32_t regvalue;
1530   uint32_t regICSRvalue;
1531   uint32_t regPLLCFGRvalue;
1532 
1533   /* Check the parameters */
1534   assert_param(RCC_OscInitStruct != (void *)NULL);
1535 
1536   /* Set all possible values for the Oscillator type parameter ---------------*/
1537   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1538                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI1 | RCC_OSCILLATORTYPE_LSI2;
1539 
1540 #if defined(RCC_HSI48_SUPPORT)
1541   RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
1542 #endif /* RCC_HSI48_SUPPORT */
1543 
1544   /* Get register values */
1545   regvalue = RCC->CR; /* Control register */
1546   regICSRvalue = RCC->ICSCR; /* Get Internal Clock Sources Calibration register */
1547   regPLLCFGRvalue = RCC->PLLCFGR; /* Get PLL Configuration register */
1548 
1549   /* Get the HSE configuration -----------------------------------------------*/
1550   RCC_OscInitStruct->HSEState = (regvalue & RCC_CR_HSEON);
1551 
1552   /* Get the MSI configuration -----------------------------------------------*/
1553   RCC_OscInitStruct->MSIState            = (regvalue & RCC_CR_MSION);
1554   RCC_OscInitStruct->MSICalibrationValue = (regICSRvalue & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
1555   RCC_OscInitStruct->MSIClockRange       = (regvalue & RCC_CR_MSIRANGE);
1556 
1557   /* Get the HSI configuration -----------------------------------------------*/
1558   RCC_OscInitStruct->HSIState            = (regvalue & RCC_CR_HSION);
1559   RCC_OscInitStruct->HSICalibrationValue = ((regICSRvalue & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
1560 
1561   /* Get the PLL configuration -----------------------------------------------*/
1562   RCC_OscInitStruct->PLL.PLLState  = ((regvalue & RCC_CR_PLLON) >> RCC_CR_PLLON_Pos) + 1U;
1563   RCC_OscInitStruct->PLL.PLLSource = (regPLLCFGRvalue & RCC_PLLCFGR_PLLSRC);
1564   RCC_OscInitStruct->PLL.PLLM      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLM);
1565   RCC_OscInitStruct->PLL.PLLN      = ((regPLLCFGRvalue & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1566   RCC_OscInitStruct->PLL.PLLP      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLP);
1567   RCC_OscInitStruct->PLL.PLLQ      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLQ);
1568   RCC_OscInitStruct->PLL.PLLR      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLR);
1569 
1570   /* Get Backup Domain register */
1571   regvalue = RCC->BDCR;
1572 
1573   /* Get the LSE configuration -----------------------------------------------*/
1574   RCC_OscInitStruct->LSEState = (regvalue & RCC_LSE_BYPASS);
1575 
1576   /* Get Control/Status register */
1577   regvalue = RCC->CSR;
1578 
1579   /* Get the LSI configuration -----------------------------------------------*/
1580   RCC_OscInitStruct->LSIState = ((regvalue & RCC_LSI_ON) > 0U) ? RCC_LSI_ON : 0U;
1581 
1582 #if defined(RCC_HSI48_SUPPORT)
1583   /* Get Control/Status register */
1584   regvalue = RCC->CRRCR;
1585 
1586   /* Get the HSI48 configuration ---------------------------------------------*/
1587   RCC_OscInitStruct->HSI48State = (regvalue & RCC_CRRCR_HSI48ON);
1588 #endif /* RCC_HSI48_SUPPORT */
1589 
1590 }
1591 
1592 /**
1593   * @brief  Configure the RCC_ClkInitStruct according to the internal
1594   *         RCC configuration registers.
1595   * @param  RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
1596   *                           will be configured.
1597   * @param  pFLatency         Pointer on the Flash Latency.
1598   * @retval None
1599   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1600 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1601 {
1602   /* Check the parameters */
1603   assert_param(RCC_ClkInitStruct != (void *)NULL);
1604   assert_param(pFLatency != (void *)NULL);
1605 
1606   /* Set all possible values for the Clock type parameter --------------------*/
1607   RCC_ClkInitStruct->ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 |
1608                                   RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK4);
1609 
1610   /* Get the SYSCLK configuration --------------------------------------------*/
1611   RCC_ClkInitStruct->SYSCLKSource = LL_RCC_GetSysClkSource();
1612 
1613   /* Get the HCLK configuration ----------------------------------------------*/
1614   RCC_ClkInitStruct->AHBCLKDivider = LL_RCC_GetAHBPrescaler();
1615 
1616   /* Get the APB1 configuration ----------------------------------------------*/
1617   RCC_ClkInitStruct->APB1CLKDivider = LL_RCC_GetAPB1Prescaler();
1618 
1619   /* Get the APB2 configuration ----------------------------------------------*/
1620   RCC_ClkInitStruct->APB2CLKDivider = LL_RCC_GetAPB2Prescaler();
1621 
1622   /* Get the AHBCLK2Divider configuration ------------------------------------*/
1623   RCC_ClkInitStruct->AHBCLK2Divider = LL_C2_RCC_GetAHBPrescaler();
1624 
1625   /* Get the AHBCLK4Divider configuration ------------------------------------*/
1626   RCC_ClkInitStruct->AHBCLK4Divider = LL_RCC_GetAHB4Prescaler();
1627 
1628   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1629   *pFLatency = __HAL_FLASH_GET_LATENCY();
1630 }
1631 
1632 /**
1633   * @brief  Enable the Clock Security System.
1634   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1635   *         is automatically disabled and an interrupt is generated to inform the
1636   *         software about the failure (Clock Security System Interrupt, CSSI),
1637   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1638   *         CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector.
1639   * @note   The Clock Security System can only be cleared by reset.
1640   * @retval None
1641   */
HAL_RCC_EnableCSS(void)1642 void HAL_RCC_EnableCSS(void)
1643 {
1644   LL_RCC_HSE_EnableCSS();
1645 }
1646 
1647 /**
1648   * @brief Handle the RCC HSE Clock Security System interrupt request.
1649   * @note  This API should be called under the NMI_Handler().
1650   * @retval None
1651   */
HAL_RCC_NMI_IRQHandler(void)1652 void HAL_RCC_NMI_IRQHandler(void)
1653 {
1654   /* Check RCC CSSF interrupt flag  */
1655   if (__HAL_RCC_GET_IT(RCC_IT_HSECSS))
1656   {
1657     /* RCC Clock Security System interrupt user callback */
1658     HAL_RCC_CSSCallback();
1659 
1660     /* Clear RCC CSS pending bit */
1661     __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS);
1662   }
1663 }
1664 
1665 /**
1666   * @brief Handle the RCC HSE Clock Security System interrupt callback.
1667   * @retval none
1668   */
HAL_RCC_CSSCallback(void)1669 __weak void HAL_RCC_CSSCallback(void)
1670 {
1671   /* NOTE : This function should not be modified, when the callback is needed,
1672             the @ref HAL_RCC_CSSCallback should be implemented in the user file
1673    */
1674 }
1675 
1676 /**
1677   * @brief  Get and clear reset flags
1678   * @param  None
1679   * @note   Once reset flags are retrieved, this API is clearing them in order
1680   *         to isolate next reset reason.
1681   * @retval can be a combination of @ref RCC_Reset_Flag
1682   */
HAL_RCC_GetResetSource(void)1683 uint32_t HAL_RCC_GetResetSource(void)
1684 {
1685   uint32_t reset;
1686 
1687   /* Get all reset flags */
1688   reset = RCC->CSR & RCC_RESET_FLAG_ALL;
1689 
1690   /* Clear Reset flags */
1691   RCC->CSR |= RCC_CSR_RMVF;
1692 
1693   return reset;
1694 }
1695 
1696 /**
1697   * @}
1698   */
1699 
1700 /**
1701   * @}
1702   */
1703 
1704 /* Private function prototypes -----------------------------------------------*/
1705 /** @addtogroup RCC_Private_Functions
1706   * @{
1707   */
1708 
1709 /**
1710   * @brief  Update number of Flash wait states in line with MSI range and current
1711             voltage range.
1712   * @param  MSI_Range  MSI range value from @ref RCC_MSIRANGE_0 to @ref RCC_MSIRANGE_11
1713   * @retval HAL status
1714   */
RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range)1715 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range)
1716 {
1717   uint32_t flash_clksrcfreq;
1718   uint32_t msifreq;
1719 
1720   /* Check the parameters */
1721   assert_param(IS_RCC_MSI_CLOCK_RANGE(MSI_Range));
1722 
1723   /* MSI frequency range in Hz */
1724   if (MSI_Range > RCC_MSIRANGE_11)
1725   {
1726     msifreq = __LL_RCC_CALC_MSI_FREQ(RCC_MSIRANGE_11);
1727   }
1728   else
1729   {
1730     msifreq = __LL_RCC_CALC_MSI_FREQ(MSI_Range);
1731   }
1732 
1733   flash_clksrcfreq = __LL_RCC_CALC_HCLK4_FREQ(msifreq, LL_RCC_GetAHB4Prescaler());
1734 
1735 #if defined(PWR_CR1_VOS)
1736   return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), HAL_PWREx_GetVoltageRange());
1737 #else
1738   return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), PWR_REGULATOR_VOLTAGE_SCALE1);
1739 #endif /* PWR_CR1_VOS */
1740 }
1741 
1742 
1743 /**
1744   * @brief  Update number of Flash wait states.
1745   * @param  Flash_ClkSrcFreq  Flash Clock Source (in MHz)
1746   * @param  VCORE_Voltage     Current Vcore voltage (PWR_REGULATOR_VOLTAGE_SCALE1 or PWR_REGULATOR_VOLTAGE_SCALE2)
1747   * @retval HAL status
1748   */
RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq,uint32_t VCORE_Voltage)1749 static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage)
1750 {
1751   /* Flash Clock source (HCLK4) range in MHz with a VCORE is range1 */
1752   const uint32_t FLASH_CLK_SRC_RANGE_VOS1[] = {18UL, 36UL, 54UL, 64UL};
1753 #if defined(PWR_CR1_VOS)
1754   /* Flash Clock source (HCLK4) range in MHz with a VCORE is range2 */
1755   const uint32_t FLASH_CLK_SRC_RANGE_VOS2[] = {6UL, 12UL, 16UL};
1756 #endif /* PWR_CR1_VOS */
1757   /* Flash Latency range */
1758   const uint32_t FLASH_LATENCY_RANGE[] = {FLASH_LATENCY_0, FLASH_LATENCY_1, FLASH_LATENCY_2, FLASH_LATENCY_3};
1759   uint32_t latency   = FLASH_LATENCY_0;  /* default value 0WS */
1760   uint32_t tickstart;
1761 
1762 #if defined(PWR_CR1_VOS)
1763   if (VCORE_Voltage == PWR_REGULATOR_VOLTAGE_SCALE1)
1764   {
1765     for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++)
1766     {
1767       if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index])
1768       {
1769         latency = FLASH_LATENCY_RANGE[index];
1770         break;
1771       }
1772     }
1773   }
1774   else  /* PWR_REGULATOR_VOLTAGE_SCALE2 */
1775   {
1776     for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS2); index++)
1777     {
1778       if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS2[index])
1779       {
1780         latency = FLASH_LATENCY_RANGE[index];
1781         break;
1782       }
1783     }
1784   }
1785 #else
1786   for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++)
1787   {
1788     if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index])
1789     {
1790       latency = FLASH_LATENCY_RANGE[index];
1791       break;
1792     }
1793   }
1794 #endif /* PWR_CR1_VOS */
1795 
1796   __HAL_FLASH_SET_LATENCY(latency);
1797 
1798   /* Get Start Tick*/
1799   tickstart = HAL_GetTick();
1800 
1801   /* Check that the new number of wait states is taken into account to access the Flash
1802      memory by reading the FLASH_ACR register */
1803   while (__HAL_FLASH_GET_LATENCY() != latency)
1804   {
1805     if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
1806     {
1807       return HAL_TIMEOUT;
1808     }
1809   }
1810   return HAL_OK;
1811 }
1812 
1813 /**
1814   * @}
1815   */
1816 
1817 #endif /* HAL_RCC_MODULE_ENABLED */
1818 /**
1819   * @}
1820   */
1821 
1822 /**
1823   * @}
1824   */
1825