1 /**
2 ******************************************************************************
3 * @file stm32wlxx_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) 2020 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 Multiple Speed Internal oscillator
28 (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
29 and I-Cache are disabled, and all peripherals are off except internal
30 SRAM, Flash and JTAG.
31
32 (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) buses:
33 all peripherals mapped on these buses are running at MSI speed.
34 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
35 (+) All GPIOs are in analog mode, except the JTAG pins which
36 are assigned to be used for debug purpose.
37
38 [..]
39 Once the device started from reset, the user application has to:
40 (+) Configure clock source to be used to drive the System clock
41 (if the application needs higher frequency/performance)
42 (+) Configure the System clock frequency and Flash settings
43 (+) Configure the AHB and APB buses prescalers
44 (+) Enable the clock for the peripheral(s) to be used
45 (+) Configure the clock source(s) for peripherals which clocks are not
46 derived from the System clock (RTC, ADC, RNG, I2S2, USARTx, LPUART1, LPTIMx, I2Cx)
47
48 @endverbatim
49 ******************************************************************************
50 */
51
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32wlxx_hal.h"
54
55 /** @addtogroup STM32WLxx_HAL_Driver
56 * @{
57 */
58
59 /** @defgroup RCC RCC
60 * @brief RCC HAL module driver
61 * @{
62 */
63
64 #ifdef HAL_RCC_MODULE_ENABLED
65
66 /* Private typedef -----------------------------------------------------------*/
67 /* Private define ------------------------------------------------------------*/
68 /** @defgroup RCC_Private_Constants RCC Private Constants
69 * @{
70 */
71 #define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
72 #define HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
73 #define MSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
74 #define LSI_TIMEOUT_VALUE (17U) /* 17 ms (16 ms starting time + 1) */
75 #define PRESCALER_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
76 #define LATENCY_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
77 #define CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */
78
79 #define PLLSOURCE_NONE (0U)
80 #define MEGA_HZ (1000000U) /* Division factor to convert Hz in Mhz */
81
82 #define RCC_PLLCFR_RESET_VALUE (RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLP_1 | RCC_PLLCFGR_PLLN_0)
83 #define RCC_EXTCFGR_RESET_VALUE (0x00030000U)
84 /**
85 * @}
86 */
87
88 /* Private macro -------------------------------------------------------------*/
89 /** @defgroup RCC_Private_Macros RCC Private Macros
90 * @{
91 */
92 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__) ((__RCC_MCOx__) & GPIO_PIN_MASK)
93
94 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
95
96 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
97
98 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__) (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
99
100 #define __COUNTOF(_A_) (sizeof(_A_) / sizeof(*(_A_)))
101 /**
102 * @}
103 */
104
105 /* Private variables ---------------------------------------------------------*/
106 /* Private function prototypes -----------------------------------------------*/
107 /** @defgroup RCC_Private_Functions RCC Private Functions
108 * @{
109 */
110 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range);
111 static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage);
112 /**
113 * @}
114 */
115
116 /* Exported functions --------------------------------------------------------*/
117
118 /** @defgroup RCC_Exported_Functions RCC Exported Functions
119 * @{
120 */
121
122 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
123 * @brief Initialization and Configuration functions
124 *
125 @verbatim
126 ===============================================================================
127 ##### Initialization and de-initialization functions #####
128 ===============================================================================
129 [..]
130 This section provides functions allowing to configure the internal and external oscillators
131 (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, HCLK1, HCLK2, HCLK3, PCLK1
132 and PCLK2).
133
134 [..] Internal/external clock and PLL configuration
135 (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
136 the PLL as System clock source.
137
138 (+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
139 The number of flash wait states is automatically adjusted when MSI range is updated with
140 HAL_RCC_OscConfig() and the MSI is used as System clock source.
141
142 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
143 clock source.
144
145 (+) HSE (high-speed external): 32 MHz crystal oscillator used directly or
146 through the PLL as System clock source. It is used also as RF clock source
147 Can be used also optionally as RTC clock source.
148
149 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally to drive RTC used for
150 Auto-wakeup from Stop and Standby modes, or the real-time clock (RTCCLK).
151
152 (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
153 (++) The first output is used to generate the high speed system clock (up to 48MHz).
154 (++) The second output is used to generate the clock for I2S2 and the random analog generator (<=48 MHz)
155 (++) The third output is used to generate a clock on ADC interface.
156
157 (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
158 (HSE used directly or through PLL as System clock source), the System clock
159 is automatically switched to MSI or the HSI oscillator (depending on the
160 STOPWUCK configuration) and an interrupt is generated if enabled.
161 The interrupt is linked to the CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector.
162
163 (+) LSECSS: once enabled, if a LSE clock failure occurs, the LSE
164 clock is no longer supplied to the RTC but no hardware action is made to the registers. If the
165 MSI was in PLL-mode, this mode is disabled.
166 In Standby mode a wakeup is generated. In other modes an interrupt can be sent to wakeup
167 the software
168
169 (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE (before and
170 after stabilization), SYSCLK, or main PLL clocks (through a configurable prescaler) on PA8 pin.
171
172 [..] System, AHB and APB buses clocks configuration
173 (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
174 HSE and main PLL.
175 The AHB clock (HCLK1) is derived from System clock through configurable
176 prescaler and used to clock the CPU1, memory and peripherals mapped
177 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
178 from AHB clock through configurable prescalers and used to clock
179 the peripherals mapped on these buses. You can use
180 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
181 The AHB3 clock (HCLK3) is derived from System clock through configurable
182 prescaler and used to clock the FLASH. APB3 (PCLK3) is derived from AHB3 clock.
183
184 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
185
186 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock divided by 32.
187 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
188 to configure this clock.
189
190 (+@) IWDG clock which is always the LSI clock.
191
192 (+) The maximum frequency of the SYSCLK, HCLK1, HCLK2, HCLK3, PCLK1 and PCLK2 is 48 MHz.
193 The clock source frequency should be adapted depending on the device voltage range
194 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
195
196 @endverbatim
197
198 Table 1. HCLK3 clock frequency.
199 +--------------------------------------------------------+
200 | Latency | HCLK3 clock frequency (MHz) |
201 | |-------------------------------------|
202 | | voltage range 1 | voltage range 2 |
203 | | 1.2 V | 1.0 V |
204 |------------------|------------------|------------------|
205 |0WS(1 HCLK cycles | HCLK3 <= 18 | HCLK3 <= 6 |
206 |------------------|------------------|------------------|
207 |1WS(2 HCLK cycles)| HCLK3 <= 36 | HCLK3 <= 12 |
208 |------------------|------------------|------------------|
209 |2WS(3 HCLK cycles)| HCLK3 <= 48 | HCLK3 <= 16 |
210 |------------------|------------------|------------------|
211
212 * @{
213 */
214
215 /**
216 * @brief Reset the RCC clock configuration to the default reset state.
217 * @note The default reset state of the clock configuration is given below:
218 * - MSI ON and used as system clock source
219 * - HSE, HSI, PLL OFF
220 * - HCLK1, HCLK2, HCLK3, PCLK1 and PCLK2 prescalers set to 1.
221 * - CSS, MCO OFF
222 * - All interrupts disabled
223 * @note This function doesn't modify the configuration of the
224 * - Peripheral clocks
225 * - LSI, LSE and RTC clocks
226 * @retval HAL status
227 */
HAL_RCC_DeInit(void)228 HAL_StatusTypeDef HAL_RCC_DeInit(void)
229 {
230 uint32_t tickstart;
231
232 /* Get Start Tick*/
233 tickstart = HAL_GetTick();
234
235 /* Set MSION bit */
236 LL_RCC_MSI_Enable();
237
238 /* Wait till MSI is ready */
239 while (LL_RCC_MSI_IsReady() == 0U)
240 {
241 if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
242 {
243 return HAL_TIMEOUT;
244 }
245 }
246
247 /* Set MSIRANGE default value */
248 LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6);
249
250 /* Set MSITRIM bits to the reset value*/
251 LL_RCC_MSI_SetCalibTrimming(RCC_MSICALIBRATION_DEFAULT);
252
253 /* Set HSITRIM bits to the reset value*/
254 LL_RCC_HSI_SetCalibTrimming(RCC_HSICALIBRATION_DEFAULT);
255
256 /* Get Start Tick*/
257 tickstart = HAL_GetTick();
258
259 /* Reset CFGR register (MSI is selected as system clock source) */
260 CLEAR_REG(RCC->CFGR);
261
262 /* Wait till MSI oscillator used as system clock */
263 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI)
264 {
265 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
266 {
267 return HAL_TIMEOUT;
268 }
269 }
270
271 /* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLON, HSEPRE bits */
272 CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON);
273
274 /* Get Start Tick*/
275 tickstart = HAL_GetTick();
276
277 /* Wait till HSE is disabled */
278 while (LL_RCC_HSE_IsReady() != 0U)
279 {
280 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
281 {
282 return HAL_TIMEOUT;
283 }
284 }
285
286 /* Reset HSEBYPPWR bit once HSE is OFF */
287 LL_RCC_HSE_DisableTcxo();
288
289 /* Get Start Tick*/
290 tickstart = HAL_GetTick();
291
292 /* Wait till PLL is fully stopped */
293 while (LL_RCC_PLL_IsReady() != 0U)
294 {
295 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
296 {
297 return HAL_TIMEOUT;
298 }
299 }
300
301 /* once PLL is OFF, reset PLLCFGR register to default value */
302 WRITE_REG(RCC->PLLCFGR, RCC_PLLCFR_RESET_VALUE);
303
304 /* Disable all interrupts */
305 CLEAR_REG(RCC->CIER);
306
307 /* Clear all flags */
308 WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
309
310 /* EXTCFGR reset*/
311 WRITE_REG(RCC->EXTCFGR, RCC_EXTCFGR_RESET_VALUE);
312
313 /* Update the SystemCoreClock global variable */
314 SystemCoreClock = MSI_VALUE;
315
316 /* Adapt Systick interrupt period */
317 if (HAL_InitTick(uwTickPrio) != HAL_OK)
318 {
319 return HAL_ERROR;
320 }
321 else
322 {
323 return HAL_OK;
324 }
325 }
326
327 /**
328 * @brief Initialize the RCC Oscillators according to the specified parameters in the
329 * @ref RCC_OscInitTypeDef.
330 * @param RCC_OscInitStruct pointer to a @ref RCC_OscInitTypeDef structure that
331 * contains the configuration information for the RCC Oscillators.
332 * @note The PLL is not disabled when used as system clock.
333 * @retval HAL status
334 */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)335 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
336 {
337 uint32_t tickstart;
338 uint32_t sysclk_source;
339 uint32_t pll_config;
340 HAL_StatusTypeDef status;
341
342 /* Check Null pointer */
343 if (RCC_OscInitStruct == NULL)
344 {
345 return HAL_ERROR;
346 }
347
348 /* Check the parameters */
349 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
350
351 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
352 pll_config = __HAL_RCC_GET_PLL_OSCSOURCE();
353
354 /*----------------------------- MSI Configuration --------------------------*/
355 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
356 {
357 /* Check the parameters */
358 assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
359 assert_param(IS_RCC_MSI_CALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
360 assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
361
362 /* When the MSI is used as system clock it will not be disabled */
363 if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
364 ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_MSI)))
365 {
366 if (RCC_OscInitStruct->MSIState == RCC_MSI_OFF)
367 {
368 return HAL_ERROR;
369 }
370 /* Otherwise, just the calibration and MSI range change are allowed */
371 else
372 {
373 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
374 must be correctly programmed according to the frequency of the AHB3 clock
375 and the supply voltage of the device. */
376 if (RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
377 {
378 /* First increase number of wait states update if necessary */
379 if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
380 {
381 return HAL_ERROR;
382 }
383
384 /* Selects the Multiple Speed oscillator (MSI) clock range .*/
385 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
386 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
387 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
388 }
389 else
390 {
391 /* Else, keep current flash latency while decreasing applies */
392 /* Selects the Multiple Speed oscillator (MSI) clock range. */
393 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
394 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
395 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
396
397 /* Decrease number of wait states update if necessary */
398 if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
399 {
400 return HAL_ERROR;
401 }
402 }
403
404 /* Update the SystemCoreClock global variable */
405 SystemCoreClock = HAL_RCC_GetHCLKFreq();
406
407 /* Configure the source of time base considering new system clocks settings */
408 status = HAL_InitTick(uwTickPrio);
409 if (status != HAL_OK)
410 {
411 return status;
412 }
413 }
414 }
415 else
416 {
417 /* Check the MSI State */
418 if (RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
419 {
420 /* Enable the Internal High Speed oscillator (MSI). */
421 __HAL_RCC_MSI_ENABLE();
422
423 /* Get timeout */
424 tickstart = HAL_GetTick();
425
426 /* Wait till MSI is ready */
427 while (LL_RCC_MSI_IsReady() == 0U)
428 {
429 if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
430 {
431 return HAL_TIMEOUT;
432 }
433 }
434
435 /* Selects the Multiple Speed oscillator (MSI) clock range. */
436 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
437 /* Adjusts the Multiple Speed oscillator (MSI) calibration value. */
438 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
439
440 }
441 else
442 {
443 /* Disable the Internal High Speed oscillator (MSI). */
444 __HAL_RCC_MSI_DISABLE();
445
446 /* Get timeout */
447 tickstart = HAL_GetTick();
448
449 /* Wait till MSI is disabled */
450 while (LL_RCC_MSI_IsReady() != 0U)
451 {
452 if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
453 {
454 return HAL_TIMEOUT;
455 }
456 }
457 }
458 }
459 }
460
461 /*------------------------------- HSE Configuration ------------------------*/
462 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
463 {
464 /* Check the parameters */
465 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
466
467 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
468 if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE) ||
469 ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSE)))
470 {
471 if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
472 {
473 return HAL_ERROR;
474 }
475 }
476 else
477 {
478 /* Set the new HSE configuration ---------------------------------------*/
479 /* Check HSE division factor */
480 assert_param(IS_RCC_HSEDIV(RCC_OscInitStruct->HSEDiv));
481
482 /* Set HSE division factor */
483 MODIFY_REG(RCC->CR, RCC_CR_HSEPRE, RCC_OscInitStruct->HSEDiv);
484
485 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
486
487 /* Check the HSE State */
488 if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
489 {
490 /* Get Start Tick */
491 tickstart = HAL_GetTick();
492
493 /* Wait till HSE is ready */
494 while (LL_RCC_HSE_IsReady() == 0U)
495 {
496 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
497 {
498 return HAL_TIMEOUT;
499 }
500 }
501 }
502 else
503 {
504 /* Get Start Tick */
505 tickstart = HAL_GetTick();
506
507 /* Wait till HSE is disabled */
508 while (LL_RCC_HSE_IsReady() != 0U)
509 {
510 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
511 {
512 return HAL_TIMEOUT;
513 }
514 }
515 }
516 }
517 }
518
519 /*----------------------------- HSI Configuration --------------------------*/
520 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
521 {
522 /* Check the parameters */
523 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
524 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
525
526 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
527 if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI) ||
528 ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSI)))
529 {
530 /* When HSI is used as system clock it will not be disabled */
531 if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
532 {
533 return HAL_ERROR;
534 }
535 /* Otherwise, just the calibration is allowed */
536 else
537 {
538 /* Adjusts the Internal High Speed oscillator (HSI) calibration value. */
539 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
540 }
541 }
542 else
543 {
544 /* Check the HSI State */
545 if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
546 {
547 /* Enable the Internal High Speed oscillator (HSI). */
548 __HAL_RCC_HSI_ENABLE();
549
550 /* Get Start Tick*/
551 tickstart = HAL_GetTick();
552
553 /* Wait till HSI is ready */
554 while (LL_RCC_HSI_IsReady() == 0U)
555 {
556 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
557 {
558 return HAL_TIMEOUT;
559 }
560 }
561
562 /* Adjusts the Internal High Speed oscillator (HSI) calibration value. */
563 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
564 }
565 else
566 {
567 /* Disable the Internal High Speed oscillator (HSI). */
568 __HAL_RCC_HSI_DISABLE();
569
570 /* Get Start Tick*/
571 tickstart = HAL_GetTick();
572
573 /* Wait till HSI is disabled */
574 while (LL_RCC_HSI_IsReady() != 0U)
575 {
576 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
577 {
578 return HAL_TIMEOUT;
579 }
580 }
581 }
582 }
583 }
584
585 /*------------------------------ LSI Configuration -------------------------*/
586 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
587 {
588 /* Check the parameters */
589 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
590
591 /* Check the LSI State */
592 if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
593 {
594 uint32_t csr_temp = RCC->CSR;
595
596 /* Check LSI division factor */
597 assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv));
598
599 if (RCC_OscInitStruct->LSIDiv != (csr_temp & RCC_CSR_LSIPRE))
600 {
601 if (((csr_temp & RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY) && \
602 ((csr_temp & RCC_CSR_LSION) != RCC_CSR_LSION))
603 {
604 /* If LSIRDY is set while LSION is not enabled,
605 LSIPRE can't be updated */
606 return HAL_ERROR;
607 }
608
609 /* Turn off LSI before changing RCC_CSR_LSIPRE */
610 if ((csr_temp & RCC_CSR_LSION) == RCC_CSR_LSION)
611 {
612 __HAL_RCC_LSI_DISABLE();
613
614 /* Get Start Tick*/
615 tickstart = HAL_GetTick();
616
617 /* Wait till LSI is disabled */
618 while (LL_RCC_LSI_IsReady() != 0U)
619 {
620 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
621 {
622 return HAL_TIMEOUT;
623 }
624 }
625 }
626
627 /* Set LSI division factor */
628 MODIFY_REG(RCC->CSR, RCC_CSR_LSIPRE, RCC_OscInitStruct->LSIDiv);
629 }
630
631 /* Enable the Internal Low Speed oscillator (LSI). */
632 __HAL_RCC_LSI_ENABLE();
633
634 /* Get Start Tick */
635 tickstart = HAL_GetTick();
636
637 /* Wait till LSI is ready */
638 while (LL_RCC_LSI_IsReady() == 0U)
639 {
640 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
641 {
642 return HAL_TIMEOUT;
643 }
644 }
645 }
646 else
647 {
648 /* Disable the Internal Low Speed oscillator (LSI). */
649 __HAL_RCC_LSI_DISABLE();
650
651 /* Get Start Tick */
652 tickstart = HAL_GetTick();
653
654 /* Wait till LSI is disabled */
655 while (LL_RCC_LSI_IsReady() != 0U)
656 {
657 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
658 {
659 return HAL_TIMEOUT;
660 }
661 }
662 }
663 }
664
665 /*------------------------------ LSE Configuration -------------------------*/
666 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
667 {
668 /* Check the parameters */
669 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
670
671 /* Update LSE configuration in Backup Domain control register */
672 /* Requires to enable write access to Backup Domain of necessary */
673
674 if (LL_PWR_IsEnabledBkUpAccess() == 0U)
675 {
676 /* Enable write access to Backup domain */
677 HAL_PWR_EnableBkUpAccess();
678
679 /* Wait for Backup domain Write protection disable */
680 tickstart = HAL_GetTick();
681
682 while (LL_PWR_IsEnabledBkUpAccess() == 0U)
683 {
684 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
685 {
686 return HAL_TIMEOUT;
687 }
688 }
689 }
690
691 /* Set the new LSE configuration -----------------------------------------*/
692 if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
693 {
694 /* Enable LSE bypasss (if requested) */
695 if ((RCC_OscInitStruct->LSEState == RCC_LSE_BYPASS)
696 || (RCC_OscInitStruct->LSEState == RCC_LSE_BYPASS_RTC_ONLY))
697 {
698 /* LSE oscillator bypass enable */
699 SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
700 }
701
702 /* Get Start Tick */
703 tickstart = HAL_GetTick();
704
705 /* LSE oscillator enable */
706 SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
707
708 /* Wait till LSE is ready */
709 while (LL_RCC_LSE_IsReady() == 0U)
710 {
711 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
712 {
713 return HAL_TIMEOUT;
714 }
715 }
716
717 /* Enable LSE system clock (if requested) */
718 if ((RCC_OscInitStruct->LSEState == RCC_LSE_ON)
719 || (RCC_OscInitStruct->LSEState == RCC_LSE_BYPASS))
720 {
721 /* Get Start Tick */
722 tickstart = HAL_GetTick();
723
724 SET_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
725
726 /* Wait till LSESYS is ready */
727 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) == 0U)
728 {
729 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
730 {
731 return HAL_TIMEOUT;
732 }
733 }
734 }
735 else
736 {
737 /* Get Start Tick */
738 tickstart = HAL_GetTick();
739
740 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
741
742 /* Wait till LSESYSRDY is cleared */
743 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
744 {
745 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
746 {
747 return HAL_TIMEOUT;
748 }
749 }
750 }
751 }
752 else
753 {
754 /* Get Start Tick */
755 tickstart = HAL_GetTick();
756
757 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
758
759 /* Wait till LSESYSRDY is cleared */
760 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
761 {
762 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
763 {
764 return HAL_TIMEOUT;
765 }
766 }
767
768 /* Get Start Tick */
769 tickstart = HAL_GetTick();
770
771 /* LSE oscillator disable */
772 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
773
774 /* Wait till LSE is disabled */
775 while (LL_RCC_LSE_IsReady() != 0U)
776 {
777 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
778 {
779 return HAL_TIMEOUT;
780 }
781 }
782 }
783 }
784
785 /*-------------------------------- PLL Configuration -----------------------*/
786 /* Check the parameters */
787 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
788
789 if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
790 {
791 /* Check if the PLL is used as system clock or not */
792 if (sysclk_source != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
793 {
794 if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
795 {
796 /* Check the parameters */
797 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
798 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
799 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
800 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
801 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
802 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
803
804 /* Disable the main PLL. */
805 __HAL_RCC_PLL_DISABLE();
806
807 /* Get Start Tick */
808 tickstart = HAL_GetTick();
809
810 /* Wait till PLL is ready */
811 while (LL_RCC_PLL_IsReady() != 0U)
812 {
813 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
814 {
815 return HAL_TIMEOUT;
816 }
817 }
818
819 /* Configure the main PLL clock source, multiplication and division factors. */
820 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
821 RCC_OscInitStruct->PLL.PLLM,
822 RCC_OscInitStruct->PLL.PLLN,
823 RCC_OscInitStruct->PLL.PLLP,
824 RCC_OscInitStruct->PLL.PLLQ,
825 RCC_OscInitStruct->PLL.PLLR);
826
827 /* Enable the main PLL. */
828 __HAL_RCC_PLL_ENABLE();
829
830 /* Enable PLL System Clock output. */
831 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
832
833 /* Get Start Tick */
834 tickstart = HAL_GetTick();
835
836 /* Wait till PLL is ready */
837 while (LL_RCC_PLL_IsReady() == 0U)
838 {
839 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
840 {
841 return HAL_TIMEOUT;
842 }
843 }
844 }
845 else
846 {
847 /* Disable the main PLL. */
848 __HAL_RCC_PLL_DISABLE();
849
850 /* Get Start Tick */
851 tickstart = HAL_GetTick();
852
853 /* Wait till PLL is disabled */
854 while (LL_RCC_PLL_IsReady() != 0U)
855 {
856 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
857 {
858 return HAL_TIMEOUT;
859 }
860 }
861
862 /* Disable the PLL source and outputs to save power when PLL is off */
863 CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLREN));
864 }
865 }
866 else
867 {
868 /* Check if there is a request to disable the PLL used as System clock source */
869 if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
870 {
871 return HAL_ERROR;
872 }
873 else
874 {
875 /* Do not return HAL_ERROR if request repeats the current configuration */
876 pll_config = RCC->PLLCFGR;
877 if ((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource)
878 || (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM)
879 || (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos))
880 || (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != RCC_OscInitStruct->PLL.PLLR))
881 {
882 return HAL_ERROR;
883 }
884 }
885 }
886 }
887 return HAL_OK;
888 }
889
890
891 /**
892 * @brief Initialize the CPU, AHB and APB buses clocks according to the specified
893 * parameters in the RCC_ClkInitStruct.
894 * @param RCC_ClkInitStruct pointer to a @ref RCC_ClkInitTypeDef structure that
895 * contains the configuration information for the RCC peripheral.
896 * @param FLatency FLASH Latency
897 * This parameter can be one of the following values:
898 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
899 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
900 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycle
901 *
902 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
903 *
904 * @note The MSI is used by default as system clock source after
905 * wake-up from Reset, wake-up from STANDBY mode. After restart from Reset,
906 * the MSI frequency is set to its default value 4 MHz.
907 *
908 * @note The HSI can be selected as system clock source after
909 * from STOP modes or in case of failure of the HSE used directly or indirectly
910 * as system clock (if the Clock Security System CSS is enabled).
911 *
912 * @note A switch from one clock source to another occurs only if the target
913 * clock source is ready (clock stable after startup delay or PLL locked).
914 * If a clock source which is not yet ready is selected, the switch will
915 * occur when the clock source is ready.
916 *
917 * @note You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
918 * currently used as system clock source.
919 *
920 * @note Depending on the device voltage range, the software has to set correctly
921 * HPRE[3:0] bits to ensure that HCLK1 not exceed the maximum allowed frequency
922 * (for more details refer to section above "Initialization/de-initialization functions")
923 * @retval None
924 */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)925 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
926 {
927 uint32_t tickstart;
928
929 /* Check Null pointer */
930 if (RCC_ClkInitStruct == NULL)
931 {
932 return HAL_ERROR;
933 }
934
935 /* Check the parameters */
936 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
937 assert_param(IS_FLASH_LATENCY(FLatency));
938
939 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
940 must be correctly programmed according to the frequency of the FLASH clock
941 (HCLK3) and the supply voltage of the device. */
942
943 /* Increasing the number of wait states because of higher CPU frequency */
944 if (FLatency > __HAL_FLASH_GET_LATENCY())
945 {
946 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
947 __HAL_FLASH_SET_LATENCY(FLatency);
948
949 /* Get Start Tick */
950 tickstart = HAL_GetTick();
951
952 /* Check that the new number of wait states is taken into account to access the Flash
953 memory by reading the FLASH_ACR register */
954 while (__HAL_FLASH_GET_LATENCY() != FLatency)
955 {
956 if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
957 {
958 return HAL_TIMEOUT;
959 }
960 }
961 }
962
963 /*-------------------------- HCLK1 Configuration ---------------------------*/
964 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
965 {
966 assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLKDivider));
967 LL_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLKDivider);
968
969 /* HCLK1 prescaler flag when value applied */
970 tickstart = HAL_GetTick();
971 while (LL_RCC_IsActiveFlag_HPRE() == 0U)
972 {
973 if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
974 {
975 return HAL_TIMEOUT;
976 }
977 }
978 }
979
980 #if defined(DUAL_CORE)
981 /*-------------------------- HCLK2 Configuration ---------------------------*/
982 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK2) == RCC_CLOCKTYPE_HCLK2)
983 {
984 assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK2Divider));
985 LL_C2_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLK2Divider);
986
987 /* HCLK2 prescaler flag when value applied */
988 tickstart = HAL_GetTick();
989 while (LL_RCC_IsActiveFlag_C2HPRE() == 0U)
990 {
991 if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
992 {
993 return HAL_TIMEOUT;
994 }
995 }
996 }
997 #endif /* DUAL_CORE */
998
999 /*-------------------------- HCLK3 Configuration ---------------------------*/
1000 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK3) == RCC_CLOCKTYPE_HCLK3)
1001 {
1002 assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK3Divider));
1003 LL_RCC_SetAHB3Prescaler(RCC_ClkInitStruct->AHBCLK3Divider);
1004
1005 /* AHB shared prescaler flag when value applied */
1006 tickstart = HAL_GetTick();
1007 while (LL_RCC_IsActiveFlag_SHDHPRE() == 0U)
1008 {
1009 if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1010 {
1011 return HAL_TIMEOUT;
1012 }
1013 }
1014 }
1015
1016 /*-------------------------- PCLK1 Configuration ---------------------------*/
1017 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1018 {
1019 assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB1CLKDivider));
1020 LL_RCC_SetAPB1Prescaler(RCC_ClkInitStruct->APB1CLKDivider);
1021
1022 /* APB1 prescaler flag when value applied */
1023 tickstart = HAL_GetTick();
1024 while (LL_RCC_IsActiveFlag_PPRE1() == 0U)
1025 {
1026 if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1027 {
1028 return HAL_TIMEOUT;
1029 }
1030 }
1031 }
1032
1033 /*-------------------------- PCLK2 Configuration ---------------------------*/
1034 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1035 {
1036 assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB2CLKDivider));
1037 LL_RCC_SetAPB2Prescaler((RCC_ClkInitStruct->APB2CLKDivider) << 3U);
1038
1039 /* APB2 prescaler flag when value applied */
1040 tickstart = HAL_GetTick();
1041 while (LL_RCC_IsActiveFlag_PPRE2() == 0U)
1042 {
1043 if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
1044 {
1045 return HAL_TIMEOUT;
1046 }
1047 }
1048 }
1049
1050 /*------------------------- SYSCLK Configuration ---------------------------*/
1051 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1052 {
1053 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1054
1055 /* HSE is selected as System Clock Source */
1056 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1057 {
1058 /* Check the HSE ready flag */
1059 if (LL_RCC_HSE_IsReady() == 0U)
1060 {
1061 return HAL_ERROR;
1062 }
1063 }
1064 /* PLL is selected as System Clock Source */
1065 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1066 {
1067 /* Check the PLL ready flag */
1068 if (LL_RCC_PLL_IsReady() == 0U)
1069 {
1070 return HAL_ERROR;
1071 }
1072 }
1073 /* MSI is selected as System Clock Source */
1074 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1075 {
1076 /* Check the MSI ready flag */
1077 if (LL_RCC_MSI_IsReady() == 0U)
1078 {
1079 return HAL_ERROR;
1080 }
1081 }
1082 /* HSI is selected as System Clock Source */
1083 else
1084 {
1085 /* Check the HSI ready flag */
1086 if (LL_RCC_HSI_IsReady() == 0U)
1087 {
1088 return HAL_ERROR;
1089 }
1090
1091 }
1092
1093 /* apply system clock switch */
1094 LL_RCC_SetSysClkSource(RCC_ClkInitStruct->SYSCLKSource);
1095
1096 /* Get Start Tick */
1097 tickstart = HAL_GetTick();
1098
1099 /* check system clock source switch status */
1100 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1101 {
1102 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1103 {
1104 return HAL_TIMEOUT;
1105 }
1106 }
1107 }
1108
1109 /* Decreasing the number of wait states because of lower CPU frequency */
1110 if (FLatency < __HAL_FLASH_GET_LATENCY())
1111 {
1112 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1113 __HAL_FLASH_SET_LATENCY(FLatency);
1114
1115 /* Get Start Tick */
1116 tickstart = HAL_GetTick();
1117
1118 /* Check that the new number of wait states is taken into account to access the Flash
1119 memory by reading the FLASH_ACR register */
1120 while (__HAL_FLASH_GET_LATENCY() != FLatency)
1121 {
1122 if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
1123 {
1124 return HAL_TIMEOUT;
1125 }
1126 }
1127 }
1128
1129 /*--------------------------------------------------------------------------*/
1130
1131 /* Update the SystemCoreClock global variable */
1132 SystemCoreClock = HAL_RCC_GetHCLKFreq();
1133
1134 /* Configure the source of time base considering new system clocks settings */
1135 return HAL_InitTick(uwTickPrio);
1136 }
1137
1138 /**
1139 * @}
1140 */
1141
1142 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1143 * @brief RCC clocks control functions
1144 *
1145 @verbatim
1146 ===============================================================================
1147 ##### Peripheral Control functions #####
1148 ===============================================================================
1149 [..]
1150 This subsection provides a set of functions allowing to:
1151
1152 (+) Output clock to MCO pin.
1153 (+) Retrieve current clock frequencies.
1154 (+) Enable the Clock Security System.
1155 (+) HSE CSS Interrupt handler.
1156 (+) Default HSE CSS callback function.
1157
1158 @endverbatim
1159 * @{
1160 */
1161
1162 /**
1163 * @brief Select the clock source to output on MCO1 pin(PA8).
1164 * @note PA8 should be configured in alternate function mode.
1165 * @param RCC_MCOx specifies the output direction for the clock source.
1166 * @arg @ref RCC_MCO1_PA8 Clock source to output on MCO1 pin(PA8).
1167 * @param RCC_MCOSource specifies the clock source to output.
1168 * This parameter can be one of the following values:
1169 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
1170 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
1171 * @arg @ref RCC_MCO1SOURCE_MSI MSI clock selected as MCO source
1172 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
1173 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO source
1174 * @arg @ref RCC_MCO1SOURCE_PLLCLK main PLLR clock selected as MCO source
1175 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
1176 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
1177 * @arg @ref RCC_MCO1SOURCE_PLLPCLK main PLLP clock selected as MCO source
1178 * @arg @ref RCC_MCO1SOURCE_PLLQCLK main PLLQ clock selected as MCO source
1179 * @param RCC_MCODiv specifies the MCO prescaler.
1180 * This parameter can be one of the following values:
1181 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1182 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
1183 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
1184 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
1185 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
1186 * @retval None
1187 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1188 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1189 {
1190 GPIO_InitTypeDef gpio_initstruct;
1191 uint32_t mco_gpio_index;
1192 GPIO_TypeDef * mco_gpio_port;
1193
1194 /* Check the parameters */
1195 assert_param(IS_RCC_MCO(RCC_MCOx));
1196 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1197 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1198
1199 /* Configure the MCO1 pin in alternate function mode */
1200 gpio_initstruct.Mode = GPIO_MODE_AF_PP;
1201 gpio_initstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1202 gpio_initstruct.Pull = GPIO_NOPULL;
1203
1204 /* Get MCOx GPIO Port */
1205 mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1206
1207 /* MCOx Clock Enable */
1208 mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1209 SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index ));
1210
1211 /* Configure the MCOx pin in alternate function mode */
1212 gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1213 gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1214 HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
1215
1216 /* Configure the microcontroller clock output (MCO) */
1217 LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
1218 }
1219
1220 /**
1221 * @brief Return the SYSCLK frequency.
1222 *
1223 * @note The system computed by this function is not the real
1224 * frequency in the chip. It is calculated based on the predefined
1225 * constant and the selected clock source:
1226 * @note If SYSCLK source is MSI, function returns values based on MSI range
1227 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1228 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1229 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1230 * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1231 * @note (*) HSI_VALUE is a constant defined in stm32wlxx_hal_conf.h file (default value
1232 * 16 MHz) but the real value may vary depending on the variations
1233 * in voltage and temperature.
1234 * @note (**) HSE_VALUE is a constant defined in stm32wlxx_hal_conf.h file (default value
1235 * 32 MHz), user has to ensure that HSE_VALUE is same as the real
1236 * frequency of the crystal used. Otherwise, this function may
1237 * have wrong result.
1238 *
1239 * @note The result of this function could be not correct when using fractional
1240 * value for HSE crystal.
1241 *
1242 * @note This function can be used by the user application to compute the
1243 * baudrate for the communication peripherals or configure other parameters.
1244 *
1245 * @note Each time SYSCLK changes, this function must be called to update the
1246 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1247 *
1248 *
1249 * @retval SYSCLK frequency
1250 */
HAL_RCC_GetSysClockFreq(void)1251 uint32_t HAL_RCC_GetSysClockFreq(void)
1252 {
1253 uint32_t sysclk_source;
1254 uint32_t pllsource;
1255 uint32_t sysclockfreq = 0U;
1256 uint32_t msifreq = 0U;
1257 uint32_t pllinputfreq;
1258
1259 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1260 pllsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1261
1262 if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
1263 ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pllsource == RCC_PLLSOURCE_MSI)))
1264 {
1265 /* MSI or PLL with MSI source used as system clock source */
1266 /* Retrieve MSI frequency range in Hz */
1267 msifreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
1268 ((LL_RCC_MSI_IsEnabledRangeSelect() == 1U) ?
1269 LL_RCC_MSI_GetRange() :
1270 LL_RCC_MSI_GetRangeAfterStandby()));
1271
1272 /* Get SYSCLK source */
1273 if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
1274 {
1275 /* MSI used as system clock source */
1276 sysclockfreq = msifreq;
1277 }
1278 }
1279 else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI)
1280 {
1281 /* HSI used as system clock source */
1282 sysclockfreq = HSI_VALUE;
1283 }
1284 else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE)
1285 {
1286 /* HSE used as system clock source */
1287 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
1288 {
1289 sysclockfreq = HSE_VALUE / 2U;
1290 }
1291 else
1292 {
1293 sysclockfreq = HSE_VALUE;
1294 }
1295 }
1296 else
1297 {
1298 /* Nothing to do */
1299 }
1300
1301 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1302 {
1303 /* PLL used as system clock source */
1304 pllsource = LL_RCC_PLL_GetMainSource();
1305
1306 switch (pllsource)
1307 {
1308 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1309 pllinputfreq = HSI_VALUE;
1310 break;
1311 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1312 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
1313 {
1314 pllinputfreq = HSE_VALUE / 2U;
1315 }
1316 else
1317 {
1318 pllinputfreq = HSE_VALUE;
1319 }
1320 break;
1321 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
1322 default:
1323 pllinputfreq = msifreq;
1324 break;
1325 }
1326 sysclockfreq = __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
1327 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetR());
1328 }
1329
1330 return sysclockfreq;
1331 }
1332
1333 /**
1334 * @brief Return the HCLK frequency.
1335 * @retval HCLK frequency in Hz
1336 */
HAL_RCC_GetHCLKFreq(void)1337 uint32_t HAL_RCC_GetHCLKFreq(void)
1338 {
1339 /* Get SysClock and Compute HCLK1 frequency --------------------------------*/
1340 return ((uint32_t)(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler())));
1341 }
1342
1343 #if defined(DUAL_CORE)
1344 /**
1345 * @brief Return the HCLK2 frequency.
1346 * @retval HCLK2 frequency in Hz
1347 */
HAL_RCC_GetHCLK2Freq(void)1348 uint32_t HAL_RCC_GetHCLK2Freq(void)
1349 {
1350 /* Get SysClock and Compute HCLK2 frequency --------------------------------*/
1351 return ((uint32_t)(__LL_RCC_CALC_HCLK2_FREQ(HAL_RCC_GetSysClockFreq(), LL_C2_RCC_GetAHBPrescaler())));
1352 }
1353 #endif /* DUAL_CORE */
1354
1355 /**
1356 * @brief Return the HCLK3 frequency.
1357 * @retval HCLK3 frequency in Hz
1358 */
HAL_RCC_GetHCLK3Freq(void)1359 uint32_t HAL_RCC_GetHCLK3Freq(void)
1360 {
1361 /* Get SysClock and Compute AHB3 frequency ---------------------------------*/
1362 return ((uint32_t)(__LL_RCC_CALC_HCLK3_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHB3Prescaler())));
1363 }
1364
1365 /**
1366 * @brief Return the PCLK1 frequency.
1367 * @retval PCLK1 frequency in Hz
1368 */
HAL_RCC_GetPCLK1Freq(void)1369 uint32_t HAL_RCC_GetPCLK1Freq(void)
1370 {
1371 /* Get HCLK source and Compute PCLK1 frequency -----------------------------*/
1372 return ((uint32_t)(__LL_RCC_CALC_PCLK1_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB1Prescaler())));
1373 }
1374
1375 /**
1376 * @brief Return the PCLK2 frequency.
1377 * @retval PCLK2 frequency in Hz
1378 */
HAL_RCC_GetPCLK2Freq(void)1379 uint32_t HAL_RCC_GetPCLK2Freq(void)
1380 {
1381 /* Get HCLK source and Compute PCLK2 frequency -----------------------------*/
1382 return ((uint32_t)(__LL_RCC_CALC_PCLK2_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB2Prescaler())));
1383 }
1384
1385 /**
1386 * @brief Configure the RCC_OscInitStruct according to the internal
1387 * RCC configuration registers.
1388 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1389 * will be configured.
1390 * @retval None
1391 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1392 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1393 {
1394 uint32_t regvalue;
1395 uint32_t regICSRvalue;
1396 uint32_t regPLLCFGRvalue;
1397
1398 /* Check the parameters */
1399 if (RCC_OscInitStruct != NULL)
1400 {
1401 /* Set all possible values for the Oscillator type parameter ---------------*/
1402 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1403 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1404
1405 /* Get register values */
1406 regvalue = RCC->CR; /* Control register */
1407 regICSRvalue = RCC->ICSCR; /* Get Internal Clock Sources Calibration register */
1408 regPLLCFGRvalue = RCC->PLLCFGR; /* Get PLL Configuration register */
1409
1410 /* Get the HSE configuration -----------------------------------------------*/
1411 RCC_OscInitStruct->HSEState = (regvalue & RCC_HSE_BYPASS_PWR);
1412 RCC_OscInitStruct->HSEDiv = (regvalue & RCC_CR_HSEPRE);
1413
1414 /* Get the MSI configuration -----------------------------------------------*/
1415 RCC_OscInitStruct->MSIState = (regvalue & RCC_CR_MSION);
1416 RCC_OscInitStruct->MSICalibrationValue = ((regICSRvalue & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos);
1417 RCC_OscInitStruct->MSIClockRange = (regvalue & RCC_CR_MSIRANGE);
1418
1419 /* Get the HSI configuration -----------------------------------------------*/
1420 RCC_OscInitStruct->HSIState = (regvalue & RCC_CR_HSION);
1421 RCC_OscInitStruct->HSICalibrationValue = ((regICSRvalue & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
1422
1423 /* Get the PLL configuration -----------------------------------------------*/
1424 RCC_OscInitStruct->PLL.PLLState = ((regvalue & RCC_CR_PLLON) >> RCC_CR_PLLON_Pos) + 1U;
1425 RCC_OscInitStruct->PLL.PLLSource = (regPLLCFGRvalue & RCC_PLLCFGR_PLLSRC);
1426 RCC_OscInitStruct->PLL.PLLM = (regPLLCFGRvalue & RCC_PLLCFGR_PLLM);
1427 RCC_OscInitStruct->PLL.PLLN = ((regPLLCFGRvalue & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1428 RCC_OscInitStruct->PLL.PLLP = (regPLLCFGRvalue & RCC_PLLCFGR_PLLP);
1429 RCC_OscInitStruct->PLL.PLLQ = (regPLLCFGRvalue & RCC_PLLCFGR_PLLQ);
1430 RCC_OscInitStruct->PLL.PLLR = (regPLLCFGRvalue & RCC_PLLCFGR_PLLR);
1431
1432 /* Get Backup Domain register */
1433 regvalue = RCC->BDCR;
1434
1435 /* Get the LSE configuration -----------------------------------------------*/
1436 RCC_OscInitStruct->LSEState = (regvalue & RCC_LSE_BYPASS);
1437
1438 /* Get Control/Status register */
1439 regvalue = RCC->CSR;
1440
1441 /* Get the LSI configuration -----------------------------------------------*/
1442 RCC_OscInitStruct->LSIState = (regvalue & RCC_LSI_ON);
1443 RCC_OscInitStruct->LSIDiv = (regvalue & RCC_CSR_LSIPRE);
1444 }
1445 }
1446
1447 /**
1448 * @brief Configure the RCC_ClkInitStruct according to the internal
1449 * RCC configuration registers.
1450 * @param RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
1451 * will be configured.
1452 * @param pFLatency Pointer to the Flash Latency variable.
1453 * @retval None
1454 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1455 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1456 {
1457 uint32_t regvalue;
1458
1459 /* Check the parameters */
1460 if ((RCC_ClkInitStruct != NULL) && (pFLatency != NULL))
1461 {
1462 /* Set all possible values for the Clock type parameter --------------------*/
1463 RCC_ClkInitStruct->ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 \
1464 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_HCLK3);
1465 #if defined(DUAL_CORE)
1466 RCC_ClkInitStruct->ClockType |= RCC_CLOCKTYPE_HCLK2;
1467 #endif /* DUAL_CORE */
1468
1469 /* Get Clock Configuration Register */
1470 regvalue = RCC->CFGR;
1471
1472 /* Get the SYSCLK configuration --------------------------------------------*/
1473 RCC_ClkInitStruct->SYSCLKSource = (regvalue & RCC_CFGR_SWS);
1474
1475 /* Get the HCLK configuration ----------------------------------------------*/
1476 RCC_ClkInitStruct->AHBCLKDivider = (regvalue & RCC_CFGR_HPRE);
1477
1478 /* Get the APB1 configuration ----------------------------------------------*/
1479 RCC_ClkInitStruct->APB1CLKDivider = (regvalue & RCC_CFGR_PPRE1);
1480
1481 /* Get the APB2 configuration ----------------------------------------------*/
1482 RCC_ClkInitStruct->APB2CLKDivider = (regvalue & RCC_CFGR_PPRE2);
1483
1484 /* Get Extended Clock Recovery Register */
1485 regvalue = RCC->EXTCFGR;
1486
1487 #if defined(DUAL_CORE)
1488 /* Get the AHBCLK2Divider configuration ------------------------------------*/
1489 RCC_ClkInitStruct->AHBCLK2Divider = (regvalue & RCC_EXTCFGR_C2HPRE);
1490 #endif /* DUAL_CORE */
1491
1492 /* Get the AHBCLK3Divider configuration ------------------------------------*/
1493 RCC_ClkInitStruct->AHBCLK3Divider = ((regvalue & RCC_EXTCFGR_SHDHPRE) << 4);
1494
1495 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1496 *pFLatency = __HAL_FLASH_GET_LATENCY();
1497 }
1498 }
1499
1500 /**
1501 * @brief Enable the Clock Security System.
1502 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1503 * is automatically disabled and an interrupt is generated to inform the
1504 * software about the failure (Clock Security System Interrupt, CSSI),
1505 * allowing the MCU to perform rescue operations. The CSSI is linked to
1506 * CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector.
1507 * @note The Clock Security System can only be cleared by reset.
1508 * @retval None
1509 */
HAL_RCC_EnableCSS(void)1510 void HAL_RCC_EnableCSS(void)
1511 {
1512 LL_RCC_HSE_EnableCSS();
1513 }
1514
1515 /**
1516 * @brief Handle the RCC HSE Clock Security System interrupt request.
1517 * @note This API should be called under the NMI_Handler().
1518 * @retval None
1519 */
HAL_RCC_NMI_IRQHandler(void)1520 void HAL_RCC_NMI_IRQHandler(void)
1521 {
1522 /* Check RCC CSSF interrupt flag */
1523 if (__HAL_RCC_GET_IT(RCC_IT_HSECSS))
1524 {
1525 /* RCC Clock Security System interrupt user callback */
1526 HAL_RCC_CSSCallback();
1527
1528 /* Clear RCC CSS pending bit */
1529 __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS);
1530 }
1531 }
1532
1533 /**
1534 * @brief Handle the RCC HSE Clock Security System interrupt callback.
1535 * @retval none
1536 */
HAL_RCC_CSSCallback(void)1537 __weak void HAL_RCC_CSSCallback(void)
1538 {
1539 /* NOTE : This function should not be modified, when the callback is needed,
1540 the @ref HAL_RCC_CSSCallback should be implemented in the user file
1541 */
1542 }
1543
1544 /**
1545 * @brief Get and clear reset flags
1546 * @note Once reset flags are retrieved, this API is clearing them in order
1547 * to isolate next reset reason.
1548 * @retval can be a combination of @ref RCC_Reset_Flag
1549 */
HAL_RCC_GetResetSource(void)1550 uint32_t HAL_RCC_GetResetSource(void)
1551 {
1552 uint32_t reset;
1553
1554 /* Get all reset flags */
1555 reset = RCC->CSR & RCC_RESET_FLAG_ALL;
1556
1557 /* Clear Reset flags */
1558 RCC->CSR |= RCC_CSR_RMVF;
1559
1560 return reset;
1561 }
1562
1563 /**
1564 * @}
1565 */
1566
1567 /**
1568 * @}
1569 */
1570
1571 /* Private function prototypes -----------------------------------------------*/
1572 /** @addtogroup RCC_Private_Functions
1573 * @{
1574 */
1575
1576
1577 /**
1578 * @brief Update number of Flash wait states in line with MSI range and current
1579 voltage range.
1580 * @param MSI_Range MSI range value from @ref RCC_MSIRANGE_0 to @ref RCC_MSIRANGE_11
1581 * @retval HAL status
1582 */
RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range)1583 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range)
1584 {
1585 uint32_t flash_clksrcfreq;
1586 uint32_t msifreq;
1587
1588 /* MSI frequency range in Hz */
1589 msifreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, MSI_Range);
1590 flash_clksrcfreq = __LL_RCC_CALC_HCLK3_FREQ(msifreq, LL_RCC_GetAHB3Prescaler());
1591
1592 return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), HAL_PWREx_GetVoltageRange());
1593 }
1594
1595
1596 /**
1597 * @brief Update number of Flash wait states.
1598 * @param Flash_ClkSrcFreq Flash Clock Source (in MHz)
1599 * @param VCORE_Voltage Current Vcore voltage
1600 * This parameter can be one of the following values:
1601 * @arg PWR_REGULATOR_VOLTAGE_SCALE1 Regulator voltage output range 1 mode
1602 * @arg PWR_REGULATOR_VOLTAGE_SCALE2 Regulator voltage output range 2 mode
1603 * @retval HAL status
1604 */
RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq,uint32_t VCORE_Voltage)1605 static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage)
1606 {
1607 /* Flash Clock source (HCLK3) range in MHz for VCORE range1 */
1608 const uint16_t FLASH_CLK_SRC_RANGE_VOS1[] = {18, 36, 48};
1609
1610 /* Flash Clock source (HCLK3) range in MHz for VCORE range2 */
1611 const uint16_t FLASH_CLK_SRC_RANGE_VOS2[] = {6, 12, 16};
1612
1613 /* Flash Latency range */
1614 const uint32_t FLASH_LATENCY_RANGE[] = {FLASH_LATENCY_0, FLASH_LATENCY_1, FLASH_LATENCY_2};
1615
1616 uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */
1617 uint32_t tickstart;
1618
1619 if (VCORE_Voltage == PWR_REGULATOR_VOLTAGE_SCALE1)
1620 {
1621 for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++)
1622 {
1623 if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index])
1624 {
1625 latency = FLASH_LATENCY_RANGE[index];
1626 break;
1627 }
1628 }
1629 }
1630 else /* PWR_REGULATOR_VOLTAGE_SCALE2 */
1631 {
1632 for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS2); index++)
1633 {
1634 if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS2[index])
1635 {
1636 latency = FLASH_LATENCY_RANGE[index];
1637 break;
1638 }
1639 }
1640 }
1641
1642 __HAL_FLASH_SET_LATENCY(latency);
1643
1644 /* Get Start Tick*/
1645 tickstart = HAL_GetTick();
1646
1647 /* Check that the new number of wait states is taken into account to access the Flash
1648 memory by reading the FLASH_ACR register */
1649 while (__HAL_FLASH_GET_LATENCY() != latency)
1650 {
1651 if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
1652 {
1653 return HAL_TIMEOUT;
1654 }
1655 }
1656 return HAL_OK;
1657 }
1658
1659 /**
1660 * @}
1661 */
1662
1663 #endif /* HAL_RCC_MODULE_ENABLED */
1664 /**
1665 * @}
1666 */
1667
1668 /**
1669 * @}
1670 */
1671