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