1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                       ##### RCC specific features #####
25   ==============================================================================
26     [..]
27       After reset the device is running from High Speed Internal oscillator
28       (64 MHz) with Flash 3 wait states. Flash prefetch buffer, D-Cache
29       and I-Cache are disabled, and all peripherals are off except internal
30       SRAM, Flash and JTAG.
31 
32       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
33           all peripherals mapped on these busses are running at HSI speed.
34       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
35       (+) All GPIOs are in analog mode, except the JTAG pins which
36           are assigned to be used for debug purpose.
37 
38     [..]
39       Once the device started from reset, the user application has to:
40       (+) Configure the clock source to be used to drive the System clock
41           (if the application needs higher frequency/performance)
42       (+) Configure the System clock frequency and Flash settings
43       (+) Configure the AHB and APB busses prescalers
44       (+) Enable the clock for the peripheral(s) to be used
45       (+) Configure the clock source(s) for peripherals which clocks are not
46           derived from the System clock (SAIx, RTC, ADC, USB, SDMMC, etc.)
47 
48   @endverbatim
49   */
50 
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32h5xx_hal.h"
53 
54 /** @addtogroup STM32H5xx_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 /* Private macro -------------------------------------------------------------*/
68 /** @defgroup RCC_Private_Macros RCC Private Macros
69   * @{
70   */
71 
72 #define MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
73 #define MCO1_GPIO_PORT        GPIOA
74 #define MCO1_PIN              GPIO_PIN_8
75 
76 #define MCO2_CLK_ENABLE()      __HAL_RCC_GPIOC_CLK_ENABLE()
77 #define MCO2_GPIO_PORT         GPIOC
78 #define MCO2_PIN               GPIO_PIN_9
79 
80 /**
81   * @}
82   */
83 
84 /* Private variables ---------------------------------------------------------*/
85 
86 /* Private function prototypes -----------------------------------------------*/
87 /* Exported functions --------------------------------------------------------*/
88 
89 /** @defgroup RCC_Exported_Functions RCC Exported Functions
90   * @{
91   */
92 
93 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
94   *  @brief    Initialization and Configuration functions
95   *
96   @verbatim
97  ===============================================================================
98            ##### Initialization and de-initialization functions #####
99  ===============================================================================
100     [..]
101       This section provides functions allowing to configure the internal and external oscillators
102       (HSE, HSI, LSE, CSI, LSI, PLL1, HSE CSS and MCOs) and the System busses clocks (SYSCLK, AHB, APB1, APB2
103        and APB3).
104 
105     [..] Internal/external clock and PLL configuration
106          (+) HSI (high-speed internal): 64 MHz factory-trimmed RC used directly or through
107              the PLL as System clock source.
108 
109          (#) CSI is a low-power RC oscillator which can be used directly as system clock, peripheral
110              clock, or PLL input. But even with frequency calibration, is less accurate than an
111              external crystal oscillator or ceramic resonator.
112 
113          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
114              clock source.
115 
116          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
117              through the PLL as System clock source. Can be used also optionally as RTC clock source.
118 
119          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
120 
121          (+) PLL1 (clocked by HSI, HSE or CSI) providing up to three independent output clocks:
122            (++) The first output is used to generate the high speed system clock (up to 240MHz).
123            (++) The second output is used to generate the clock for the USB (48 MHz), the FDCAN1/2,
124                 the SPI1/2/3, the OCTOSPI, the RNG (<=48 MHz), the SDMMC1/2 and to generate an accurate
125                 clock to achieve high-quality audio performance on SAI1/2 interface.
126 
127          (+) PLL2 (clocked by HSI, HSE or CSI) providing up to three independent output clocks:
128            (++) The first output is used to generate the clock for the LPTIMs, the SPI1/2/3 and to generate
129                 an accurate clock to achieve high-quality audio performance on SAI1/2 interface.
130            (++) The second output is used to generate the clock for USARTs, the UARTs, the LPUART1,
131                 the FDCAN1/2, the SPI4/5/6 and the USB.
132            (++) The third output is used to generate the clock the SDMMC1/2, the ADC/DAC, the I2C1/2,
133                 the I3C1/2 and the OCTOSPI.
134 
135          (+) PLL3 (clocked by HSI , HSE or CSI) providing up to three independent output clocks:
136            (++) The first output is used to generate the clock for SPI1/2/3 and to generate an accurate
137                 clock to achieve high-quality audio performance on SAI1/2 interface.
138            (++) The second  output is used to generate the clock for USARTs, the UARTs, the LPUART1,
139                 the SPI4/5/6 and the USB.
140            (++) The third output is used to generate the clock for the I2Cs, the I3Cs and the LPTIMs.
141 
142          (+) HSE CSS (HSE Clock Security System): once enabled, if a HSE clock failure occurs
143             (HSE used directly or through PLL1 as System clock source), the System clock
144              is automatically switched to HSI and an interrupt is generated if enabled.
145              The interrupt is linked to the Cortex-M33 NMI (Non-Maskable Interrupt)
146              exception vector.
147 
148          (#) MCO1 (micro controller clock output1), used to output HSI, LSE, HSE, PLL1(PLL1_Q)
149              or HSI48 clock (through a configurable pre-scaler) on PA8 pin.
150 
151          (#) MCO2 (micro controller clock output2), used to output HSE, PLL2(PLL2_P), SYSCLK,
152              LSI, CSI, or PLL1(PLL1_P) clock (through a configurable pre-scaler) on PC9 pin.
153 
154     [..] System, AHB and APB busses clocks configuration
155          (+) Several clock sources can be used to drive the System clock (SYSCLK): CSI, HSI, HSE and the main PLL.
156              The AHB clock (HCLK) is derived from System clock through configurable
157              prescaler and used to clock the CPU, memory and peripherals mapped
158              on AHB bus (DMA, GPIO...). APB1 (PCLK1), APB2 (PCLK2) and APB3 (PCLK3) clocks are derived
159              from AHB clock through configurable prescalers and used to clock
160              the peripherals mapped on these busses. You can use
161              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
162 
163          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
164 
165            (+@) SAI: the SAI clock can be derived either from specific PLL (PLL1, PLL2 or PLL3),
166                 the per_ck clock (HSE, HSI or CSI) or from an external clock mapped on the SAI_CKIN pin.
167                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
168            (+@) SPI/I2S: the SPI1/2/3 clock can be derived either from specific PLL (PLL1, PLL2 or PLL3),
169                 the per_ck clock (HSE, HSI or CSI) or from an external clock mapped on the SPI_CKIN pin.
170                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
171            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
172                 divided by 2 to 31.
173                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
174                 to configure this clock.
175            (+@) USB: USB requires a frequency equal to 48 MHz to work correctly. This clock is derived
176                 of the main PLL or PLL2 through PLLQ divider. You have to use HAL_RCCEx_PeriphCLKConfig()
177                 function to configure this clock.
178            (+@) UCPD: the UCPD clock is derived from HSI (divided by 4) clock.
179            (+@) SDMMC: SDMMC1/2 peripherals require a frequency equal or lower than 48 MHz.
180                 This clock is derived from the PLL1 or PLL2 through PLL1Q or PLL2R divider. You have
181                 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
182            (+@) IWDG clock which is always the LSI clock. You have to use HAL_RCCEx_PeriphCLKConfig()
183                 function to configure this clock.
184            (+@) RNG: the RNG clock can be derived either from PLL1Q, HSI48, LSE or LSI clock. You have
185                 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
186            (+@) DAC: the DAC clock can be derived either from LSE or LSI clock. You have
187                 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
188            (+@) FDCAN: the FDCAN1/2 clock can be derived either from HSE, PLL1Q or PLL2Q clock. You have
189                 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
190            (+@) CEC: the CEC clock can be derived either from LSE, LSI or CSI (divided by 122) clock.You have
191                 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
192            (+@) ETH: the Ethernet clock is derived from PLL1Q clock.
193 
194 
195 
196          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1, PCLK2 and PCLK3 is 240 MHz.
197              The clock source frequency should be adapted depending on the device voltage range
198              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
199 
200   @endverbatim
201 
202 
203            Table 1. HCLK clock frequency for STM32H5xx devices
204            +-----------------------------------------------------------------------------------------------+
205            | Latency         |                          HCLK clock frequency (MHz)                         |
206            |                 |-----------------------------------------------------------------------------|
207            |                 |  voltage range 0  |  voltage range 1 | voltage range 2  | voltage range 3   |
208            |                 |    1.26 - 1.35V   |   1.15 - 1.26V   |   1.05 - 1.15V   |   0,95 - 1,05V    |
209            |-----------------|-------------------|------------------|------------------|-------------------|
210            |0WS(1 CPU cycles)|   0 < HCLK <= 38  |  0 < HCLK <= 32  |  0 < HCLK <= 26  | 0 < HCLK <= 16    |
211            |-----------------|-------------------|------------------|------------------|-------------------|
212            |1WS(2 CPU cycles)|  38 < HCLK <= 76  | 32 < HCLK <= 64  | 26 < HCLK <= 50  | 16 < HCLK <= 32   |
213            |-----------------|-------------------|------------------|------------------|-------------------|
214            |2WS(3 CPU cycles)|  76 < HCLK <= 114 | 64 < HCLK <= 96  | 50 < HCLK <= 80  | 32 < HCLK <= 50   |
215            |-----------------|-------------------|------------------|------------------|-------------------|
216            |3WS(4 CPU cycles)| 114 < HCLK <= 152 | 96 < HCLK <= 128 | 80 < HCLK <= 106 | 50 < HCLK <= 65   |
217            |-----------------|-------------------|------------------|------------------|-------------------|
218            |4WS(5 CPU cycles)|  152 < HCLK <= 190| 128 < HCLK <= 160| 106 < HCLK <= 130| 65 < HCLK <= 80   |
219            |-----------------|-------------------|------------------|------------------|-------------------|
220            |5WS(6 CPU cycles)|  190 < HCLK <= 240| 160 < HCLK <= 180|        NA        |         NA        |
221            +-----------------+-------------------+------------------+------------------+-------------------+
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   *            - HSI ON and used as system clock source
229   *            - HSE, CSI, PLL, PLL2 and PLL3 OFF
230   *            - AHB, APB1 and APB2 prescaler set to 1.
231   *            - HSECSS, MCO1 and MCO2 OFF
232   *            - All interrupts disabled
233   * @note   This function doesn't modify the configuration of the
234   *            - Peripheral clocks
235   *            - LSI, LSE and RTC clocks
236   * @retval HAL Status.
237   */
238 
HAL_RCC_DeInit(void)239 HAL_StatusTypeDef HAL_RCC_DeInit(void)
240 {
241   uint32_t tickstart;
242 
243   /* Increasing the CPU frequency */
244   if (FLASH_LATENCY_DEFAULT  > __HAL_FLASH_GET_LATENCY())
245   {
246     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
247     __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT);
248 
249     /* Check that the new number of wait states is taken into account to access the Flash
250     memory by reading the FLASH_ACR register */
251     if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT)
252     {
253       return HAL_ERROR;
254     }
255 
256   }
257 
258   /* Get start tick*/
259   tickstart = HAL_GetTick();
260 
261   /* Set HSION bit */
262   SET_BIT(RCC->CR, RCC_CR_HSION);
263 
264   /* Wait till HSI is ready */
265   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
266   {
267     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
268     {
269       return HAL_TIMEOUT;
270     }
271   }
272 
273   /* Set HSIDIV Default value */
274   CLEAR_BIT(RCC->CR, RCC_CR_HSIDIV);
275 
276   /* Set HSITRIM default value */
277   WRITE_REG(RCC->HSICFGR, RCC_HSICFGR_HSITRIM_6);
278 
279 
280   /* Adapt Systick interrupt period */
281   if (HAL_InitTick(uwTickPrio) != HAL_OK)
282   {
283     return HAL_ERROR;
284   }
285 
286   /* Get start tick*/
287   tickstart = HAL_GetTick();
288 
289   /* Reset CFGR register (HSI is selected as system clock source) */
290   CLEAR_REG(RCC->CFGR1);
291   CLEAR_REG(RCC->CFGR2);
292 
293   /* Wait till clock switch is ready */
294   while (READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS) != 0U)
295   {
296     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
297     {
298       return HAL_TIMEOUT;
299     }
300   }
301 
302   /* Reset HSECSSON, HSEON, HSIKERON, CSION, CSIKERON and HSI48ON bits */
303   CLEAR_BIT(RCC->CR, RCC_CR_CSION | RCC_CR_CSIKERON | RCC_CR_HSECSSON | RCC_CR_HSIKERON | RCC_CR_HSI48ON | \
304             RCC_CR_HSEON);
305 
306   /* Reset HSEEXT bit*/
307   CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT);
308 
309   /* Get Start Tick */
310   tickstart = HAL_GetTick();
311 
312   /* Clear PLL1ON bit */
313   CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON);
314 
315   /* Wait till PLL1 is disabled */
316   while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
317   {
318     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
319     {
320       return HAL_TIMEOUT;
321     }
322   }
323 
324   /* Get Start Tick */
325   tickstart = HAL_GetTick();
326 
327   /* Reset PLL2N bit */
328   CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
329 
330   /* Wait till PLL2 is disabled */
331   while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U)
332   {
333     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
334     {
335       return HAL_TIMEOUT;
336     }
337   }
338 
339 #if defined(RCC_CR_PLL3ON)
340 
341   /* Get Start Tick */
342   tickstart = HAL_GetTick();
343 
344   /* Reset PLL3 bit */
345   CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
346 
347   /* Wait till PLL3 is disabled */
348   while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U)
349   {
350     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
351     {
352       return HAL_TIMEOUT;
353     }
354   }
355 #endif /* RCC_CR_PLL3ON */
356 
357   /* Reset PLL1CFGR register */
358   CLEAR_REG(RCC->PLL1CFGR);
359 
360   /* Reset PLL1DIVR register */
361   WRITE_REG(RCC->PLL1DIVR, 0x01010280U);
362 
363   /* Reset PLL1FRACR register */
364   CLEAR_REG(RCC->PLL1FRACR);
365 
366   /* Reset PLL2CFGR register */
367   CLEAR_REG(RCC->PLL2CFGR);
368 
369   /* Reset PLL2DIVR register */
370   WRITE_REG(RCC->PLL2DIVR, 0x01010280U);
371 
372   /* Reset PLL2FRACR register */
373   CLEAR_REG(RCC->PLL2FRACR);
374 
375 #if defined(RCC_CR_PLL3ON)
376   /* Reset PLL3CFGR register */
377   CLEAR_REG(RCC->PLL3CFGR);
378 
379   /* Reset PLL3DIVR register */
380   WRITE_REG(RCC->PLL3DIVR, 0x01010280U);
381 
382   /* Reset PLL3FRACR register */
383   CLEAR_REG(RCC->PLL3FRACR);
384 #endif /* RCC_CR_PLL3ON */
385 
386   /* Reset HSEBYP bit */
387   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
388 
389   /* Disable all interrupts */
390   CLEAR_REG(RCC->CIER);
391 
392   /* Clear all interrupts flags */
393   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
394 
395   /* Reset all RSR flags */
396   SET_BIT(RCC->RSR, RCC_RSR_RMVF);
397 
398   /* Update the SystemCoreClock global variable */
399   SystemCoreClock = HSI_VALUE;
400 
401   /* Decreasing the number of wait states because of lower CPU frequency */
402   if (FLASH_LATENCY_DEFAULT  < __HAL_FLASH_GET_LATENCY())
403   {
404     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
405     __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT);
406 
407     /* Check that the new number of wait states is taken into account to access the Flash
408     memory by reading the FLASH_ACR register */
409     if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT)
410     {
411       return HAL_ERROR;
412     }
413   }
414 
415   /* Adapt Systick interrupt period */
416   if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
417   {
418     return HAL_ERROR;
419   }
420   else
421   {
422     return HAL_OK;
423   }
424 }
425 
426 /**
427   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
428   *         RCC_OscInitTypeDef.
429   * @param  pOscInitStruct pointer to an RCC_OscInitTypeDef structure that
430   *         contains the configuration information for the RCC Oscillators.
431   * @note   The PLL is not disabled when used as system clock.
432   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
433   *         supported by this macro. User should request a transition to LSE Off
434   *         first and then LSE On or LSE Bypass.
435   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
436   *         supported by this macro. User should request a transition to HSE Off
437   *         first and then HSE On or HSE Bypass.
438   * @retval HAL status
439   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * pOscInitStruct)440 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *pOscInitStruct)
441 {
442   uint32_t tickstart;
443   uint32_t temp_sysclksrc;
444   uint32_t temp_pllckselr;
445   uint32_t temp1_pllckcfg;
446   uint32_t temp2_pllckcfg;
447 
448   /* Check Null pointer */
449   if (pOscInitStruct == NULL)
450   {
451     return HAL_ERROR;
452   }
453 
454   /* Check the parameters */
455   assert_param(IS_RCC_OSCILLATORTYPE(pOscInitStruct->OscillatorType));
456   temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
457   temp_pllckselr = __HAL_RCC_GET_PLL_OSCSOURCE();
458 
459   /*----------------------------- CSI Configuration --------------------------*/
460   if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_CSI) == RCC_OSCILLATORTYPE_CSI)
461   {
462     /* Check the parameters */
463     assert_param(IS_RCC_CSI(pOscInitStruct->CSIState));
464     assert_param(IS_RCC_CSICALIBRATION_VALUE(pOscInitStruct->CSICalibrationValue));
465 
466     /* When the CSI is used as system clock it will not be disabled */
467     if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_CSI) ||
468         ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_CSI)))
469     {
470       if (pOscInitStruct->CSIState == RCC_CSI_OFF)
471       {
472         return HAL_ERROR;
473       }
474 
475       /* Otherwise, just the calibration and CSI is allowed */
476       else
477       {
478         /* Adjusts the Internal Low-power oscillator (CSI) calibration value.*/
479         __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->CSICalibrationValue);
480       }
481     }
482     else
483     {
484       /* Check the CSI State */
485       if ((pOscInitStruct->CSIState) != RCC_CSI_OFF)
486       {
487         /* Enable the Internal High Speed oscillator (CSI). */
488         __HAL_RCC_CSI_ENABLE();
489 
490         /* Get Start Tick*/
491         tickstart = HAL_GetTick();
492 
493         /* Wait till CSI is ready */
494         while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U)
495         {
496           if ((HAL_GetTick() - tickstart) > CSI_TIMEOUT_VALUE)
497           {
498             return HAL_TIMEOUT;
499           }
500         }
501 
502         /* Adjusts the Internal High Speed oscillator (CSI) calibration value.*/
503         __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->CSICalibrationValue);
504       }
505       else
506       {
507         /* Disable the Internal High Speed oscillator (CSI). */
508         __HAL_RCC_CSI_DISABLE();
509 
510         /* Get Start Tick*/
511         tickstart = HAL_GetTick();
512 
513         /* Wait till CSI is disabled */
514         while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U)
515         {
516           if ((HAL_GetTick() - tickstart) > CSI_TIMEOUT_VALUE)
517           {
518             return HAL_TIMEOUT;
519           }
520         }
521       }
522     }
523   }
524   /*------------------------------- HSE Configuration ------------------------*/
525   if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
526   {
527     /* Check the parameters */
528     assert_param(IS_RCC_HSE(pOscInitStruct->HSEState));
529 
530     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
531     if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
532         ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_HSE)))
533     {
534       if (pOscInitStruct->HSEState == RCC_HSE_OFF)
535       {
536         return HAL_ERROR;
537       }
538     }
539     else
540     {
541       /* Set the new HSE configuration ---------------------------------------*/
542       __HAL_RCC_HSE_CONFIG(pOscInitStruct->HSEState);
543 
544       /* Check the HSE State */
545       if (pOscInitStruct->HSEState != RCC_HSE_OFF)
546       {
547         /* Get Start Tick*/
548         tickstart = HAL_GetTick();
549 
550         /* Wait till HSE is ready */
551         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
552         {
553           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
554           {
555             return HAL_TIMEOUT;
556           }
557         }
558       }
559       else
560       {
561         /* Get Start Tick*/
562         tickstart = HAL_GetTick();
563 
564         /* Wait till HSE is disabled */
565         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
566         {
567           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
568           {
569             return HAL_TIMEOUT;
570           }
571         }
572       }
573     }
574   }
575   /*----------------------------- HSI Configuration --------------------------*/
576   if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
577   {
578     /* Check the parameters */
579     assert_param(IS_RCC_HSI(pOscInitStruct->HSIState));
580     assert_param(IS_RCC_HSIDIV(pOscInitStruct->HSIDiv));
581     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(pOscInitStruct->HSICalibrationValue));
582 
583     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
584     if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
585         ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_HSI)))
586     {
587       /* When HSI is used as system clock it will not be disabled */
588       if (pOscInitStruct->HSIState == RCC_HSI_OFF)
589       {
590         return HAL_ERROR;
591       }
592       /* Otherwise, HSI calibration and division may be allowed */
593       else
594       {
595 
596         /* HSI division is allowed if HSI is used as system clock */
597         if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI)
598         {
599           if (__HAL_RCC_GET_HSI_DIVIDER() != (pOscInitStruct->HSIDiv))
600           {
601             /* Adjust the HSI division factor */
602             __HAL_RCC_HSI_DIVIDER_CONFIG(pOscInitStruct->HSIDiv);
603 
604             /* Update the SystemCoreClock global variable with new HSI value  */
605             (void) HAL_RCC_GetHCLKFreq();
606 
607             /* Configure the source of time base considering new system clocks settings*/
608             if (HAL_InitTick(uwTickPrio) != HAL_OK)
609             {
610               return HAL_ERROR;
611             }
612           }
613         }
614 
615         /* Get Start Tick*/
616         tickstart = HAL_GetTick();
617 
618         /* Wait till HSI is ready */
619         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
620         {
621           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
622           {
623             return HAL_TIMEOUT;
624           }
625         }
626         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
627         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->HSICalibrationValue);
628       }
629     }
630     else
631     {
632       /* Check the HSI State */
633       if (pOscInitStruct->HSIState != RCC_HSI_OFF)
634       {
635         /* Adjust the HSI division factor */
636         __HAL_RCC_HSI_DIVIDER_CONFIG(pOscInitStruct->HSIDiv);
637 
638         /* Enable the HSI oscillator */
639         __HAL_RCC_HSI_ENABLE();
640 
641         /* Get Start Tick*/
642         tickstart = HAL_GetTick();
643 
644         /* Wait till HSI is ready */
645         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
646         {
647           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
648           {
649             return HAL_TIMEOUT;
650           }
651         }
652 
653         /* Adjust the Internal High Speed oscillator (HSI) calibration value.*/
654         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->HSICalibrationValue);
655       }
656       else
657       {
658         /* Disable the Internal High Speed oscillator (HSI). */
659         __HAL_RCC_HSI_DISABLE();
660 
661         /* Get Start Tick*/
662         tickstart = HAL_GetTick();
663 
664         /* Wait till HSI is disabled */
665         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
666         {
667           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
668           {
669             return HAL_TIMEOUT;
670           }
671         }
672       }
673     }
674   }
675   /*------------------------------ LSI Configuration -------------------------*/
676   if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
677   {
678 
679     /* Check the parameters */
680     assert_param(IS_RCC_LSI(pOscInitStruct->LSIState));
681 
682     /* Update LSI configuration in Backup Domain control register    */
683 
684     /* Check the LSI State */
685     if (pOscInitStruct->LSIState != RCC_LSI_OFF)
686     {
687       /* Enable the Internal Low Speed oscillator (LSI). */
688       __HAL_RCC_LSI_ENABLE();
689 
690       /* Get Start Tick*/
691       tickstart = HAL_GetTick();
692 
693       /* Wait till LSI is ready */
694       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) == 0U)
695       {
696         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
697         {
698           return HAL_TIMEOUT;
699         }
700       }
701     }
702     else
703     {
704       /* Disable the Internal Low Speed oscillator (LSI). */
705       __HAL_RCC_LSI_DISABLE();
706 
707       /* Get Start Tick*/
708       tickstart = HAL_GetTick();
709 
710       /* Wait till LSI is disabled */
711       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) != 0U)
712       {
713         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
714         {
715           return HAL_TIMEOUT;
716         }
717       }
718     }
719 
720   }
721   /*------------------------------ LSE Configuration -------------------------*/
722   if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
723   {
724 
725     /* Check the parameters */
726     assert_param(IS_RCC_LSE(pOscInitStruct->LSEState));
727 
728     /* Update LSE configuration in Backup Domain control register    */
729     /* Requires to enable write access to Backup Domain */
730     if (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP))
731     {
732       /* Enable write access to Backup domain */
733       SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP);
734 
735       /* Wait for Backup domain Write protection disable */
736       tickstart = HAL_GetTick();
737 
738       while (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP))
739       {
740         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
741         {
742           return HAL_TIMEOUT;
743         }
744       }
745     }
746 
747     /* Set the new LSE configuration -----------------------------------------*/
748     __HAL_RCC_LSE_CONFIG(pOscInitStruct->LSEState);
749 
750     /* Check the LSE State */
751     if (pOscInitStruct->LSEState != RCC_LSE_OFF)
752     {
753       /* Get Start Tick*/
754       tickstart = HAL_GetTick();
755 
756       /* Wait till LSE is ready */
757       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
758       {
759         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
760         {
761           return HAL_TIMEOUT;
762         }
763       }
764     }
765     else
766     {
767       /* Get Start Tick*/
768       tickstart = HAL_GetTick();
769 
770       /* Wait till LSE is disabled */
771       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
772       {
773         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
774         {
775           return HAL_TIMEOUT;
776         }
777       }
778     }
779 
780   }
781   /*------------------------------ HSI48 Configuration -----------------------*/
782   if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
783   {
784     /* Check the parameters */
785     assert_param(IS_RCC_HSI48(pOscInitStruct->HSI48State));
786 
787     /* Check the HSI48 State */
788     if (pOscInitStruct->HSI48State != RCC_HSI48_OFF)
789     {
790       /* Enable the Internal High Speed oscillator (HSI48). */
791       __HAL_RCC_HSI48_ENABLE();
792 
793       /* Get Start Tick*/
794       tickstart = HAL_GetTick();
795 
796       /* Wait till HSI48 is ready */
797       while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
798       {
799         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
800         {
801           return HAL_TIMEOUT;
802         }
803       }
804     }
805     else
806     {
807       /* Disable the Internal High Speed oscillator (HSI48). */
808       __HAL_RCC_HSI48_DISABLE();
809 
810       /* Get Start Tick*/
811       tickstart = HAL_GetTick();
812 
813       /* Wait till HSI48 is disabled */
814       while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U)
815       {
816         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
817         {
818           return HAL_TIMEOUT;
819         }
820       }
821     }
822   }
823 
824   /*-------------------------------- PLL1 Configuration -----------------------*/
825   /* Check the parameters */
826   assert_param(IS_RCC_PLL(pOscInitStruct->PLL.PLLState));
827 
828   if ((pOscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
829   {
830     /* Check if the PLL1 is used as system clock or not */
831     if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
832     {
833       if ((pOscInitStruct->PLL.PLLState) == RCC_PLL_ON)
834       {
835         /* Check the parameters */
836         assert_param(IS_RCC_PLL1_SOURCE(pOscInitStruct->PLL.PLLSource));
837         assert_param(IS_RCC_PLL1_DIVM_VALUE(pOscInitStruct->PLL.PLLM));
838         assert_param(IS_RCC_PLL1_MULN_VALUE(pOscInitStruct->PLL.PLLN));
839         assert_param(IS_RCC_PLL1_DIVP_VALUE(pOscInitStruct->PLL.PLLP));
840         assert_param(IS_RCC_PLL1_DIVQ_VALUE(pOscInitStruct->PLL.PLLQ));
841         assert_param(IS_RCC_PLL1_DIVR_VALUE(pOscInitStruct->PLL.PLLR));
842 
843         /* Disable the PLL1. */
844         __HAL_RCC_PLL1_DISABLE();
845 
846         /* Get Start Tick*/
847         tickstart = HAL_GetTick();
848 
849         /* Wait till PLL1 is disabled */
850         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
851         {
852           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
853           {
854             return HAL_TIMEOUT;
855           }
856         }
857 
858         /* Configure the PLL1 clock source, multiplication and division factors. */
859         __HAL_RCC_PLL1_CONFIG(pOscInitStruct->PLL.PLLSource,
860                               pOscInitStruct->PLL.PLLM,
861                               pOscInitStruct->PLL.PLLN,
862                               pOscInitStruct->PLL.PLLP,
863                               pOscInitStruct->PLL.PLLQ,
864                               pOscInitStruct->PLL.PLLR);
865 
866         assert_param(IS_RCC_PLL1_FRACN_VALUE(pOscInitStruct->PLL.PLLFRACN));
867 
868         /* Disable PLL1FRACN . */
869         __HAL_RCC_PLL1_FRACN_DISABLE();
870 
871         /* Configure PLL  PLL1FRACN */
872         __HAL_RCC_PLL1_FRACN_CONFIG(pOscInitStruct->PLL.PLLFRACN);
873 
874         /* Enable PLL1FRACN . */
875         __HAL_RCC_PLL1_FRACN_ENABLE();
876 
877         assert_param(IS_RCC_PLL1_VCIRGE_VALUE(pOscInitStruct->PLL.PLLRGE));
878 
879         /* Select PLL1 input reference frequency range: VCI */
880         __HAL_RCC_PLL1_VCIRANGE(pOscInitStruct->PLL.PLLRGE) ;
881 
882         assert_param(IS_RCC_PLL1_VCORGE_VALUE(pOscInitStruct->PLL.PLLVCOSEL));
883 
884         /* Select PLL1 output frequency range : VCO */
885         __HAL_RCC_PLL1_VCORANGE(pOscInitStruct->PLL.PLLVCOSEL) ;
886 
887         /* Enable PLL1 System Clock output. */
888         __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVP);
889 
890         /* Enable the PLL1. */
891         __HAL_RCC_PLL1_ENABLE();
892 
893         /* Get Start Tick*/
894         tickstart = HAL_GetTick();
895 
896         /* Wait till PLL1 is ready */
897         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
898         {
899           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
900           {
901             return HAL_TIMEOUT;
902           }
903         }
904       }
905       else
906       {
907         /* Disable the PLL1. */
908         __HAL_RCC_PLL1_DISABLE();
909 
910         /* Get Start Tick*/
911         tickstart = HAL_GetTick();
912 
913         /* Wait till PLL1 is disabled */
914         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
915         {
916           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
917           {
918             return HAL_TIMEOUT;
919           }
920         }
921 
922         /* Unselect PLL1 clock source and disable all PLL1 outputs to save power */
923         RCC->PLL1CFGR &= ~(RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1PEN | RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1REN);
924 
925       }
926     }
927     else
928     {
929       /* Do not return HAL_ERROR if request repeats the current configuration */
930       temp1_pllckcfg = RCC->PLL1CFGR;
931       temp2_pllckcfg = RCC->PLL1DIVR;
932       if (((pOscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
933           (READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1SRC) != pOscInitStruct->PLL.PLLSource) ||
934           ((READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1M) >> \
935             RCC_PLL1CFGR_PLL1M_Pos) != (pOscInitStruct->PLL.PLLM)) ||
936           (READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1N) != (pOscInitStruct->PLL.PLLN - 1U)) ||
937           ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1P) >> \
938             RCC_PLL1DIVR_PLL1P_Pos) != (pOscInitStruct->PLL.PLLP - 1U)) ||
939           ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1Q) >> \
940             RCC_PLL1DIVR_PLL1Q_Pos) != (pOscInitStruct->PLL.PLLQ - 1U)) ||
941           ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1R) >> \
942             RCC_PLL1DIVR_PLL1R_Pos) != (pOscInitStruct->PLL.PLLR - 1U)))
943       {
944         return HAL_ERROR;
945       }
946 
947       /* FRACN1 on-the-fly value update */
948       if ((READ_BIT(RCC->PLL1FRACR, RCC_PLL1FRACR_PLL1FRACN) >> \
949            RCC_PLL1FRACR_PLL1FRACN_Pos) != (pOscInitStruct->PLL.PLLFRACN))
950       {
951         assert_param(IS_RCC_PLL1_FRACN_VALUE(pOscInitStruct->PLL.PLLFRACN));
952 
953         /* Disable PLL1FRACN . */
954         __HAL_RCC_PLL1_FRACN_DISABLE();
955 
956         /* Configure PLL PLL1FRACN */
957         __HAL_RCC_PLL1_FRACN_CONFIG(pOscInitStruct->PLL.PLLFRACN);
958 
959         /* Enable PLL1FRACN . */
960         __HAL_RCC_PLL1_FRACN_ENABLE();
961       }
962 
963     }
964   }
965   return HAL_OK;
966 }
967 
968 /**
969   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
970   *         parameters in the pClkInitStruct.
971   * @param  pClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
972   *         contains the configuration information for the RCC peripheral.
973   * @param  FLatency  FLASH Latency
974   *          This parameter can be one of the following values:
975   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
976   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
977   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
978   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
979   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
980   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
981   *
982   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
983   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
984   *
985   * @note   The HSI is used by default as system clock source after
986   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
987   *         the HSI frequency is set to its default value 64 MHz.
988   *
989   * @note   The HSI or CSI can be selected as system clock source after wake-up
990   *         from STOP modes or in case of failure of the HSE when used directly or indirectly
991   *         as system clock (if the Clock Security System CSS is enabled).
992   *
993   * @note   A switch from one clock source to another occurs only if the target
994   *         clock source is ready (clock stable after startup delay or PLL locked).
995   *         If a clock source which is not yet ready is selected, the switch will
996   *         occur when the clock source is ready.
997   *
998   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
999   *         currently used as system clock source.
1000   *
1001   * @retval HAL Status.
1002   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * pClkInitStruct,uint32_t FLatency)1003 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *pClkInitStruct, uint32_t FLatency)
1004 {
1005   HAL_StatusTypeDef halstatus;
1006   uint32_t tickstart;
1007 
1008   /* Check Null pointer */
1009   if (pClkInitStruct == NULL)
1010   {
1011     return HAL_ERROR;
1012   }
1013 
1014   /* Check the parameters */
1015   assert_param(IS_RCC_CLOCKTYPE(pClkInitStruct->ClockType));
1016   assert_param(IS_FLASH_LATENCY(FLatency));
1017 
1018   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1019     must be correctly programmed according to the frequency of the CPU clock
1020     (HCLK) and the supply voltage of the device. */
1021 
1022   /* Increasing the number of wait states because of higher CPU frequency */
1023   if (FLatency > __HAL_FLASH_GET_LATENCY())
1024   {
1025     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1026     __HAL_FLASH_SET_LATENCY(FLatency);
1027 
1028     /* Check that the new number of wait states is taken into account to access the Flash
1029     memory by reading the FLASH_ACR register */
1030     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1031     {
1032       return HAL_ERROR;
1033     }
1034   }
1035 
1036   /* Increasing the BUS frequency divider */
1037   /*-------------------------- PCLK3 Configuration ---------------------------*/
1038   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3)
1039   {
1040     if ((pClkInitStruct->APB3CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE3) >> 8))
1041     {
1042       assert_param(IS_RCC_PCLK(pClkInitStruct->APB3CLKDivider));
1043       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, ((pClkInitStruct->APB3CLKDivider) << 8));
1044     }
1045   }
1046   /*-------------------------- PCLK2 Configuration ---------------------------*/
1047   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1048   {
1049     if ((pClkInitStruct->APB2CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4))
1050     {
1051       assert_param(IS_RCC_PCLK(pClkInitStruct->APB2CLKDivider));
1052       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pClkInitStruct->APB2CLKDivider) << 4));
1053     }
1054   }
1055 
1056   /*-------------------------- PCLK1 Configuration ---------------------------*/
1057   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1058   {
1059     if ((pClkInitStruct->APB1CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1060     {
1061       assert_param(IS_RCC_PCLK(pClkInitStruct->APB1CLKDivider));
1062       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pClkInitStruct->APB1CLKDivider);
1063     }
1064   }
1065 
1066   /*-------------------------- HCLK Configuration --------------------------*/
1067   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1068   {
1069     if ((pClkInitStruct->AHBCLKDivider) > (RCC->CFGR2 & RCC_CFGR2_HPRE))
1070     {
1071       assert_param(IS_RCC_HCLK(pClkInitStruct->AHBCLKDivider));
1072       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pClkInitStruct->AHBCLKDivider);
1073     }
1074   }
1075 
1076   /*------------------------- SYSCLK Configuration ---------------------------*/
1077   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1078   {
1079     assert_param(IS_RCC_SYSCLKSOURCE(pClkInitStruct->SYSCLKSource));
1080 
1081     /* PLL is selected as System Clock Source */
1082     if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1083     {
1084       /* Check the PLL ready flag */
1085       if (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
1086       {
1087         return HAL_ERROR;
1088       }
1089     }
1090     else
1091     {
1092       /* HSE is selected as System Clock Source */
1093       if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1094       {
1095         /* Check the HSE ready flag */
1096         if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1097         {
1098           return HAL_ERROR;
1099         }
1100       }
1101       /* CSI is selected as System Clock Source */
1102       else if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI)
1103       {
1104         /* Check the CSI ready flag */
1105         if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U)
1106         {
1107           return HAL_ERROR;
1108         }
1109       }
1110       /* HSI is selected as System Clock Source */
1111       else
1112       {
1113         /* Check the HSI ready flag */
1114         if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1115         {
1116           return HAL_ERROR;
1117         }
1118       }
1119     }
1120 
1121     MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, pClkInitStruct->SYSCLKSource);
1122 
1123     /* Get Start Tick*/
1124     tickstart = HAL_GetTick();
1125 
1126     if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1127     {
1128       while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1129       {
1130         if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1131         {
1132           return HAL_TIMEOUT;
1133         }
1134       }
1135     }
1136     else
1137     {
1138       if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1139       {
1140         while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
1141         {
1142           if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1143           {
1144             return HAL_TIMEOUT;
1145           }
1146         }
1147       }
1148       else if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI)
1149       {
1150         while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_CSI)
1151         {
1152           if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1153           {
1154             return HAL_TIMEOUT;
1155           }
1156         }
1157       }
1158       else
1159       {
1160         while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
1161         {
1162           if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1163           {
1164             return HAL_TIMEOUT;
1165           }
1166         }
1167       }
1168     }
1169   }
1170 
1171   /* Decreasing the BUS frequency divider */
1172   /*-------------------------- HCLK Configuration --------------------------*/
1173   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1174   {
1175     if ((pClkInitStruct->AHBCLKDivider) < (RCC->CFGR2 & RCC_CFGR2_HPRE))
1176     {
1177       assert_param(IS_RCC_HCLK(pClkInitStruct->AHBCLKDivider));
1178       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pClkInitStruct->AHBCLKDivider);
1179     }
1180   }
1181 
1182   /* Decreasing the number of wait states because of lower CPU frequency */
1183   if (FLatency < __HAL_FLASH_GET_LATENCY())
1184   {
1185     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1186     __HAL_FLASH_SET_LATENCY(FLatency);
1187 
1188     /* Check that the new number of wait states is taken into account to access the Flash
1189     memory by reading the FLASH_ACR register */
1190     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1191     {
1192       return HAL_ERROR;
1193     }
1194   }
1195 
1196   /*-------------------------- PCLK1 Configuration ---------------------------*/
1197   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1198   {
1199     if ((pClkInitStruct->APB1CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1200     {
1201       assert_param(IS_RCC_PCLK(pClkInitStruct->APB1CLKDivider));
1202       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pClkInitStruct->APB1CLKDivider);
1203     }
1204   }
1205 
1206   /*-------------------------- PCLK2 Configuration ---------------------------*/
1207   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1208   {
1209     if ((pClkInitStruct->APB2CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4))
1210     {
1211       assert_param(IS_RCC_PCLK(pClkInitStruct->APB2CLKDivider));
1212       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pClkInitStruct->APB2CLKDivider) << 4));
1213     }
1214   }
1215 
1216   /*-------------------------- PCLK3 Configuration ---------------------------*/
1217   if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3)
1218   {
1219     if ((pClkInitStruct->APB3CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE3) >> 8))
1220     {
1221       assert_param(IS_RCC_PCLK(pClkInitStruct->APB3CLKDivider));
1222       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, ((pClkInitStruct->APB3CLKDivider) << 8));
1223     }
1224   }
1225 
1226   /* Update the SystemCoreClock global variable */
1227   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1228 
1229   /* Configure the source of time base considering new system clocks settings*/
1230   halstatus = HAL_InitTick(uwTickPrio);
1231 
1232   return halstatus;
1233 }
1234 
1235 /**
1236   * @}
1237   */
1238 
1239 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1240   *  @brief   RCC clocks control functions
1241   *
1242 @verbatim
1243  ===============================================================================
1244                       ##### Peripheral Control functions #####
1245  ===============================================================================
1246     [..]
1247     This subsection provides a set of functions allowing to:
1248 
1249     (+) Output clock to MCO pin.
1250     (+) Retrieve current clock frequencies.
1251     (+) Enable the Clock Security System.
1252 
1253 @endverbatim
1254   * @{
1255   */
1256 
1257 /**
1258   * @brief  Select the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9).
1259   * @note   PA8/PC9 should be configured in alternate function mode.
1260   * @param  RCC_MCOx  specifies the output direction for the clock source.
1261   *          For STM32H5xx family this parameter can have only one value:
1262   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
1263   *            @arg @ref RCC_MCO2  Clock source to output on MCO2 pin(PC9).
1264   * @param  RCC_MCOSource  specifies the clock source to output.
1265   *          This parameter can be one of the following values:
1266   *            @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source
1267   *            @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source
1268   *            @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source
1269   *            @arg RCC_MCO1SOURCE_PLL1QCLK:  PLL1Q clock selected as MCO1 source
1270   *            @arg RCC_MCO1SOURCE_HSI48: HSI48 (48MHZ) selected as MCO1 source
1271   *            @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source
1272   *            @arg RCC_MCO2SOURCE_PLL2PCLK: PLL2P clock selected as MCO2 source
1273   *            @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source
1274   *            @arg RCC_MCO2SOURCE_PLL1PCLK:  PLL1P clock selected as MCO2 source
1275   *            @arg RCC_MCO2SOURCE_CSI:  CSI clock selected as MCO2 source
1276   *            @arg RCC_MCO2SOURCE_LSI:  LSI clock selected as MCO2 source
1277   * @param  RCC_MCODiv  specifies the MCO prescaler.
1278   *          This parameter can be one of the following values:
1279   *            @arg RCC_MCODIV_1 up to RCC_MCODIV_15  : divider applied to MCOx clock
1280   * @retval None
1281   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1282 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1283 {
1284   GPIO_InitTypeDef GPIO_InitStruct;
1285   /* Check the parameters */
1286   assert_param(IS_RCC_MCO(RCC_MCOx));
1287   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1288   /* RCC_MCO1 */
1289   if (RCC_MCOx == RCC_MCO1)
1290   {
1291     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1292 
1293     /* MCO1 Clock Enable */
1294     MCO1_CLK_ENABLE();
1295 
1296     /* Configure the MCO1 pin in alternate function mode */
1297     GPIO_InitStruct.Pin = MCO1_PIN;
1298     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1299     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1300     GPIO_InitStruct.Pull = GPIO_NOPULL;
1301     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1302     HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1303 
1304     /* Mask MCO1 and MCO1PRE[3:0] bits then Select MCO1 clock source and pre-scaler */
1305     MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO1SEL | RCC_CFGR1_MCO1PRE), (RCC_MCOSource | RCC_MCODiv));
1306   }
1307   else
1308   {
1309     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
1310 
1311     /* MCO2 Clock Enable */
1312     MCO2_CLK_ENABLE();
1313 
1314     /* Configure the MCO2 pin in alternate function mode */
1315     GPIO_InitStruct.Pin = MCO2_PIN;
1316     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1317     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1318     GPIO_InitStruct.Pull = GPIO_NOPULL;
1319     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1320     HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct);
1321 
1322     /* Mask MCO2 and MCO2PRE[3:0] bits then Select MCO2 clock source and pre-scaler */
1323     MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO2SEL | RCC_CFGR1_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 7U)));
1324   }
1325 }
1326 
1327 /**
1328   * @brief  Return the SYSCLK frequency.
1329   *
1330   * @note   The system frequency computed by this function may not be the real
1331   *         frequency in the chip. It is calculated based on the predefined
1332   *         constants of the selected clock source:
1333   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1334   * @note     If SYSCLK source is CSI, function returns values based on CSI_VALUE(**)
1335   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
1336   * @note     If SYSCLK source is PLL, function returns values based on HSI_VALUE(*), CSI_VALUE(**)
1337   *           or HSE_VALUE(***) multiplied/divided by the PLL factors.
1338   * @note     (*) HSI_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value
1339   *               64 MHz) but the real value may vary depending on the variations
1340   *               in voltage and temperature.
1341   * @note     (**) CSI_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value
1342   *               4 MHz) but the real value may vary depending on the variations
1343   *               in voltage and temperature.
1344   * @note     (***) HSE_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value
1345   *                24 MHz), user has to ensure that HSE_VALUE is same as the real
1346   *                frequency of the crystal used. Otherwise, this function may
1347   *                have wrong result.
1348   *
1349   * @note   The result of this function could be not correct when using fractional
1350   *         value for HSE crystal.
1351   *
1352   * @note   This function can be used by the user application to compute the
1353   *         baudrate for the communication peripherals or configure other parameters.
1354   *
1355   * @note   Each time SYSCLK changes, this function must be called to update the
1356   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1357   *
1358   *
1359   * @retval SYSCLK frequency
1360   */
HAL_RCC_GetSysClockFreq(void)1361 uint32_t HAL_RCC_GetSysClockFreq(void)
1362 {
1363   uint32_t pllsource;
1364   uint32_t pllp;
1365   uint32_t pllm;
1366   uint32_t pllfracen;
1367   uint32_t sysclockfreq;
1368   uint32_t hsivalue;
1369   float_t fracn1;
1370   float_t pllvco;
1371 
1372   if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_CSI)
1373   {
1374     /* CSI used as system clock  source */
1375     sysclockfreq = CSI_VALUE;
1376   }
1377   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
1378   {
1379     /* HSI used as system clock source */
1380     if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIVF) != 0U)
1381     {
1382       sysclockfreq = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos));
1383     }
1384     else
1385     {
1386       sysclockfreq = (uint32_t) HSI_VALUE;
1387     }
1388   }
1389   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
1390   {
1391     /* HSE used as system clock source */
1392     sysclockfreq = HSE_VALUE;
1393   }
1394 
1395   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1396   {
1397     /* PLL used as system clock  source */
1398 
1399     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
1400     SYSCLK = PLL_VCO / PLLR
1401     */
1402     pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
1403     pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos);
1404     pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN) >> RCC_PLL1CFGR_PLL1FRACEN_Pos);
1405     fracn1 = (float_t)(uint32_t)(pllfracen * ((RCC->PLL1FRACR & \
1406                                                RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos));
1407 
1408     if (pllm != 0U)
1409     {
1410       switch (pllsource)
1411       {
1412         case RCC_PLL1_SOURCE_HSI:  /* HSI used as PLL1 clock source */
1413 
1414           if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIVF) != 0U)
1415           {
1416             hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos));
1417             pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1418                                                             (fracn1 / (float_t)0x2000) + (float_t)1);
1419           }
1420           else
1421           {
1422             pllvco = ((float_t)HSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1423                                                              (fracn1 / (float_t)0x2000) + (float_t)1);
1424           }
1425 
1426           break;
1427 
1428         case RCC_PLL1_SOURCE_HSE:  /* HSE used as PLL1 clock source */
1429           pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1430                                                            (fracn1 / (float_t)0x2000) + (float_t)1);
1431 
1432           break;
1433 
1434         case RCC_PLL1_SOURCE_CSI:  /* CSI used as PLL1 clock source */
1435         default:
1436           pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1437                                                            (fracn1 / (float_t)0x2000) + (float_t)1);
1438           break;
1439       }
1440 
1441       pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U) ;
1442       sysclockfreq = (uint32_t)(float_t)(pllvco / (float_t)pllp);
1443     }
1444     else
1445     {
1446       sysclockfreq = 0;
1447     }
1448   }
1449 
1450   else
1451   {
1452     /* HSI is the default system clock source */
1453     sysclockfreq = (uint32_t) HSI_VALUE;
1454   }
1455 
1456   return sysclockfreq;
1457 }
1458 
1459 /**
1460   * @brief  Return the HCLK frequency.
1461   * @note   Each time HCLK changes, this function must be called to update the
1462   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1463   *
1464   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1465   * @retval HCLK frequency in Hz
1466   */
HAL_RCC_GetHCLKFreq(void)1467 uint32_t HAL_RCC_GetHCLKFreq(void)
1468 {
1469 
1470   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) \
1471                                                                 >> RCC_CFGR2_HPRE_Pos] & 0x1FU);
1472 
1473   return SystemCoreClock;
1474 }
1475 
1476 /**
1477   * @brief  Return the PCLK1 frequency.
1478   * @note   Each time PCLK1 changes, this function must be called to update the
1479   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1480   * @retval PCLK1 frequency in Hz
1481   */
HAL_RCC_GetPCLK1Freq(void)1482 uint32_t HAL_RCC_GetPCLK1Freq(void)
1483 {
1484   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1485   return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos]) & 0x1FU));
1486 }
1487 
1488 /**
1489   * @brief  Return the PCLK2 frequency.
1490   * @note   Each time PCLK2 changes, this function must be called to update the
1491   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1492   * @retval PCLK2 frequency in Hz
1493   */
HAL_RCC_GetPCLK2Freq(void)1494 uint32_t HAL_RCC_GetPCLK2Freq(void)
1495 {
1496   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1497   return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE2) >> RCC_CFGR2_PPRE2_Pos]) & 0x1FU));
1498 }
1499 
1500 /**
1501   * @brief  Return the PCLK3 frequency.
1502   * @note   Each time PCLK3 changes, this function must be called to update the
1503   *         right PCLK3 value. Otherwise, any configuration based on this function will be incorrect.
1504   * @retval PCLK3 frequency in Hz
1505   */
HAL_RCC_GetPCLK3Freq(void)1506 uint32_t HAL_RCC_GetPCLK3Freq(void)
1507 {
1508   /* Get HCLK source and Compute PCLK3 frequency ---------------------------*/
1509   return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE3) >> RCC_CFGR2_PPRE3_Pos]) & 0x1FU));
1510 }
1511 /**
1512   * @brief  Configure the pOscInitStruct according to the internal
1513   *         RCC configuration registers.
1514   * @param  pOscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1515   *         will be configured.
1516   * @retval None
1517   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * pOscInitStruct)1518 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *pOscInitStruct)
1519 {
1520   uint32_t regval;
1521   uint32_t reg1val;
1522   uint32_t reg2val;
1523 
1524   /* Check the parameters */
1525   assert_param(pOscInitStruct != (void *)NULL);
1526 
1527   /* Set all possible values for the Oscillator type parameter ---------------*/
1528   pOscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_CSI | \
1529                                    RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1530 
1531   /* Get Control register */
1532   regval = RCC->CR;
1533 
1534   /* Get the HSE configuration -----------------------------------------------*/
1535   pOscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_HSEEXT));
1536 
1537   /* Get the CSI configuration -----------------------------------------------*/
1538   pOscInitStruct->CSIState = regval & RCC_CR_CSION;
1539 
1540   /* Get the HSI configuration -----------------------------------------------*/
1541   pOscInitStruct->HSIState = regval & RCC_CR_HSION;
1542   pOscInitStruct->HSIDiv = regval & RCC_CR_HSIDIV;
1543   pOscInitStruct->HSICalibrationValue = (uint32_t)(READ_BIT(RCC->HSICFGR, \
1544                                                             RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos);
1545 
1546   /* Get BDCR register */
1547   regval = RCC->BDCR;
1548 
1549   /* Get the LSE configuration -----------------------------------------------*/
1550   pOscInitStruct->LSEState = (regval & (RCC_BDCR_LSEON | RCC_BDCR_LSEBYP | RCC_BDCR_LSEEXT));
1551 
1552   /* Get the LSI configuration -----------------------------------------------*/
1553   pOscInitStruct->LSIState = regval & RCC_BDCR_LSION;
1554 
1555   /* Get Control register */
1556   regval = RCC->CR;
1557 
1558   /* Get the HSI48 configuration ---------------------------------------------*/
1559   pOscInitStruct->HSI48State = regval & RCC_CR_HSI48ON;
1560 
1561   /* Get the PLL configuration -----------------------------------------------*/
1562   if ((regval & RCC_CR_PLL1ON) == RCC_CR_PLL1ON)
1563   {
1564     pOscInitStruct->PLL.PLLState = RCC_PLL_ON;
1565   }
1566   else
1567   {
1568     pOscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1569   }
1570 
1571   /* Get PLL configuration register */
1572   reg1val = RCC->PLL1CFGR;
1573   reg2val = RCC->PLL1DIVR;
1574 
1575   pOscInitStruct->PLL.PLLSource = (uint32_t)(reg1val & RCC_PLL1CFGR_PLL1SRC);
1576   pOscInitStruct->PLL.PLLM = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos);
1577   pOscInitStruct->PLL.PLLN = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) + 1U);
1578   pOscInitStruct->PLL.PLLQ = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U);
1579   pOscInitStruct->PLL.PLLR = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U);
1580   pOscInitStruct->PLL.PLLP = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U);
1581   pOscInitStruct->PLL.PLLRGE = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1RGE));
1582   pOscInitStruct->PLL.PLLVCOSEL = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1VCOSEL) >> RCC_PLL1CFGR_PLL1VCOSEL_Pos);
1583   pOscInitStruct->PLL.PLLFRACN = (uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) \
1584                                              >> RCC_PLL1FRACR_PLL1FRACN_Pos));
1585 }
1586 
1587 /**
1588   * @brief  Configure the pClkInitStruct according to the internal
1589   *         RCC configuration registers.
1590   * @param  pClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1591   *         will be configured.
1592   * @param  pFLatency  Pointer on the Flash Latency.
1593   * @retval None
1594   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * pClkInitStruct,uint32_t * pFLatency)1595 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *pClkInitStruct, uint32_t *pFLatency)
1596 {
1597   uint32_t regval;
1598 
1599   /* Check the parameters */
1600   assert_param(pClkInitStruct != (void *)NULL);
1601   assert_param(pFLatency != (void *)NULL);
1602 
1603   /* Set all possible values for the Clock type parameter --------------------*/
1604   pClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
1605                               RCC_CLOCKTYPE_PCLK3;
1606 
1607   /* Get the SYSCLK configuration --------------------------------------------*/
1608   pClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR1 & RCC_CFGR1_SW);
1609 
1610   /* Get the HCLK configuration ----------------------------------------------*/
1611   regval = RCC->CFGR2;
1612   pClkInitStruct->AHBCLKDivider = (uint32_t)(regval & RCC_CFGR2_HPRE);
1613 
1614   /* Get the APB1 configuration ----------------------------------------------*/
1615   pClkInitStruct->APB1CLKDivider = (uint32_t)(regval & RCC_CFGR2_PPRE1);
1616 
1617   /* Get the APB2 configuration ----------------------------------------------*/
1618   pClkInitStruct->APB2CLKDivider = (uint32_t)((regval & RCC_CFGR2_PPRE2) >> 4);
1619 
1620   /* Get the APB3 configuration ----------------------------------------------*/
1621   pClkInitStruct->APB3CLKDivider = (uint32_t)((regval & RCC_CFGR2_PPRE3) >> 8);
1622 
1623   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1624   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1625 }
1626 
1627 /**
1628   * @brief  Get and clear reset flags
1629   * @note   Once reset flags are retrieved, this API is clearing them in order
1630   *         to isolate next reset reason.
1631   * @retval can be a combination of @ref RCC_Reset_Flag
1632   */
HAL_RCC_GetResetSource(void)1633 uint32_t HAL_RCC_GetResetSource(void)
1634 {
1635   uint32_t reset;
1636 
1637   /* Get all reset flags */
1638   reset = RCC->RSR & RCC_RESET_FLAG_ALL;
1639 
1640   /* Clear Reset flags */
1641   RCC->RSR |= RCC_RSR_RMVF;
1642 
1643   return reset;
1644 }
1645 
1646 /**
1647   * @brief  Enable the HSE Clock Security System.
1648   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1649   *         is automatically disabled and an interrupt is generated to inform the
1650   *         software about the failure (Clock Security System Interrupt, CSSI),
1651   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1652   *         the Cortex-M NMI (Non-Maskable Interrupt) exception vector.
1653   * @note   The Clock Security System can only be cleared by reset.
1654   * @retval None
1655   */
HAL_RCC_EnableCSS(void)1656 void HAL_RCC_EnableCSS(void)
1657 {
1658   SET_BIT(RCC->CR, RCC_CR_HSECSSON);
1659 }
1660 
1661 /**
1662   * @brief Handle the RCC Clock Security System interrupt request.
1663   * @note This API should be called under the NMI_Handler().
1664   * @retval None
1665   */
HAL_RCC_NMI_IRQHandler(void)1666 void HAL_RCC_NMI_IRQHandler(void)
1667 {
1668   /* Check RCC CSSF interrupt flag  */
1669   if (__HAL_RCC_GET_IT(RCC_IT_HSECSS))
1670   {
1671     /* RCC Clock Security System interrupt user callback */
1672     HAL_RCC_CSSCallback();
1673 
1674     /* Clear RCC CSS pending bit */
1675     __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS);
1676   }
1677 }
1678 
1679 /**
1680   * @brief  RCC HSE Clock Security System interrupt callback.
1681   * @retval none
1682   */
HAL_RCC_CSSCallback(void)1683 __weak void HAL_RCC_CSSCallback(void)
1684 {
1685   /* NOTE : This function should not be modified, when the callback is needed,
1686             the HAL_RCC_CSSCallback should be implemented in the user file
1687    */
1688 }
1689 
1690 /**
1691   * @}
1692   */
1693 
1694 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1695   *  @brief Attributes management functions.
1696   *
1697 @verbatim
1698  ===============================================================================
1699                        ##### RCC attributes functions #####
1700  ===============================================================================
1701     [..]
1702     This subsection provides a set of functions allowing to:
1703 
1704     (+) Configure the RCC item(s) attributes.
1705     (+) Get the attribute of an RCC item.
1706 
1707 @endverbatim
1708   * @{
1709   */
1710 /**
1711   * @brief  Configure the RCC item(s) attribute(s).
1712   * @note   Available attributes are to secure items and set RCC as privileged (*).
1713   *         Default state is non-secure and unprivileged access allowed.
1714   * @note   Secure and non-secure attributes can only be set from the secure
1715   *         state when the system implements the security (TZEN=1).
1716   * @param  Item Item(s) to set attributes on.
1717   *         This parameter can be a one or a combination of @ref RCC_items (**).
1718   * @param  Attributes specifies the RCC secure/privilege attributes.
1719   *         This parameter can be a value of @RCC_attributes
1720   * @retval None
1721   *
1722   * (*)   : For stm32h503xx devices, attributes specifies the privilege attribute only (no items).
1723   * (**)  : For stm32h503xx devices, this parameter is unused, it can take 0 or any other numerical value.
1724   */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1725 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1726 {
1727 
1728   /* Check the parameters */
1729   assert_param(IS_RCC_ATTRIBUTES(Attributes));
1730 
1731 #if defined(RCC_SECCFGR_HSISEC)
1732   assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1733 
1734   switch (Attributes)
1735   {
1736 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1737     /* Secure Privilege attribute */
1738     case RCC_SEC_PRIV:
1739       SET_BIT(RCC->SECCFGR, Item);
1740       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1741       break;
1742     /* Secure Non-Privilege attribute */
1743     case RCC_SEC_NPRIV:
1744       SET_BIT(RCC->SECCFGR, Item);
1745       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1746       break;
1747     /* Non-secure Privilege attribute */
1748     case RCC_NSEC_PRIV:
1749       CLEAR_BIT(RCC->SECCFGR, Item);
1750       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1751       break;
1752     /* Non-secure Non-Privilege attribute */
1753     case RCC_NSEC_NPRIV:
1754       CLEAR_BIT(RCC->SECCFGR, Item);
1755       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1756       break;
1757 #else /* __ARM_FEATURE_CMSE */
1758     /* Non-secure Privilege attribute */
1759     case RCC_NSEC_PRIV:
1760       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1761       break;
1762     /* Non-secure Non-Privilege attribute */
1763     case RCC_NSEC_NPRIV:
1764       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1765       break;
1766 #endif /* __ARM_FEATURE_CMSE */
1767     default:
1768       /* Nothing to do */
1769       break;
1770   }
1771 
1772 #else /* RCC_SECCFGR_HSISEC */
1773 
1774   UNUSED(Item);
1775 
1776   switch (Attributes)
1777   {
1778     /* Privilege attribute */
1779     case RCC_PRIV:
1780       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV);
1781       break;
1782     /* Non-secure Non-Privilege attribute */
1783     case RCC_NPRIV:
1784       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV);
1785       break;
1786     default:
1787       /* Nothing to do */
1788       break;
1789   }
1790 
1791 #endif /* RCC_SECCFGR_HSISEC */
1792 }
1793 
1794 /**
1795   * @brief  Get the attribute of an RCC item.
1796   * @note   Secure and non-secure attributes are only available from secure state
1797   *         when the system implements the security (TZEN=1)
1798   * @param  Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
1799   *         This parameter can be a one value of @ref RCC_items except RCC_ALL. (*)
1800   * @param  pAttributes pointer to return the attributes.
1801   * @retval HAL Status.
1802   *
1803   * (*)  : This parameter is unused for stm32h503xx devices, it can take 0 or any other numerical value.
1804   */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1805 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1806 {
1807   uint32_t attributes;
1808 
1809   /* Check null pointer */
1810   if (pAttributes == NULL)
1811   {
1812     return HAL_ERROR;
1813   }
1814 
1815 #if defined(RCC_SECCFGR_HSISEC)
1816   /* Check the parameters */
1817   assert_param(IS_RCC_SINGLE_ITEM_ATTRIBUTES(Item));
1818 
1819 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1820 
1821   /* Check item security */
1822   if ((RCC->SECCFGR & Item) == Item)
1823   {
1824     /* Get Secure privileges attribute */
1825     attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_SPRIV) == 0U) ? RCC_SEC_NPRIV : RCC_SEC_PRIV;
1826   }
1827   else
1828   {
1829     /* Get Non-Secure privileges attribute */
1830     attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1831   }
1832 #else  /* __ARM_FEATURE_CMSE */
1833   attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1834 #endif /* __ARM_FEATURE_CMSE */
1835 
1836 #else /* RCC_SECCFGR_HSISEC */
1837   UNUSED(Item);
1838   /* Get privileges attribute */
1839   attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_PRIV) == 0U) ? RCC_NPRIV : RCC_PRIV;
1840 #endif /* RCC_SECCFGR_HSISEC */
1841 
1842   /* return value */
1843   *pAttributes = attributes;
1844 
1845   return HAL_OK;
1846 }
1847 
1848 /**
1849   * @}
1850   */
1851 
1852 /**
1853   * @}
1854   */
1855 
1856 /* Private function prototypes -----------------------------------------------*/
1857 #endif /* HAL_RCC_MODULE_ENABLED */
1858 /**
1859   * @}
1860   */
1861 
1862 /**
1863   * @}
1864   */
1865