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