1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_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   * @attention
12   *
13   * Copyright (c) 2024 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                       ##### RCC specific features #####
24   ==============================================================================
25     [..]
26       After reset the device is running from High Speed Internal oscillator
27       (64 MHz RC oscillator) with Flash 1 wait state. All peripherals clock are off except internal
28       SRAM, Flash and GPIO for SWD communication.
29 
30       (+) The prescaler is DIV 4
31       (+) The clock for all peripherals is switched off, except the SRAM and FLASH and GPIO.
32       (+) All GPIOs are in input mode, except the SWD pins which
33           are assigned to be used for debug purpose.
34 
35     [..]
36       Once the device started from reset, the user application has to:
37       (+) Configure the clock source to be used to drive the System clock
38           (if the application needs higher frequency/performance)
39       (+) Configure the System clock frequency and Flash settings
40       (+) Enable the clock for the peripheral(s) to be used
41       (+) Configure the clock source(s) for peripherals which clocks are not
42           always 16MHz or 32 MHz (SMPS, SPI2I2S, SPI3I2S)
43 
44   @endverbatim
45   ******************************************************************************
46   */
47 
48 /* Includes ------------------------------------------------------------------*/
49 #include "stm32wb0x_hal.h"
50 
51 /** @addtogroup STM32WB0x_HAL_Driver
52   * @{
53   */
54 
55 /** @defgroup RCC RCC
56   * @brief RCC HAL module driver
57   * @{
58   */
59 
60 #ifdef HAL_RCC_MODULE_ENABLED
61 
62 /* Private typedef -----------------------------------------------------------*/
63 /* Private define ------------------------------------------------------------*/
64 /** @defgroup RCC_Private_Constants RCC Private Constants
65   * @{
66   */
67 #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
68 #define HSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
69 #define LSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
70 #define PLL_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
71 #define LATENCY_TIMEOUT_VALUE      (2U)    /* 2 ms (minimum Tick + 1)   */
72 
73 /**
74   * @}
75   */
76 
77 /* Private macros ------------------------------------------------------------*/
78 /** @defgroup RCC_Private_Macros RCC Private Macros
79   * @{
80   */
81 #if defined(STM32WB06) || defined(STM32WB07)
82 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
83 #define MCO1_GPIO_PORT        GPIOA
84 #define MCO1_PIN              GPIO_PIN_5
85 #define MCO1_GPIO_AF          GPIO_AF0_MCO
86 #endif
87 
88 #define __MCO2_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
89 #define MCO2_GPIO_PORT        GPIOA
90 #define MCO2_PIN              GPIO_PIN_11
91 #define MCO2_GPIO_AF          GPIO_AF0_MCO
92 
93 #define __MCO3_CLK_ENABLE()   __HAL_RCC_GPIOB_CLK_ENABLE()
94 #if defined(STM32WB06) || defined(STM32WB07)
95 #define MCO3_GPIO_PORT        GPIOB
96 #define MCO3_PIN              GPIO_PIN_15
97 #define MCO3_GPIO_AF          GPIO_AF2_MCO
98 #endif
99 #if defined(STM32WB05) || defined(STM32WB09 )
100 #define MCO3_GPIO_PORT        GPIOB
101 #define MCO3_PIN              GPIO_PIN_14
102 #define MCO3_GPIO_AF          GPIO_AF3_MCO
103 #endif
104 
105 /**
106   * @}
107   */
108 
109 /* Private variables ---------------------------------------------------------*/
110 /* Private function prototypes -----------------------------------------------*/
111 /* Exported functions --------------------------------------------------------*/
112 
113 /** @defgroup RCC_Exported_Functions RCC Exported Functions
114   * @{
115   */
116 
117 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
118   *  @brief    Initialization and Configuration functions
119   *
120   @verbatim
121  ===============================================================================
122            ##### Initialization and de-initialization functions #####
123  ===============================================================================
124     [..]
125       This section provides functions allowing to configure the internal and external oscillators
126       (HSE, HSI, LSE, LSI, PLL and MCO) and the System busses clocks (SYSCLK).
127 
128     [..] Internal/external clock and PLL configuration
129          (+) HSI (high-speed internal): 64 MHz factory-trimmed RC used through
130              the PLL as System clock source.
131 
132          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG, LPUART,
133              RF system Auto-wakeup from DeepStop modes.
134              clock source.
135 
136          (+) HSE (high-speed external): 32 MHz crystal oscillator.
137 
138          (+) LSE (low-speed external): 32.768 KHz oscillator used as IWDG, RTC, LPUART,
139              RF system Auto-wakeup from DeepStop modes.
140 
141          (+) PLL (clocked by HSI, HSE) providing system clock.
142 
143          (+) MCO (microcontroller clock output): used to output HSI, HSE, SYSCLK,
144              HSI64M_DIV2048, RC64MPLL clock (through a configurable prescaler) on PA5, PA11 & PB15 pins.
145 
146          -@- All the peripheral clocks have an always 16 MHz or 32 MHz to maintain fixed baud rate
147              while system clock is switching from a frequency to another from the System clock (SYSCLK).
148              An always 32 or 16 MHz requested by few peripherals like the MR_BLE radio IP for instance.
149              An always 16 MHz requested by few peripherals like serial interfaces or like flash controller and
150              MR_BLE radio IP (to have a fixed reference clock to manage delays).
151 
152            (+@) A programmable prescaled clock for I2S block, that can be 16 MHz / 32 MHz.
153                 You have to use @ref __HAL_RCC_SPI2I2S_CONFIG(), @ref __HAL_RCC_SPI3I2S_CONFIG and
154                 @ref HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
155 
156          (+) The maximum frequency of the SYSCLK is 64 MHz.
157              The maximum frequency of the CLK_SYS_BLE is 32 MHz.
158 
159   @endverbatim
160 
161            Table 1. Flash Latency vs Clock frequency.
162            +-------------------------------------------------------+
163            | Wait State      |    System  clock frequency (MHz)    |
164            |-----------------|-------------------------------------|
165            |0WS(1 CPU cycles)|         SYSCLK < 38 MHz             |
166            |-----------------|-------------------------------------|
167            |1WS(2 CPU cycles)|         SYSCLK >= 38 MHz            |
168            +-----------------+-------------------------------------+
169 
170   * @{
171   */
172 
173 /**
174   * @brief  Reset the RCC clock configuration to the default reset state.
175   * @note   The default reset state of the clock configuration is given below:
176   *            - HSI 16MHz, PLL OFF
177   * @note   This function doesn't modify the configuration of the
178   *            - Peripheral clocks
179   *            - LSI and LSE clocks
180   * @retval HAL status
181   */
HAL_RCC_DeInit(void)182 HAL_StatusTypeDef HAL_RCC_DeInit(void)
183 {
184   uint32_t tickstart;
185   uint32_t vl_mask;
186 
187   /* If DIRECT_HSE configuration is enabled we need to re-enable the HSI */
188   if (LL_RCC_DIRECT_HSE_IsEnabled())
189   {
190     LL_RCC_DIRECT_HSE_Disable();
191   }
192 
193   /* Get Start Tick*/
194   tickstart = HAL_GetTick();
195 
196   /* Disable the HSE clock source */
197   __HAL_RCC_HSE_CONFIG(RCC_HSE_OFF);
198 
199   /* Wait for HSE READY bit to be reset */
200   while (LL_RCC_HSE_IsReady() != 0U)
201   {
202     if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
203     {
204       return HAL_TIMEOUT;
205     }
206   }
207 
208   /* Get Start Tick*/
209   tickstart = HAL_GetTick();
210 
211   /* Disable the RC64MPLL clock source */
212   LL_RCC_RC64MPLL_Disable();
213 
214   /* Set the System Clock prescaler to reset state */
215   LL_RCC_SetRC64MPLLPrescaler(LL_RCC_RC64MPLL_DIV_4);
216 
217   /* Wait for PLL READY bit to be reset */
218   while (LL_RCC_RC64MPLL_IsReady() != 0U)
219   {
220     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
221     {
222       return HAL_TIMEOUT;
223     }
224   }
225 
226   /* Get Start Tick*/
227   tickstart = HAL_GetTick();
228 
229   /* Insure HSIRDY bit is set */
230   while (LL_RCC_HSI_IsReady() == 0U)
231   {
232     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
233     {
234       return HAL_TIMEOUT;
235     }
236   }
237 
238   /* Clear all interrupt flags */
239   vl_mask = RCC_CIFR_LSIRDYF | RCC_CIFR_LSERDYF | RCC_CIFR_HSIRDYF | RCC_CIFR_HSERDYF | RCC_CIFR_HSIPLLRDYF;
240   LL_RCC_WriteReg(CIFR, vl_mask);
241 
242   /* Clear reset flags */
243   LL_RCC_ClearResetFlags();
244 
245   /* Update SystemCoreClock global variable */
246   SystemCoreClock = HSI_VALUE / 4;
247 
248   /* Adapt Systick interrupt period */
249   if (HAL_InitTick(HAL_GetTickPrio()) != HAL_OK)
250   {
251     return HAL_ERROR;
252   }
253 
254   return HAL_OK;
255 }
256 
257 /**
258   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
259   *         @ref RCC_OscInitTypeDef.
260   * @param  RCC_OscInitStruct  pointer to a @ref RCC_OscInitTypeDef structure that
261   *         contains the configuration information for the RCC Oscillators.
262   * @retval HAL status
263   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)264 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
265 {
266   uint32_t tickstart;
267 
268   /* Check Null pointer */
269   if (RCC_OscInitStruct == NULL)
270   {
271     return HAL_ERROR;
272   }
273 
274   /* Check the parameters */
275   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
276 
277   /*------------------------------- HSI Configuration ------------------------*/
278   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
279   {
280     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
281     __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIState);
282 
283     if(RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
284     {
285       /* Get Start Tick*/
286       tickstart = HAL_GetTick();
287 
288       /* Wait till HSI is disabled */
289       while (LL_RCC_HSI_IsReady() == 1U)
290       {
291         if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
292         {
293           return HAL_TIMEOUT;
294         }
295       }
296     }
297     else
298     {
299       /* Get Start Tick*/
300       tickstart = HAL_GetTick();
301 
302       /* Wait till HSI is enabled */
303       while (LL_RCC_HSI_IsReady() != 1U)
304       {
305         if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
306         {
307           return HAL_TIMEOUT;
308         }
309       }
310     }
311   }
312 
313   /*------------------------------- HSE Configuration ------------------------*/
314   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
315   {
316     /* Check the parameters */
317     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
318 
319     /* Set HSE Capacitor Tuning */
320     LL_RCC_HSE_SetCapacitorTuning(CFG_HW_RCC_HSE_CAPACITOR_TUNE);
321 
322     /* Set HSE Current Control */
323     LL_RCC_HSE_SetCurrentControl(LL_RCC_HSE_CURRENTMAX_3);
324 
325     /* Set the new HSE configuration ---------------------------------------*/
326     __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
327 
328     /* Check the HSE State */
329     if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
330     {
331       /* Get Start Tick*/
332       tickstart = HAL_GetTick();
333 
334       /* Wait till HSE is ready */
335       while (LL_RCC_HSE_IsReady() == 0U)
336       {
337         if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
338         {
339           return HAL_TIMEOUT;
340         }
341       }
342     }
343     else
344     {
345       /* Get Start Tick*/
346       tickstart = HAL_GetTick();
347 
348       /* Wait till HSE is disabled */
349       while (LL_RCC_HSE_IsReady() != 0U)
350       {
351         if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
352         {
353           return HAL_TIMEOUT;
354         }
355       }
356     }
357   }
358 
359   /*--------------------------------- LSI Configuration -----------------------------*/
360   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
361   {
362     /* Check the parameters */
363     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
364 
365     /* Check the LSI State */
366     if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
367     {
368       /* Disable the LSI */
369       __HAL_RCC_LSI_DISABLE();
370       while (__HAL_RCC_GET_LSI_READYFLAG() != 0U);
371 
372       /* Disable the LSE */
373       __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
374 
375       /* Configure the Low Speed Clock to LSI */
376       LL_RCC_LSCO_SetSource(LL_RCC_LSCO_CLKSOURCE_LSI);
377 
378       /*  Enable the Internal Low Speed oscillator (LSI)  */
379       __HAL_RCC_LSI_ENABLE();
380 
381       /* Get Start Tick*/
382       tickstart = HAL_GetTick();
383 
384       /* Wait till LSI is ready */
385       while (__HAL_RCC_GET_LSI_READYFLAG() == 0U)
386       {
387         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
388         {
389           return HAL_TIMEOUT;
390         }
391       }
392     }
393     else
394     {
395 
396       /* Disable the Internal Low Speed oscillator (LSI). */
397       __HAL_RCC_LSI_DISABLE();
398 
399       /* Get Start Tick*/
400       tickstart = HAL_GetTick();
401 
402       /* Wait till LSI is disabled */
403       while (__HAL_RCC_GET_LSI_READYFLAG() != 0U)
404       {
405         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
406         {
407           return HAL_TIMEOUT;
408         }
409       }
410     }
411   }
412 
413   /*------------------------------ LSE Configuration -------------------------*/
414   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
415   {
416 
417     /* Check the parameters */
418     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
419 
420     /* Disable LSI */
421     __HAL_RCC_LSI_DISABLE();
422 
423     /* Disable LSE */
424     __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
425     while (__HAL_RCC_GET_LSE_READYFLAG() != 0);
426 
427     /* Configure the PB12 and PB13 in NO PULL mode */
428     LL_PWR_SetNoPullB(LL_PWR_GPIO_BIT_12 |
429                       LL_PWR_GPIO_BIT_13);
430 
431     /* Configure the Low Speed Clock to LSE */
432     LL_RCC_LSCO_SetSource(LL_RCC_LSCO_CLKSOURCE_LSE);
433 
434     /* Set LSE oscillator drive capability */
435     __HAL_RCC_LSEDRIVE_CONFIG(LSE_DRIVE_LEVEL);
436 
437 
438     /* Set the new LSE state */
439     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
440 
441     /* Check the LSE State */
442     if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
443     {
444       /* Get Start Tick*/
445       tickstart = HAL_GetTick();
446 
447       /* Wait till LSE is ready */
448       while (__HAL_RCC_GET_LSE_READYFLAG() == 0U)
449       {
450         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
451         {
452           return HAL_TIMEOUT;
453         }
454       }
455     }
456     else
457     {
458       /* Get Start Tick*/
459       tickstart = HAL_GetTick();
460 
461       /* Wait till LSE is disabled */
462       while (__HAL_RCC_GET_LSE_READYFLAG() != 0U)
463       {
464         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
465         {
466           return HAL_TIMEOUT;
467         }
468       }
469     }
470   }
471 
472   /*------------------------------ LSE Bypass Configuration ------------------*/
473   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE_BYPASS) == RCC_OSCILLATORTYPE_LSE_BYPASS)
474   {
475 
476     /* Check the parameters */
477     assert_param(IS_RCC_LSE_BYPASS(RCC_OscInitStruct->LSEBYPASSState));
478 
479     /* Set the new LSE Bypass configuration -----------------------------------------*/
480     __HAL_RCC_LSE_BYPASS_CONFIG(RCC_OscInitStruct->LSEBYPASSState);
481 
482     /* Check the LSE Bypass State */
483     if (RCC_OscInitStruct->LSEBYPASSState != RCC_LSE_OFF)
484     {
485       /* Get Start Tick*/
486       tickstart = HAL_GetTick();
487 
488       /* Wait till LSE is ready */
489       while (LL_RCC_LSE_IsBypassEnabled() == 0U)
490       {
491         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
492         {
493           return HAL_TIMEOUT;
494         }
495       }
496     }
497     else
498     {
499       /* Get Start Tick*/
500       tickstart = HAL_GetTick();
501 
502       /* Wait till LSE is disabled */
503       while (LL_RCC_LSE_IsBypassEnabled() != 0U)
504       {
505         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
506         {
507           return HAL_TIMEOUT;
508         }
509       }
510     }
511   }
512 
513   return HAL_OK;
514 }
515 
516 
517 /**
518   * @brief  Initialize the system clock according to the specified
519   *         parameters in the RCC_ClkInitStruct.
520   * @param  RCC_ClkInitStruct  pointer to a @ref RCC_ClkInitTypeDef structure that
521   *         contains the configuration information for the RCC peripheral.
522   * @param  FLatency  FLASH Latency
523   *          This parameter can be one of the following values:
524   *            @arg FLASH_WAIT_STATES_0   FLASH 0 wait state cycle
525   *            @arg FLASH_WAIT_STATES_1   FLASH 1 wait state cycle
526   *
527   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
528   *         and updated within this function
529   *
530   * @note   A switch from one clock source to another occurs only if the target
531   *         clock source is ready (clock stable after startup delay).
532   *         If a clock source which is not yet ready is selected, the switch will
533   *         occur when the clock source is ready.
534   *
535   * @note   You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
536   *         currently used as system clock source.
537   *
538   * @retval HAL status
539   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)540 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
541 {
542   uint32_t tickstart;
543 
544   /* Check Null pointer */
545   if (RCC_ClkInitStruct == NULL)
546   {
547     return HAL_ERROR;
548   }
549 
550   /* Check the parameters */
551   assert_param(IS_FLASH_WAIT_STATES(FLatency));
552 
553   /* Set FALSH_WAIT_STATES_1 */
554   __HAL_FLASH_SET_WAIT_STATES(FLatency);
555 
556   /*------------------------- SYSCLK Configuration ---------------------------*/
557   assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
558   assert_param(IS_RCC_SYSCLK_DIVIDER(RCC_ClkInitStruct->SYSCLKDivider));
559 
560   /* HSI is selected as System Clock Source */
561   if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
562   {
563     LL_RCC_HSI_Enable();
564 
565     /* Check the HSI ready flag */
566     if (LL_RCC_HSI_IsReady() == 0U)
567     {
568       return HAL_ERROR;
569     }
570 
571     /* Disable the RC64MPLL*/
572     __HAL_RCC_RC64MPLL_DISABLE();
573 
574     /* Configure the RC64MPLL multiplication factor */
575     __HAL_RCC_RC64MPLL_PRESC_CONFIG(RCC_ClkInitStruct->SYSCLKDivider);
576   }
577 
578   /* RC64MPLL is selected as System Clock Source */
579   if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_RC64MPLL)
580   {
581     /* Check the HSI ready flag */
582     if (LL_RCC_HSI_IsReady() == 0U)
583     {
584       return HAL_ERROR;
585     }
586 
587     /* Check the HSE ready flag */
588     if (LL_RCC_HSE_IsReady() == 0U)
589     {
590       return HAL_ERROR;
591     }
592 
593     /* Enable the RC64MPLL*/
594     __HAL_RCC_RC64MPLL_ENABLE();
595 
596     /* Get Start Tick*/
597     tickstart = HAL_GetTick();
598 
599     /* Wait till RC64MPLL is ready */
600     while (LL_RCC_RC64MPLL_IsReady() == 0)
601     {
602       if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
603       {
604         return HAL_TIMEOUT;
605       }
606     }
607 
608     /* Configure the RC64MPLL multiplication factor */
609     __HAL_RCC_RC64MPLL_PRESC_CONFIG(RCC_ClkInitStruct->SYSCLKDivider);
610   }
611 
612   /* DIRECT_HSE is selected as System Clock Source */
613   if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_DIRECT_HSE)
614   {
615     /* Enable the DIRECT_HSE configuration */
616     LL_RCC_DIRECT_HSE_Enable();
617 
618     /* Check the HSI ready flag */
619     if (LL_RCC_HSI_IsReady() != 0U)
620     {
621       return HAL_ERROR;
622     }
623 
624     /* Check the HSE ready flag */
625     if (LL_RCC_HSE_IsReady() == 0U)
626     {
627       return HAL_ERROR;
628     }
629 
630     /* Configure the DIRECT_HSE multiplication factor */
631     __HAL_RCC_DIRECT_HSE_PRESC_CONFIG(RCC_ClkInitStruct->SYSCLKDivider);
632   }
633 
634   /*----------------------- FLASH Latency Configuration ------------------------*/
635   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
636      must be correctly programmed according to the frequency of the FLASH clock */
637 
638   /* Setup flash wait states because according the system clock frequency */
639   if (FLatency != __HAL_FLASH_GET_WAIT_STATES())
640   {
641     /* Program the new number of wait states to the LATENCY bits in the FLASH_CONFIG register */
642     __HAL_FLASH_SET_WAIT_STATES(FLatency);
643 
644     /* Get Start Tick*/
645     tickstart = HAL_GetTick();
646 
647     /* Check that the new number of wait states is taken into account to access the Flash
648        memory by reading the FLASH_CONFIG register */
649     while (__HAL_FLASH_GET_WAIT_STATES() != FLatency)
650     {
651       if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
652       {
653         return HAL_TIMEOUT;
654       }
655     }
656   }
657 
658   /*---------------------------------------------------------------------------*/
659 
660   /* Update the SystemCoreClock global variable */
661   for (volatile int i = 0; i < 6; i++)
662   {
663     __asm("NOP");
664   }
665   SystemCoreClockUpdate();
666 
667   /* Configure the source of time base considering new system clocks settings*/
668   return HAL_InitTick(HAL_GetTickPrio());
669 }
670 
671 /**
672   * @}
673   */
674 
675 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
676   *  @brief   RCC clocks control functions
677   *
678 @verbatim
679  ===============================================================================
680                       ##### Peripheral Control functions #####
681  ===============================================================================
682     [..]
683     This subsection provides a set of functions allowing to:
684 
685     (+) Output clock to MCO pin.
686     (+) Retrieve current clock frequencies.
687 
688 @endverbatim
689   * @{
690   */
691 
692 /**
693   * @brief  Select the clock source to output on MCO1 pin(PA5) or MC02 pin (PA11) or MCO3 pin (PB14/PB15).
694   * @note   PA5, PA11 or PB14/PB15 should be configured in alternate function mode.
695   * @param  RCC_MCOx  specifies the output direction for the clock source.
696   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA5)
697   *            @arg @ref RCC_MCO2  Clock source to output on MCO2 pin(PA11)
698   *            @arg @ref RCC_MCO3  Clock source to output on MCO3 pin(PB14/PB15)
699   * @param  RCC_MCOSource  specifies the clock source to output.
700   *          This parameter can be one of the following values:
701   *            @arg @ref RCC_MCOSOURCE_NOCLOCK         MCO output disabled, no clock on MCO
702   *            @arg @ref RCC_MCO1SOURCE_SYSCLK          System  clock selected as MCO source
703   *            @arg @ref RCC_MCO1SOURCE_HSI             HSI clock selected as MCO source
704   *            @arg @ref RCC_MCO1SOURCE_HSE             HSE clock selected as MCO source
705   *            @arg @ref RCC_MCOSOURCE_RC64MPLL        RC64MPLL clock selected as MCO source
706   *            @arg @ref RCC_MCOSOURCE_HSI64M_DIV2048  HSI64M_DIV2048 clock selected as MCO source
707   *            @arg @ref RCC_MCOSOURCE_SMPS            SMPS clock selected as MCO source
708   *            @arg @ref RCC_MCOSOURCE_ADC             ADC clock before stabilization selected as MCO source
709   * @param  RCC_MCODiv  specifies the MCO prescaler.
710   *          This parameter can be one of the following values:
711   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
712   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
713   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
714   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
715   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
716   *            @arg @ref RCC_MCODIV_32  division by 32 applied to MCO clock
717   * @retval None
718   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)719 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
720 {
721   GPIO_InitTypeDef GPIO_InitStruct;
722 
723   /* Check the parameters */
724   assert_param(IS_RCC_MCO(RCC_MCOx));
725   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
726   assert_param(IS_RCC_MCOSOURCE(RCC_MCOSource));
727 
728   /* Common GPIO init parameters */
729   GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
730   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
731   GPIO_InitStruct.Pull      = GPIO_NOPULL;
732 
733 #if defined(MCO1_PIN)
734   if (RCC_MCOx == RCC_MCO1)
735   {
736     /* MCO1 Clock Enable */
737     __MCO1_CLK_ENABLE();
738     /* Configure the MCO1 pin in alternate function mode */
739     GPIO_InitStruct.Pin       = MCO1_PIN;
740     GPIO_InitStruct.Alternate = MCO1_GPIO_AF;
741     HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
742   }
743 #endif
744 
745   if (RCC_MCOx == RCC_MCO2)
746   {
747     /* MCO2 Clock Enable */
748     __MCO2_CLK_ENABLE();
749     /* Configure the MCO2 pin in alternate function mode */
750     GPIO_InitStruct.Pin       = MCO2_PIN;
751     GPIO_InitStruct.Alternate = MCO2_GPIO_AF;
752     HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct);
753   }
754 
755   if (RCC_MCOx == RCC_MCO3)
756   {
757     /* MCO3 Clock Enable */
758     __MCO3_CLK_ENABLE();
759     /* Configure the MCO3 pin in alternate function mode */
760     GPIO_InitStruct.Pin       = MCO3_PIN;
761     GPIO_InitStruct.Alternate = MCO3_GPIO_AF;
762     HAL_GPIO_Init(MCO3_GPIO_PORT, &GPIO_InitStruct);
763   }
764 
765   /* Mask MCOSEL[] and CCOPRE[] bits then set MCO clock source and prescaler */
766   LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
767 }
768 
769 /**
770   * @brief  Return the SYSCLK frequency.
771   *
772   * @note   The system  computed by this function is not the real
773   *         frequency in the chip. It is calculated based on the predefined
774   *         constant and the selected clock source. The return value is the
775   *         content of the SystemCoreClock CMSIS variable
776   *
777   * @retval SYSCLK frequency
778   */
HAL_RCC_GetSysClockFreq(void)779 uint32_t HAL_RCC_GetSysClockFreq(void)
780 {
781   return SystemCoreClock;
782 }
783 
784 /**
785   * @brief  Configure the RCC_OscInitStruct according to the internal
786   *         RCC configuration registers.
787   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
788   *         will be configured.
789   * @retval None
790   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)791 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
792 {
793   /* Check the parameters */
794   assert_param(RCC_OscInitStruct != (void *)NULL);
795 
796   /* Set all possible values for the Oscillator type parameter ---------------*/
797   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | \
798                                       RCC_OSCILLATORTYPE_LSE | \
799                                       RCC_OSCILLATORTYPE_LSI | \
800                                       RCC_OSCILLATORTYPE_LSE_BYPASS;
801 
802 
803   /* Get the HSE configuration -----------------------------------------------*/
804   if (LL_RCC_HSE_IsEnabled())
805   {
806     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
807   }
808   else
809   {
810     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
811   }
812 
813   /* Get the LSE configuration -----------------------------------------------*/
814   if (LL_RCC_LSE_IsEnabled())
815   {
816     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
817   }
818   else
819   {
820     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
821   }
822 
823   /* Get the LSE Bypass configuration ----------------------------------------*/
824   if (LL_RCC_LSE_IsBypassEnabled())
825   {
826     RCC_OscInitStruct->LSEBYPASSState = RCC_LSE_BYPASS_ON;
827   }
828   else
829   {
830     RCC_OscInitStruct->LSEBYPASSState = RCC_LSE_BYPASS_OFF;
831   }
832 
833   /* Get the LSI configuration -----------------------------------------------*/
834   if (LL_RCC_LSI_IsEnabled())
835   {
836     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
837   }
838   else
839   {
840     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
841   }
842 }
843 
844 /**
845   * @brief  Configure the RCC_ClkInitStruct according to the internal
846   *         RCC configuration registers.
847   * @param  RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
848   *         will be configured.
849   * @param  pFLatency Pointer on the Flash Latency.
850   * @retval None
851   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)852 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
853 {
854   /* Check the parameters */
855   assert_param(RCC_ClkInitStruct != (void *)NULL);
856   assert_param(pFLatency != (void *)NULL);
857 
858   /* Set all possible values for the Clock type parameter --------------------*/
859 
860   /* Get the SYSCLK configuration --------------------------------------------*/
861   if (LL_RCC_DIRECT_HSE_IsEnabled())
862   {
863     RCC_ClkInitStruct->SYSCLKSource = RCC_SYSCLKSOURCE_DIRECT_HSE;
864   }
865   else
866   {
867     RCC_ClkInitStruct->SYSCLKSource = RCC_SYSCLKSOURCE_RC64MPLL;
868   }
869 
870   /* Get the SYSCLK Divider --------------------------------------------------*/
871 #if defined(RCC_CFGR_CLKSYSDIV_STATUS)
872   RCC_ClkInitStruct->SYSCLKDivider = LL_RCC_GetCLKSYSPrescalerStatus();
873 #else
874   if (LL_RCC_DIRECT_HSE_IsEnabled())
875   {
876     RCC_ClkInitStruct->SYSCLKDivider = LL_RCC_GetDirectHSEPrescaler();
877   }
878   else
879   {
880     RCC_ClkInitStruct->SYSCLKDivider = LL_RCC_GetRC64MPLLPrescaler();
881   }
882 #endif
883 
884   /* Get the Flash Wait State (Latency) configuration ------------------------*/
885   *pFLatency = __HAL_FLASH_GET_WAIT_STATES();
886 }
887 
888 /**
889   * @}
890   */
891 
892 /**
893   * @}
894   */
895 
896 #endif /* HAL_RCC_MODULE_ENABLED */
897 /**
898   * @}
899   */
900 
901 /**
902   * @}
903   */
904