1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_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) 2019 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file in
18   * the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                       ##### RCC specific features #####
24   ==============================================================================
25     [..]
26       After reset the device is running from Multiple Speed Internal oscillator
27       (4 MHz) with Flash 0 wait state. I-Cache is disabled, and all peripherals
28       are off except internal SRAMs, Flash and JTAG.
29 
30       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) buses:
31           all peripherals mapped on these buses are running at MSI speed.
32       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
33       (+) All GPIOs are in analog mode, except the JTAG pins which
34           are assigned to be used for debug purpose.
35 
36     [..]
37       Once the device is started from reset, the user application has to:
38       (+) Configure the clock source to be used to drive the System clock
39           (if the application needs higher frequency/performance)
40       (+) Configure the System clock frequency and Flash settings
41       (+) Configure the AHB and APB buses prescalers
42       (+) Enable the clock for the peripheral(s) to be used
43       (+) Configure the clock source(s) for peripherals which clocks are not
44           derived from the System clock (SAIx, RTC, ADC, USB FS/SDMMC1/RNG, FDCAN)
45 
46   @endverbatim
47   ******************************************************************************
48   */
49 
50 /* Includes ------------------------------------------------------------------*/
51 #include "stm32l5xx_hal.h"
52 
53 /** @addtogroup STM32L5xx_HAL_Driver
54   * @{
55   */
56 
57 /** @defgroup RCC RCC
58   * @brief RCC HAL module driver
59   * @{
60   */
61 
62 #ifdef HAL_RCC_MODULE_ENABLED
63 
64 /* Private typedef -----------------------------------------------------------*/
65 /* Private define ------------------------------------------------------------*/
66 /** @defgroup RCC_Private_Constants RCC Private Constants
67   * @{
68   */
69 #define LSI_TIMEOUT_VALUE          7UL     /* 7 ms (maximum 6ms + 1) */
70 #define HSI48_TIMEOUT_VALUE        2UL     /* 2 ms (minimum Tick + 1) */
71 #define PLL_TIMEOUT_VALUE          2UL     /* 2 ms (minimum Tick + 1) */
72 #define CLOCKSWITCH_TIMEOUT_VALUE  5000UL  /* 5 s    */
73 /**
74   * @}
75   */
76 
77 /* Private macro -------------------------------------------------------------*/
78 /** @defgroup RCC_Private_Macros RCC Private Macros
79   * @{
80   */
81 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
82 #define MCO1_GPIO_PORT        GPIOA
83 #define MCO1_PIN              GPIO_PIN_8
84 /**
85   * @}
86   */
87 
88 /* Private variables ---------------------------------------------------------*/
89 
90 /* Private function prototypes -----------------------------------------------*/
91 /** @defgroup RCC_Private_Functions RCC Private Functions
92   * @{
93   */
94 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
95 static uint32_t          RCC_GetSysClockFreqFromPLLSource(void);
96 /**
97   * @}
98   */
99 
100 /* Exported functions --------------------------------------------------------*/
101 
102 /** @defgroup RCC_Exported_Functions RCC Exported Functions
103   * @{
104   */
105 
106 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
107   *  @brief    Initialization and Configuration functions
108   *
109   @verbatim
110  ===============================================================================
111            ##### Initialization and de-initialization functions #####
112  ===============================================================================
113     [..]
114       This section provides functions allowing to configure the internal and external oscillators
115       (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
116        and APB2).
117 
118     [..] Internal/external clock and PLL configuration
119          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
120              the PLL as System clock source.
121 
122          (+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHz to 48MHz.
123              It can be used to generate the clock for the USB FS (48 MHz).
124              The number of flash wait states is automatically adjusted when MSI range is updated with
125              HAL_RCC_OscConfig() and the MSI is used as System clock source.
126 
127          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
128              clock source.
129 
130          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
131              through the PLL as System clock source. Can be used also optionally as RTC clock source.
132 
133          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
134 
135          (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
136            (++) The first output is used to generate the high speed system clock (up to 110 MHz).
137            (++) The second output is used to generate the clock for the USB FS (48 MHz),
138                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
139            (++) The third output is used to generate an accurate clock to achieve
140                 high-quality audio performance on SAI interface.
141 
142          (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
143            (++) The first output is used to generate the ADCs clock.
144            (++) The second output is used to generate the clock for the USB FS (48 MHz),
145                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
146            (++) The third output is used to generate an accurate clock to achieve
147                 high-quality audio performance on SAI interface.
148 
149          (+) PLLSAI2 (clocked by HSI, HSE or MSI) providing an independent output clock:
150            (++) The output is used to generate an accurate clock to achieve
151                 high-quality audio performance on SAI interface.
152 
153          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
154             (HSE used directly or through PLL as System clock source), the System clock
155              is automatically switched to HSI and an interrupt is generated.
156              The interrupt is linked to the Cortex-M33 NMI (non-maskable interrupt)
157              exception vector.
158 
159          (+) CSS on LSE (Clock security system on LSE): once enabled for RTC, if a LSE clock
160              failure occurs it is not supplied anymore to the RTC. If the MSI was used in
161              PLL-mode, this mode is disabled. The CSS on LSE failure is detected by a tamper event.
162 
163          (+) MCO (microcontroller clock output): used to output LSI, LSE, System clock, HSI, HSI48,
164              HSE, main PLL clock or MSI (through a configurable prescaler) on PA8 pin.
165 
166     [..] System, AHB and APB buses clocks configuration
167          (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
168              HSE and main PLL.
169              The AHB clock (HCLK) is derived from System clock through configurable
170              prescaler and used to clock the CPU, memory and peripherals mapped
171              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
172              from AHB clock through configurable prescalers and used to clock
173              the peripherals mapped on these buses. You can use
174              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
175 
176          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
177 
178            (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
179                 from an external clock mapped on the SAI_CKIN pin.
180                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
181            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
182                 divided by 2 to 31.
183                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
184                 to configure this clock.
185            (+@) USB FS, SDMMC1 and RNG: USB FS requires a frequency equal to 48 MHz
186                 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
187                 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
188                 through PLLQ divider. You have to enable the peripheral clock and use
189                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
190            (+@) IWDG clock which is always the LSI clock.
191 
192 
193          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 110 MHz.
194              The clock source frequency should be adapted depending on the device voltage range
195              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
196 
197   @endverbatim
198   @internal
199              Depending on the device voltage range, the maximum frequency should be
200              adapted accordingly:
201 
202              (++) Table 1. HCLK clock frequency for STM32L5 devices
203              (++) +---------------------------------------------------------------------------+
204              (++) | Latency         |                 HCLK clock frequency (MHz)              |
205              (++) |                 |---------------------------------------------------------|
206              (++) |                 |  voltage range 0  |  voltage range 1 | voltage range 2  |
207              (++) |-----------------|-------------------|------------------|------------------|
208              (++) |0WS(1 CPU cycles)|   0 < HCLK <= 20  |  0 < HCLK <= 8   |  0 < HCLK <= 8   |
209              (++) |-----------------|-------------------|------------------|------------------|
210              (++) |1WS(2 CPU cycles)|  20 < HCLK <= 40  |  20 < HCLK <= 40 |  8 < HCLK <= 16  |
211              (++) |-----------------|-------------------|------------------|------------------|
212              (++) |2WS(3 CPU cycles)|  40 < HCLK <= 60  |  40 < HCLK <= 60 | 16 < HCLK <= 26  |
213              (++) |-----------------|-------------------|------------------|------------------|
214              (++) |3WS(4 CPU cycles)|  60 < HCLK <= 80  |  60 < HCLK <= 80 |                  |
215              (++) |-----------------|-------------------|------------------|------------------|
216              (++) |4WS(5 CPU cycles)|  80 < HCLK <= 100 |                  |                  |
217              (++) |-----------------|-------------------|------------------|------------------|
218              (++) |5WS(6 CPU cycles)| 100 < HCLK <= 110 |                  |                  |
219              (++) +---------------------------------------------------------------------------+
220 
221   @endinternal
222   * @{
223   */
224 
225 /**
226   * @brief  Reset the RCC clock configuration to the default reset state.
227   * @note   The default reset state of the clock configuration is given below:
228   *            - MSI ON and used as system clock source
229   *            - HSE, HSI, HSI48, LSI, LSE, PLL, PLLSAI1 and PLLISAI2 OFF
230   *            - AHB, APB1 and APB2 prescaler set to 1.
231   *            - CSS, MCO1 OFF
232   *            - All interrupts disabled
233   *            - All interrupt and reset flags cleared
234   * @note   This function doesn't modify the configuration of the
235   *            - Peripheral clocks source selection
236   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
237   *         and is updated by this function
238   * @retval HAL status
239   */
HAL_RCC_DeInit(void)240 HAL_StatusTypeDef HAL_RCC_DeInit(void)
241 {
242   uint32_t   tickstart;
243   FlagStatus pwrclkchanged = RESET;
244 
245   /* Set MSION bit */
246   SET_BIT(RCC->CR, RCC_CR_MSION);
247 
248   /* Insure MSIRDY bit is set before writing default MSIRANGE value */
249   /* Get start tick */
250   tickstart = HAL_GetTick();
251 
252   /* Wait till MSI is ready */
253   while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
254   {
255     if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
256     {
257       /* New check to avoid false timeout detection in case of preemption */
258       if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
259       {
260         return HAL_TIMEOUT;
261       }
262     }
263   }
264 
265   /* Set MSIRANGE default value */
266   MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
267 
268   /* Reset CFGR register (MSI is selected as system clock source) */
269   CLEAR_REG(RCC->CFGR);
270 
271   /* Insure MSI selected as system clock source */
272   /* Get start tick */
273   tickstart = HAL_GetTick();
274 
275   /* Update the SystemCoreClock global variable for MSI as system clock source */
276   SystemCoreClock = MSI_VALUE;
277 
278   /* Configure the source of time base considering new system clock settings  */
279   if (HAL_InitTick(uwTickPrio) != HAL_OK)
280   {
281     return HAL_ERROR;
282   }
283 
284   /* Wait till system clock source is ready */
285   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_SYSCLKSOURCE_STATUS_MSI)
286   {
287     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
288     {
289       /* New check to avoid false timeout detection in case of preemption */
290       if (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_SYSCLKSOURCE_STATUS_MSI)
291       {
292         return HAL_TIMEOUT;
293       }
294     }
295   }
296 
297   /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
298   CLEAR_BIT(RCC->CR, RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_PLLON |
299             RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON);
300 
301   /* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */
302   /* Get start tick */
303   tickstart = HAL_GetTick();
304 
305 #if defined(RCC_PLLSAI2_SUPPORT)
306 
307   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
308   {
309     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
310     {
311       /* New check to avoid false timeout detection in case of preemption */
312       if (READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
313       {
314         return HAL_TIMEOUT;
315       }
316     }
317   }
318 
319 #else
320 
321   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
322   {
323     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
324     {
325       /* New check to avoid false timeout detection in case of preemption */
326       if (READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
327       {
328         return HAL_TIMEOUT;
329       }
330     }
331   }
332 
333 #endif /* RCC_PLLSAI2_SUPPORT */
334 
335   /* Reset PLLCFGR register */
336   CLEAR_REG(RCC->PLLCFGR);
337   SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4);
338 
339   /* Reset PLLSAI1CFGR register */
340   CLEAR_REG(RCC->PLLSAI1CFGR);
341   SET_BIT(RCC->PLLSAI1CFGR,  RCC_PLLSAI1CFGR_PLLSAI1N_4);
342 
343   /* Reset PLLSAI2CFGR register */
344   CLEAR_REG(RCC->PLLSAI2CFGR);
345   SET_BIT(RCC->PLLSAI2CFGR,  RCC_PLLSAI2CFGR_PLLSAI2N_4);
346 
347   /* Reset LSION bit */
348   CLEAR_BIT(RCC->CSR, RCC_CSR_LSION);
349 
350   /* Insure LSIRDY bit is reset before LSIPRE bit reset */
351   /* Get start tick */
352   tickstart = HAL_GetTick();
353 
354   /* Wait till LSI is disabled */
355   while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
356   {
357     if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
358     {
359       /* New check to avoid false timeout detection in case of preemption */
360       if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
361       {
362         return HAL_TIMEOUT;
363       }
364     }
365   }
366 
367   /* Reset LSIPRE bit */
368   CLEAR_BIT(RCC->CSR, RCC_CSR_LSIPRE);
369 
370   /* Reset HSI48ON bit */
371   CLEAR_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON);
372 
373   /* Reset HSEBYP bit */
374   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
375 
376   /* Disable all interrupts */
377   CLEAR_REG(RCC->CIER);
378 
379   /* Clear all interrupt flags */
380   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
381 
382   /* Clear all reset flags */
383   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
384 
385   /* Reset LSEON/LSESYSON/LSEBYP in Backup domain register */
386   /* Requires to enable write access to Backup Domain if necessary */
387   if (HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN))
388   {
389     __HAL_RCC_PWR_CLK_ENABLE();
390     pwrclkchanged = SET;
391   }
392 
393   if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
394   {
395     /* Enable write access to Backup domain */
396     SET_BIT(PWR->CR1, PWR_CR1_DBP);
397   }
398 
399   /* Reset LSEON/LSEBYP/LSESYSEN bit */
400   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
401   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP | RCC_BDCR_LSESYSEN);
402 
403   /* Restore clock configuration if changed */
404   if (pwrclkchanged == SET)
405   {
406     __HAL_RCC_PWR_CLK_DISABLE();
407   }
408 
409   return HAL_OK;
410 }
411 
412 /**
413   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
414   *         RCC_OscInitTypeDef.
415   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
416   *         contains the configuration information for the RCC Oscillators.
417   * @note   The PLL is not disabled when used as system clock.
418   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
419   *         supported by this macro. User should request a transition to LSE Off
420   *         first and then LSE On or LSE Bypass.
421   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
422   *         supported by this macro. User should request a transition to HSE Off
423   *         first and then HSE On or HSE Bypass.
424   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
425   *         and is updated by this function in case of simple MSI range update when MSI
426   *         used as system clock.
427   * @retval HAL status
428   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)429 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
430 {
431   uint32_t tickstart;
432   HAL_StatusTypeDef status;
433   uint32_t sysclk_source, pll_config;
434 
435   /* Check Null pointer */
436   if (RCC_OscInitStruct == NULL)
437   {
438     return HAL_ERROR;
439   }
440 
441   /* Check the parameters */
442   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
443 
444   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
445   pll_config = __HAL_RCC_GET_PLL_OSCSOURCE();
446 
447   /*----------------------------- MSI Configuration --------------------------*/
448   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
449   {
450     /* Check the parameters */
451     assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
452     assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
453     assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
454 
455     /* Check if MSI is used as system clock or as PLL source when PLL is selected as system clock */
456     if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
457         ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_MSI)))
458     {
459       if ((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
460       {
461         return HAL_ERROR;
462       }
463 
464       /* Otherwise, just the calibration and MSI range change are allowed */
465       else
466       {
467         /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
468            must be correctly programmed according to the frequency of the CPU clock
469            (HCLK) and the supply voltage of the device. */
470         if (RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
471         {
472           /* First increase number of wait states update if necessary */
473           if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
474           {
475             return HAL_ERROR;
476           }
477 
478           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
479           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
480           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
481           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
482         }
483         else
484         {
485           /* Else, keep current flash latency while decreasing applies */
486           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
487           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
488           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
489           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
490 
491           /* Decrease number of wait states update if necessary */
492           /* Only possible when MSI is the System clock source  */
493           if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
494           {
495             if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
496             {
497               return HAL_ERROR;
498             }
499           }
500         }
501 
502         /* Update the SystemCoreClock global variable */
503         SystemCoreClock = HAL_RCC_GetHCLKFreq();
504 
505         /* Configure the source of time base considering new system clocks settings*/
506         status = HAL_InitTick(uwTickPrio);
507         if (status != HAL_OK)
508         {
509           return status;
510         }
511       }
512     }
513     else
514     {
515       /* Check the MSI State */
516       if (RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
517       {
518         /* Enable the Internal High Speed oscillator (MSI). */
519         __HAL_RCC_MSI_ENABLE();
520 
521         /* Get timeout */
522         tickstart = HAL_GetTick();
523 
524         /* Wait till MSI is ready */
525         while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
526         {
527           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
528           {
529             /* New check to avoid false timeout detection in case of preemption */
530             if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
531             {
532               return HAL_TIMEOUT;
533             }
534           }
535         }
536         /* Selects the Multiple Speed oscillator (MSI) clock range .*/
537         __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
538         /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
539         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
540 
541       }
542       else
543       {
544         /* Disable the Internal High Speed oscillator (MSI). */
545         __HAL_RCC_MSI_DISABLE();
546 
547         /* Get timeout */
548         tickstart = HAL_GetTick();
549 
550         /* Wait till MSI is ready */
551         while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U)
552         {
553           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
554           {
555             /* New check to avoid false timeout detection in case of preemption */
556             if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U)
557             {
558               return HAL_TIMEOUT;
559             }
560           }
561         }
562       }
563     }
564   }
565   /*------------------------------- HSE Configuration ------------------------*/
566   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
567   {
568     /* Check the parameters */
569     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
570 
571     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
572     if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE) ||
573         ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSE)))
574     {
575       if ((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
576       {
577         return HAL_ERROR;
578       }
579     }
580     else
581     {
582       /* Set the new HSE configuration ---------------------------------------*/
583       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
584 
585       /* Check the HSE State */
586       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
587       {
588         /* Get Start Tick*/
589         tickstart = HAL_GetTick();
590 
591         /* Wait till HSE is ready */
592         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
593         {
594           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
595           {
596             /* New check to avoid false timeout detection in case of preemption */
597             if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
598             {
599               return HAL_TIMEOUT;
600             }
601           }
602         }
603       }
604       else
605       {
606         /* Get Start Tick*/
607         tickstart = HAL_GetTick();
608 
609         /* Wait till HSE is disabled */
610         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
611         {
612           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
613           {
614             /* New check to avoid false timeout detection in case of preemption */
615             if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
616             {
617               return HAL_TIMEOUT;
618             }
619           }
620         }
621       }
622     }
623   }
624   /*----------------------------- HSI Configuration --------------------------*/
625   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
626   {
627     /* Check the parameters */
628     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
629     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
630 
631     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
632     if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI) ||
633         ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSI)))
634     {
635       /* When HSI is used as system clock it will not be disabled */
636       if ((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
637       {
638         return HAL_ERROR;
639       }
640       /* Otherwise, just the calibration is allowed */
641       else
642       {
643         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
644         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
645       }
646     }
647     else
648     {
649       /* Check the HSI State */
650       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
651       {
652         /* Enable the Internal High Speed oscillator (HSI). */
653         __HAL_RCC_HSI_ENABLE();
654 
655         /* Get Start Tick*/
656         tickstart = HAL_GetTick();
657 
658         /* Wait till HSI is ready */
659         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
660         {
661           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
662           {
663             /* New check to avoid false timeout detection in case of preemption */
664             if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
665             {
666               return HAL_TIMEOUT;
667             }
668           }
669         }
670 
671         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
672         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
673       }
674       else
675       {
676         /* Disable the Internal High Speed oscillator (HSI). */
677         __HAL_RCC_HSI_DISABLE();
678 
679         /* Get Start Tick*/
680         tickstart = HAL_GetTick();
681 
682         /* Wait till HSI is disabled */
683         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
684         {
685           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
686           {
687             /* New check to avoid false timeout detection in case of preemption */
688             if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
689             {
690               return HAL_TIMEOUT;
691             }
692           }
693         }
694       }
695     }
696   }
697   /*------------------------------ LSI Configuration -------------------------*/
698   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
699   {
700     /* Check the parameters */
701     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
702 
703     /* Check the LSI State */
704     if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
705     {
706       /* Apply prescaler value */
707       if (RCC_OscInitStruct->LSIDiv == RCC_LSI_DIV1)
708       {
709         CLEAR_BIT(RCC->CSR, RCC_CSR_LSIPRE);
710       }
711       else
712       {
713         SET_BIT(RCC->CSR, RCC_CSR_LSIPRE);
714       }
715 
716       /* Enable the Internal Low Speed oscillator (LSI). */
717       __HAL_RCC_LSI_ENABLE();
718 
719       /* Get Start Tick*/
720       tickstart = HAL_GetTick();
721 
722       /* Wait till LSI is ready */
723       while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
724       {
725         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
726         {
727           /* New check to avoid false timeout detection in case of preemption */
728           if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
729           {
730             return HAL_TIMEOUT;
731           }
732         }
733       }
734     }
735     else
736     {
737       /* Disable the Internal Low Speed oscillator (LSI). */
738       __HAL_RCC_LSI_DISABLE();
739 
740       /* Get Start Tick*/
741       tickstart = HAL_GetTick();
742 
743       /* Wait till LSI is disabled */
744       while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
745       {
746         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
747         {
748           /* New check to avoid false timeout detection in case of preemption */
749           if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
750           {
751             return HAL_TIMEOUT;
752           }
753         }
754       }
755     }
756   }
757   /*------------------------------ LSE Configuration -------------------------*/
758   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
759   {
760     FlagStatus       pwrclkchanged = RESET;
761 
762     /* Check the parameters */
763     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
764 
765     /* Update LSE configuration in Backup Domain control register    */
766     /* Requires to enable write access to Backup Domain of necessary */
767     if (HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN))
768     {
769       __HAL_RCC_PWR_CLK_ENABLE();
770       pwrclkchanged = SET;
771     }
772 
773     if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
774     {
775       /* Enable write access to Backup domain */
776       SET_BIT(PWR->CR1, PWR_CR1_DBP);
777 
778       /* Wait for Backup domain Write protection disable */
779       tickstart = HAL_GetTick();
780 
781       while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
782       {
783         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
784         {
785           /* New check to avoid false timeout detection in case of preemption */
786           if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
787           {
788             return HAL_TIMEOUT;
789           }
790         }
791       }
792     }
793 
794     /* Set the new LSE configuration -----------------------------------------*/
795     if ((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEON) != 0U)
796     {
797       if ((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEBYP) != 0U)
798       {
799         /* LSE oscillator bypass enable */
800         SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
801         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
802       }
803       else
804       {
805         /* LSE oscillator enable */
806         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
807       }
808     }
809     else
810     {
811       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
812       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
813     }
814 
815     /* Check the LSE State */
816     if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
817     {
818       /* Get Start Tick*/
819       tickstart = HAL_GetTick();
820 
821       /* Wait till LSE is ready */
822       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
823       {
824         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
825         {
826           /* New check to avoid false timeout detection in case of preemption */
827           if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
828           {
829             return HAL_TIMEOUT;
830           }
831         }
832       }
833 
834       /* Enable LSESYS additionally if requested */
835       if ((RCC_OscInitStruct->LSEState & RCC_BDCR_LSESYSEN) != 0U)
836       {
837         SET_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
838 
839         /* Wait till LSESYS is ready */
840         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) == 0U)
841         {
842           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
843           {
844             /* New check to avoid false timeout detection in case of preemption */
845             if (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) == 0U)
846             {
847               return HAL_TIMEOUT;
848             }
849           }
850         }
851       }
852       else
853       {
854         /* Make sure LSESYSEN/LSESYSRDY are reset */
855         CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
856 
857         /* Wait till LSESYSRDY is cleared */
858         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
859         {
860           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
861           {
862             /* New check to avoid false timeout detection in case of preemption */
863             if (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
864             {
865               return HAL_TIMEOUT;
866             }
867           }
868         }
869       }
870     }
871     else
872     {
873       /* Get Start Tick*/
874       tickstart = HAL_GetTick();
875 
876       /* Wait till LSE is disabled */
877       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
878       {
879         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
880         {
881           /* New check to avoid false timeout detection in case of preemption */
882           if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
883           {
884             return HAL_TIMEOUT;
885           }
886         }
887       }
888 
889       if (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN) != 0U)
890       {
891         /* Reset LSESYSEN once LSE is disabled */
892         CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
893 
894         /* Wait till LSESYSRDY is cleared */
895         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
896         {
897           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
898           {
899             /* New check to avoid false timeout detection in case of preemption */
900             if (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
901             {
902               return HAL_TIMEOUT;
903             }
904           }
905         }
906       }
907     }
908 
909     /* Restore clock configuration if changed */
910     if (pwrclkchanged == SET)
911     {
912       __HAL_RCC_PWR_CLK_DISABLE();
913     }
914   }
915   /*------------------------------ HSI48 Configuration -----------------------*/
916   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
917   {
918     /* Check the parameters */
919     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
920 
921     /* Check the LSI State */
922     if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
923     {
924       /* Enable the Internal Low Speed oscillator (HSI48). */
925       __HAL_RCC_HSI48_ENABLE();
926 
927       /* Get Start Tick*/
928       tickstart = HAL_GetTick();
929 
930       /* Wait till HSI48 is ready */
931       while (READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
932       {
933         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
934         {
935           /* New check to avoid false timeout detection in case of preemption */
936           if (READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
937           {
938             return HAL_TIMEOUT;
939           }
940         }
941       }
942     }
943     else
944     {
945       /* Disable the Internal Low Speed oscillator (HSI48). */
946       __HAL_RCC_HSI48_DISABLE();
947 
948       /* Get Start Tick*/
949       tickstart = HAL_GetTick();
950 
951       /* Wait till HSI48 is disabled */
952       while (READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
953       {
954         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
955         {
956           /* New check to avoid false timeout detection in case of preemption */
957           if (READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
958           {
959             return HAL_TIMEOUT;
960           }
961         }
962       }
963     }
964   }
965   /*-------------------------------- PLL Configuration -----------------------*/
966   /* Check the parameters */
967   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
968 
969   if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
970   {
971     /* Check if the PLL is used as system clock or not */
972     if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
973     {
974       if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
975       {
976         /* Check the parameters */
977         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
978         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
979         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
980         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
981         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
982         assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
983 
984         /* Disable the main PLL. */
985         __HAL_RCC_PLL_DISABLE();
986 
987         /* Get Start Tick*/
988         tickstart = HAL_GetTick();
989 
990         /* Wait till PLL is ready */
991         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
992         {
993           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
994           {
995             /* New check to avoid false timeout detection in case of preemption */
996             if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
997             {
998               return HAL_TIMEOUT;
999             }
1000           }
1001         }
1002 
1003         /* Configure the main PLL clock source, multiplication and division factors. */
1004         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
1005                              RCC_OscInitStruct->PLL.PLLM,
1006                              RCC_OscInitStruct->PLL.PLLN,
1007                              RCC_OscInitStruct->PLL.PLLP,
1008                              RCC_OscInitStruct->PLL.PLLQ,
1009                              RCC_OscInitStruct->PLL.PLLR);
1010 
1011         /* Enable the main PLL. */
1012         __HAL_RCC_PLL_ENABLE();
1013 
1014         /* Enable PLL System Clock output. */
1015         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
1016 
1017         /* Get Start Tick*/
1018         tickstart = HAL_GetTick();
1019 
1020         /* Wait till PLL is ready */
1021         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1022         {
1023           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1024           {
1025             /* New check to avoid false timeout detection in case of preemption */
1026             if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1027             {
1028               return HAL_TIMEOUT;
1029             }
1030           }
1031         }
1032       }
1033       else
1034       {
1035         /* Disable the main PLL. */
1036         __HAL_RCC_PLL_DISABLE();
1037 
1038         /* Get Start Tick*/
1039         tickstart = HAL_GetTick();
1040 
1041         /* Wait till PLL is disabled */
1042         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1043         {
1044           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1045           {
1046             /* New check to avoid false timeout detection in case of preemption */
1047             if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1048             {
1049               return HAL_TIMEOUT;
1050             }
1051           }
1052         }
1053 
1054         /* Unselect PLL clock source and disable outputs to save power */
1055         RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC | RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
1056       }
1057     }
1058     else
1059     {
1060       /* Check if there is a request to disable the PLL used as System clock source */
1061       if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_OFF)
1062       {
1063         return HAL_ERROR;
1064       }
1065       else
1066       {
1067         pll_config = RCC->PLLCFGR;
1068         /* Do not return HAL_ERROR if request repeats the current configuration */
1069         if ((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC)  != RCC_OscInitStruct->PLL.PLLSource) ||
1070             (READ_BIT(pll_config, RCC_PLLCFGR_PLLM)    != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
1071             (READ_BIT(pll_config, RCC_PLLCFGR_PLLN)    != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) ||
1072             (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) ||
1073             (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ)    != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
1074             (READ_BIT(pll_config, RCC_PLLCFGR_PLLR)    != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
1075         {
1076           return HAL_ERROR;
1077         }
1078       }
1079     }
1080   }
1081 
1082   return HAL_OK;
1083 }
1084 
1085 /**
1086   * @brief  Initialize the CPU, AHB and APB buses clocks according to the specified
1087   *         parameters in the RCC_ClkInitStruct.
1088   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
1089   *         contains the configuration information for the RCC peripheral.
1090   * @param  FLatency  FLASH Latency
1091   *          This parameter can be one of the following values:
1092   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
1093   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
1094   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
1095   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
1096   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
1097   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
1098   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
1099   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
1100   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
1101   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
1102   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
1103   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
1104   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
1105   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
1106   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
1107   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
1108   *
1109   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1110   *         and is updated by this function
1111   *
1112   * @note   The MSI is used by default as system clock source after
1113   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
1114   *         the MSI frequency is set to its default value 4 MHz.
1115   *
1116   * @note   The HSI can be selected as system clock source after
1117   *         from STOP modes or in case of failure of the HSE used directly or indirectly
1118   *         as system clock (if the Clock Security System CSS is enabled).
1119   *
1120   * @note   A switch from one clock source to another occurs only if the target
1121   *         clock source is ready (clock stable after startup delay or PLL locked).
1122   *         If a clock source which is not yet ready is selected, the switch will
1123   *         occur when the clock source is ready.
1124   *
1125   * @note   HAL_RCC_ClockConfig() function takes care of clock switching transition state
1126   *         with AHB prescaler when switching from HSE or HSI or MSI to PLL with AHB
1127   *         frequency (HCLK) higher than 80 MHz and when switching from PLL with HCLK
1128   *         higher than 80 MHz to HSE or HSI or MSI currently used as system clock source.
1129   *
1130   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
1131   *         currently used as system clock source.
1132   *
1133   * @note   Depending on the device voltage range, the software has to set correctly
1134   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
1135   *         (for more details refer to section above "Initialization/de-initialization functions")
1136   * @retval None
1137   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)1138 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
1139 {
1140   uint32_t tickstart;
1141   uint32_t pllfreq;
1142   uint32_t hpre = RCC_SYSCLK_DIV1;
1143 
1144   /* Check Null pointer */
1145   if (RCC_ClkInitStruct == NULL)
1146   {
1147     return HAL_ERROR;
1148   }
1149 
1150   /* Check the parameters */
1151   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
1152   assert_param(IS_FLASH_LATENCY(FLatency));
1153 
1154   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1155     must be correctly programmed according to the frequency of the CPU clock
1156     (HCLK) and the supply voltage of the device. */
1157 
1158   /* Increasing the number of wait states because of higher CPU frequency */
1159   if (FLatency > __HAL_FLASH_GET_LATENCY())
1160   {
1161     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1162     __HAL_FLASH_SET_LATENCY(FLatency);
1163 
1164     /* Check that the new number of wait states is taken into account to access the Flash
1165     memory by reading the FLASH_ACR register */
1166     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1167     {
1168       return HAL_ERROR;
1169     }
1170   }
1171 
1172   /*----------------- HCLK Configuration prior to SYSCLK----------------------*/
1173   /* Apply higher HCLK prescaler request here to ensure CPU clock is not of of spec when SYSCLK is increased */
1174   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1175   {
1176     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1177 
1178     if(RCC_ClkInitStruct->AHBCLKDivider > READ_BIT(RCC->CFGR, RCC_CFGR_HPRE))
1179     {
1180       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
1181     }
1182   }
1183 
1184   /*------------------------- SYSCLK Configuration ---------------------------*/
1185   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1186   {
1187     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1188 
1189     /* PLL is selected as System Clock Source */
1190     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1191     {
1192       /* Check the PLL ready flag */
1193       if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1194       {
1195         return HAL_ERROR;
1196       }
1197 
1198       /* Transition state management when selecting PLL as SYSCLK source and */
1199       /* target frequency above 80Mhz */
1200       /* Compute target PLL output frequency */
1201       pllfreq = RCC_GetSysClockFreqFromPLLSource();
1202 
1203       /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1204       if (pllfreq > 80000000U)
1205       {
1206         /* If lowest HCLK prescaler, apply intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1207         if (READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
1208         {
1209           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1210           hpre = RCC_SYSCLK_DIV2;
1211         }
1212       }
1213     }
1214     else
1215     {
1216       /* HSE is selected as System Clock Source */
1217       if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1218       {
1219         /* Check the HSE ready flag */
1220         if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1221         {
1222           return HAL_ERROR;
1223         }
1224       }
1225       /* MSI is selected as System Clock Source */
1226       else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1227       {
1228         /* Check the MSI ready flag */
1229         if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1230         {
1231           return HAL_ERROR;
1232         }
1233       }
1234       /* HSI is selected as System Clock Source */
1235       else
1236       {
1237         /* Check the HSI ready flag */
1238         if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1239         {
1240           return HAL_ERROR;
1241         }
1242       }
1243 
1244       /* Transition state management when when going down from PLL used as */
1245       /* SYSCLK source and frequency above 80Mhz */
1246       pllfreq = HAL_RCC_GetSysClockFreq();
1247 
1248       /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
1249       if (pllfreq > 80000000U)
1250       {
1251         /* If lowest HCLK prescaler, apply intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
1252         if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
1253         {
1254           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1255           hpre = RCC_SYSCLK_DIV2;
1256         }
1257       }
1258     }
1259 
1260     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
1261 
1262     /* Get Start Tick*/
1263     tickstart = HAL_GetTick();
1264 
1265     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1266     {
1267       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1268       {
1269         /* New check to avoid false timeout detection in case of preemption */
1270         if (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1271         {
1272           return HAL_TIMEOUT;
1273         }
1274       }
1275     }
1276   }
1277 
1278   /* Is intermediate HCLK prescaler 2 applied internally, resume with HCLK prescaler 1 */
1279   if(hpre == RCC_SYSCLK_DIV2)
1280   {
1281     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
1282   }
1283 
1284   /*----------------- HCLK Configuration after SYSCLK-------------------------*/
1285   /* Apply lower HCLK prescaler request here to ensure CPU clock is not of of spec when SYSCLK is set */
1286   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1287   {
1288     if(RCC_ClkInitStruct->AHBCLKDivider < READ_BIT(RCC->CFGR, RCC_CFGR_HPRE))
1289     {
1290       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
1291     }
1292   }
1293 
1294   /* Allow decreasing of the number of wait states (because of lower CPU frequency expected) */
1295   if (FLatency < __HAL_FLASH_GET_LATENCY())
1296   {
1297     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1298     __HAL_FLASH_SET_LATENCY(FLatency);
1299 
1300     /* Check that the new number of wait states is taken into account to access the Flash
1301     memory by reading the FLASH_ACR register */
1302     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1303     {
1304       return HAL_ERROR;
1305     }
1306   }
1307 
1308   /*-------------------------- PCLK1 Configuration ---------------------------*/
1309   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1310   {
1311     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1312     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
1313   }
1314 
1315   /*-------------------------- PCLK2 Configuration ---------------------------*/
1316   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1317   {
1318     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1319     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
1320   }
1321 
1322   /* Update the SystemCoreClock global variable */
1323   SystemCoreClock = HAL_RCC_GetHCLKFreq();
1324 
1325   /* Configure the source of time base considering new system clocks settings*/
1326   return HAL_InitTick(uwTickPrio);
1327 }
1328 
1329 /**
1330   * @}
1331   */
1332 
1333 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1334   *  @brief   RCC clocks control functions
1335   *
1336 @verbatim
1337  ===============================================================================
1338                       ##### Peripheral Control functions #####
1339  ===============================================================================
1340     [..]
1341     This subsection provides a set of functions allowing to:
1342 
1343     (+) Output clock to MCO pin.
1344     (+) Retrieve current clock frequencies.
1345     (+) Enable the Clock Security System.
1346 
1347 @endverbatim
1348   * @{
1349   */
1350 
1351 /**
1352   * @brief  Select the clock source to output on MCO pin(PA8).
1353   * @note   PA8 should be configured in alternate function mode.
1354   * @param  RCC_MCOx  specifies the output direction for the clock source.
1355   *          For STM32L5xx family this parameter can have only one value:
1356   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
1357   * @param  RCC_MCOSource  specifies the clock source to output.
1358   *          This parameter can be one of the following values:
1359   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
1360   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
1361   *            @arg @ref RCC_MCO1SOURCE_MSI  MSI clock selected as MCO source
1362   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
1363   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO sourcee
1364   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
1365   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
1366   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
1367   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source
1368   * @param  RCC_MCODiv  specifies the MCO prescaler.
1369   *          This parameter can be one of the following values:
1370   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
1371   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
1372   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
1373   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
1374   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
1375   * @retval None
1376   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1377 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1378 {
1379   GPIO_InitTypeDef GPIO_InitStruct;
1380   /* Check the parameters */
1381   assert_param(IS_RCC_MCO(RCC_MCOx));
1382   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1383   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1384 
1385   /* MCO Clock Enable */
1386   __MCO1_CLK_ENABLE();
1387 
1388   /* Configure the MCO1 pin in alternate function mode */
1389   GPIO_InitStruct.Pin = MCO1_PIN;
1390   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1391   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1392   GPIO_InitStruct.Pull = GPIO_NOPULL;
1393   GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1394   HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1395 
1396   /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1397   MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1398 }
1399 
1400 /**
1401   * @brief  Return the SYSCLK frequency.
1402   *
1403   * @note   The system frequency computed by this function is not the real
1404   *         frequency in the chip. It is calculated based on the predefined
1405   *         constant and the selected clock source:
1406   * @note     If SYSCLK source is MSI, function returns values based on MSI
1407   *             Value as defined by the MSI range.
1408   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1409   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1410   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1411   *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1412   * @note     (*) HSI_VALUE is a constant defined in stm32l5xx_hal_conf.h file (default value
1413   *               16 MHz) but the real value may vary depending on the variations
1414   *               in voltage and temperature.
1415   * @note     (**) HSE_VALUE is a constant defined in stm32l5xx_hal_conf.h file (default value
1416   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1417   *                frequency of the crystal used. Otherwise, this function may
1418   *                have wrong result.
1419   *
1420   * @note   The result of this function could be not correct when using fractional
1421   *         value for HSE crystal.
1422   *
1423   * @note   This function can be used by the user application to compute the
1424   *         baudrate for the communication peripherals or configure other parameters.
1425   *
1426   * @note   Each time SYSCLK changes, this function must be called to update the
1427   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1428   *
1429   *
1430   * @retval SYSCLK frequency
1431   */
HAL_RCC_GetSysClockFreq(void)1432 uint32_t HAL_RCC_GetSysClockFreq(void)
1433 {
1434   uint32_t msirange = 0U, sysclockfreq = 0U;
1435   uint32_t pllvco, pllsource, pllr, pllm;    /* no init needed */
1436   uint32_t sysclk_source, pll_oscsource;
1437 
1438   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1439   pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1440 
1441   if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
1442       ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
1443   {
1444     /* MSI or PLL with MSI source used as system clock source */
1445 
1446     /* Get SYSCLK source */
1447     if (READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1448     {
1449       /* MSISRANGE from RCC_CSR applies */
1450       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1451     }
1452     else
1453     {
1454       /* MSIRANGE from RCC_CR applies */
1455       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1456     }
1457     /*MSI frequency range in Hz*/
1458     msirange = MSIRangeTable[msirange];
1459 
1460     if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
1461     {
1462       /* MSI used as system clock source */
1463       sysclockfreq = msirange;
1464     }
1465   }
1466   else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI)
1467   {
1468     /* HSI used as system clock source */
1469     sysclockfreq = HSI_VALUE;
1470   }
1471   else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE)
1472   {
1473     /* HSE used as system clock source */
1474     sysclockfreq = HSE_VALUE;
1475   }
1476   else
1477   {
1478     /* unexpected case: sysclockfreq at 0 */
1479   }
1480 
1481   if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1482   {
1483     /* PLL used as system clock  source */
1484 
1485     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1486     SYSCLK = PLL_VCO / PLLR
1487     */
1488     pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1489     pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1490 
1491     switch (pllsource)
1492     {
1493       case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1494         pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1495         break;
1496 
1497       case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1498         pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1499         break;
1500 
1501       case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1502       default:
1503         pllvco = (msirange / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1504         break;
1505     }
1506     pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U;
1507     sysclockfreq = pllvco / pllr;
1508   }
1509 
1510   return sysclockfreq;
1511 }
1512 
1513 /**
1514   * @brief  Return the HCLK frequency.
1515   * @note   Each time HCLK changes, this function must be called to update the
1516   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1517   * @retval HCLK frequency in Hz
1518   */
HAL_RCC_GetHCLKFreq(void)1519 uint32_t HAL_RCC_GetHCLKFreq(void)
1520 {
1521   return (HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]);
1522 }
1523 
1524 /**
1525   * @brief  Return the PCLK1 frequency.
1526   * @note   Each time PCLK1 changes, this function must be called to update the
1527   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1528   * @retval PCLK1 frequency in Hz
1529   */
HAL_RCC_GetPCLK1Freq(void)1530 uint32_t HAL_RCC_GetPCLK1Freq(void)
1531 {
1532   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1533   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
1534 }
1535 
1536 /**
1537   * @brief  Return the PCLK2 frequency.
1538   * @note   Each time PCLK2 changes, this function must be called to update the
1539   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1540   * @retval PCLK2 frequency in Hz
1541   */
HAL_RCC_GetPCLK2Freq(void)1542 uint32_t HAL_RCC_GetPCLK2Freq(void)
1543 {
1544   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1545   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
1546 }
1547 
1548 /**
1549   * @brief  Configure the RCC_OscInitStruct according to the internal
1550   *         RCC configuration registers.
1551   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1552   *         will be configured.
1553   * @retval None
1554   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1555 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1556 {
1557   /* Check the parameters */
1558   assert_param(RCC_OscInitStruct != (void *)NULL);
1559 
1560   /* Set all possible values for the Oscillator type parameter ---------------*/
1561   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1562                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1563 
1564   /* Get the HSE configuration -----------------------------------------------*/
1565   if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1566   {
1567     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1568   }
1569   else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
1570   {
1571     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1572   }
1573   else
1574   {
1575     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1576   }
1577 
1578   /* Get the MSI configuration -----------------------------------------------*/
1579   if ((RCC->CR & RCC_CR_MSION) == RCC_CR_MSION)
1580   {
1581     RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1582   }
1583   else
1584   {
1585     RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1586   }
1587 
1588   RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos);
1589   RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->CR & RCC_CR_MSIRANGE));
1590 
1591   /* Get the HSI configuration -----------------------------------------------*/
1592   if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
1593   {
1594     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1595   }
1596   else
1597   {
1598     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1599   }
1600 
1601   RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
1602 
1603   /* Get the LSE configuration -----------------------------------------------*/
1604   if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1605   {
1606     if ((RCC->BDCR & RCC_BDCR_LSESYSEN) == RCC_BDCR_LSESYSEN)
1607     {
1608       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1609     }
1610     else
1611     {
1612       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
1613     }
1614   }
1615   else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1616   {
1617     if ((RCC->BDCR & RCC_BDCR_LSESYSEN) == RCC_BDCR_LSESYSEN)
1618     {
1619       RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1620     }
1621     else
1622     {
1623       RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
1624     }
1625   }
1626   else
1627   {
1628     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1629   }
1630 
1631   /* Get the LSI configuration -----------------------------------------------*/
1632   if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
1633   {
1634     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1635   }
1636   else
1637   {
1638     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1639   }
1640 
1641   if ((RCC->CSR & RCC_CSR_LSIPRE) == RCC_CSR_LSIPRE)
1642   {
1643     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
1644   }
1645   else
1646   {
1647     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
1648   }
1649 
1650   /* Get the HSI48 configuration ---------------------------------------------*/
1651   if ((RCC->CRRCR & RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1652   {
1653     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1654   }
1655   else
1656   {
1657     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1658   }
1659 
1660   /* Get the PLL configuration -----------------------------------------------*/
1661   if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
1662   {
1663     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1664   }
1665   else
1666   {
1667     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1668   }
1669   RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1670   RCC_OscInitStruct->PLL.PLLM = (uint32_t)(((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U);
1671   RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1672   RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1673   RCC_OscInitStruct->PLL.PLLR = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1674   RCC_OscInitStruct->PLL.PLLP = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos);
1675 }
1676 
1677 /**
1678   * @brief  Configure the RCC_ClkInitStruct according to the internal
1679   *         RCC configuration registers.
1680   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1681   *         will be configured.
1682   * @param  pFLatency  Pointer on the Flash Latency.
1683   * @retval None
1684   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1685 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1686 {
1687   /* Check the parameters */
1688   assert_param(RCC_ClkInitStruct != (void *)NULL);
1689   assert_param(pFLatency != (void *)NULL);
1690 
1691   /* Set all possible values for the Clock type parameter --------------------*/
1692   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1693 
1694   /* Get the SYSCLK configuration --------------------------------------------*/
1695   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1696 
1697   /* Get the HCLK configuration ----------------------------------------------*/
1698   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1699 
1700   /* Get the APB1 configuration ----------------------------------------------*/
1701   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1702 
1703   /* Get the APB2 configuration ----------------------------------------------*/
1704   RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U);
1705 
1706   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1707   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1708 }
1709 
1710 /**
1711   * @brief  Enable the Clock Security System.
1712   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1713   *         is automatically disabled and an interrupt is generated to inform the
1714   *         software about the failure (Clock Security System Interrupt, CSSI),
1715   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1716   *         the Cortex-M33 NMI (Non-Maskable Interrupt) exception vector.
1717   * @note   The Clock Security System can only be cleared by reset.
1718   * @retval None
1719   */
HAL_RCC_EnableCSS(void)1720 void HAL_RCC_EnableCSS(void)
1721 {
1722   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1723 }
1724 
1725 /**
1726   * @brief Handle the RCC Clock Security System interrupt request.
1727   * @note This API should be called under the NMI_Handler().
1728   * @retval None
1729   */
HAL_RCC_NMI_IRQHandler(void)1730 void HAL_RCC_NMI_IRQHandler(void)
1731 {
1732   /* Check RCC CSSF interrupt flag  */
1733   if (__HAL_RCC_GET_IT(RCC_IT_CSS))
1734   {
1735     /* RCC Clock Security System interrupt user callback */
1736     HAL_RCC_CSSCallback();
1737 
1738     /* Clear RCC CSS pending bit */
1739     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1740   }
1741 }
1742 
1743 /**
1744   * @brief  RCC Clock Security System interrupt callback.
1745   * @retval none
1746   */
HAL_RCC_CSSCallback(void)1747 __weak void HAL_RCC_CSSCallback(void)
1748 {
1749   /* NOTE : This function should not be modified, when the callback is needed,
1750             the HAL_RCC_CSSCallback should be implemented in the user file
1751    */
1752 }
1753 
1754 /**
1755   * @brief  Get and clear reset flags
1756   * @note   Once reset flags are retrieved, this API is clearing them in order
1757   *         to isolate next reset reason.
1758   * @retval can be a combination of @ref RCC_Reset_Flag
1759   */
HAL_RCC_GetResetSource(void)1760 uint32_t HAL_RCC_GetResetSource(void)
1761 {
1762   uint32_t reset;
1763 
1764   /* Get all reset flags */
1765   reset = RCC->CSR & RCC_RESET_FLAG_ALL;
1766 
1767   /* Clear Reset flags */
1768   RCC->CSR |= RCC_CSR_RMVF;
1769 
1770   return reset;
1771 }
1772 
1773 /**
1774   * @}
1775   */
1776 
1777 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1778   *  @brief Attributes management functions.
1779   *
1780 @verbatim
1781  ===============================================================================
1782                        ##### RCC attributes functions #####
1783  ===============================================================================
1784 
1785 @endverbatim
1786   * @{
1787   */
1788 
1789 /**
1790   * @brief  Configure the RCC item attribute(s).
1791   * @note   Available attributes are to secure items and set RCC as privileged.
1792   *         Default state is not secure and unprivileged access allowed.
1793   * @note   Secure and non-secure attributes can only be set from the secure
1794   *         state when the system implements the security (TZEN=1).
1795   * @note   Security and privilege attributes can be set independently.
1796   * @param  Item Item(s) to set attributes on.
1797   *         This parameter can be a one or a combination of @ref RCC_items
1798   * @param  Attributes can be one or a combination of the following values:
1799   *            @arg @ref RCC_PRIV         Privileged-only access
1800   *            @arg @ref RCC_NPRIV        Privileged/Non-privileged access
1801   *            @arg @ref RCC_SEC          Secure-only access
1802   *            @arg @ref RCC_NSEC         Secure/Non-secure access
1803   * @retval None
1804   */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1805 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1806 {
1807   /* Check the parameters */
1808   assert_param(IS_RCC_ITEMS_ATTRIBUTES(Item));
1809   assert_param(IS_RCC_ATTRIBUTES(Attributes));
1810 
1811   /* Privilege/non-privilege attribute */
1812   if ((Attributes & RCC_PRIV) == RCC_PRIV)
1813   {
1814     SET_BIT(RCC->CR, RCC_CR_PRIV);
1815   }
1816   else if ((Attributes & RCC_NPRIV) == RCC_NPRIV)
1817   {
1818     CLEAR_BIT(RCC->CR, RCC_CR_PRIV);
1819   }
1820   else
1821   {
1822     /* do nothing */
1823   }
1824 
1825 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1826 
1827   /* Secure/non-secure attribute */
1828   if ((Attributes & RCC_SEC) == RCC_SEC)
1829   {
1830     SET_BIT(RCC_S->SECCFGR, Item);
1831   }
1832   else if ((Attributes & RCC_NSEC) == RCC_NSEC)
1833   {
1834     CLEAR_BIT(RCC_S->SECCFGR, Item);
1835   }
1836   else
1837   {
1838     /* do nothing */
1839   }
1840 
1841 #endif /* __ARM_FEATURE_CMSE */
1842 }
1843 
1844 /**
1845   * @brief  Get the attribute of a RCC item.
1846   * @note   Secure and non-secure attributes are only available from secure state
1847   *         when the system implements the security (TZEN=1)
1848   * @param  Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
1849   * @param  pAttributes pointer to return the attributes value.
1850   * @retval HAL Status.
1851   */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1852 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1853 {
1854   uint32_t attributes;
1855 
1856   /* Check null pointer */
1857   if (pAttributes == NULL)
1858   {
1859     return HAL_ERROR;
1860   }
1861 
1862   /* Check the parameters */
1863   assert_param(IS_RCC_ITEMS_ATTRIBUTES(Item));
1864 
1865   /* Get privilege or non-privilege attribute */
1866   if (READ_BIT(RCC->CR, RCC_CR_PRIV) != 0U)
1867   {
1868     attributes = RCC_PRIV;
1869   }
1870   else
1871   {
1872     attributes = RCC_NPRIV;
1873   }
1874 
1875 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1876 
1877   /* Get the secure or non-secure attribute state */
1878   if ((RCC_S->SECCFGR & Item) == Item)
1879   {
1880     attributes |= RCC_SEC;
1881   }
1882   else
1883   {
1884     attributes |= RCC_NSEC;
1885   }
1886 
1887 #endif /* __ARM_FEATURE_CMSE */
1888 
1889   /* return value */
1890   *pAttributes = attributes;
1891 
1892   return HAL_OK;
1893 }
1894 
1895 
1896 /**
1897   * @}
1898   */
1899 
1900 /**
1901   * @}
1902   */
1903 
1904 /* Private function prototypes -----------------------------------------------*/
1905 /** @addtogroup RCC_Private_Functions
1906   * @{
1907   */
1908 /**
1909   * @brief  Update number of Flash wait states in line with MSI range and current
1910             voltage range.
1911   * @param  msirange  MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
1912   * @retval HAL status
1913   */
RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)1914 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
1915 {
1916   uint32_t latency = FLASH_LATENCY_0;  /* default value 0WS */
1917   uint32_t vos;
1918 
1919   if (__HAL_RCC_PWR_IS_CLK_ENABLED())
1920   {
1921     vos = HAL_PWREx_GetVoltageRange();
1922   }
1923   else
1924   {
1925     __HAL_RCC_PWR_CLK_ENABLE();
1926     vos = HAL_PWREx_GetVoltageRange();
1927     __HAL_RCC_PWR_CLK_DISABLE();
1928   }
1929 
1930   if ((vos == PWR_REGULATOR_VOLTAGE_SCALE0) || (vos == PWR_REGULATOR_VOLTAGE_SCALE1))
1931   {
1932     if (msirange > RCC_MSIRANGE_8)
1933     {
1934       /* MSI > 16Mhz */
1935       if (msirange > RCC_MSIRANGE_10)
1936       {
1937         /* MSI 48Mhz */
1938         latency = FLASH_LATENCY_2; /* 2WS */
1939       }
1940       else
1941       {
1942         /* MSI 24Mhz or 32Mhz */
1943         latency = FLASH_LATENCY_1; /* 1WS */
1944       }
1945     }
1946     /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
1947   }
1948   else
1949   {
1950     if (msirange > RCC_MSIRANGE_8)
1951     {
1952       /* MSI > 16Mhz */
1953       latency = FLASH_LATENCY_3; /* 3WS */
1954     }
1955     else
1956     {
1957       if (msirange == RCC_MSIRANGE_8)
1958       {
1959         /* MSI 16Mhz */
1960         latency = FLASH_LATENCY_2; /* 2WS */
1961       }
1962       else if (msirange == RCC_MSIRANGE_7)
1963       {
1964         /* MSI 8Mhz */
1965         latency = FLASH_LATENCY_1; /* 1WS */
1966       }
1967       else
1968       {
1969         /* MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1970       }
1971     }
1972   }
1973 
1974   __HAL_FLASH_SET_LATENCY(latency);
1975 
1976   /* Check that the new number of wait states is taken into account to access the Flash
1977      memory by reading the FLASH_ACR register */
1978   if ((FLASH->ACR & FLASH_ACR_LATENCY) != latency)
1979   {
1980     return HAL_ERROR;
1981   }
1982 
1983   return HAL_OK;
1984 }
1985 
1986 /**
1987   * @brief  Compute SYSCLK frequency based on PLL SYSCLK source.
1988   * @retval SYSCLK frequency
1989   */
RCC_GetSysClockFreqFromPLLSource(void)1990 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1991 {
1992   uint32_t msirange, pllvco, pllsource, pllr, pllm, sysclockfreq;    /* no init needed */
1993 
1994   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1995      SYSCLK = PLL_VCO / PLLR
1996    */
1997   pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1998   pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1999 
2000   switch (pllsource)
2001   {
2002     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
2003       pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
2004       break;
2005 
2006     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
2007       pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
2008       break;
2009 
2010     case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
2011       /* Get MSI range source */
2012       if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
2013       { /* MSISRANGE from RCC_CSR applies */
2014         msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
2015       }
2016       else
2017       { /* MSIRANGE from RCC_CR applies */
2018         msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
2019       }
2020         /*MSI frequency range in HZ*/
2021         pllvco = MSIRangeTable[msirange];
2022         break;
2023     default:
2024       /* unexpected */
2025       pllvco = 0;
2026       break;
2027   }
2028 
2029   pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U;
2030   sysclockfreq = pllvco / pllr;
2031 
2032   return sysclockfreq;
2033 }
2034 
2035 /**
2036   * @}
2037   */
2038 
2039 #endif /* HAL_RCC_MODULE_ENABLED */
2040 /**
2041   * @}
2042   */
2043 
2044 /**
2045   * @}
2046   */
2047 
2048