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