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