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