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