1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_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       (from 8 MHz to reach 16MHz) with Flash 0 wait state. Flash prefetch buffer
29       is disabled.
30       (+) There is no prescaler on High speed (AHBs) except for AHB5 and no
31           prescaler Low speed (APBs) busses: all peripherals mapped on these
32           busses are running at HSI speed.
33       (+) The clock for all peripherals is switched off, except SRAMs and FLASH.
34       (+) All GPIOs are in analog mode, except the JTAG pins which
35           are assigned to be used for debug purpose.
36 
37     [..]
38       Once the device started, the user application has to:
39       (+) Configure the clock source to be used to drive the System clock
40           (if the application needs higher frequency/performance)
41       (+) Configure the System clock frequency and Flash settings
42       (+) Configure the AHB and APB busses prescalers
43       (+) Enable the clock for the peripheral(s) to be used
44       (+) Configure the kernel clock source(s) for peripherals which clocks are
45           not derived from the System clock.
46 
47   @endverbatim
48   ******************************************************************************
49   */
50 
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32wbaxx_hal.h"
53 
54 /** @addtogroup STM32WBAxx_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 /* timeout value */
71 /* LSI maximum timeout is 16 us plus 4 LSI clock cycles when prediv is used */
72 #define LSI_TIMEOUT_VALUE               ((5u * 128u * 1000u) / LSI_VALUE)
73 #define PLL_TIMEOUT_VALUE               2U        /* 2 ms (minimum Tick + 1) */
74 #define PLL_FRAC_WAIT_VALUE             1U        /* PLL Fractional part waiting time before new latch enable : 1 ms */
75 #define PLL1_NDIV_TIMEOUT_VALUE         10U       /* SYSCLK divider delay when going from divide to not divide. 10 ms when 2-steps */
76 #define CLOCKSWITCH_TIMEOUT_VALUE       5000U     /* 5 s    */
77 #define PLL_INPUTRANGE0_FREQMAX         8000000u  /* 8 MHz is maximum frequency for VCO input range 0 */
78 /**
79   * @}
80   */
81 
82 /* Private macro -------------------------------------------------------------*/
83 /** @defgroup RCC_Private_Macros RCC Private Macros
84   * @{
85   */
86 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
87 #define MCO1_GPIO_PORT        GPIOA
88 #define MCO1_PIN              GPIO_PIN_8
89 /**
90   * @}
91   */
92 
93 /* Private variables ---------------------------------------------------------*/
94 
95 /* Private function prototypes -----------------------------------------------*/
96 /** @defgroup RCC_Private_Functions RCC Private Functions
97   * @{
98   */
99 static float_t RCC_PLL1_GetVCOOutputFreq(void);
100 /**
101   * @}
102   */
103 
104 /* Exported functions --------------------------------------------------------*/
105 
106 /** @defgroup RCC_Exported_Functions RCC Exported Functions
107   * @{
108   */
109 
110 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
111   *  @brief    Initialization and Configuration functions
112   *
113   @verbatim
114  ===============================================================================
115            ##### Initialization and de-initialization functions #####
116  ===============================================================================
117     [..]
118       This section provides functions allowing to configure the internal and external oscillators
119       (HSE, HSI, LSE, LSI (LSI1 or LSI2), PLL1, CSS and MCO) and the System busses clocks (SYSCLK,
120       AHB1, AHB2, AHB4, AHB5, APB1, APB2 and APB7).
121 
122     [..] Internal/external clock and PLL1 configuration
123          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
124              the PLL1 as System clock source.
125 
126          (+) LSI (low-speed internal):
127            (++) LSI1: 32 kHz low-speed low power internal RC that drives the independent watchdog
128                 and optionally the RTC used for auto-wakeup from Stop and Standby modes
129            (++) LSI2: 32 kHz low-speed low drift internal RC that drives optionally the RTC or
130                 2.4 GHz RADIO sleep timer used for auto-wakeup from Stop and Standby modes.
131 
132          (+) HSE (high-speed external): 32 MHz crystal oscillator used directly or
133              through the PLL1 as System clock source. Can be used also optionally as RTC clock source.
134 
135          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source
136              and 2.4 GHz RADIO sleep timer.
137 
138          (+) PLL1 (clocked by HSI or HSE) providing up to three independent output clocks:
139            (++) The P output is used to generate an accurate clock to achieve
140                 high-quality audio performance on SAI interface and ADC4.
141            (++) The Q output is used to generate the clock for the SAI1 and RNG.
142            (++) The R output is used to generate the high speed system clock (up to 100MHz).
143 
144          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
145             (HSE used directly or through PLL1 as System clock source), the System clock
146              is automatically switched to HSI and an interrupt is generated if enabled.
147              The interrupt is linked to the Cortex-M33 NMI (Non-Maskable Interrupt)
148              exception vector.
149 
150          (+) MCO (microcontroller clock output): used to output LSI, HSI, LSE, HSE32, SYSCLK, HCLK5 and
151              PLL1 R, P, Q clocks (through a configurable prescaler) on PA8 pin.
152 
153     [..] System, AHB and APB busses clocks configuration
154          (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
155              HSE and main PLL1.
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 APB7 (PCLK7) 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 kernel clocks are derived from the System clock (SYSCLK) but some
164              peripheral can select a different source (you have to use HAL_RCCEx_PeriphCLKConfig()
165              function to configure it) :
166            (+@) U(S)ARTx (x = 1, 2) : Kernel clock can be PCLKx, SYSCLK, HSI or LSE.
167            (+@) I2Cx (x = 1, 3) : Kernel clock can be PCLKx, SYSCLK or HSI.
168            (+@) LPTIMx (x = 1, 2) : Kernel clock can be PCLKx, LSI, HSI or LSE.
169            (+@) SPIx (x = 1, 3) : Kernel clock can be PCLKx, SYSCLK or HSI.
170            (+@) SAI1 : Kernel clock can be PLL1P, PLL1Q, SYSCLK, a clock provided on CKIN pin or HSI.
171            (+@) RNG : Kernel clock can be LSE, LSI, HSI or PLL1Q.
172            (+@) LPUART1 : Kernel clock can be PCLKx, SYSCLK, HSI or LSE.
173            (+@) RTC : Kernel clock can be derived either from the LSI, LSE or HSE clock divided by 32.
174            (+@) ADC4 : Kernel clock can be HCLK, SYSCLK, PLL1P, HSE or HSI clock.
175            (+@) 2.4 GHz RADIO sleep timer : Kernel clock can be LSE, LSI, or HSE divided by 1000 clock.
176 
177 
178          (+) The maximum frequency of SYSCLK / AHB1 / AHB2 / AHB4 / APB1 / APB2 / APB7 is
179               (++) 100 MHz at voltage range 1
180               (++) 16 MHZ at voltage range 2
181 
182          (+) The maximum frequency of AHB5 is
183               (++) 32 MHz at voltage range 1
184               (++) 12 MHZ at voltage range 2
185 
186              The clock source frequency should be adapted depending on the device voltage range
187              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
188 
189   @endverbatim
190 
191      (++)  Table 1. HCLK clock frequency for STM32WBAxx devices
192      (++)  +-------------------------------------------------------+
193      (++)  | Latency         |     HCLK clock frequency (MHz)      |
194      (++)  |                 |-------------------------------------|
195      (++)  |                 | voltage scaling  | voltage scaling  |
196      (++)  |                 |      range 1     |      range 1     |
197      (++)  |-----------------|------------------|------------------|
198      (++)  |0WS(1 CPU cycles)|     HCLK <=  32  |     HCLK <=  8   |
199      (++)  |-----------------|------------------|------------------|
200      (++)  |1WS(2 CPU cycles)|     HCLK <=  64  |     HCLK <= 16   |
201      (++)  |-----------------|------------------|------------------|
202      (++)  |2WS(3 CPU cycles)|     HCLK <=  96  |        -         |
203      (++)  |-----------------|------------------|------------------|
204      (++)  |3WS(4 CPU cycles)|     HCLK <= 100  |        -         |
205      (++)  +-----------------+------------------+------------------+
206   * @{
207   */
208 
209 /**
210   * @brief  Reset the RCC clock configuration to the default reset state.
211   * @note   The default reset state of the clock configuration is given below:
212   *            - HSI ON and used as system clock source
213   *            - HSE and PLL1 OFF
214   *            - AHB, APB1, APB2 and APB7 prescaler set to 1.
215   *            - CSS, MCO1 OFF
216   *            - All interrupts disabled and cleared
217   * @note   This function doesn't modify the configuration of the
218   *            - Peripheral clocks
219   *            - LSI, LSE and RTC clocks
220   * @retval None
221   */
HAL_RCC_DeInit(void)222 HAL_StatusTypeDef HAL_RCC_DeInit(void)
223 {
224   uint32_t tickstart;
225 
226   /* Get start tick*/
227   tickstart = HAL_GetTick();
228 
229   /* Set HSION bit */
230   SET_BIT(RCC->CR, RCC_CR_HSION);
231 
232   /* Wait till HSI is ready */
233   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
234   {
235     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
236     {
237       return HAL_TIMEOUT;
238     }
239   }
240 
241   /* Set HSITRIM default value */
242   MODIFY_REG(RCC->ICSCR3, RCC_ICSCR3_HSITRIM, 0x00100000U);
243 
244   /* Get start tick*/
245   tickstart = HAL_GetTick();
246 
247   /* Reset CFGR1 register (HSI is selected as system clock source) */
248   CLEAR_REG(RCC->CFGR1);
249 
250   /* Wait till clock switch is ready */
251   while (READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS) != 0U)
252   {
253     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
254     {
255       return HAL_TIMEOUT;
256     }
257   }
258 
259   /* Set AHBx and APBx prescaler to their default values */
260   CLEAR_REG(RCC->CFGR2);
261   CLEAR_REG(RCC->CFGR3);
262   WRITE_REG(RCC->CFGR4, 0x00000010);
263 
264   /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
265   RCC->CR = RCC_CR_HSION;
266 
267   /* Then again to HSEBYP in case bypass was enabled */
268   RCC->CR = RCC_CR_HSION;
269 
270   /* Get Start Tick */
271   tickstart = HAL_GetTick();
272 
273   /* Wait till PLL1 is disabled */
274   while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
275   {
276     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
277     {
278       return HAL_TIMEOUT;
279     }
280   }
281 
282   /* Reset PLL1CFGR register */
283   CLEAR_REG(RCC->PLL1CFGR);
284 
285   /* Reset PLL1DIVR register */
286   WRITE_REG(RCC->PLL1DIVR, 0x01010280U);
287 
288   /* Reset PLL1FRACR register */
289   CLEAR_REG(RCC->PLL1FRACR);
290 
291   /* Disable all interrupts */
292   CLEAR_REG(RCC->CIER);
293 
294   /* Clear all interrupts flags */
295   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
296 
297   /* Update the SystemCoreClock global variable */
298   SystemCoreClock = HSI_VALUE;
299 
300   /* Adapt Systick interrupt period */
301   if (HAL_InitTick(uwTickPrio) != HAL_OK)
302   {
303     return HAL_ERROR;
304   }
305   else
306   {
307     return HAL_OK;
308   }
309 }
310 
311 
312 /**
313   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
314   *         RCC_OscInitTypeDef.
315   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
316   *         contains the configuration information for the RCC Oscillators.
317   * @note   The PLL1 is not disabled when used as system clock.
318   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
319   *         supported by this function. User should request a transition to HSE Off
320   *         first and then to HSE On or HSE Bypass.
321   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
322   *         supported by this function. User should request a transition to LSE Off
323   *         first and then LSE On or LSE Bypass.
324   * @retval HAL status
325   */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * RCC_OscInitStruct)326 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *RCC_OscInitStruct)
327 {
328   uint32_t tickstart;
329   uint32_t sysclksrc;
330   uint32_t pllsrc;
331   uint32_t tmpreg1;
332   uint32_t tmpreg2;
333   uint32_t mask;
334 
335   /* Check Null pointer */
336   if (RCC_OscInitStruct == NULL)
337   {
338     return HAL_ERROR;
339   }
340 
341   /* Check the parameters */
342   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
343 
344   sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
345   pllsrc = __HAL_RCC_GET_PLL1_OSCSOURCE();
346 
347   /*------------------------------- HSE Configuration ------------------------*/
348   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
349   {
350     /* Check the parameters */
351     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
352 
353     /* When the HSE is used as system clock or clock source for PLL1 in these cases it is not allowed to be disabled */
354     if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
355         ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pllsrc == RCC_PLLSOURCE_HSE)))
356     {
357       if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
358       {
359         return HAL_ERROR;
360       }
361       else
362       {
363         /* Otherwise, applying divider is allowed */
364         if (sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE)
365         {
366           assert_param(IS_RCC_HSEDIV(RCC_OscInitStruct->HSEDiv));
367 
368           /* Adjust the HSE division factor */
369           __HAL_RCC_HSE_CONFIG(RCC_HSE_ON | RCC_OscInitStruct->HSEDiv);
370 
371           /* Update the SystemCoreClock global variable with HSE value */
372           SystemCoreClock = (HSE_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSEPRE)) >> RCC_CR_HSEPRE_Pos)));
373 
374           /* Adapt Systick interrupt period */
375           if (HAL_InitTick(uwTickPrio) != HAL_OK)
376           {
377             return HAL_ERROR;
378           }
379         }
380       }
381     }
382     else
383     {
384       /* Check the HSE State */
385       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
386       {
387         assert_param(IS_RCC_HSEDIV(RCC_OscInitStruct->HSEDiv));
388 
389         /* Set the new HSE configuration ---------------------------------------*/
390         __HAL_RCC_HSE_CONFIG((RCC_OscInitStruct->HSEState | RCC_OscInitStruct->HSEDiv));
391 
392         /* Get Start Tick*/
393         tickstart = HAL_GetTick();
394 
395         /* Wait till HSE is ready */
396         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
397         {
398           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
399           {
400             return HAL_TIMEOUT;
401           }
402         }
403       }
404       else
405       {
406         /* Set the new HSE configuration ---------------------------------------*/
407         __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
408 
409         /* Get Start Tick*/
410         tickstart = HAL_GetTick();
411 
412         /* Wait till HSE is disabled */
413         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
414         {
415           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
416           {
417             return HAL_TIMEOUT;
418           }
419         }
420       }
421     }
422   }
423 
424   /*----------------------------- HSI Configuration --------------------------*/
425   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
426   {
427     /* Check the parameters */
428     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
429     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
430 
431     /* Check if HSI is used as system clock or as PLL1 source when PLL1 is selected as system clock */
432     if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
433         ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pllsrc == RCC_PLLSOURCE_HSI)))
434     {
435       /* When HSI is used as system clock it will not be disabled */
436       if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
437       {
438         return HAL_ERROR;
439       }
440       /* Otherwise, just the calibration is allowed */
441       else
442       {
443         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
444         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
445       }
446     }
447     else
448     {
449       /* Check the HSI State */
450       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
451       {
452         /* Enable the Internal High Speed oscillator (HSI). */
453         __HAL_RCC_HSI_ENABLE();
454 
455         /* Get Start Tick*/
456         tickstart = HAL_GetTick();
457 
458         /* Wait till HSI is ready */
459         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
460         {
461           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
462           {
463             return HAL_TIMEOUT;
464           }
465         }
466 
467         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
468         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
469       }
470       else
471       {
472         /* Disable the Internal High Speed oscillator (HSI). */
473         __HAL_RCC_HSI_DISABLE();
474 
475         /* Get Start Tick*/
476         tickstart = HAL_GetTick();
477 
478         /* Wait till HSI is disabled */
479         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
480         {
481           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
482           {
483             return HAL_TIMEOUT;
484           }
485         }
486       }
487     }
488   }
489 
490   /*------------------------------ LSI Configuration -------------------------*/
491   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
492   {
493     /* Check the parameters */
494     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
495 
496     FlagStatus  pwrclkchanged = RESET;
497 
498     /* Update LSI1 configuration in Backup Domain control register    */
499     /* Requires to enable write access to Backup Domain of necessary */
500     if (__HAL_RCC_PWR_IS_CLK_ENABLED() != 0x01)
501     {
502       __HAL_RCC_PWR_CLK_ENABLE();
503       pwrclkchanged = SET;
504     }
505 
506     if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
507     {
508       /* Enable write access to Backup domain */
509       SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
510 
511       /* Wait for Backup domain Write protection disable */
512       tickstart = HAL_GetTick();
513 
514       while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
515       {
516         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
517         {
518           return HAL_TIMEOUT;
519         }
520       }
521     }
522 
523     /* Get BDCR1 register value */
524     tmpreg1 = RCC->BDCR1;
525 
526     /* Define mask depending on LSI presence */
527     mask = RCC_BDCR1_LSI1ON;
528 #if defined(RCC_LSI2_SUPPORT)
529     mask |= RCC_BDCR1_LSI2ON;
530 #endif /* RCC_LSI2_SUPPORT */
531 
532     /* Check the LSI1 State */
533     if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
534     {
535       if ((RCC_OscInitStruct->LSIState & RCC_LSI1_ON) != 0x00u)
536       {
537         /* Check LSI1 division factor */
538         assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv));
539 
540         /* Check is LSIDiv is requested to be changed and LSI is already ON */
541         if ((RCC_OscInitStruct->LSIDiv != (tmpreg1 & RCC_BDCR1_LSI1PREDIV)) && ((tmpreg1 & RCC_BDCR1_LSI1RDY) != 0x00u))
542         {
543           /* Disable LSI1 */
544           tmpreg1 &= ~RCC_BDCR1_LSI1ON;
545           RCC->BDCR1 = tmpreg1;
546 
547           /* Get Start Tick*/
548           tickstart = HAL_GetTick();
549 
550           /* Wait till LSI1 is disabled */
551           while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSI1RDY) != 0x00u)
552           {
553             if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
554             {
555               /* LSI1 may be forced ON by IWDG */
556               return HAL_TIMEOUT;
557             }
558           }
559 #if defined(STM32WBAXX_SI_CUT1_0)
560           /* Wait at least 1 half LSI clock period before apppling new LSI1 prediv value */
561           HAL_Delay(1);
562 #endif
563         }
564 
565         /* Set LSI1 division factor */
566         tmpreg1 &= ~RCC_BDCR1_LSI1PREDIV;
567         tmpreg1 |= RCC_OscInitStruct->LSIDiv;
568       }
569 
570       /* Enable Concerned LSI */
571       tmpreg1 |= RCC_OscInitStruct->LSIState;
572       RCC->BDCR1 = tmpreg1;
573 
574       /* Get Start Tick*/
575       tickstart = HAL_GetTick();
576 
577       /* Wait till LSI is ready : LSIRDY bit is position ON shifted by 1 */
578       while (READ_BIT(RCC->BDCR1, (RCC_OscInitStruct->LSIState << 1)) == 0x00u)
579       {
580         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
581         {
582           return HAL_TIMEOUT;
583         }
584       }
585 
586 #if defined(RCC_LSI2_SUPPORT)
587       /* Disable other LSI in case it was ON */
588       mask ^= RCC_OscInitStruct->LSIState;
589       tmpreg1 &= ~mask;
590       RCC->BDCR1 = tmpreg1;
591 
592       /* Get Start Tick*/
593       tickstart = HAL_GetTick();
594 
595       /* Wait till other LSI is disabled */
596       while (READ_BIT(RCC->BDCR1, (mask << 1)) != 0x00u)
597       {
598         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
599         {
600           return HAL_TIMEOUT;
601         }
602       }
603 #endif
604     }
605     else
606     {
607       /* Disable the Internal Low Speed oscillator LSI1 and LSI2 is available */
608       tmpreg1 &= ~mask;
609       RCC->BDCR1 = tmpreg1;
610 
611       /* Get Start Tick*/
612       tickstart = HAL_GetTick();
613 
614       /* Wait till LSI is disabled : LSIRDY bit position is ON shifted by 1 */
615       while (READ_BIT(RCC->BDCR1, (mask << 1)) != 0x00u)
616       {
617         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
618         {
619           return HAL_TIMEOUT;
620         }
621       }
622     }
623     /* Restore clock configuration if changed */
624     if (pwrclkchanged == SET)
625     {
626       __HAL_RCC_PWR_CLK_DISABLE();
627     }
628   }
629 
630   /*------------------------------ LSE Configuration -------------------------*/
631   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
632   {
633     FlagStatus       pwrclkchanged = RESET;
634 
635     /* Check the parameters */
636     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
637 
638     /* Update LSE configuration in Backup Domain control register    */
639     /* Requires to enable write access to Backup Domain of necessary */
640     if (__HAL_RCC_PWR_IS_CLK_ENABLED() != 0x01)
641     {
642       __HAL_RCC_PWR_CLK_ENABLE();
643       pwrclkchanged = SET;
644     }
645 
646     if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
647     {
648       /* Enable write access to Backup domain */
649       SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
650 
651       /* Wait for Backup domain Write protection disable */
652       tickstart = HAL_GetTick();
653 
654       while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
655       {
656         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
657         {
658           return HAL_TIMEOUT;
659         }
660       }
661     }
662 
663     /* Set the new LSE configuration -----------------------------------------*/
664     /* Check the LSE State */
665     if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
666     {
667       /* If LSE is already on or in bypass mode, only LSE system can be modified */
668       tmpreg1 = (RCC->BDCR1 & ~RCC_BDCR1_LSESYSEN);
669       tmpreg1 |= RCC_OscInitStruct->LSEState;
670       RCC->BDCR1 = tmpreg1;
671 
672       /* Get Start Tick*/
673       tickstart = HAL_GetTick();
674 
675       /* Wait till LSE is ready */
676       while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSERDY) == 0U)
677       {
678         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
679         {
680           return HAL_TIMEOUT;
681         }
682       }
683 
684       /* Enable LSESYS additionally if requested */
685       if ((RCC_OscInitStruct->LSEState & RCC_BDCR1_LSESYSEN) != 0U)
686       {
687         /* Wait till LSESYS is ready */
688         while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSRDY) == 0U)
689         {
690           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
691           {
692             return HAL_TIMEOUT;
693           }
694         }
695       }
696       else
697       {
698         /* Wait till LSESYSRDY is cleared */
699         while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSRDY) != 0U)
700         {
701           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
702           {
703             return HAL_TIMEOUT;
704           }
705         }
706       }
707     }
708     else
709     {
710       CLEAR_BIT(RCC->BDCR1, (RCC_BDCR1_LSEON | RCC_BDCR1_LSESYSEN));
711       CLEAR_BIT(RCC->BDCR1, RCC_BDCR1_LSEBYP);
712 
713       /* Get Start Tick*/
714       tickstart = HAL_GetTick();
715 
716       /* Wait till LSE is disabled */
717       while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSERDY) != 0U)
718       {
719         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
720         {
721           return HAL_TIMEOUT;
722         }
723       }
724 
725       if (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSEN) != 0U)
726       {
727         /* Wait till LSESYSRDY is cleared */
728         while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSRDY) != 0U)
729         {
730           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
731           {
732             return HAL_TIMEOUT;
733           }
734         }
735       }
736     }
737 
738     /* Restore clock configuration if changed */
739     if (pwrclkchanged == SET)
740     {
741       __HAL_RCC_PWR_CLK_DISABLE();
742     }
743   }
744 
745   /*-------------------------------- PLL1 Configuration -----------------------*/
746   /* Check the parameters */
747   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL1.PLLState));
748 
749   if ((RCC_OscInitStruct->PLL1.PLLState) != RCC_PLL_NONE)
750   {
751     /* Check if the PLL1 is used as system clock or not */
752     if (sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
753     {
754       if ((RCC_OscInitStruct->PLL1.PLLState) == RCC_PLL_ON)
755       {
756         /* Check the parameters */
757         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL1.PLLSource));
758         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL1.PLLM));
759         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL1.PLLN));
760         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL1.PLLP));
761         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL1.PLLQ));
762         assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL1.PLLR));
763 
764         /* Disable the main PLL1. */
765         tmpreg1 = (RCC->CR & ~RCC_CR_PLL1ON);
766         RCC->CR = tmpreg1;
767 
768         /* Get Start Tick*/
769         tickstart = HAL_GetTick();
770 
771         /* Wait till PLL1 is disabled */
772         do
773         {
774           tmpreg1 = RCC->CR;
775           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
776           {
777             return HAL_TIMEOUT;
778           }
779         } while ((tmpreg1 & RCC_CR_PLL1RDY) != 0U);
780 
781         /* Compute VCO input frequency and define range accordingly. First check clock source frequency */
782         if (RCC_OscInitStruct->PLL1.PLLSource == RCC_PLLSOURCE_HSE)
783         {
784           /* Clock source is HSE or HSE/2 */
785           pllsrc = HSE_VALUE >> ((tmpreg1 & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos);
786         }
787         else
788         {
789           /* Clock source is HSI */
790           pllsrc = HSI_VALUE;
791         }
792 
793         /* Compute VCO input frequency depending on M divider */
794         pllsrc = (pllsrc / RCC_OscInitStruct->PLL1.PLLM);
795         assert_param(IS_RCC_PLL_VCOINPUTFREQ(pllsrc));
796 
797         if (pllsrc > PLL_INPUTRANGE0_FREQMAX)
798         {
799           /* Reuse pllsrc local variable to store range */
800           pllsrc = RCC_PLL_VCOINPUT_RANGE1;
801         }
802         else
803         {
804           /* Reuse pllsrc local variable to store range */
805           pllsrc = RCC_PLL_VCOINPUT_RANGE0;
806         }
807 
808         /* Configure PLL1 source, PLLM divider, VCO input range and enable PLL1R output. Clear also FRACEN*/
809         tmpreg2 = RCC->PLL1CFGR;
810         tmpreg2 &= ~(RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1RGE | RCC_PLL1CFGR_PLL1FRACEN | RCC_PLL1CFGR_PLL1M);
811         tmpreg2 |= (RCC_OscInitStruct->PLL1.PLLSource | pllsrc |
812                     ((RCC_OscInitStruct->PLL1.PLLM - 1u) << RCC_PLL1CFGR_PLL1M_Pos) | RCC_PLL1CFGR_PLL1REN);
813         RCC->PLL1CFGR = tmpreg2;
814 
815         /* Configure PLLN multiplication factor and PLLP, PLLQ, PLLR dividers */
816         tmpreg2 = ((RCC_OscInitStruct->PLL1.PLLN - 1u) |
817                    ((RCC_OscInitStruct->PLL1.PLLP - 1u) << RCC_PLL1DIVR_PLL1P_Pos) |
818                    ((RCC_OscInitStruct->PLL1.PLLQ - 1u) << RCC_PLL1DIVR_PLL1Q_Pos) |
819                    ((RCC_OscInitStruct->PLL1.PLLR - 1u) << RCC_PLL1DIVR_PLL1R_Pos));
820         RCC->PLL1DIVR = tmpreg2;
821 
822         if (RCC_OscInitStruct->PLL1.PLLFractional != 0x00u)
823         {
824           assert_param(IS_RCC_PLLFRACN_VALUE(RCC_OscInitStruct->PLL1.PLLFractional));
825 
826           /* Configure PLL1 PLL1FRACN */
827           __HAL_RCC_PLL1_FRACN_CONFIG(RCC_OscInitStruct->PLL1.PLLFractional);
828 
829           /* Enable PLL1FRACEN */
830           __HAL_RCC_PLL1_FRACN_ENABLE();
831         }
832 
833         /* Enable the main PLL1. */
834         __HAL_RCC_PLL1_ENABLE();
835 
836         /* Get Start Tick*/
837         tickstart = HAL_GetTick();
838 
839         /* Wait till PLL1 is ready */
840         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
841         {
842           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
843           {
844             return HAL_TIMEOUT;
845           }
846         }
847       }
848       else
849       {
850         /* Disable the main PLL1. */
851         __HAL_RCC_PLL1_DISABLE();
852 
853         /* Get Start Tick*/
854         tickstart = HAL_GetTick();
855 
856         /* Wait till PLL1 is disabled */
857         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
858         {
859           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
860           {
861             return HAL_TIMEOUT;
862           }
863         }
864 
865         /* CLear the PLL1 source and disable outputs to save power when PLL1 is off */
866         CLEAR_BIT(RCC->PLL1CFGR, (RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1PEN | \
867                                   RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1REN));
868       }
869     }
870     else
871     {
872       /* Check if there is a request to disable the PLL1 used as System clock source */
873       if ((RCC_OscInitStruct->PLL1.PLLState) == RCC_PLL_OFF)
874       {
875         return HAL_ERROR;
876       }
877       else
878       {
879         /* Do not return HAL_ERROR if request repeats the current configuration */
880         tmpreg1 = RCC->PLL1CFGR;
881         tmpreg2 = RCC->PLL1DIVR;
882 
883         if (((tmpreg1 & RCC_PLL1CFGR_PLL1SRC) != RCC_OscInitStruct->PLL1.PLLSource) ||
884             (((tmpreg1 & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) != (RCC_OscInitStruct->PLL1.PLLM - 1u)) ||
885             (((tmpreg2 & RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) != (RCC_OscInitStruct->PLL1.PLLN - 1u)) ||
886             (((tmpreg2 & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) != (RCC_OscInitStruct->PLL1.PLLP - 1u)) ||
887             (((tmpreg2 & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) != (RCC_OscInitStruct->PLL1.PLLQ - 1u)) ||
888             (((tmpreg2 & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) != (RCC_OscInitStruct->PLL1.PLLR - 1u)))
889         {
890           return HAL_ERROR;
891         }
892         else
893         {
894           /* Check if only fractional part needs to be updated  */
895           tmpreg1 = ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos);
896 
897           if (RCC_OscInitStruct->PLL1.PLLFractional != tmpreg1)
898           {
899             assert_param(IS_RCC_PLLFRACN_VALUE(RCC_OscInitStruct->PLL1.PLLFractional));
900 
901             /* Disable PLL1FRACEN */
902             __HAL_RCC_PLL1_FRACN_DISABLE();
903 
904             /* Get Start Tick*/
905             tickstart = HAL_GetTick();
906 
907             /* Wait at least 2 CK_REF (PLL input source divided by M) period to make sure next latched value will be taken into account. */
908             while ((HAL_GetTick() - tickstart) < PLL_FRAC_WAIT_VALUE)
909             {
910             }
911 
912             /* Configure PLL1 PLL1FRACN */
913             __HAL_RCC_PLL1_FRACN_CONFIG(RCC_OscInitStruct->PLL1.PLLFractional);
914 
915             /* Enable PLL1FRACEN to latch new value. */
916             __HAL_RCC_PLL1_FRACN_ENABLE();
917           }
918         }
919       }
920     }
921   }
922   return HAL_OK;
923 }
924 
925 /**
926   * @brief  Initialize the CPU, AHB and APB bus clocks according to the specified
927   *         parameters in the RCC_ClkInitStruct.
928   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
929   *         contains the configuration information for the RCC peripheral.
930   * @param  FLatency  FLASH Latency
931   *         This parameter can be one of the following values:
932   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
933   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
934   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
935   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
936   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
937   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
938   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
939   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
940   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
941   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
942   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
943   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
944   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
945   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
946   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
947   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
948   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
949   * @note   The HSI (16 MHz) is used by default as system clock source after
950   *         startup from Reset, wake-up from STANDBY mode.
951   * @note   A switch from one clock source to another occurs only if the target
952   *         clock source is ready (clock stable after startup delay or PLL1 locked).
953   *         If a clock source which is not yet ready is selected, the switch will
954   *         occur when the clock source is ready.
955   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
956   *         currently used as system clock source.
957   * @note   The SYSCLK shall only be switched to a higher frequency when incremental
958   *         frequency step is 47 MHz. When this is not respected device operation cannot
959   *         be guaranteed. For bigger incremental frequency steps the PLL1RCLKPRE division
960   *         shall be used.
961   * @note   HCLK5 frequency shall not be higher than 32 MHz in range 1, 12 MHz in range 2.
962   *         Two different fields allow to configure HCLK5 prescaler: one when System clock
963   *         source is to PLL1, other for any other sources.
964   *         HCLK5 prescaler is switched automatically by hardware, but configuration shall
965   *         always be performed before setting new PLL1 source as Sysclk source.
966   * @retval None
967   */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)968 HAL_StatusTypeDef  HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
969 {
970   uint32_t tmpreg1;
971   uint32_t update;
972   uint32_t tickstart;
973 
974   /* Check Null pointer */
975   if (RCC_ClkInitStruct == NULL)
976   {
977     return HAL_ERROR;
978   }
979 
980   /* Check the parameters */
981   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
982   assert_param(IS_FLASH_LATENCY(FLatency));
983 
984   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
985    must be correctly programmed according to the frequency of the CPU clock
986   (HCLK) and the supply voltage of the device. */
987 
988   /* Increasing the number of wait states because of higher CPU frequency */
989   if (FLatency > __HAL_FLASH_GET_LATENCY())
990   {
991     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
992     __HAL_FLASH_SET_LATENCY(FLatency);
993 
994     /* Check that the new number of wait states is taken into account to access the Flash
995     memory by reading the FLASH_ACR register */
996     if (__HAL_FLASH_GET_LATENCY() != FLatency)
997     {
998       return HAL_ERROR;
999     }
1000   }
1001 
1002   /*-------------------------- HCLK5 Configuration --------------------------*/
1003   /* HCLK5 prescaler is switched automatically by hardware, but configuration shall
1004     always be performed before setting new PLL1 source as Sysclk source. */
1005   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK5) == RCC_CLOCKTYPE_HCLK5)
1006   {
1007     assert_param(IS_RCC_HCLK5_HSEHSI(RCC_ClkInitStruct->AHB5_HSEHSI_CLKDivider));
1008     assert_param(IS_RCC_HCLK5_PLL1(RCC_ClkInitStruct->AHB5_PLL1_CLKDivider));
1009     MODIFY_REG(RCC->CFGR4, (RCC_CFGR4_HDIV5 | RCC_CFGR4_HPRE5),
1010                (RCC_ClkInitStruct->AHB5_PLL1_CLKDivider | RCC_ClkInitStruct->AHB5_HSEHSI_CLKDivider));
1011   }
1012 
1013   /*------------------------- SYSCLK Configuration ---------------------------*/
1014   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1015   {
1016     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1017 
1018     /* Read CR register */
1019     tmpreg1 = RCC->CR;
1020 
1021     /* PLL1 is selected as System Clock Source */
1022     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1023     {
1024       /* Check the PLL1 ready flag */
1025       if ((tmpreg1 & RCC_CR_PLL1RDY) == 0U)
1026       {
1027         return HAL_ERROR;
1028       }
1029       else
1030       {
1031         if (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR1_SWS_Pos))
1032         {
1033           /* Whatever is PLL frequency, use step prediv to reach maximum frequency. */
1034           /* Select pll1r to be prediv with 2-step divider when selected as Sysclk source */
1035           MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRESTEP, RCC_PLL1CFGR_PLL1RCLKPRE);
1036 #if defined(STM32WBAXX_SI_CUT1_0)
1037           /* add 2 pulse on CLKPRE bit : clear and set it back */
1038           CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1039           SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1040           CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1041           SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1042 #endif
1043         }
1044       }
1045     }
1046     else
1047     {
1048       /* HSE is selected as System Clock Source */
1049       if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1050       {
1051         /* Check the HSE ready flag */
1052         if ((tmpreg1 & RCC_CR_HSERDY) == 0U)
1053         {
1054           return HAL_ERROR;
1055         }
1056       }
1057       /* HSI is selected as System Clock Source */
1058       else
1059       {
1060         /* Check the HSI ready flag */
1061         if ((tmpreg1 & RCC_CR_HSIRDY) == 0U)
1062         {
1063           return HAL_ERROR;
1064         }
1065       }
1066     }
1067 
1068     /* Switch System clock source */
1069     MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, RCC_ClkInitStruct->SYSCLKSource);
1070 
1071     /* Get Start Tick*/
1072     tickstart = HAL_GetTick();
1073 
1074     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR1_SWS_Pos))
1075     {
1076       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1077       {
1078         return HAL_TIMEOUT;
1079       }
1080     }
1081 
1082     /* If PLL1rCLK is asked to be SYSCLK source, clear prediv. */
1083     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1084     {
1085       /* Set PLL1R prediv to not divided */
1086       CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1087 
1088       /* Get Start Tick*/
1089       tickstart = HAL_GetTick();
1090 
1091       /* Wait until PLL1 not divided is ready */
1092       while ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1RCLKPRERDY) == 0x00u)
1093       {
1094         if ((HAL_GetTick() - tickstart) > PLL1_NDIV_TIMEOUT_VALUE)
1095         {
1096           return HAL_TIMEOUT;
1097         }
1098       }
1099     }
1100   }
1101 
1102   /* Get CFGR2 content value, and reset update variable */
1103   tmpreg1 = RCC->CFGR2;
1104   update = 0x00u;
1105 
1106   /*-------------------------- HCLK Configuration --------------------------*/
1107   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1108   {
1109     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1110 
1111     /* update HCLK1 divider and notify register is required */
1112     tmpreg1 &= ~RCC_CFGR2_HPRE;
1113     tmpreg1 |= RCC_ClkInitStruct->AHBCLKDivider;
1114     update = 0x01u;
1115   }
1116 
1117 
1118   /*-------------------------- PCLK1 Configuration ---------------------------*/
1119   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1120   {
1121     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1122 
1123     /* update PCLK1 divider and notify register is required */
1124     tmpreg1 &= ~RCC_CFGR2_PPRE1;
1125     tmpreg1 |= RCC_ClkInitStruct->APB1CLKDivider;
1126     update = 0x01u;
1127   }
1128 
1129   /*-------------------------- PCLK2 Configuration ---------------------------*/
1130   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1131   {
1132     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1133 
1134     /* update PCLK2 divider and notify register is required */
1135     tmpreg1 &= ~RCC_CFGR2_PPRE2;
1136     tmpreg1 |= (RCC_ClkInitStruct->APB2CLKDivider << (RCC_CFGR2_PPRE2_Pos - RCC_CFGR2_PPRE1_Pos));
1137     update = 0x01u;
1138   }
1139 
1140   /* update CFGR2 if required */
1141   if (update != 0x00u)
1142   {
1143     RCC->CFGR2 = tmpreg1;
1144   }
1145 
1146   /*-------------------------- PCLK7 Configuration ---------------------------*/
1147   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK7) == RCC_CLOCKTYPE_PCLK7)
1148   {
1149     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB7CLKDivider));
1150     WRITE_REG(RCC->CFGR3, RCC_ClkInitStruct->APB7CLKDivider);
1151   }
1152 
1153   /* Decreasing the number of wait states because of lower CPU frequency */
1154   if (FLatency < __HAL_FLASH_GET_LATENCY())
1155   {
1156     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1157     __HAL_FLASH_SET_LATENCY(FLatency);
1158 
1159     /* Check that the new number of wait states is taken into account to access the Flash
1160     memory by reading the FLASH_ACR register */
1161     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1162     {
1163       return HAL_ERROR;
1164     }
1165   }
1166 
1167   /* Update the SystemCoreClock global variable */
1168   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1169 
1170   /* Configure the source of time base considering new system clocks settings*/
1171   return HAL_InitTick(uwTickPrio);
1172 }
1173 
1174 /**
1175   * @}
1176   */
1177 
1178 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1179   * @brief   RCC clocks control functions
1180   *
1181 @verbatim
1182  ===============================================================================
1183                       ##### Peripheral Control functions #####
1184  ===============================================================================
1185     [..]
1186     This subsection provides a set of functions allowing to:
1187 
1188     (+) Output clock to MCO pin.
1189     (+) Retrieve current clock frequencies.
1190     (+) Enable the Clock Security System.
1191 
1192 @endverbatim
1193   * @{
1194   */
1195 
1196 /**
1197   * @brief  Select the clock source to output on MCO pin (PA8).
1198   * @note   PA8 should be configured in alternate function mode.
1199   * @param  RCC_MCOx  specifies the output direction for the clock source.
1200   *         For STM32WBAxx family this parameter can have only one value:
1201   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
1202   * @param  RCC_MCOSource  specifies the clock source to output.
1203   *          This parameter can be one of the following values:
1204   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK   MCO output disabled, no clock on MCO
1205   *            @arg @ref RCC_MCO1SOURCE_SYSCLK    System  clock selected as MCO source
1206   *            @arg @ref RCC_MCO1SOURCE_HSI       HSI clock selected as MCO source
1207   *            @arg @ref RCC_MCO1SOURCE_HSE       HSE clock selected as MCO source
1208   *            @arg @ref RCC_MCO1SOURCE_PLL1RCLK  PLL1R clock selected as MCO source
1209   *            @arg @ref RCC_MCO1SOURCE_LSI       LSI clock selected as MCO source
1210   *            @arg @ref RCC_MCO1SOURCE_LSE       LSE clock selected as MCO source
1211   *            @arg @ref RCC_MCO1SOURCE_PLL1PCLK  PLL1P clock selected as MCO source
1212   *            @arg @ref RCC_MCO1SOURCE_PLL1QCLK  PLL1Q clock selected as MCO source
1213   *            @arg @ref RCC_MCO1SOURCE_HCLK5     HCLK5 clock selected as MCO source
1214   * @param  RCC_MCODiv  specifies the MCO prescaler.
1215   *          This parameter can be one of the following values:
1216   *            @arg @ref RCC_MCODIV_1   no division applied to MCO clock
1217   *            @arg @ref RCC_MCODIV_2   division by 2 applied to MCO clock
1218   *            @arg @ref RCC_MCODIV_4   division by 4 applied to MCO clock
1219   *            @arg @ref RCC_MCODIV_8   division by 8 applied to MCO clock
1220   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
1221   * @retval None
1222   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1223 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1224 {
1225   GPIO_InitTypeDef GPIO_InitStruct;
1226 
1227   /* Check the parameters */
1228   assert_param(IS_RCC_MCO(RCC_MCOx));
1229   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1230   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1231 
1232   /* MCO Clock Enable */
1233   __MCO1_CLK_ENABLE();
1234 
1235   /* Configure the MCO1 pin in alternate function mode */
1236   GPIO_InitStruct.Pin = MCO1_PIN;
1237   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1238   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1239   GPIO_InitStruct.Pull = GPIO_NOPULL;
1240   GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1241   HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1242 
1243   /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1244   MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCOSEL | RCC_CFGR1_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1245 }
1246 
1247 /**
1248   * @brief  Return the SYSCLK frequency.
1249   * @note   The system frequency computed by this function is not the real
1250   *         frequency in the chip. It is calculated based on the predefined
1251   *         constant and the selected clock source:
1252   * @note   If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1253   * @note   If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1254   * @note   If SYSCLK source is PLL1, function returns values based on HSE_VALUE(**),
1255   *         HSI_VALUE(*) or MSI Value multiplied/divided by the PLL1 factors.
1256   * @note   (*)  HSI_VALUE is a constant defined in stm32wbaxx_hal_conf.h file (default value
1257   *              16 MHz) but the real value may vary depending on the variations
1258   *              in voltage and temperature.
1259   * @note   (**) HSE_VALUE is a constant defined in stm32wbaxx_hal_conf.h file (default value
1260   *              32 MHz), user has to ensure that HSE_VALUE is same as the real
1261   *              frequency of the crystal used. Otherwise, this function may
1262   *              have wrong result.
1263   * @note   The result of this function could be not correct when using fractional
1264   *         value for HSE crystal.
1265   * @note   This function can be used by the user application to compute the
1266   *         baudrate for the communication peripherals or configure other parameters.
1267   * @note   Each time SYSCLK changes, this function must be called to update the
1268   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1269   * @retval SYSCLK frequency
1270   */
HAL_RCC_GetSysClockFreq(void)1271 uint32_t HAL_RCC_GetSysClockFreq(void)
1272 {
1273   uint32_t sysclk;
1274 
1275   /* Get SYSCLK source */
1276   sysclk = __HAL_RCC_GET_SYSCLK_SOURCE();
1277 
1278   if (sysclk == RCC_SYSCLKSOURCE_STATUS_HSI)
1279   {
1280     /* HSI used as system clock source */
1281     sysclk = HSI_VALUE;
1282   }
1283   else if (sysclk == RCC_SYSCLKSOURCE_STATUS_HSE)
1284   {
1285     /* HSE used as system clock source. Check if HSE is divided by 2 */
1286     sysclk = (HSE_VALUE >> ((RCC->CR & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos));
1287   }
1288   else
1289   {
1290     /* PLL1 used as system clock source */
1291     sysclk = HAL_RCC_GetPLL1RFreq();
1292   }
1293 
1294   return sysclk;
1295 }
1296 
1297 /**
1298   * @brief  Return the HCLK frequency.
1299   * @note   Each time HCLK changes, this function must be called to update the
1300   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1301   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1302   * @retval HCLK frequency in Hz
1303   */
HAL_RCC_GetHCLKFreq(void)1304 uint32_t HAL_RCC_GetHCLKFreq(void)
1305 {
1306   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1307   return SystemCoreClock;
1308 }
1309 
1310 /**
1311   * @brief  Return the PCLK1 frequency.
1312   * @note   Each time PCLK1 changes, this function must be called to update the
1313   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1314   * @retval PCLK1 frequency in Hz
1315   */
HAL_RCC_GetPCLK1Freq(void)1316 uint32_t HAL_RCC_GetPCLK1Freq(void)
1317 {
1318   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1319   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos]);
1320 }
1321 
1322 /**
1323   * @brief  Return the PCLK2 frequency.
1324   * @note   Each time PCLK2 changes, this function must be called to update the
1325   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1326   * @retval PCLK2 frequency in Hz
1327   */
HAL_RCC_GetPCLK2Freq(void)1328 uint32_t HAL_RCC_GetPCLK2Freq(void)
1329 {
1330   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1331   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE2) >> RCC_CFGR2_PPRE2_Pos]);
1332 }
1333 
1334 /**
1335   * @brief  Return the PCLK7 frequency.
1336   * @note   Each time PCLK7 changes, this function must be called to update the
1337   *         right PCLK7 value. Otherwise, any configuration based on this function will be incorrect.
1338   * @retval PCLK7 frequency in Hz
1339   */
HAL_RCC_GetPCLK7Freq(void)1340 uint32_t HAL_RCC_GetPCLK7Freq(void)
1341 {
1342   /* Get HCLK source and Compute PCLK7 frequency ---------------------------*/
1343   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR3 & RCC_CFGR3_PPRE7) >> RCC_CFGR3_PPRE7_Pos]);
1344 }
1345 
1346 /**
1347   * @brief  Return the HCLK5 frequency.
1348   * @note   Each time HCLK5 changes, this function must be called to update the
1349   *         right HCLK5 value. Otherwise, any configuration based on this function will be incorrect.
1350   * @note   HCLK5 frequency depends on System clock source :
1351             - whenever PLL1 is selected as System clock source, HPRE5 prescaler is internally used to
1352             divide SYSCLK frequency and feed HCLK5.
1353             - whenever HSI or HSE are selected as System clock source, HDIV5 prescaler is internally used to
1354             divide SYSCLK frequency and feed HCLK5.
1355   *         right HCLK5 value. Otherwise, any configuration based on this function will be incorrect.
1356   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1357   * @retval HCLK frequency in Hz
1358   */
HAL_RCC_GetHCLK5Freq(void)1359 uint32_t HAL_RCC_GetHCLK5Freq(void)
1360 {
1361   uint32_t tmp;
1362   uint32_t hclk5freq;
1363 
1364   /* Get source of SYSCLK */
1365   tmp = (RCC->CFGR1 & RCC_CFGR1_SWS);
1366 
1367   /* Depending on SYSCLK source */
1368   if (tmp != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1369   {
1370     /* HSI or HSE are source of SYSCLK, compute divider */
1371     tmp = (RCC->CFGR4 & RCC_CFGR4_HDIV5) >> RCC_CFGR4_HDIV5_Pos;
1372     tmp += 1u;
1373   }
1374   else
1375   {
1376     /* PLL1 is source of SYSCLK, compute prescaler */
1377     tmp = AHB5PrescTable[(RCC->CFGR4 & RCC_CFGR4_HPRE5)];
1378   }
1379 
1380   /* Get SYCLK frequency */
1381   hclk5freq = (HAL_RCC_GetSysClockFreq() / tmp);
1382 
1383   return hclk5freq;
1384 }
1385 
1386 /**
1387   * @brief  Return the PLL1P frequency.
1388   * @retval PLL1P frequency in Hz
1389   */
HAL_RCC_GetPLL1PFreq(void)1390 uint32_t HAL_RCC_GetPLL1PFreq(void)
1391 {
1392   uint32_t pllp;
1393 
1394   /* PLL1P divider */
1395   pllp = ((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U;
1396 
1397   /* Compute VCO output frequency and return PLL1P one */
1398   return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllp);
1399 }
1400 
1401 /**
1402   * @brief  Return the PLL1Q frequency.
1403   * @retval PLL1Q frequency in Hz
1404   */
HAL_RCC_GetPLL1QFreq(void)1405 uint32_t HAL_RCC_GetPLL1QFreq(void)
1406 {
1407   uint32_t pllq;
1408 
1409   /* PLL1Q divider */
1410   pllq = ((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U;
1411 
1412   /* Compute VCO output frequency and return PLL1Q one */
1413   return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllq);
1414 }
1415 
1416 /**
1417   * @brief  Return the PLL1R frequency.
1418   * @retval PLL1R frequency in Hz
1419   */
HAL_RCC_GetPLL1RFreq(void)1420 uint32_t HAL_RCC_GetPLL1RFreq(void)
1421 {
1422   uint32_t pllr;
1423 
1424   /* PLL1R divider */
1425   pllr = ((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U;
1426 
1427   /* Compute VCO output frequency and return PLL1R one */
1428   return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllr);
1429 }
1430 
1431 /**
1432   * @brief  Configure the RCC_OscInitStruct according to the internal
1433   *         RCC configuration registers.
1434   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1435   *         will be configured.
1436   * @retval None
1437   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1438 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1439 {
1440   uint32_t regvalue;
1441   uint32_t mask;
1442 
1443   /* Check the parameters */
1444   assert_param(RCC_OscInitStruct != (void *)NULL);
1445 
1446   /* Set all possible values for the Oscillator type parameter ---------------*/
1447   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI  | \
1448                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1449 
1450   /* Get Backup Domain register 1 */
1451   regvalue = RCC->BDCR1;
1452 
1453   /* Get the LSE configuration -----------------------------------------------*/
1454   mask = (RCC_BDCR1_LSEBYP | RCC_BDCR1_LSESYSEN | RCC_BDCR1_LSEON);
1455   RCC_OscInitStruct->LSEState = (regvalue & mask);
1456 
1457   /* Get the LSI configuration -----------------------------------------------*/
1458   mask = RCC_BDCR1_LSI1ON;
1459 #if defined(RCC_LSI2_SUPPORT)
1460   mask |= RCC_BDCR1_LSI2ON;
1461 #endif
1462   RCC_OscInitStruct->LSIState = (regvalue & mask);
1463   RCC_OscInitStruct->LSIDiv = (regvalue & RCC_BDCR1_LSI1PREDIV);
1464 
1465   /* Get Control register */
1466   regvalue = RCC->CR;
1467 
1468   /* Get the HSE configuration -----------------------------------------------*/
1469   RCC_OscInitStruct->HSEState = (regvalue & RCC_CR_HSEON);
1470   RCC_OscInitStruct->HSEDiv = (regvalue & RCC_CR_HSEPRE);
1471 
1472   /* Get the HSI configuration -----------------------------------------------*/
1473   RCC_OscInitStruct->HSIState = (regvalue & RCC_CR_HSION);
1474   RCC_OscInitStruct->HSICalibrationValue = ((RCC->ICSCR3 & RCC_ICSCR3_HSITRIM) >> RCC_ICSCR3_HSITRIM_Pos);
1475 
1476   /* Get the PLL1 configuration -----------------------------------------------*/
1477   if ((regvalue & RCC_CR_PLL1ON) != 0x00u)
1478   {
1479     RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_ON;
1480   }
1481   else
1482   {
1483     RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_OFF;
1484   }
1485 
1486   /* Get PLL1 configuration register */
1487   regvalue = RCC->PLL1CFGR;
1488   RCC_OscInitStruct->PLL1.PLLSource = (regvalue & RCC_PLL1CFGR_PLL1SRC);
1489   RCC_OscInitStruct->PLL1.PLLM = (((regvalue & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U);
1490 
1491   /* Check if fractional part is enable */
1492   if ((regvalue & RCC_PLL1CFGR_PLL1FRACEN) != 0x00u)
1493   {
1494     regvalue = (((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos));
1495   }
1496   else
1497   {
1498     regvalue = 0;
1499   }
1500   RCC_OscInitStruct->PLL1.PLLFractional = regvalue;
1501 
1502   /* Get PLL1 dividers register */
1503   regvalue = RCC->PLL1DIVR;
1504   RCC_OscInitStruct->PLL1.PLLN = ((regvalue & RCC_PLL1DIVR_PLL1N) + 1U);
1505   RCC_OscInitStruct->PLL1.PLLQ = (((regvalue & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U);
1506   RCC_OscInitStruct->PLL1.PLLR = (((regvalue & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U);
1507   RCC_OscInitStruct->PLL1.PLLP = (((regvalue & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U);
1508 
1509 }
1510 
1511 /**
1512   * @brief  Configure the RCC_ClkInitStruct according to the internal
1513   *         RCC configuration registers.
1514   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1515   *         will be configured.
1516   * @param  pFLatency  Pointer on the Flash Latency.
1517   * @retval None
1518   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1519 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1520 {
1521   uint32_t tmpreg1;
1522 
1523   /* Check the parameters */
1524   assert_param(RCC_ClkInitStruct != (void *)NULL);
1525   assert_param(pFLatency != (void *)NULL);
1526 
1527   /* Set all possible values for the Clock type parameter --------------------*/
1528   RCC_ClkInitStruct->ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 |
1529                                   RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK7 | RCC_CLOCKTYPE_HCLK5);
1530 
1531   /* Get the SYSCLK configuration --------------------------------------------*/
1532   RCC_ClkInitStruct->SYSCLKSource = (RCC->CFGR1 & RCC_CFGR1_SW);
1533 
1534   /* Get the HCLK configuration ----------------------------------------------*/
1535   tmpreg1 = RCC->CFGR2;
1536   RCC_ClkInitStruct->AHBCLKDivider = (tmpreg1 & RCC_CFGR2_HPRE);
1537 
1538   /* Get the PCLK1 configuration ----------------------------------------------*/
1539   RCC_ClkInitStruct->APB1CLKDivider = (tmpreg1 & RCC_CFGR2_PPRE1);
1540 
1541   /* Get the PCLK2 configuration ----------------------------------------------*/
1542   RCC_ClkInitStruct->APB2CLKDivider = ((tmpreg1 & RCC_CFGR2_PPRE2) >> (RCC_CFGR2_PPRE2_Pos - RCC_CFGR2_PPRE1_Pos));
1543 
1544   /* Get the PCLK7 configuration ----------------------------------------------*/
1545   RCC_ClkInitStruct->APB7CLKDivider = (RCC->CFGR3 & RCC_CFGR3_PPRE7);
1546 
1547   /* Get the PCLK1 configuration ----------------------------------------------*/
1548   tmpreg1 = RCC->CFGR4;
1549   RCC_ClkInitStruct->AHB5_PLL1_CLKDivider = (tmpreg1 & RCC_CFGR4_HPRE5);
1550   RCC_ClkInitStruct->AHB5_HSEHSI_CLKDivider = (tmpreg1 & RCC_CFGR4_HDIV5);
1551 
1552   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1553   *pFLatency = (FLASH->ACR & FLASH_ACR_LATENCY);
1554 }
1555 
1556 /**
1557   * @brief  Enable the Clock Security System.
1558   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1559   *         is automatically disabled and an interrupt is generated to inform the
1560   *         software about the failure (Clock Security System Interrupt, CSSI),
1561   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1562   *         the Cortex-M33 NMI (Non-Maskable Interrupt) exception vector.
1563   * @note   The Clock Security System can only be cleared by reset.
1564   * @retval None
1565   */
HAL_RCC_EnableCSS(void)1566 void HAL_RCC_EnableCSS(void)
1567 {
1568   SET_BIT(RCC->CR, RCC_CR_HSECSSON);
1569 }
1570 
1571 /**
1572   * @brief Handle the RCC Clock Security System interrupt request.
1573   * @note This API should be called under the NMI_Handler().
1574   * @retval None
1575   */
HAL_RCC_NMI_IRQHandler(void)1576 void HAL_RCC_NMI_IRQHandler(void)
1577 {
1578   /* Check RCC CSSF interrupt flag  */
1579   if (__HAL_RCC_GET_IT(RCC_IT_CSS))
1580   {
1581     /* Clear RCC CSS pending bit */
1582     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1583 
1584     /* RCC Clock Security System interrupt user callback */
1585     HAL_RCC_CSSCallback();
1586   }
1587 }
1588 
1589 /**
1590   * @brief  RCC Clock Security System interrupt callback.
1591   * @retval none
1592   */
HAL_RCC_CSSCallback(void)1593 __weak void HAL_RCC_CSSCallback(void)
1594 {
1595   /* NOTE : This function should not be modified, when the callback is needed,
1596             the HAL_RCC_CSSCallback should be implemented in the user file
1597    */
1598 }
1599 
1600 /**
1601   * @brief  Get and clear reset flags
1602   * @note   Once reset flags are retrieved, this API is clearing them in order
1603   *         to isolate next reset reason.
1604   * @retval can be a combination of @ref RCC_Reset_Flag
1605   */
HAL_RCC_GetResetSource(void)1606 uint32_t HAL_RCC_GetResetSource(void)
1607 {
1608   uint32_t reset;
1609 
1610   /* Get all reset flags */
1611   reset = RCC->CSR & RCC_RESET_FLAG_ALL;
1612 
1613   /* Clear Reset flags */
1614   RCC->CSR |= RCC_CSR_RMVF;
1615 
1616   return reset;
1617 }
1618 
1619 /**
1620   * @}
1621   */
1622 
1623 #if defined(RCC_PRIVCFGR_NSPRIV)
1624 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1625   *  @brief Attributes management functions.
1626   *
1627 @verbatim
1628  ===============================================================================
1629                        ##### RCC attributes functions #####
1630  ===============================================================================
1631 @endverbatim
1632   * @{
1633   */
1634 /**
1635   * @brief  Configure the RCC item attribute(s).
1636   * @note   Available attributes are to secure items and set RCC as privileged.
1637   * @param  Item Item(s) to set attributes on.
1638   *         This parameter can be a one or a combination of @ref RCC_items
1639   * @param  Attributes specifies the RCC secure/privilege attributes.
1640   *         This parameter can be a value of @ref RCC_attributes
1641   * @retval None
1642   */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1643 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1644 {
1645   /* Check the parameters */
1646   assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1647   assert_param(IS_RCC_ATTRIBUTES(Attributes));
1648 
1649   switch (Attributes)
1650   {
1651 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1652     /* Secure Privilege attribute */
1653     case RCC_SEC_PRIV:
1654       SET_BIT(RCC->SECCFGR, Item);
1655       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1656       break;
1657     /* Secure Non-Privilege attribute */
1658     case RCC_SEC_NPRIV:
1659       SET_BIT(RCC->SECCFGR, Item);
1660       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1661       break;
1662     /* Non-secure Privilege attribute */
1663     case RCC_NSEC_PRIV:
1664       CLEAR_BIT(RCC->SECCFGR, Item);
1665       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1666       break;
1667     /* Non-secure Non-Privilege attribute */
1668     case RCC_NSEC_NPRIV:
1669       CLEAR_BIT(RCC->SECCFGR, Item);
1670       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1671       break;
1672 #else
1673     /* Non-secure Privilege attribute */
1674     case RCC_NSEC_PRIV:
1675       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1676       break;
1677     /* Non-secure Non-Privilege attribute */
1678     case RCC_NSEC_NPRIV:
1679       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1680       break;
1681 #endif /* __ARM_FEATURE_CMSE */
1682     default:
1683       /* Nothing to do */
1684       break;
1685   }
1686 }
1687 /**
1688   * @}
1689   */
1690 
1691 /**
1692   * @brief  Get the attribute of a RCC item.
1693   * @note   Secure and non-secure attributes are only available from secure state
1694   *         when the system implements the security (TZEN=1)
1695   * @param  Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
1696   *         This parameter can be a one value of @ref RCC_items except RCC_ALL.
1697   * @param  pAttributes pointer to return the attributes.
1698   * @retval HAL Status.
1699   */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1700 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1701 {
1702   uint32_t attributes;
1703 
1704   /* Check null pointer */
1705   if (pAttributes == NULL)
1706   {
1707     return HAL_ERROR;
1708   }
1709 
1710   /* Check the parameters */
1711   assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1712 
1713 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1714   /* Check item security */
1715   if ((RCC->SECCFGR & Item) == Item)
1716   {
1717     /* Get Secure privileges attribute */
1718     attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_SPRIV) == 0U) ? RCC_SEC_NPRIV : RCC_SEC_PRIV;
1719   }
1720   else
1721   {
1722     /* Get Non-Secure privileges attribute */
1723     attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1724   }
1725 #else
1726   /* Get Non-Secure privileges attribute */
1727   attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1728 #endif /* __ARM_FEATURE_CMSE */
1729 
1730   /* return value */
1731   *pAttributes = attributes;
1732 
1733   return HAL_OK;
1734 }
1735 /**
1736   * @}
1737   */
1738 #endif
1739 
1740 /* Private functions ---------------------------------------------------------*/
1741 /** @addtogroup RCC_Private_Functions
1742   * @{
1743   */
1744 /**
1745   * @brief  Compute PLL1 VCO output frequency
1746   * @retval Value of PLL1 VCO output frequency
1747   */
RCC_PLL1_GetVCOOutputFreq(void)1748 static float_t RCC_PLL1_GetVCOOutputFreq(void)
1749 {
1750   uint32_t tmpreg1;
1751   uint32_t tmp;
1752   float_t pllsrc;
1753   float_t pllm;
1754   float_t plln;
1755   float_t pllfracn;
1756 
1757   /* Get PLL1 DIVR register value */
1758   tmpreg1 = RCC->PLL1DIVR;
1759 
1760   /* Retrieve PLL1 multiplication factor */
1761   tmp = (tmpreg1 & RCC_PLL1DIVR_PLL1N) + 1U;
1762   plln = (float_t) tmp;
1763 
1764   /* Get PLL1 CFGR register value */
1765   tmpreg1 = RCC->PLL1CFGR;
1766 
1767   /* Retrieve PLL1 divider */
1768   tmp = ((tmpreg1 & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U;
1769   pllm = (float_t) tmp;
1770 
1771   /* Check if fractional part is enable */
1772   if ((tmpreg1 & RCC_PLL1CFGR_PLL1FRACEN) != 0x00u)
1773   {
1774     tmp = ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos);
1775   }
1776   else
1777   {
1778     tmp = 0u;
1779   }
1780   pllfracn = (float_t)tmp;
1781 
1782   /* determine PLL source */
1783   switch (tmpreg1 & RCC_PLL1CFGR_PLL1SRC)
1784   {
1785     /* HSI used as PLL1 clock source */
1786     case RCC_PLLSOURCE_HSI:
1787       pllsrc = (float_t)HSI_VALUE;
1788       break;
1789 
1790     /* HSE used as PLL1 clock source */
1791     case RCC_PLLSOURCE_HSE:
1792       tmp = (HSE_VALUE >> ((RCC->CR & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos));
1793       pllsrc = (float_t)tmp;
1794       break;
1795 
1796     default:
1797       pllsrc = (float_t)0;
1798       break;
1799   }
1800 
1801   /* Compute VCO output frequency */
1802   return ((pllsrc / pllm) * (plln + (pllfracn / (float_t)0x2000u)));
1803 }
1804 
1805 
1806 /**
1807   * @}
1808   */
1809 #endif /* HAL_RCC_MODULE_ENABLED */
1810 /**
1811   * @}
1812   */
1813 
1814 /**
1815   * @}
1816   */
1817 
1818 /**
1819   * @}
1820   */
1821 
1822