1 /**
2 ******************************************************************************
3 * @file stm32wbaxx_hal_rcc.c
4 * @author MCD Application Team
5 * @brief RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Reset and Clock Control (RCC) peripheral:
8 * + Initialization and de-initialization functions
9 * + Peripheral Control functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2022 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### RCC specific features #####
25 ==============================================================================
26 [..]
27 After reset the device is running from High Speed Internal oscillator
28 (from 8 MHz to reach 16MHz) with Flash 0 wait state. Flash prefetch buffer
29 is disabled.
30 (+) There is no prescaler on High speed (AHBs) except for AHB5 and no
31 prescaler Low speed (APBs) busses: all peripherals mapped on these
32 busses are running at HSI speed.
33 (+) The clock for all peripherals is switched off, except SRAMs 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, 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 busses prescalers
43 (+) Enable the clock for the peripheral(s) to be used
44 (+) Configure the kernel clock source(s) for peripherals which clocks are
45 not derived from the System clock.
46
47 @endverbatim
48 ******************************************************************************
49 */
50
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32wbaxx_hal.h"
53
54 /** @addtogroup STM32WBAxx_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 /* timeout value */
71 /* LSI maximum timeout is 16 us plus 4 LSI clock cycles when prediv is used */
72 #define LSI_TIMEOUT_VALUE ((5u * 128u * 1000u) / LSI_VALUE)
73 #define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
74 #define PLL_FRAC_WAIT_VALUE 1U /* PLL Fractional part waiting time before new latch enable : 1 ms */
75 #define PLL1_NDIV_TIMEOUT_VALUE 10U /* SYSCLK divider delay when going from divide to not divide. 10 ms when 2-steps */
76 #define CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */
77 #define PLL_INPUTRANGE0_FREQMAX 8000000u /* 8 MHz is maximum frequency for VCO input range 0 */
78 /**
79 * @}
80 */
81
82 /* Private macro -------------------------------------------------------------*/
83 /** @defgroup RCC_Private_Macros RCC Private Macros
84 * @{
85 */
86 #define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
87 #define MCO1_GPIO_PORT GPIOA
88 #define MCO1_PIN GPIO_PIN_8
89 /**
90 * @}
91 */
92
93 /* Private variables ---------------------------------------------------------*/
94
95 /* Private function prototypes -----------------------------------------------*/
96 /** @defgroup RCC_Private_Functions RCC Private Functions
97 * @{
98 */
99 static float_t RCC_PLL1_GetVCOOutputFreq(void);
100 /**
101 * @}
102 */
103
104 /* Exported functions --------------------------------------------------------*/
105
106 /** @defgroup RCC_Exported_Functions RCC Exported Functions
107 * @{
108 */
109
110 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
111 * @brief Initialization and Configuration functions
112 *
113 @verbatim
114 ===============================================================================
115 ##### Initialization and de-initialization functions #####
116 ===============================================================================
117 [..]
118 This section provides functions allowing to configure the internal and external oscillators
119 (HSE, HSI, LSE, LSI (LSI1 or LSI2), PLL1, CSS and MCO) and the System busses clocks (SYSCLK,
120 AHB1, AHB2, AHB4, AHB5, APB1, APB2 and APB7).
121
122 [..] Internal/external clock and PLL1 configuration
123 (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
124 the PLL1 as System clock source.
125
126 (+) LSI (low-speed internal):
127 (++) LSI1: 32 kHz low-speed low power internal RC that drives the independent watchdog
128 and optionally the RTC used for auto-wakeup from Stop and Standby modes
129 (++) LSI2: 32 kHz low-speed low drift internal RC that drives optionally the RTC or
130 2.4 GHz RADIO sleep timer used for auto-wakeup from Stop and Standby modes.
131
132 (+) HSE (high-speed external): 32 MHz crystal oscillator used directly or
133 through the PLL1 as System clock source. Can be used also optionally as RTC clock source.
134
135 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source
136 and 2.4 GHz RADIO sleep timer.
137
138 (+) PLL1 (clocked by HSI or HSE) providing up to three independent output clocks:
139 (++) The P output is used to generate an accurate clock to achieve
140 high-quality audio performance on SAI interface and ADC4.
141 (++) The Q output is used to generate the clock for the SAI1 and RNG.
142 (++) The R output is used to generate the high speed system clock (up to 100MHz).
143
144 (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
145 (HSE used directly or through PLL1 as System clock source), the System clock
146 is automatically switched to HSI and an interrupt is generated if enabled.
147 The interrupt is linked to the Cortex-M33 NMI (Non-Maskable Interrupt)
148 exception vector.
149
150 (+) MCO (microcontroller clock output): used to output LSI, HSI, LSE, HSE32, SYSCLK, HCLK5 and
151 PLL1 R, P, Q clocks (through a configurable prescaler) on PA8 pin.
152
153 [..] System, AHB and APB busses clocks configuration
154 (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
155 HSE and main PLL1.
156 The AHB clock (HCLK) is derived from System clock through configurable
157 prescaler and used to clock the CPU, memory and peripherals mapped
158 on AHB bus (DMA, GPIO...). APB1 (PCLK1), APB2 (PCLK2) and APB7 (PCLK7) clocks are derived
159 from AHB clock through configurable prescalers and used to clock
160 the peripherals mapped on these busses. You can use
161 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
162
163 -@- All the peripheral kernel clocks are derived from the System clock (SYSCLK) but some
164 peripheral can select a different source (you have to use HAL_RCCEx_PeriphCLKConfig()
165 function to configure it) :
166 (+@) U(S)ARTx (x = 1, 2) : Kernel clock can be PCLKx, SYSCLK, HSI or LSE.
167 (+@) I2Cx (x = 1, 3) : Kernel clock can be PCLKx, SYSCLK or HSI.
168 (+@) LPTIMx (x = 1, 2) : Kernel clock can be PCLKx, LSI, HSI or LSE.
169 (+@) SPIx (x = 1, 3) : Kernel clock can be PCLKx, SYSCLK or HSI.
170 (+@) SAI1 : Kernel clock can be PLL1P, PLL1Q, SYSCLK, a clock provided on CKIN pin or HSI.
171 (+@) RNG : Kernel clock can be LSE, LSI, HSI or PLL1Q.
172 (+@) LPUART1 : Kernel clock can be PCLKx, SYSCLK, HSI or LSE.
173 (+@) RTC : Kernel clock can be derived either from the LSI, LSE or HSE clock divided by 32.
174 (+@) ADC4 : Kernel clock can be HCLK, SYSCLK, PLL1P, HSE or HSI clock.
175 (+@) 2.4 GHz RADIO sleep timer : Kernel clock can be LSE, LSI, or HSE divided by 1000 clock.
176
177
178 (+) The maximum frequency of SYSCLK / AHB1 / AHB2 / AHB4 / APB1 / APB2 / APB7 is
179 (++) 100 MHz at voltage range 1
180 (++) 16 MHZ at voltage range 2
181
182 (+) The maximum frequency of AHB5 is
183 (++) 32 MHz at voltage range 1
184 (++) 12 MHZ at voltage range 2
185
186 The clock source frequency should be adapted depending on the device voltage range
187 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
188
189 @endverbatim
190
191 (++) Table 1. HCLK clock frequency for STM32WBAxx devices
192 (++) +-------------------------------------------------------+
193 (++) | Latency | HCLK clock frequency (MHz) |
194 (++) | |-------------------------------------|
195 (++) | | voltage scaling | voltage scaling |
196 (++) | | range 1 | range 1 |
197 (++) |-----------------|------------------|------------------|
198 (++) |0WS(1 CPU cycles)| HCLK <= 32 | HCLK <= 8 |
199 (++) |-----------------|------------------|------------------|
200 (++) |1WS(2 CPU cycles)| HCLK <= 64 | HCLK <= 16 |
201 (++) |-----------------|------------------|------------------|
202 (++) |2WS(3 CPU cycles)| HCLK <= 96 | - |
203 (++) |-----------------|------------------|------------------|
204 (++) |3WS(4 CPU cycles)| HCLK <= 100 | - |
205 (++) +-----------------+------------------+------------------+
206 * @{
207 */
208
209 /**
210 * @brief Reset the RCC clock configuration to the default reset state.
211 * @note The default reset state of the clock configuration is given below:
212 * - HSI ON and used as system clock source
213 * - HSE and PLL1 OFF
214 * - AHB, APB1, APB2 and APB7 prescaler set to 1.
215 * - CSS, MCO1 OFF
216 * - All interrupts disabled and cleared
217 * @note This function doesn't modify the configuration of the
218 * - Peripheral clocks
219 * - LSI, LSE and RTC clocks
220 * @retval None
221 */
HAL_RCC_DeInit(void)222 HAL_StatusTypeDef HAL_RCC_DeInit(void)
223 {
224 uint32_t tickstart;
225
226 /* Get start tick*/
227 tickstart = HAL_GetTick();
228
229 /* Set HSION bit */
230 SET_BIT(RCC->CR, RCC_CR_HSION);
231
232 /* Wait till HSI is ready */
233 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
234 {
235 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
236 {
237 return HAL_TIMEOUT;
238 }
239 }
240
241 /* Set HSITRIM default value */
242 MODIFY_REG(RCC->ICSCR3, RCC_ICSCR3_HSITRIM, 0x00100000U);
243
244 /* Get start tick*/
245 tickstart = HAL_GetTick();
246
247 /* Reset CFGR1 register (HSI is selected as system clock source) */
248 CLEAR_REG(RCC->CFGR1);
249
250 /* Wait till clock switch is ready */
251 while (READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS) != 0U)
252 {
253 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
254 {
255 return HAL_TIMEOUT;
256 }
257 }
258
259 /* Set AHBx and APBx prescaler to their default values */
260 CLEAR_REG(RCC->CFGR2);
261 CLEAR_REG(RCC->CFGR3);
262 WRITE_REG(RCC->CFGR4, 0x00000010);
263
264 /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
265 RCC->CR = RCC_CR_HSION;
266
267 /* Then again to HSEBYP in case bypass was enabled */
268 RCC->CR = RCC_CR_HSION;
269
270 /* Get Start Tick */
271 tickstart = HAL_GetTick();
272
273 /* Wait till PLL1 is disabled */
274 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
275 {
276 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
277 {
278 return HAL_TIMEOUT;
279 }
280 }
281
282 /* Reset PLL1CFGR register */
283 CLEAR_REG(RCC->PLL1CFGR);
284
285 /* Reset PLL1DIVR register */
286 WRITE_REG(RCC->PLL1DIVR, 0x01010280U);
287
288 /* Reset PLL1FRACR register */
289 CLEAR_REG(RCC->PLL1FRACR);
290
291 /* Disable all interrupts */
292 CLEAR_REG(RCC->CIER);
293
294 /* Clear all interrupts flags */
295 WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
296
297 /* Update the SystemCoreClock global variable */
298 SystemCoreClock = HSI_VALUE;
299
300 /* Adapt Systick interrupt period */
301 if (HAL_InitTick(uwTickPrio) != HAL_OK)
302 {
303 return HAL_ERROR;
304 }
305 else
306 {
307 return HAL_OK;
308 }
309 }
310
311
312 /**
313 * @brief Initialize the RCC Oscillators according to the specified parameters in the
314 * RCC_OscInitTypeDef.
315 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
316 * contains the configuration information for the RCC Oscillators.
317 * @note The PLL1 is not disabled when used as system clock.
318 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
319 * supported by this function. User should request a transition to HSE Off
320 * first and then to HSE On or HSE Bypass.
321 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
322 * supported by this function. User should request a transition to LSE Off
323 * first and then LSE On or LSE Bypass.
324 * @retval HAL status
325 */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * RCC_OscInitStruct)326 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *RCC_OscInitStruct)
327 {
328 uint32_t tickstart;
329 uint32_t sysclksrc;
330 uint32_t pllsrc;
331 uint32_t tmpreg1;
332 uint32_t tmpreg2;
333 uint32_t mask;
334
335 /* Check Null pointer */
336 if (RCC_OscInitStruct == NULL)
337 {
338 return HAL_ERROR;
339 }
340
341 /* Check the parameters */
342 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
343
344 sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
345 pllsrc = __HAL_RCC_GET_PLL1_OSCSOURCE();
346
347 /*------------------------------- HSE Configuration ------------------------*/
348 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
349 {
350 /* Check the parameters */
351 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
352
353 /* When the HSE is used as system clock or clock source for PLL1 in these cases it is not allowed to be disabled */
354 if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
355 ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pllsrc == RCC_PLLSOURCE_HSE)))
356 {
357 if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
358 {
359 return HAL_ERROR;
360 }
361 else
362 {
363 /* Otherwise, applying divider is allowed */
364 if (sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE)
365 {
366 assert_param(IS_RCC_HSEDIV(RCC_OscInitStruct->HSEDiv));
367
368 /* Adjust the HSE division factor */
369 __HAL_RCC_HSE_CONFIG(RCC_HSE_ON | RCC_OscInitStruct->HSEDiv);
370
371 /* Update the SystemCoreClock global variable with HSE value */
372 SystemCoreClock = (HSE_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSEPRE)) >> RCC_CR_HSEPRE_Pos)));
373
374 /* Adapt Systick interrupt period */
375 if (HAL_InitTick(uwTickPrio) != HAL_OK)
376 {
377 return HAL_ERROR;
378 }
379 }
380 }
381 }
382 else
383 {
384 /* Check the HSE State */
385 if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
386 {
387 assert_param(IS_RCC_HSEDIV(RCC_OscInitStruct->HSEDiv));
388
389 /* Set the new HSE configuration ---------------------------------------*/
390 __HAL_RCC_HSE_CONFIG((RCC_OscInitStruct->HSEState | RCC_OscInitStruct->HSEDiv));
391
392 /* Get Start Tick*/
393 tickstart = HAL_GetTick();
394
395 /* Wait till HSE is ready */
396 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
397 {
398 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
399 {
400 return HAL_TIMEOUT;
401 }
402 }
403 }
404 else
405 {
406 /* Set the new HSE configuration ---------------------------------------*/
407 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
408
409 /* Get Start Tick*/
410 tickstart = HAL_GetTick();
411
412 /* Wait till HSE is disabled */
413 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
414 {
415 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
416 {
417 return HAL_TIMEOUT;
418 }
419 }
420 }
421 }
422 }
423
424 /*----------------------------- HSI Configuration --------------------------*/
425 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
426 {
427 /* Check the parameters */
428 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
429 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
430
431 /* Check if HSI is used as system clock or as PLL1 source when PLL1 is selected as system clock */
432 if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
433 ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pllsrc == RCC_PLLSOURCE_HSI)))
434 {
435 /* When HSI is used as system clock it will not be disabled */
436 if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
437 {
438 return HAL_ERROR;
439 }
440 /* Otherwise, just the calibration is allowed */
441 else
442 {
443 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
444 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
445 }
446 }
447 else
448 {
449 /* Check the HSI State */
450 if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
451 {
452 /* Enable the Internal High Speed oscillator (HSI). */
453 __HAL_RCC_HSI_ENABLE();
454
455 /* Get Start Tick*/
456 tickstart = HAL_GetTick();
457
458 /* Wait till HSI is ready */
459 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
460 {
461 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
462 {
463 return HAL_TIMEOUT;
464 }
465 }
466
467 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
468 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
469 }
470 else
471 {
472 /* Disable the Internal High Speed oscillator (HSI). */
473 __HAL_RCC_HSI_DISABLE();
474
475 /* Get Start Tick*/
476 tickstart = HAL_GetTick();
477
478 /* Wait till HSI is disabled */
479 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
480 {
481 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
482 {
483 return HAL_TIMEOUT;
484 }
485 }
486 }
487 }
488 }
489
490 /*------------------------------ LSI Configuration -------------------------*/
491 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
492 {
493 /* Check the parameters */
494 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
495
496 FlagStatus pwrclkchanged = RESET;
497
498 /* Update LSI1 configuration in Backup Domain control register */
499 /* Requires to enable write access to Backup Domain of necessary */
500 if (__HAL_RCC_PWR_IS_CLK_ENABLED() != 0x01)
501 {
502 __HAL_RCC_PWR_CLK_ENABLE();
503 pwrclkchanged = SET;
504 }
505
506 if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
507 {
508 /* Enable write access to Backup domain */
509 SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
510
511 /* Wait for Backup domain Write protection disable */
512 tickstart = HAL_GetTick();
513
514 while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
515 {
516 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
517 {
518 return HAL_TIMEOUT;
519 }
520 }
521 }
522
523 /* Get BDCR1 register value */
524 tmpreg1 = RCC->BDCR1;
525
526 /* Define mask depending on LSI presence */
527 mask = RCC_BDCR1_LSI1ON;
528 #if defined(RCC_LSI2_SUPPORT)
529 mask |= RCC_BDCR1_LSI2ON;
530 #endif /* RCC_LSI2_SUPPORT */
531
532 /* Check the LSI1 State */
533 if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
534 {
535 if ((RCC_OscInitStruct->LSIState & RCC_LSI1_ON) != 0x00u)
536 {
537 /* Check LSI1 division factor */
538 assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv));
539
540 /* Check is LSIDiv is requested to be changed and LSI is already ON */
541 if ((RCC_OscInitStruct->LSIDiv != (tmpreg1 & RCC_BDCR1_LSI1PREDIV)) && ((tmpreg1 & RCC_BDCR1_LSI1RDY) != 0x00u))
542 {
543 /* Disable LSI1 */
544 tmpreg1 &= ~RCC_BDCR1_LSI1ON;
545 RCC->BDCR1 = tmpreg1;
546
547 /* Get Start Tick*/
548 tickstart = HAL_GetTick();
549
550 /* Wait till LSI1 is disabled */
551 while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSI1RDY) != 0x00u)
552 {
553 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
554 {
555 /* LSI1 may be forced ON by IWDG */
556 return HAL_TIMEOUT;
557 }
558 }
559 #if defined(STM32WBAXX_SI_CUT1_0)
560 /* Wait at least 1 half LSI clock period before apppling new LSI1 prediv value */
561 HAL_Delay(1);
562 #endif
563 }
564
565 /* Set LSI1 division factor */
566 tmpreg1 &= ~RCC_BDCR1_LSI1PREDIV;
567 tmpreg1 |= RCC_OscInitStruct->LSIDiv;
568 }
569
570 /* Enable Concerned LSI */
571 tmpreg1 |= RCC_OscInitStruct->LSIState;
572 RCC->BDCR1 = tmpreg1;
573
574 /* Get Start Tick*/
575 tickstart = HAL_GetTick();
576
577 /* Wait till LSI is ready : LSIRDY bit is position ON shifted by 1 */
578 while (READ_BIT(RCC->BDCR1, (RCC_OscInitStruct->LSIState << 1)) == 0x00u)
579 {
580 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
581 {
582 return HAL_TIMEOUT;
583 }
584 }
585
586 #if defined(RCC_LSI2_SUPPORT)
587 /* Disable other LSI in case it was ON */
588 mask ^= RCC_OscInitStruct->LSIState;
589 tmpreg1 &= ~mask;
590 RCC->BDCR1 = tmpreg1;
591
592 /* Get Start Tick*/
593 tickstart = HAL_GetTick();
594
595 /* Wait till other LSI is disabled */
596 while (READ_BIT(RCC->BDCR1, (mask << 1)) != 0x00u)
597 {
598 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
599 {
600 return HAL_TIMEOUT;
601 }
602 }
603 #endif
604 }
605 else
606 {
607 /* Disable the Internal Low Speed oscillator LSI1 and LSI2 is available */
608 tmpreg1 &= ~mask;
609 RCC->BDCR1 = tmpreg1;
610
611 /* Get Start Tick*/
612 tickstart = HAL_GetTick();
613
614 /* Wait till LSI is disabled : LSIRDY bit position is ON shifted by 1 */
615 while (READ_BIT(RCC->BDCR1, (mask << 1)) != 0x00u)
616 {
617 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
618 {
619 return HAL_TIMEOUT;
620 }
621 }
622 }
623 /* Restore clock configuration if changed */
624 if (pwrclkchanged == SET)
625 {
626 __HAL_RCC_PWR_CLK_DISABLE();
627 }
628 }
629
630 /*------------------------------ LSE Configuration -------------------------*/
631 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
632 {
633 FlagStatus pwrclkchanged = RESET;
634
635 /* Check the parameters */
636 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
637
638 /* Update LSE configuration in Backup Domain control register */
639 /* Requires to enable write access to Backup Domain of necessary */
640 if (__HAL_RCC_PWR_IS_CLK_ENABLED() != 0x01)
641 {
642 __HAL_RCC_PWR_CLK_ENABLE();
643 pwrclkchanged = SET;
644 }
645
646 if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
647 {
648 /* Enable write access to Backup domain */
649 SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
650
651 /* Wait for Backup domain Write protection disable */
652 tickstart = HAL_GetTick();
653
654 while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
655 {
656 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
657 {
658 return HAL_TIMEOUT;
659 }
660 }
661 }
662
663 /* Set the new LSE configuration -----------------------------------------*/
664 /* Check the LSE State */
665 if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
666 {
667 /* If LSE is already on or in bypass mode, only LSE system can be modified */
668 tmpreg1 = (RCC->BDCR1 & ~RCC_BDCR1_LSESYSEN);
669 tmpreg1 |= RCC_OscInitStruct->LSEState;
670 RCC->BDCR1 = tmpreg1;
671
672 /* Get Start Tick*/
673 tickstart = HAL_GetTick();
674
675 /* Wait till LSE is ready */
676 while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSERDY) == 0U)
677 {
678 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
679 {
680 return HAL_TIMEOUT;
681 }
682 }
683
684 /* Enable LSESYS additionally if requested */
685 if ((RCC_OscInitStruct->LSEState & RCC_BDCR1_LSESYSEN) != 0U)
686 {
687 /* Wait till LSESYS is ready */
688 while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSRDY) == 0U)
689 {
690 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
691 {
692 return HAL_TIMEOUT;
693 }
694 }
695 }
696 else
697 {
698 /* Wait till LSESYSRDY is cleared */
699 while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSRDY) != 0U)
700 {
701 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
702 {
703 return HAL_TIMEOUT;
704 }
705 }
706 }
707 }
708 else
709 {
710 CLEAR_BIT(RCC->BDCR1, (RCC_BDCR1_LSEON | RCC_BDCR1_LSESYSEN));
711 CLEAR_BIT(RCC->BDCR1, RCC_BDCR1_LSEBYP);
712
713 /* Get Start Tick*/
714 tickstart = HAL_GetTick();
715
716 /* Wait till LSE is disabled */
717 while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSERDY) != 0U)
718 {
719 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
720 {
721 return HAL_TIMEOUT;
722 }
723 }
724
725 if (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSEN) != 0U)
726 {
727 /* Wait till LSESYSRDY is cleared */
728 while (READ_BIT(RCC->BDCR1, RCC_BDCR1_LSESYSRDY) != 0U)
729 {
730 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
731 {
732 return HAL_TIMEOUT;
733 }
734 }
735 }
736 }
737
738 /* Restore clock configuration if changed */
739 if (pwrclkchanged == SET)
740 {
741 __HAL_RCC_PWR_CLK_DISABLE();
742 }
743 }
744
745 /*-------------------------------- PLL1 Configuration -----------------------*/
746 /* Check the parameters */
747 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL1.PLLState));
748
749 if ((RCC_OscInitStruct->PLL1.PLLState) != RCC_PLL_NONE)
750 {
751 /* Check if the PLL1 is used as system clock or not */
752 if (sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
753 {
754 if ((RCC_OscInitStruct->PLL1.PLLState) == RCC_PLL_ON)
755 {
756 /* Check the parameters */
757 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL1.PLLSource));
758 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL1.PLLM));
759 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL1.PLLN));
760 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL1.PLLP));
761 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL1.PLLQ));
762 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL1.PLLR));
763
764 /* Disable the main PLL1. */
765 tmpreg1 = (RCC->CR & ~RCC_CR_PLL1ON);
766 RCC->CR = tmpreg1;
767
768 /* Get Start Tick*/
769 tickstart = HAL_GetTick();
770
771 /* Wait till PLL1 is disabled */
772 do
773 {
774 tmpreg1 = RCC->CR;
775 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
776 {
777 return HAL_TIMEOUT;
778 }
779 } while ((tmpreg1 & RCC_CR_PLL1RDY) != 0U);
780
781 /* Compute VCO input frequency and define range accordingly. First check clock source frequency */
782 if (RCC_OscInitStruct->PLL1.PLLSource == RCC_PLLSOURCE_HSE)
783 {
784 /* Clock source is HSE or HSE/2 */
785 pllsrc = HSE_VALUE >> ((tmpreg1 & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos);
786 }
787 else
788 {
789 /* Clock source is HSI */
790 pllsrc = HSI_VALUE;
791 }
792
793 /* Compute VCO input frequency depending on M divider */
794 pllsrc = (pllsrc / RCC_OscInitStruct->PLL1.PLLM);
795 assert_param(IS_RCC_PLL_VCOINPUTFREQ(pllsrc));
796
797 if (pllsrc > PLL_INPUTRANGE0_FREQMAX)
798 {
799 /* Reuse pllsrc local variable to store range */
800 pllsrc = RCC_PLL_VCOINPUT_RANGE1;
801 }
802 else
803 {
804 /* Reuse pllsrc local variable to store range */
805 pllsrc = RCC_PLL_VCOINPUT_RANGE0;
806 }
807
808 /* Configure PLL1 source, PLLM divider, VCO input range and enable PLL1R output. Clear also FRACEN*/
809 tmpreg2 = RCC->PLL1CFGR;
810 tmpreg2 &= ~(RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1RGE | RCC_PLL1CFGR_PLL1FRACEN | RCC_PLL1CFGR_PLL1M);
811 tmpreg2 |= (RCC_OscInitStruct->PLL1.PLLSource | pllsrc |
812 ((RCC_OscInitStruct->PLL1.PLLM - 1u) << RCC_PLL1CFGR_PLL1M_Pos) | RCC_PLL1CFGR_PLL1REN);
813 RCC->PLL1CFGR = tmpreg2;
814
815 /* Configure PLLN multiplication factor and PLLP, PLLQ, PLLR dividers */
816 tmpreg2 = ((RCC_OscInitStruct->PLL1.PLLN - 1u) |
817 ((RCC_OscInitStruct->PLL1.PLLP - 1u) << RCC_PLL1DIVR_PLL1P_Pos) |
818 ((RCC_OscInitStruct->PLL1.PLLQ - 1u) << RCC_PLL1DIVR_PLL1Q_Pos) |
819 ((RCC_OscInitStruct->PLL1.PLLR - 1u) << RCC_PLL1DIVR_PLL1R_Pos));
820 RCC->PLL1DIVR = tmpreg2;
821
822 if (RCC_OscInitStruct->PLL1.PLLFractional != 0x00u)
823 {
824 assert_param(IS_RCC_PLLFRACN_VALUE(RCC_OscInitStruct->PLL1.PLLFractional));
825
826 /* Configure PLL1 PLL1FRACN */
827 __HAL_RCC_PLL1_FRACN_CONFIG(RCC_OscInitStruct->PLL1.PLLFractional);
828
829 /* Enable PLL1FRACEN */
830 __HAL_RCC_PLL1_FRACN_ENABLE();
831 }
832
833 /* Enable the main PLL1. */
834 __HAL_RCC_PLL1_ENABLE();
835
836 /* Get Start Tick*/
837 tickstart = HAL_GetTick();
838
839 /* Wait till PLL1 is ready */
840 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
841 {
842 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
843 {
844 return HAL_TIMEOUT;
845 }
846 }
847 }
848 else
849 {
850 /* Disable the main PLL1. */
851 __HAL_RCC_PLL1_DISABLE();
852
853 /* Get Start Tick*/
854 tickstart = HAL_GetTick();
855
856 /* Wait till PLL1 is disabled */
857 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
858 {
859 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
860 {
861 return HAL_TIMEOUT;
862 }
863 }
864
865 /* CLear the PLL1 source and disable outputs to save power when PLL1 is off */
866 CLEAR_BIT(RCC->PLL1CFGR, (RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1PEN | \
867 RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1REN));
868 }
869 }
870 else
871 {
872 /* Check if there is a request to disable the PLL1 used as System clock source */
873 if ((RCC_OscInitStruct->PLL1.PLLState) == RCC_PLL_OFF)
874 {
875 return HAL_ERROR;
876 }
877 else
878 {
879 /* Do not return HAL_ERROR if request repeats the current configuration */
880 tmpreg1 = RCC->PLL1CFGR;
881 tmpreg2 = RCC->PLL1DIVR;
882
883 if (((tmpreg1 & RCC_PLL1CFGR_PLL1SRC) != RCC_OscInitStruct->PLL1.PLLSource) ||
884 (((tmpreg1 & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) != (RCC_OscInitStruct->PLL1.PLLM - 1u)) ||
885 (((tmpreg2 & RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) != (RCC_OscInitStruct->PLL1.PLLN - 1u)) ||
886 (((tmpreg2 & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) != (RCC_OscInitStruct->PLL1.PLLP - 1u)) ||
887 (((tmpreg2 & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) != (RCC_OscInitStruct->PLL1.PLLQ - 1u)) ||
888 (((tmpreg2 & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) != (RCC_OscInitStruct->PLL1.PLLR - 1u)))
889 {
890 return HAL_ERROR;
891 }
892 else
893 {
894 /* Check if only fractional part needs to be updated */
895 tmpreg1 = ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos);
896
897 if (RCC_OscInitStruct->PLL1.PLLFractional != tmpreg1)
898 {
899 assert_param(IS_RCC_PLLFRACN_VALUE(RCC_OscInitStruct->PLL1.PLLFractional));
900
901 /* Disable PLL1FRACEN */
902 __HAL_RCC_PLL1_FRACN_DISABLE();
903
904 /* Get Start Tick*/
905 tickstart = HAL_GetTick();
906
907 /* Wait at least 2 CK_REF (PLL input source divided by M) period to make sure next latched value will be taken into account. */
908 while ((HAL_GetTick() - tickstart) < PLL_FRAC_WAIT_VALUE)
909 {
910 }
911
912 /* Configure PLL1 PLL1FRACN */
913 __HAL_RCC_PLL1_FRACN_CONFIG(RCC_OscInitStruct->PLL1.PLLFractional);
914
915 /* Enable PLL1FRACEN to latch new value. */
916 __HAL_RCC_PLL1_FRACN_ENABLE();
917 }
918 }
919 }
920 }
921 }
922 return HAL_OK;
923 }
924
925 /**
926 * @brief Initialize the CPU, AHB and APB bus clocks according to the specified
927 * parameters in the RCC_ClkInitStruct.
928 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
929 * contains the configuration information for the RCC peripheral.
930 * @param FLatency FLASH Latency
931 * This parameter can be one of the following values:
932 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
933 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
934 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles
935 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles
936 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles
937 * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles
938 * @arg FLASH_LATENCY_6 FLASH 6 Latency cycles
939 * @arg FLASH_LATENCY_7 FLASH 7 Latency cycles
940 * @arg FLASH_LATENCY_8 FLASH 8 Latency cycles
941 * @arg FLASH_LATENCY_9 FLASH 9 Latency cycles
942 * @arg FLASH_LATENCY_10 FLASH 10 Latency cycles
943 * @arg FLASH_LATENCY_11 FLASH 11 Latency cycles
944 * @arg FLASH_LATENCY_12 FLASH 12 Latency cycles
945 * @arg FLASH_LATENCY_13 FLASH 13 Latency cycles
946 * @arg FLASH_LATENCY_14 FLASH 14 Latency cycles
947 * @arg FLASH_LATENCY_15 FLASH 15 Latency cycles
948 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
949 * @note The HSI (16 MHz) is used by default as system clock source after
950 * startup from Reset, wake-up from STANDBY mode.
951 * @note A switch from one clock source to another occurs only if the target
952 * clock source is ready (clock stable after startup delay or PLL1 locked).
953 * If a clock source which is not yet ready is selected, the switch will
954 * occur when the clock source is ready.
955 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is
956 * currently used as system clock source.
957 * @note The SYSCLK shall only be switched to a higher frequency when incremental
958 * frequency step is 47 MHz. When this is not respected device operation cannot
959 * be guaranteed. For bigger incremental frequency steps the PLL1RCLKPRE division
960 * shall be used.
961 * @note HCLK5 frequency shall not be higher than 32 MHz in range 1, 12 MHz in range 2.
962 * Two different fields allow to configure HCLK5 prescaler: one when System clock
963 * source is to PLL1, other for any other sources.
964 * HCLK5 prescaler is switched automatically by hardware, but configuration shall
965 * always be performed before setting new PLL1 source as Sysclk source.
966 * @retval None
967 */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)968 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
969 {
970 uint32_t tmpreg1;
971 uint32_t update;
972 uint32_t tickstart;
973
974 /* Check Null pointer */
975 if (RCC_ClkInitStruct == NULL)
976 {
977 return HAL_ERROR;
978 }
979
980 /* Check the parameters */
981 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
982 assert_param(IS_FLASH_LATENCY(FLatency));
983
984 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
985 must be correctly programmed according to the frequency of the CPU clock
986 (HCLK) and the supply voltage of the device. */
987
988 /* Increasing the number of wait states because of higher CPU frequency */
989 if (FLatency > __HAL_FLASH_GET_LATENCY())
990 {
991 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
992 __HAL_FLASH_SET_LATENCY(FLatency);
993
994 /* Check that the new number of wait states is taken into account to access the Flash
995 memory by reading the FLASH_ACR register */
996 if (__HAL_FLASH_GET_LATENCY() != FLatency)
997 {
998 return HAL_ERROR;
999 }
1000 }
1001
1002 /*-------------------------- HCLK5 Configuration --------------------------*/
1003 /* HCLK5 prescaler is switched automatically by hardware, but configuration shall
1004 always be performed before setting new PLL1 source as Sysclk source. */
1005 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK5) == RCC_CLOCKTYPE_HCLK5)
1006 {
1007 assert_param(IS_RCC_HCLK5_HSEHSI(RCC_ClkInitStruct->AHB5_HSEHSI_CLKDivider));
1008 assert_param(IS_RCC_HCLK5_PLL1(RCC_ClkInitStruct->AHB5_PLL1_CLKDivider));
1009 MODIFY_REG(RCC->CFGR4, (RCC_CFGR4_HDIV5 | RCC_CFGR4_HPRE5),
1010 (RCC_ClkInitStruct->AHB5_PLL1_CLKDivider | RCC_ClkInitStruct->AHB5_HSEHSI_CLKDivider));
1011 }
1012
1013 /*------------------------- SYSCLK Configuration ---------------------------*/
1014 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1015 {
1016 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1017
1018 /* Read CR register */
1019 tmpreg1 = RCC->CR;
1020
1021 /* PLL1 is selected as System Clock Source */
1022 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1023 {
1024 /* Check the PLL1 ready flag */
1025 if ((tmpreg1 & RCC_CR_PLL1RDY) == 0U)
1026 {
1027 return HAL_ERROR;
1028 }
1029 else
1030 {
1031 if (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR1_SWS_Pos))
1032 {
1033 /* Whatever is PLL frequency, use step prediv to reach maximum frequency. */
1034 /* Select pll1r to be prediv with 2-step divider when selected as Sysclk source */
1035 MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRESTEP, RCC_PLL1CFGR_PLL1RCLKPRE);
1036 #if defined(STM32WBAXX_SI_CUT1_0)
1037 /* add 2 pulse on CLKPRE bit : clear and set it back */
1038 CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1039 SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1040 CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1041 SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1042 #endif
1043 }
1044 }
1045 }
1046 else
1047 {
1048 /* HSE is selected as System Clock Source */
1049 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1050 {
1051 /* Check the HSE ready flag */
1052 if ((tmpreg1 & RCC_CR_HSERDY) == 0U)
1053 {
1054 return HAL_ERROR;
1055 }
1056 }
1057 /* HSI is selected as System Clock Source */
1058 else
1059 {
1060 /* Check the HSI ready flag */
1061 if ((tmpreg1 & RCC_CR_HSIRDY) == 0U)
1062 {
1063 return HAL_ERROR;
1064 }
1065 }
1066 }
1067
1068 /* Switch System clock source */
1069 MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, RCC_ClkInitStruct->SYSCLKSource);
1070
1071 /* Get Start Tick*/
1072 tickstart = HAL_GetTick();
1073
1074 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR1_SWS_Pos))
1075 {
1076 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1077 {
1078 return HAL_TIMEOUT;
1079 }
1080 }
1081
1082 /* If PLL1rCLK is asked to be SYSCLK source, clear prediv. */
1083 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1084 {
1085 /* Set PLL1R prediv to not divided */
1086 CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RCLKPRE);
1087
1088 /* Get Start Tick*/
1089 tickstart = HAL_GetTick();
1090
1091 /* Wait until PLL1 not divided is ready */
1092 while ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1RCLKPRERDY) == 0x00u)
1093 {
1094 if ((HAL_GetTick() - tickstart) > PLL1_NDIV_TIMEOUT_VALUE)
1095 {
1096 return HAL_TIMEOUT;
1097 }
1098 }
1099 }
1100 }
1101
1102 /* Get CFGR2 content value, and reset update variable */
1103 tmpreg1 = RCC->CFGR2;
1104 update = 0x00u;
1105
1106 /*-------------------------- HCLK Configuration --------------------------*/
1107 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1108 {
1109 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1110
1111 /* update HCLK1 divider and notify register is required */
1112 tmpreg1 &= ~RCC_CFGR2_HPRE;
1113 tmpreg1 |= RCC_ClkInitStruct->AHBCLKDivider;
1114 update = 0x01u;
1115 }
1116
1117
1118 /*-------------------------- PCLK1 Configuration ---------------------------*/
1119 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1120 {
1121 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1122
1123 /* update PCLK1 divider and notify register is required */
1124 tmpreg1 &= ~RCC_CFGR2_PPRE1;
1125 tmpreg1 |= RCC_ClkInitStruct->APB1CLKDivider;
1126 update = 0x01u;
1127 }
1128
1129 /*-------------------------- PCLK2 Configuration ---------------------------*/
1130 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1131 {
1132 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1133
1134 /* update PCLK2 divider and notify register is required */
1135 tmpreg1 &= ~RCC_CFGR2_PPRE2;
1136 tmpreg1 |= (RCC_ClkInitStruct->APB2CLKDivider << (RCC_CFGR2_PPRE2_Pos - RCC_CFGR2_PPRE1_Pos));
1137 update = 0x01u;
1138 }
1139
1140 /* update CFGR2 if required */
1141 if (update != 0x00u)
1142 {
1143 RCC->CFGR2 = tmpreg1;
1144 }
1145
1146 /*-------------------------- PCLK7 Configuration ---------------------------*/
1147 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK7) == RCC_CLOCKTYPE_PCLK7)
1148 {
1149 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB7CLKDivider));
1150 WRITE_REG(RCC->CFGR3, RCC_ClkInitStruct->APB7CLKDivider);
1151 }
1152
1153 /* Decreasing the number of wait states because of lower CPU frequency */
1154 if (FLatency < __HAL_FLASH_GET_LATENCY())
1155 {
1156 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1157 __HAL_FLASH_SET_LATENCY(FLatency);
1158
1159 /* Check that the new number of wait states is taken into account to access the Flash
1160 memory by reading the FLASH_ACR register */
1161 if (__HAL_FLASH_GET_LATENCY() != FLatency)
1162 {
1163 return HAL_ERROR;
1164 }
1165 }
1166
1167 /* Update the SystemCoreClock global variable */
1168 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1169
1170 /* Configure the source of time base considering new system clocks settings*/
1171 return HAL_InitTick(uwTickPrio);
1172 }
1173
1174 /**
1175 * @}
1176 */
1177
1178 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1179 * @brief RCC clocks control functions
1180 *
1181 @verbatim
1182 ===============================================================================
1183 ##### Peripheral Control functions #####
1184 ===============================================================================
1185 [..]
1186 This subsection provides a set of functions allowing to:
1187
1188 (+) Output clock to MCO pin.
1189 (+) Retrieve current clock frequencies.
1190 (+) Enable the Clock Security System.
1191
1192 @endverbatim
1193 * @{
1194 */
1195
1196 /**
1197 * @brief Select the clock source to output on MCO pin (PA8).
1198 * @note PA8 should be configured in alternate function mode.
1199 * @param RCC_MCOx specifies the output direction for the clock source.
1200 * For STM32WBAxx family this parameter can have only one value:
1201 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1202 * @param RCC_MCOSource specifies the clock source to output.
1203 * This parameter can be one of the following values:
1204 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
1205 * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO source
1206 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
1207 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO source
1208 * @arg @ref RCC_MCO1SOURCE_PLL1RCLK PLL1R clock selected as MCO source
1209 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
1210 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
1211 * @arg @ref RCC_MCO1SOURCE_PLL1PCLK PLL1P clock selected as MCO source
1212 * @arg @ref RCC_MCO1SOURCE_PLL1QCLK PLL1Q clock selected as MCO source
1213 * @arg @ref RCC_MCO1SOURCE_HCLK5 HCLK5 clock selected as MCO source
1214 * @param RCC_MCODiv specifies the MCO prescaler.
1215 * This parameter can be one of the following values:
1216 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1217 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
1218 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
1219 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
1220 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
1221 * @retval None
1222 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1223 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1224 {
1225 GPIO_InitTypeDef GPIO_InitStruct;
1226
1227 /* Check the parameters */
1228 assert_param(IS_RCC_MCO(RCC_MCOx));
1229 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1230 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1231
1232 /* MCO Clock Enable */
1233 __MCO1_CLK_ENABLE();
1234
1235 /* Configure the MCO1 pin in alternate function mode */
1236 GPIO_InitStruct.Pin = MCO1_PIN;
1237 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1238 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1239 GPIO_InitStruct.Pull = GPIO_NOPULL;
1240 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1241 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1242
1243 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1244 MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCOSEL | RCC_CFGR1_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1245 }
1246
1247 /**
1248 * @brief Return the SYSCLK frequency.
1249 * @note The system frequency computed by this function is not the real
1250 * frequency in the chip. It is calculated based on the predefined
1251 * constant and the selected clock source:
1252 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1253 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1254 * @note If SYSCLK source is PLL1, function returns values based on HSE_VALUE(**),
1255 * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL1 factors.
1256 * @note (*) HSI_VALUE is a constant defined in stm32wbaxx_hal_conf.h file (default value
1257 * 16 MHz) but the real value may vary depending on the variations
1258 * in voltage and temperature.
1259 * @note (**) HSE_VALUE is a constant defined in stm32wbaxx_hal_conf.h file (default value
1260 * 32 MHz), user has to ensure that HSE_VALUE is same as the real
1261 * frequency of the crystal used. Otherwise, this function may
1262 * have wrong result.
1263 * @note The result of this function could be not correct when using fractional
1264 * value for HSE crystal.
1265 * @note This function can be used by the user application to compute the
1266 * baudrate for the communication peripherals or configure other parameters.
1267 * @note Each time SYSCLK changes, this function must be called to update the
1268 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1269 * @retval SYSCLK frequency
1270 */
HAL_RCC_GetSysClockFreq(void)1271 uint32_t HAL_RCC_GetSysClockFreq(void)
1272 {
1273 uint32_t sysclk;
1274
1275 /* Get SYSCLK source */
1276 sysclk = __HAL_RCC_GET_SYSCLK_SOURCE();
1277
1278 if (sysclk == RCC_SYSCLKSOURCE_STATUS_HSI)
1279 {
1280 /* HSI used as system clock source */
1281 sysclk = HSI_VALUE;
1282 }
1283 else if (sysclk == RCC_SYSCLKSOURCE_STATUS_HSE)
1284 {
1285 /* HSE used as system clock source. Check if HSE is divided by 2 */
1286 sysclk = (HSE_VALUE >> ((RCC->CR & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos));
1287 }
1288 else
1289 {
1290 /* PLL1 used as system clock source */
1291 sysclk = HAL_RCC_GetPLL1RFreq();
1292 }
1293
1294 return sysclk;
1295 }
1296
1297 /**
1298 * @brief Return the HCLK frequency.
1299 * @note Each time HCLK changes, this function must be called to update the
1300 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1301 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1302 * @retval HCLK frequency in Hz
1303 */
HAL_RCC_GetHCLKFreq(void)1304 uint32_t HAL_RCC_GetHCLKFreq(void)
1305 {
1306 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1307 return SystemCoreClock;
1308 }
1309
1310 /**
1311 * @brief Return the PCLK1 frequency.
1312 * @note Each time PCLK1 changes, this function must be called to update the
1313 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1314 * @retval PCLK1 frequency in Hz
1315 */
HAL_RCC_GetPCLK1Freq(void)1316 uint32_t HAL_RCC_GetPCLK1Freq(void)
1317 {
1318 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1319 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos]);
1320 }
1321
1322 /**
1323 * @brief Return the PCLK2 frequency.
1324 * @note Each time PCLK2 changes, this function must be called to update the
1325 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1326 * @retval PCLK2 frequency in Hz
1327 */
HAL_RCC_GetPCLK2Freq(void)1328 uint32_t HAL_RCC_GetPCLK2Freq(void)
1329 {
1330 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1331 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE2) >> RCC_CFGR2_PPRE2_Pos]);
1332 }
1333
1334 /**
1335 * @brief Return the PCLK7 frequency.
1336 * @note Each time PCLK7 changes, this function must be called to update the
1337 * right PCLK7 value. Otherwise, any configuration based on this function will be incorrect.
1338 * @retval PCLK7 frequency in Hz
1339 */
HAL_RCC_GetPCLK7Freq(void)1340 uint32_t HAL_RCC_GetPCLK7Freq(void)
1341 {
1342 /* Get HCLK source and Compute PCLK7 frequency ---------------------------*/
1343 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR3 & RCC_CFGR3_PPRE7) >> RCC_CFGR3_PPRE7_Pos]);
1344 }
1345
1346 /**
1347 * @brief Return the HCLK5 frequency.
1348 * @note Each time HCLK5 changes, this function must be called to update the
1349 * right HCLK5 value. Otherwise, any configuration based on this function will be incorrect.
1350 * @note HCLK5 frequency depends on System clock source :
1351 - whenever PLL1 is selected as System clock source, HPRE5 prescaler is internally used to
1352 divide SYSCLK frequency and feed HCLK5.
1353 - whenever HSI or HSE are selected as System clock source, HDIV5 prescaler is internally used to
1354 divide SYSCLK frequency and feed HCLK5.
1355 * right HCLK5 value. Otherwise, any configuration based on this function will be incorrect.
1356 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1357 * @retval HCLK frequency in Hz
1358 */
HAL_RCC_GetHCLK5Freq(void)1359 uint32_t HAL_RCC_GetHCLK5Freq(void)
1360 {
1361 uint32_t tmp;
1362 uint32_t hclk5freq;
1363
1364 /* Get source of SYSCLK */
1365 tmp = (RCC->CFGR1 & RCC_CFGR1_SWS);
1366
1367 /* Depending on SYSCLK source */
1368 if (tmp != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1369 {
1370 /* HSI or HSE are source of SYSCLK, compute divider */
1371 tmp = (RCC->CFGR4 & RCC_CFGR4_HDIV5) >> RCC_CFGR4_HDIV5_Pos;
1372 tmp += 1u;
1373 }
1374 else
1375 {
1376 /* PLL1 is source of SYSCLK, compute prescaler */
1377 tmp = AHB5PrescTable[(RCC->CFGR4 & RCC_CFGR4_HPRE5)];
1378 }
1379
1380 /* Get SYCLK frequency */
1381 hclk5freq = (HAL_RCC_GetSysClockFreq() / tmp);
1382
1383 return hclk5freq;
1384 }
1385
1386 /**
1387 * @brief Return the PLL1P frequency.
1388 * @retval PLL1P frequency in Hz
1389 */
HAL_RCC_GetPLL1PFreq(void)1390 uint32_t HAL_RCC_GetPLL1PFreq(void)
1391 {
1392 uint32_t pllp;
1393
1394 /* PLL1P divider */
1395 pllp = ((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U;
1396
1397 /* Compute VCO output frequency and return PLL1P one */
1398 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllp);
1399 }
1400
1401 /**
1402 * @brief Return the PLL1Q frequency.
1403 * @retval PLL1Q frequency in Hz
1404 */
HAL_RCC_GetPLL1QFreq(void)1405 uint32_t HAL_RCC_GetPLL1QFreq(void)
1406 {
1407 uint32_t pllq;
1408
1409 /* PLL1Q divider */
1410 pllq = ((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U;
1411
1412 /* Compute VCO output frequency and return PLL1Q one */
1413 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllq);
1414 }
1415
1416 /**
1417 * @brief Return the PLL1R frequency.
1418 * @retval PLL1R frequency in Hz
1419 */
HAL_RCC_GetPLL1RFreq(void)1420 uint32_t HAL_RCC_GetPLL1RFreq(void)
1421 {
1422 uint32_t pllr;
1423
1424 /* PLL1R divider */
1425 pllr = ((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U;
1426
1427 /* Compute VCO output frequency and return PLL1R one */
1428 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllr);
1429 }
1430
1431 /**
1432 * @brief Configure the RCC_OscInitStruct according to the internal
1433 * RCC configuration registers.
1434 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1435 * will be configured.
1436 * @retval None
1437 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1438 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1439 {
1440 uint32_t regvalue;
1441 uint32_t mask;
1442
1443 /* Check the parameters */
1444 assert_param(RCC_OscInitStruct != (void *)NULL);
1445
1446 /* Set all possible values for the Oscillator type parameter ---------------*/
1447 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1448 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1449
1450 /* Get Backup Domain register 1 */
1451 regvalue = RCC->BDCR1;
1452
1453 /* Get the LSE configuration -----------------------------------------------*/
1454 mask = (RCC_BDCR1_LSEBYP | RCC_BDCR1_LSESYSEN | RCC_BDCR1_LSEON);
1455 RCC_OscInitStruct->LSEState = (regvalue & mask);
1456
1457 /* Get the LSI configuration -----------------------------------------------*/
1458 mask = RCC_BDCR1_LSI1ON;
1459 #if defined(RCC_LSI2_SUPPORT)
1460 mask |= RCC_BDCR1_LSI2ON;
1461 #endif
1462 RCC_OscInitStruct->LSIState = (regvalue & mask);
1463 RCC_OscInitStruct->LSIDiv = (regvalue & RCC_BDCR1_LSI1PREDIV);
1464
1465 /* Get Control register */
1466 regvalue = RCC->CR;
1467
1468 /* Get the HSE configuration -----------------------------------------------*/
1469 RCC_OscInitStruct->HSEState = (regvalue & RCC_CR_HSEON);
1470 RCC_OscInitStruct->HSEDiv = (regvalue & RCC_CR_HSEPRE);
1471
1472 /* Get the HSI configuration -----------------------------------------------*/
1473 RCC_OscInitStruct->HSIState = (regvalue & RCC_CR_HSION);
1474 RCC_OscInitStruct->HSICalibrationValue = ((RCC->ICSCR3 & RCC_ICSCR3_HSITRIM) >> RCC_ICSCR3_HSITRIM_Pos);
1475
1476 /* Get the PLL1 configuration -----------------------------------------------*/
1477 if ((regvalue & RCC_CR_PLL1ON) != 0x00u)
1478 {
1479 RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_ON;
1480 }
1481 else
1482 {
1483 RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_OFF;
1484 }
1485
1486 /* Get PLL1 configuration register */
1487 regvalue = RCC->PLL1CFGR;
1488 RCC_OscInitStruct->PLL1.PLLSource = (regvalue & RCC_PLL1CFGR_PLL1SRC);
1489 RCC_OscInitStruct->PLL1.PLLM = (((regvalue & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U);
1490
1491 /* Check if fractional part is enable */
1492 if ((regvalue & RCC_PLL1CFGR_PLL1FRACEN) != 0x00u)
1493 {
1494 regvalue = (((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos));
1495 }
1496 else
1497 {
1498 regvalue = 0;
1499 }
1500 RCC_OscInitStruct->PLL1.PLLFractional = regvalue;
1501
1502 /* Get PLL1 dividers register */
1503 regvalue = RCC->PLL1DIVR;
1504 RCC_OscInitStruct->PLL1.PLLN = ((regvalue & RCC_PLL1DIVR_PLL1N) + 1U);
1505 RCC_OscInitStruct->PLL1.PLLQ = (((regvalue & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U);
1506 RCC_OscInitStruct->PLL1.PLLR = (((regvalue & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U);
1507 RCC_OscInitStruct->PLL1.PLLP = (((regvalue & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U);
1508
1509 }
1510
1511 /**
1512 * @brief Configure the RCC_ClkInitStruct according to the internal
1513 * RCC configuration registers.
1514 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1515 * will be configured.
1516 * @param pFLatency Pointer on the Flash Latency.
1517 * @retval None
1518 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1519 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1520 {
1521 uint32_t tmpreg1;
1522
1523 /* Check the parameters */
1524 assert_param(RCC_ClkInitStruct != (void *)NULL);
1525 assert_param(pFLatency != (void *)NULL);
1526
1527 /* Set all possible values for the Clock type parameter --------------------*/
1528 RCC_ClkInitStruct->ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 |
1529 RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK7 | RCC_CLOCKTYPE_HCLK5);
1530
1531 /* Get the SYSCLK configuration --------------------------------------------*/
1532 RCC_ClkInitStruct->SYSCLKSource = (RCC->CFGR1 & RCC_CFGR1_SW);
1533
1534 /* Get the HCLK configuration ----------------------------------------------*/
1535 tmpreg1 = RCC->CFGR2;
1536 RCC_ClkInitStruct->AHBCLKDivider = (tmpreg1 & RCC_CFGR2_HPRE);
1537
1538 /* Get the PCLK1 configuration ----------------------------------------------*/
1539 RCC_ClkInitStruct->APB1CLKDivider = (tmpreg1 & RCC_CFGR2_PPRE1);
1540
1541 /* Get the PCLK2 configuration ----------------------------------------------*/
1542 RCC_ClkInitStruct->APB2CLKDivider = ((tmpreg1 & RCC_CFGR2_PPRE2) >> (RCC_CFGR2_PPRE2_Pos - RCC_CFGR2_PPRE1_Pos));
1543
1544 /* Get the PCLK7 configuration ----------------------------------------------*/
1545 RCC_ClkInitStruct->APB7CLKDivider = (RCC->CFGR3 & RCC_CFGR3_PPRE7);
1546
1547 /* Get the PCLK1 configuration ----------------------------------------------*/
1548 tmpreg1 = RCC->CFGR4;
1549 RCC_ClkInitStruct->AHB5_PLL1_CLKDivider = (tmpreg1 & RCC_CFGR4_HPRE5);
1550 RCC_ClkInitStruct->AHB5_HSEHSI_CLKDivider = (tmpreg1 & RCC_CFGR4_HDIV5);
1551
1552 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1553 *pFLatency = (FLASH->ACR & FLASH_ACR_LATENCY);
1554 }
1555
1556 /**
1557 * @brief Enable the Clock Security System.
1558 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1559 * is automatically disabled and an interrupt is generated to inform the
1560 * software about the failure (Clock Security System Interrupt, CSSI),
1561 * allowing the MCU to perform rescue operations. The CSSI is linked to
1562 * the Cortex-M33 NMI (Non-Maskable Interrupt) exception vector.
1563 * @note The Clock Security System can only be cleared by reset.
1564 * @retval None
1565 */
HAL_RCC_EnableCSS(void)1566 void HAL_RCC_EnableCSS(void)
1567 {
1568 SET_BIT(RCC->CR, RCC_CR_HSECSSON);
1569 }
1570
1571 /**
1572 * @brief Handle the RCC Clock Security System interrupt request.
1573 * @note This API should be called under the NMI_Handler().
1574 * @retval None
1575 */
HAL_RCC_NMI_IRQHandler(void)1576 void HAL_RCC_NMI_IRQHandler(void)
1577 {
1578 /* Check RCC CSSF interrupt flag */
1579 if (__HAL_RCC_GET_IT(RCC_IT_CSS))
1580 {
1581 /* RCC Clock Security System interrupt user callback */
1582 HAL_RCC_CSSCallback();
1583
1584 /* Clear RCC CSS pending bit */
1585 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1586 }
1587 }
1588
1589 /**
1590 * @brief RCC Clock Security System interrupt callback.
1591 * @retval none
1592 */
HAL_RCC_CSSCallback(void)1593 __weak void HAL_RCC_CSSCallback(void)
1594 {
1595 /* NOTE : This function should not be modified, when the callback is needed,
1596 the HAL_RCC_CSSCallback should be implemented in the user file
1597 */
1598 }
1599
1600 /**
1601 * @brief Get and clear reset flags
1602 * @note Once reset flags are retrieved, this API is clearing them in order
1603 * to isolate next reset reason.
1604 * @retval can be a combination of @ref RCC_Reset_Flag
1605 */
HAL_RCC_GetResetSource(void)1606 uint32_t HAL_RCC_GetResetSource(void)
1607 {
1608 uint32_t reset;
1609
1610 /* Get all reset flags */
1611 reset = RCC->CSR & RCC_RESET_FLAG_ALL;
1612
1613 /* Clear Reset flags */
1614 RCC->CSR |= RCC_CSR_RMVF;
1615
1616 return reset;
1617 }
1618
1619 /**
1620 * @}
1621 */
1622
1623 #if defined(RCC_PRIVCFGR_NSPRIV)
1624 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1625 * @brief Attributes management functions.
1626 *
1627 @verbatim
1628 ===============================================================================
1629 ##### RCC attributes functions #####
1630 ===============================================================================
1631 @endverbatim
1632 * @{
1633 */
1634 /**
1635 * @brief Configure the RCC item attribute(s).
1636 * @note Available attributes are to secure items and set RCC as privileged.
1637 * @param Item Item(s) to set attributes on.
1638 * This parameter can be a one or a combination of @ref RCC_items
1639 * @param Attributes specifies the RCC secure/privilege attributes.
1640 * This parameter can be a value of @ref RCC_attributes
1641 * @retval None
1642 */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1643 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1644 {
1645 /* Check the parameters */
1646 assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1647 assert_param(IS_RCC_ATTRIBUTES(Attributes));
1648
1649 switch (Attributes)
1650 {
1651 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1652 /* Secure Privilege attribute */
1653 case RCC_SEC_PRIV:
1654 SET_BIT(RCC->SECCFGR, Item);
1655 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1656 break;
1657 /* Secure Non-Privilege attribute */
1658 case RCC_SEC_NPRIV:
1659 SET_BIT(RCC->SECCFGR, Item);
1660 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1661 break;
1662 /* Non-secure Privilege attribute */
1663 case RCC_NSEC_PRIV:
1664 CLEAR_BIT(RCC->SECCFGR, Item);
1665 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1666 break;
1667 /* Non-secure Non-Privilege attribute */
1668 case RCC_NSEC_NPRIV:
1669 CLEAR_BIT(RCC->SECCFGR, Item);
1670 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1671 break;
1672 #else
1673 /* Non-secure Privilege attribute */
1674 case RCC_NSEC_PRIV:
1675 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1676 break;
1677 /* Non-secure Non-Privilege attribute */
1678 case RCC_NSEC_NPRIV:
1679 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1680 break;
1681 #endif /* __ARM_FEATURE_CMSE */
1682 default:
1683 /* Nothing to do */
1684 break;
1685 }
1686 }
1687 /**
1688 * @}
1689 */
1690
1691 /**
1692 * @brief Get the attribute of a RCC item.
1693 * @note Secure and non-secure attributes are only available from secure state
1694 * when the system implements the security (TZEN=1)
1695 * @param Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
1696 * This parameter can be a one value of @ref RCC_items except RCC_ALL.
1697 * @param pAttributes pointer to return the attributes.
1698 * @retval HAL Status.
1699 */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1700 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1701 {
1702 uint32_t attributes;
1703
1704 /* Check null pointer */
1705 if (pAttributes == NULL)
1706 {
1707 return HAL_ERROR;
1708 }
1709
1710 /* Check the parameters */
1711 assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1712
1713 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1714 /* Check item security */
1715 if ((RCC->SECCFGR & Item) == Item)
1716 {
1717 /* Get Secure privileges attribute */
1718 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_SPRIV) == 0U) ? RCC_SEC_NPRIV : RCC_SEC_PRIV;
1719 }
1720 else
1721 {
1722 /* Get Non-Secure privileges attribute */
1723 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1724 }
1725 #else
1726 /* Get Non-Secure privileges attribute */
1727 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1728 #endif /* __ARM_FEATURE_CMSE */
1729
1730 /* return value */
1731 *pAttributes = attributes;
1732
1733 return HAL_OK;
1734 }
1735 /**
1736 * @}
1737 */
1738 #endif
1739
1740 /* Private functions ---------------------------------------------------------*/
1741 /** @addtogroup RCC_Private_Functions
1742 * @{
1743 */
1744 /**
1745 * @brief Compute PLL1 VCO output frequency
1746 * @retval Value of PLL1 VCO output frequency
1747 */
RCC_PLL1_GetVCOOutputFreq(void)1748 static float_t RCC_PLL1_GetVCOOutputFreq(void)
1749 {
1750 uint32_t tmpreg1;
1751 uint32_t tmp;
1752 float_t pllsrc;
1753 float_t pllm;
1754 float_t plln;
1755 float_t pllfracn;
1756
1757 /* Get PLL1 DIVR register value */
1758 tmpreg1 = RCC->PLL1DIVR;
1759
1760 /* Retrieve PLL1 multiplication factor */
1761 tmp = (tmpreg1 & RCC_PLL1DIVR_PLL1N) + 1U;
1762 plln = (float_t) tmp;
1763
1764 /* Get PLL1 CFGR register value */
1765 tmpreg1 = RCC->PLL1CFGR;
1766
1767 /* Retrieve PLL1 divider */
1768 tmp = ((tmpreg1 & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U;
1769 pllm = (float_t) tmp;
1770
1771 /* Check if fractional part is enable */
1772 if ((tmpreg1 & RCC_PLL1CFGR_PLL1FRACEN) != 0x00u)
1773 {
1774 tmp = ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos);
1775 }
1776 else
1777 {
1778 tmp = 0u;
1779 }
1780 pllfracn = (float_t)tmp;
1781
1782 /* determine PLL source */
1783 switch (tmpreg1 & RCC_PLL1CFGR_PLL1SRC)
1784 {
1785 /* HSI used as PLL1 clock source */
1786 case RCC_PLLSOURCE_HSI:
1787 pllsrc = (float_t)HSI_VALUE;
1788 break;
1789
1790 /* HSE used as PLL1 clock source */
1791 case RCC_PLLSOURCE_HSE:
1792 tmp = (HSE_VALUE >> ((RCC->CR & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos));
1793 pllsrc = (float_t)tmp;
1794 break;
1795
1796 default:
1797 pllsrc = (float_t)0;
1798 break;
1799 }
1800
1801 /* Compute VCO output frequency */
1802 return ((pllsrc / pllm) * (plln + (pllfracn / (float_t)0x2000u)));
1803 }
1804
1805
1806 /**
1807 * @}
1808 */
1809 #endif /* HAL_RCC_MODULE_ENABLED */
1810 /**
1811 * @}
1812 */
1813
1814 /**
1815 * @}
1816 */
1817
1818 /**
1819 * @}
1820 */
1821
1822