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