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