1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_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) 2023 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file in
18   * 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 Internal High Speed oscillator
28       (HSI 64MHz) and all peripherals are off except internal SRAM, BSEC, PWR, IAC,
29       RIFSC, RISAF and JTAG
30       (+) There is no pre-scaler on High speed (AHB) and Low speed (APB) buses;
31           all peripherals mapped on these buses are running at HSI speed.
32       (+) All GPIOs are in analog mode , except the JTAG pins which
33           are assigned to be used for debug purpose.
34 
35     [..]
36       Once the device started from reset, the user application has to:
37       (+) Configure the clock source to be used to drive the System clock
38           (if the application needs higher frequency/performance than HSI)
39       (+) Configure the CPU and System bus clock frequencies
40       (+) Configure the AHB and APB buses pre-scalers
41       (+) Enable the clock for the peripheral(s) to be used
42       (+) Configure the clock kernel source(s) for peripherals which clocks are not
43           derived from the System clock
44 
45                       ##### RCC Limitations #####
46   ==============================================================================
47     [..]
48       A delay between an RCC peripheral clock enable and the effective peripheral
49       enabling should be taken into account in order to manage the peripheral read/write
50       from/to registers.
51       (+) This delay depends on the peripheral mapping.
52       (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle
53           after the clock enable bit is set on the hardware register
54       (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle
55           after the clock enable bit is set on the hardware register
56 
57     [..]
58       Implemented Workaround:
59       (+) For AHB & APB peripherals, a dummy read to the peripheral register has been
60           inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
61 
62     [..]
63       Incorrect APB prescaler setting:
64       (+) As described in the product errata, after enabling the bus clock to the
65       peripheral and changing the default APB prescaler setting, performing a
66       configuration on the bus peripheral does not update the peripheral registers,
67       resulting in unexpected behavior.
68 
69   @endverbatim
70   */
71 
72 /* Includes ------------------------------------------------------------------*/
73 #include "stm32n6xx_hal.h"
74 
75 /** @addtogroup STM32N6xx_HAL_Driver
76   * @{
77   */
78 
79 /** @defgroup RCC  RCC
80   * @brief RCC HAL module driver
81   * @{
82   */
83 
84 #ifdef HAL_RCC_MODULE_ENABLED
85 
86 /* Private typedef -----------------------------------------------------------*/
87 /* Private defines -----------------------------------------------------------*/
88 /** @defgroup RCC_Private_Constants RCC Private Constants
89   * @{
90   */
91 #define RCC_MSI_TIMEOUT_VALUE         1U    /* 1 ms */
92 #define RCC_HSI_TIMEOUT_VALUE         1U    /* 1 ms */
93 #define RCC_HSE_TIMEOUT_VALUE         HSE_STARTUP_TIMEOUT
94 #define RCC_LSI_TIMEOUT_VALUE         1U    /* 1 ms */
95 #define RCC_CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s  */
96 
97 #define RCC_PLL1_CONFIG           0U
98 #define RCC_PLL2_CONFIG           1U
99 #define RCC_PLL3_CONFIG           2U
100 #define RCC_PLL4_CONFIG           3U
101 
102 #define RCC_ITEM_GROUP_IDX_OSC        0x0UL
103 #define RCC_ITEM_GROUP_IDX_PLL        0x1UL
104 #define RCC_ITEM_GROUP_IDX_IC         0x2UL
105 #define RCC_ITEM_GROUP_IDX_SYSCFG     0x3UL
106 #define RCC_ITEM_GROUP_IDX_BUS        0x4UL
107 #define RCC_ITEM_GROUP_IDX_MEM        0x5UL
108 /**
109   * @}
110   */
111 
112 /* Private macros ------------------------------------------------------------*/
113 /** @defgroup RCC_Private_Macros RCC Private Macros
114   * @{
115   */
116 #define RCC_MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
117 #define RCC_MCO1_GPIO_PORT        GPIOA
118 #define RCC_MCO1_PIN              GPIO_PIN_8
119 
120 #define RCC_MCO2_CLK_ENABLE()     __HAL_RCC_GPIOC_CLK_ENABLE()
121 #define RCC_MCO2_GPIO_PORT        GPIOC
122 #define RCC_MCO2_PIN              GPIO_PIN_9
123 /**
124   * @}
125   */
126 
127 /* Private variables ---------------------------------------------------------*/
128 /* Private function prototypes -----------------------------------------------*/
129 static HAL_StatusTypeDef RCC_PLL_Config(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit);
130 static HAL_StatusTypeDef RCC_PLL_Enable(uint32_t PLLnumber);
131 static uint32_t RCC_PLL_IsNewConfig(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit);
132 static uint32_t RCC_PLL_Source_IsReady(uint32_t PLLSource);
133 static uint32_t RCC_IC_CheckPLLSources(uint32_t PLLSource1, uint32_t PLLSource2);
134 static void RCC_ATTR_ConfigItemGroup(uint32_t ItemGroup, uint32_t Item, uint32_t Attributes);
135 
136 /* Exported functions --------------------------------------------------------*/
137 /** @defgroup RCC_Exported_Functions RCC Exported Functions
138   * @{
139   */
140 
141 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
142   *  @brief    Initialization and Configuration functions
143   *
144 @verbatim
145  ===============================================================================
146            ##### Initialization and de-initialization functions #####
147  ===============================================================================
148     [..]
149       This section provides functions allowing to configure the internal/external oscillators
150       (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the CPU and System buses clocks (SYSCLK, AHB1,
151        AHB2, AHB3, AHB4, AHB5, APB1, APB2, APB4 and APB5).
152 
153     [..] Internal/external clock and PLL configuration
154          (#) HSI (high-speed internal), 64 MHz factory-trimmed RC used directly or through
155              the PLL as System clock source.
156 
157          (#) MSI is a low-power RC oscillator which can be used directly as system clock, peripheral
158              clock, or PLL input.But even with frequency calibration, is less accurate than an
159              external crystal oscillator or ceramic resonator.
160 
161          (#) LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC
162              clock source.
163 
164          (#) HSE (high-speed external), 4 to 48 MHz crystal oscillator used directly or
165              through the PLL as System clock source. Can be used also as RTC clock source.
166 
167          (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
168 
169          (#) PLL , The RCC features three independent PLLs (clocked by HSI , HSE or MSI),
170              featuring three different output clocks and able  to work either in integer or Fractional mode.
171            (++) A main PLL, PLL1, which is generally used to provide clocks to the CPU
172                 and to some peripherals via the ICx mux.
173            (++) Two dedicated PLLs, PLL2 and PLL3, which are used to generate the kernel clock for peripherals.
174 
175          (#) HSE CSS (Clock security system), once enabled and if a HSE clock failure occurs
176             (HSE used directly or through PLL as System clock source), the System clock
177              is automatically switched to HSI and an interrupt is generated if enabled.
178              The interrupt is linked to the Cortex-M NMI (Non-Maskable Interrupt)
179              exception vector.
180 
181          (#) LSE CSS (Clock security system), once enabled and if a LSE clock failure occurs
182              the LSE is no more provided to RTC, it allows to wake-up from standby mode and protect the
183              backup registers and BKPSRAM via TAMP. The LSE CSS may be re-armed for further attempt(s) to use LSE.
184 
185          (#) MCO1 (micro controller clock output), used to output HSI, LSE, HSE, LSI, MSI, CPU (SYSA), IC5 mux
186              or IC10 mux clock (through a configurable pre-scaler) on PA8 pin.
187 
188          (#) MCO2 (micro controller clock output), used to output HSI, LSE, HSE, LSI, MSI, System Bus (SYSB),
189              IC15 mux or IC20 mux clock (through a configurable pre-scaler) on PC9 pin.
190 
191     [..] CPU, System bus, AHB and APB buses clocks configuration
192          (#) Several clock sources can be used to drive independently the CPU (CPUCLK) and System bus clock (SYSCLK):
193              HSI, MSI, HSE or ICx mux.
194              The AHB clock (HCLK) is derived from System core clock through configurable
195              pre-scaler and used to clock the CPU, memory and peripherals mapped
196              on AHB and APB bus through configurable pre-scalers
197              and used to clock the peripherals mapped on these buses. You can use
198              "HAL_RCC_GetSysClockFreq()" function to retrieve system clock frequency.
199 
200          -@- All the peripheral clocks are derived from the System bus clock (SYSCLK).
201 
202 @endverbatim
203   * @{
204   */
205 
206 /**
207   * @brief  Resets the RCC clock configuration to the default reset state.
208   * @note   The default reset state of the clock configuration is given below:
209   *            - HSI ON and used as CPU and system clock source
210   *            - MSI and HSE OFF
211   *            - PLL1, PLL2, PLL3 and PLL4 bypassed
212   *            - AHB, APB Bus prescalers set to 1
213   *            - CSS, MCO1 and MCO2 OFF
214   *            - All interrupts disabled
215   * @note   This function doesn't modify the configuration of the
216   *            - Peripheral clocks
217   *            - Memory clocks
218   *            - Misc clocks
219   *            - LSI, LSE and RTC clocks
220   *            - ICx selections and dividers
221   * @retval HAL status
222   */
HAL_RCC_DeInit(void)223 HAL_StatusTypeDef HAL_RCC_DeInit(void)
224 {
225   uint32_t tickstart;
226 
227   /* Disable all interrupts except default one */
228   WRITE_REG(RCC->CIER, RCC_CIER_HSECSSIE);
229 
230   /* Clear all interrupts flags */
231   WRITE_REG(RCC->CICR, RCC_CICR_LSIRDYC | RCC_CICR_LSERDYC | RCC_CICR_MSIRDYC | RCC_CICR_HSIRDYC | RCC_CICR_HSERDYC | \
232             RCC_CICR_PLL1RDYC | RCC_CICR_PLL2RDYC | RCC_CICR_PLL3RDYC | RCC_CICR_PLL4RDYC | \
233             RCC_CICR_LSECSSC | RCC_CICR_HSECSSC | RCC_CICR_WKUPFC);
234 
235   /* Clear reset source flags */
236   SET_BIT(RCC->RSR, RCC_RSR_RMVF);
237 
238   /* Restore default HSI */
239   LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV_1);
240   LL_RCC_HSI_Enable();
241 
242   /* Get Start Tick */
243   tickstart = HAL_GetTick();
244 
245   /* Wait for HSI READY bit */
246   while (LL_RCC_HSI_IsReady() == 0U)
247   {
248     if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
249     {
250       return HAL_TIMEOUT;
251     }
252   }
253 
254   /* Reset CFGR1 register to select HSI as CPU and system bus clock */
255   CLEAR_REG(RCC->CFGR1);
256 
257   /* Get Start Tick */
258   tickstart = HAL_GetTick();
259 
260   /* Wait till clock switch is ready */
261   while (READ_BIT(RCC->CFGR1, (RCC_CFGR1_CPUSWS | RCC_CFGR1_SYSSWS)) != 0U)
262   {
263     if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
264     {
265       return HAL_TIMEOUT;
266     }
267   }
268 
269   /* Update the SystemCoreClock variable */
270   SystemCoreClock = HSI_VALUE;
271 
272   /* Adapt Systick interrupt period */
273   if (HAL_InitTick(uwTickPrio) != HAL_OK)
274   {
275     return HAL_TIMEOUT;
276   }
277 
278   /* Reset PLL1 registers to default value */
279   WRITE_REG(RCC->PLL1CFGR1, 0x08202500U);
280   WRITE_REG(RCC->PLL1CFGR2, 0x00800000U);
281   WRITE_REG(RCC->PLL1CFGR3, 0x4900000DU);
282   /* Reset PLL2 registers to default value */
283   WRITE_REG(RCC->PLL2CFGR1, 0x08000000U);
284   WRITE_REG(RCC->PLL2CFGR2, 0x00000000U);
285   WRITE_REG(RCC->PLL2CFGR3, 0x49000005U);
286   /* Reset PLL3 registers to default value */
287   WRITE_REG(RCC->PLL3CFGR1, 0x08000000U);
288   WRITE_REG(RCC->PLL3CFGR2, 0x00000000U);
289   WRITE_REG(RCC->PLL3CFGR3, 0x49000005U);
290   /* Reset PLL4 registers to default value */
291   WRITE_REG(RCC->PLL4CFGR1, 0x08000000U);
292   WRITE_REG(RCC->PLL4CFGR2, 0x00000000U);
293   WRITE_REG(RCC->PLL4CFGR3, 0x49000005U);
294 
295   /* Reset MSION, HSEON, PLL1ON, PLL2ON, PLL3ON and PLL4ON bits */
296   WRITE_REG(RCC->CCR, RCC_CCR_MSIONC | RCC_CCR_HSEONC | \
297             RCC_CCR_PLL1ONC | RCC_CCR_PLL2ONC | RCC_CCR_PLL3ONC | RCC_CCR_PLL4ONC);
298 
299   /* Get Start Tick */
300   tickstart = HAL_GetTick();
301 
302   /* Wait for all PLL ready bits to be reset */
303   while (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY | RCC_SR_PLL2RDY | RCC_SR_PLL3RDY | RCC_SR_PLL4RDY)) != 0U)
304   {
305     if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
306     {
307       return HAL_TIMEOUT;
308     }
309   }
310 
311   /* Reset prescalers in CFGR2 register to default values*/
312   WRITE_REG(RCC->CFGR2, 0x00100000U);
313 
314   /* Reset MSICFGR register */
315   CLEAR_REG(RCC->MSICFGR);
316 
317   /* Reset HSIMCR register to default value */
318   WRITE_REG(RCC->HSIMCR, 0x001F07A1U);
319 
320   /* Reset HSECFGR register to default value */
321   WRITE_REG(RCC->HSECFGR, 0x00000800U);
322 
323   /* Reset STOPCR register to default value */
324   WRITE_REG(RCC->STOPCR, 0x00000002U);
325 
326   /* Disable MCO1 and MCO2 */
327   CLEAR_BIT(RCC->MISCENR, RCC_MISCENR_MCO1EN | RCC_MISCENR_MCO2EN);
328 
329   return HAL_OK;
330 }
331 
332 /**
333   * @brief  Initializes the RCC Oscillators according to the specified parameters in the
334   *         RCC_OscInitTypeDef.
335   * @param  pRCC_OscInitStruct  Pointer to an RCC_OscInitTypeDef structure that
336   *         contains the configuration information for the RCC Oscillators.
337   * @note   LSE control requires that the backup domain shall be previously enabled
338   *         with HAL_PWR_EnableBkUpAccess().
339   * @note   The PLL is not disabled when used as system clock.
340   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
341   *         supported by this function. User should request a transition to LSE Off
342   *         first and then LSE On or LSE Bypass.
343   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
344   *         supported by this function. User should request a transition to HSE Off
345   *         first and then HSE On or HSE Bypass.
346   * @note   This function does not protect the MCOxSEL, the PERSEL and the PPPSEL glitch-free muxes
347   *         (Mux selection cannot be changed if selected input clock is inactive).
348   * @retval HAL status
349   */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * pRCC_OscInitStruct)350 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef  *pRCC_OscInitStruct)
351 {
352   uint32_t tickstart;
353   uint32_t sysclksrc;
354   uint32_t cpuclksrc;
355   uint32_t pll1src;
356   uint32_t pll2src;
357   uint32_t pll3src;
358   uint32_t pll4src;
359   uint32_t rccsr;
360 
361   /* Check Null pointer */
362   if (pRCC_OscInitStruct == NULL)
363   {
364     return HAL_ERROR;
365   }
366 
367   /* Check the parameters */
368   assert_param(IS_RCC_OSCILLATORTYPE(pRCC_OscInitStruct->OscillatorType));
369 
370   cpuclksrc = LL_RCC_GetCpuClkSource();
371   sysclksrc = LL_RCC_GetSysClkSource();
372   pll1src = LL_RCC_PLL1_GetSource();
373   pll2src = LL_RCC_PLL2_GetSource();
374   pll3src = LL_RCC_PLL3_GetSource();
375   pll4src = LL_RCC_PLL4_GetSource();
376   rccsr = RCC->SR;
377 
378   /*------------------------------- HSE Configuration ------------------------*/
379   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
380   {
381     /* Check the parameters */
382     assert_param(IS_RCC_HSE(pRCC_OscInitStruct->HSEState));
383 
384     /* When the HSE is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled */
385     if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_HSE) || (sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
386         ((pll1src == LL_RCC_PLLSOURCE_HSE) && (((rccsr & RCC_SR_PLL1RDY) == RCC_SR_PLL1RDY))) ||
387         ((pll2src == LL_RCC_PLLSOURCE_HSE) && (((rccsr & RCC_SR_PLL2RDY) == RCC_SR_PLL2RDY))) ||
388         ((pll3src == LL_RCC_PLLSOURCE_HSE) && (((rccsr & RCC_SR_PLL3RDY) == RCC_SR_PLL3RDY))) ||
389         ((pll4src == LL_RCC_PLLSOURCE_HSE) && (((rccsr & RCC_SR_PLL4RDY) == RCC_SR_PLL4RDY))))
390     {
391       if (pRCC_OscInitStruct->HSEState == RCC_HSE_OFF)
392       {
393         return HAL_ERROR;
394       }
395       /* HSE ON , nothing to do */
396     }
397     else
398     {
399       /* Set the new HSE configuration ---------------------------------------*/
400       __HAL_RCC_HSE_CONFIG(pRCC_OscInitStruct->HSEState);
401 
402       /* Get Start Tick*/
403       tickstart = HAL_GetTick();
404 
405       /* Check the HSE State */
406       if (pRCC_OscInitStruct->HSEState != RCC_HSE_OFF)
407       {
408         /* Wait till HSE is ready */
409         while (READ_BIT(RCC->SR, RCC_SR_HSERDY) == 0U)
410         {
411           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
412           {
413             return HAL_TIMEOUT;
414           }
415         }
416       }
417       else
418       {
419         /* Wait till HSE is disabled */
420         while (READ_BIT(RCC->SR, RCC_SR_HSERDY) != 0U)
421         {
422           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
423           {
424             return HAL_TIMEOUT;
425           }
426         }
427       }
428     }
429   }
430 
431   /*----------------------------- HSI Configuration --------------------------*/
432   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
433   {
434     /* Check the parameters */
435     assert_param(IS_RCC_HSI(pRCC_OscInitStruct->HSIState));
436 
437     /* When the HSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled */
438     if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_HSI) || (sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
439         ((pll1src == LL_RCC_PLLSOURCE_HSI) && (((rccsr & RCC_SR_PLL1RDY) == RCC_SR_PLL1RDY))) ||
440         ((pll2src == LL_RCC_PLLSOURCE_HSI) && (((rccsr & RCC_SR_PLL2RDY) == RCC_SR_PLL2RDY))) ||
441         ((pll3src == LL_RCC_PLLSOURCE_HSI) && (((rccsr & RCC_SR_PLL3RDY) == RCC_SR_PLL3RDY))) ||
442         ((pll4src == LL_RCC_PLLSOURCE_HSI) && (((rccsr & RCC_SR_PLL4RDY) == RCC_SR_PLL4RDY))))
443     {
444       /* When HSI is used as system clock it will not be disabled */
445       if (pRCC_OscInitStruct->HSIState == RCC_HSI_OFF)
446       {
447         return HAL_ERROR;
448       }
449       /* Otherwise, just the divider and calibration is allowed */
450       else
451       {
452         /* Check the parameters */
453         assert_param(IS_RCC_HSI_DIV(pRCC_OscInitStruct->HSIDiv));
454         assert_param(IS_RCC_HSI_CALIBRATION_VALUE(pRCC_OscInitStruct->HSICalibrationValue));
455 
456         /* Set the HSI Divider */
457         __HAL_RCC_HSI_DIVIDER_CONFIG(pRCC_OscInitStruct->HSIDiv);
458         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
459         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pRCC_OscInitStruct->HSICalibrationValue);
460       }
461     }
462     else
463     {
464       /* Check the HSI State */
465       if (pRCC_OscInitStruct->HSIState != RCC_HSI_OFF)
466       {
467         /* Check the parameters */
468         assert_param(IS_RCC_HSI_DIV(pRCC_OscInitStruct->HSIDiv));
469         assert_param(IS_RCC_HSI_CALIBRATION_VALUE(pRCC_OscInitStruct->HSICalibrationValue));
470 
471         /* Enable the Internal High Speed oscillator (HSI). */
472         __HAL_RCC_HSI_ENABLE();
473 
474         /* Get Start Tick*/
475         tickstart = HAL_GetTick();
476 
477         /* Wait till HSI is ready */
478         while (LL_RCC_HSI_IsReady() == 0U)
479         {
480           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
481           {
482             return HAL_TIMEOUT;
483           }
484         }
485 
486         /* Set the HSI Divider */
487         __HAL_RCC_HSI_DIVIDER_CONFIG(pRCC_OscInitStruct->HSIDiv);
488         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
489         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pRCC_OscInitStruct->HSICalibrationValue);
490       }
491       else
492       {
493         /* Disable the Internal High Speed oscillator (HSI). */
494         __HAL_RCC_HSI_DISABLE();
495 
496         /* Get Start Tick*/
497         tickstart = HAL_GetTick();
498 
499         /* Wait till HSI is disabled */
500         while (LL_RCC_HSI_IsReady() != 0U)
501         {
502           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
503           {
504             return HAL_TIMEOUT;
505           }
506         }
507       }
508     }
509   }
510 
511   /*----------------------------- MSI Configuration --------------------------*/
512   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
513   {
514     /* Check the parameters */
515     assert_param(IS_RCC_MSI(pRCC_OscInitStruct->MSIState));
516 
517     /* When the MSI is used as cpu/system bus clock or clock source for any PLL, it is not allowed to be disabled */
518     /* but just to update the MSI calibration value */
519     if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_MSI) || (sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI) ||
520         ((pll1src == LL_RCC_PLLSOURCE_MSI) && (((rccsr & RCC_SR_PLL1RDY) == RCC_SR_PLL1RDY))) ||
521         ((pll2src == LL_RCC_PLLSOURCE_MSI) && (((rccsr & RCC_SR_PLL2RDY) == RCC_SR_PLL2RDY))) ||
522         ((pll3src == LL_RCC_PLLSOURCE_MSI) && (((rccsr & RCC_SR_PLL3RDY) == RCC_SR_PLL3RDY))) ||
523         ((pll4src == LL_RCC_PLLSOURCE_MSI) && (((rccsr & RCC_SR_PLL4RDY) == RCC_SR_PLL4RDY))))
524     {
525       /* When MSI is used as system clock it will not disabled */
526       if (pRCC_OscInitStruct->MSIState == RCC_MSI_OFF)
527       {
528         return HAL_ERROR;
529       }
530       /* Otherwise, just the calibration is allowed */
531       else
532       {
533         /* Check the parameters */
534         assert_param(IS_RCC_MSI_CALIBRATION_VALUE(pRCC_OscInitStruct->MSICalibrationValue));
535 
536         /* Adjusts the Internal High Speed oscillator (MSI) calibration value.*/
537         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(pRCC_OscInitStruct->MSICalibrationValue);
538       }
539     }
540     else
541     {
542       /* Check the MSI State */
543       if ((pRCC_OscInitStruct->MSIState) != RCC_MSI_OFF)
544       {
545         /* Check the parameters */
546         assert_param(IS_RCC_MSI_FREQUENCY(pRCC_OscInitStruct->MSIFrequency));
547         assert_param(IS_RCC_MSI_CALIBRATION_VALUE(pRCC_OscInitStruct->MSICalibrationValue));
548 
549         /* Set the frequency */
550         __HAL_RCC_MSI_FREQUENCY_CONFIG(pRCC_OscInitStruct->MSIFrequency);
551 
552         /* Enable the Internal High Speed oscillator (MSI). */
553         __HAL_RCC_MSI_ENABLE();
554 
555         /* Get Start Tick*/
556         tickstart = HAL_GetTick();
557 
558         /* Wait till MSI is ready */
559         while (LL_RCC_MSI_IsReady() == 0U)
560         {
561           if ((HAL_GetTick() - tickstart) > RCC_MSI_TIMEOUT_VALUE)
562           {
563             return HAL_TIMEOUT;
564           }
565         }
566 
567         /* Adjusts the Internal High Speed oscillator (MSI) calibration value.*/
568         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(pRCC_OscInitStruct->MSICalibrationValue);
569       }
570       else
571       {
572         /* Ignore MSI frequency and calibration values in disable case */
573         /* Disable the Internal High Speed oscillator (MSI). */
574         __HAL_RCC_MSI_DISABLE();
575 
576         /* Get Start Tick*/
577         tickstart = HAL_GetTick();
578 
579         /* Wait till MSI is disabled */
580         while (LL_RCC_MSI_IsReady() != 0U)
581         {
582           if ((HAL_GetTick() - tickstart) > RCC_MSI_TIMEOUT_VALUE)
583           {
584             return HAL_TIMEOUT;
585           }
586         }
587       }
588     }
589   }
590 
591   /*------------------------------ LSI Configuration -------------------------*/
592   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
593   {
594     /* Check the parameters */
595     assert_param(IS_RCC_LSI(pRCC_OscInitStruct->LSIState));
596 
597     /* Check the LSI State */
598     if ((pRCC_OscInitStruct->LSIState) != RCC_LSI_OFF)
599     {
600       /* Enable the Internal Low Speed oscillator (LSI). */
601       __HAL_RCC_LSI_ENABLE();
602 
603       /* Get Start Tick*/
604       tickstart = HAL_GetTick();
605 
606       /* Wait till LSI is ready */
607       while (LL_RCC_LSI_IsReady() == 0U)
608       {
609         if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
610         {
611           return HAL_TIMEOUT;
612         }
613       }
614     }
615     else
616     {
617       /* Disable the Internal Low Speed oscillator (LSI). */
618       __HAL_RCC_LSI_DISABLE();
619 
620       /* Get Start Tick*/
621       tickstart = HAL_GetTick();
622 
623       /* Wait till LSI is ready */
624       while (LL_RCC_LSI_IsReady() != 0U)
625       {
626         if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
627         {
628           return HAL_TIMEOUT;
629         }
630       }
631     }
632   }
633 
634   /*------------------------------ LSE Configuration -------------------------*/
635   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
636   {
637     /* Check the parameters */
638     assert_param(IS_RCC_LSE(pRCC_OscInitStruct->LSEState));
639 
640     /* Set the new LSE configuration -----------------------------------------*/
641     __HAL_RCC_LSE_CONFIG(pRCC_OscInitStruct->LSEState);
642     /* Check the LSE State */
643     if ((pRCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
644     {
645       /* Get Start Tick*/
646       tickstart = HAL_GetTick();
647 
648       /* Wait till LSE is ready */
649       while (LL_RCC_LSE_IsReady() == 0U)
650       {
651         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
652         {
653           return HAL_TIMEOUT;
654         }
655       }
656     }
657     else
658     {
659       /* Get Start Tick*/
660       tickstart = HAL_GetTick();
661 
662       /* Wait till LSE is disabled */
663       while (LL_RCC_LSE_IsReady() != 0U)
664       {
665         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
666         {
667           return HAL_TIMEOUT;
668         }
669       }
670     }
671   }
672 
673   /*-------------------------------- PLL1 Configuration ----------------------*/
674   /* Check the parameters */
675   assert_param(IS_RCC_PLL(pRCC_OscInitStruct->PLL1.PLLState));
676 
677   if (pRCC_OscInitStruct->PLL1.PLLState != RCC_PLL_NONE)
678   {
679     uint32_t new_pll_config = RCC_PLL_IsNewConfig(RCC_PLL1_CONFIG, &(pRCC_OscInitStruct->PLL1));
680     uint32_t pll1_ready = LL_RCC_PLL1_IsReady();
681     if (new_pll_config == 1U)
682     {
683       uint32_t ic1src = LL_RCC_IC1_GetSource();
684       uint32_t ic2src = LL_RCC_IC2_GetSource();
685       uint32_t ic6src = LL_RCC_IC6_GetSource();
686       uint32_t ic11src = LL_RCC_IC11_GetSource();
687       /* PLL1 should not be disabled / reconfigured if used for IC1 (cpuclksrc) - return HAL_ERROR */
688       if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_IC1) && (ic1src == LL_RCC_ICCLKSOURCE_PLL1))
689       {
690         return HAL_ERROR;
691       }
692 
693       /* PLL1 should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc) - return HAL_ERROR  */
694       if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_IC2_IC6_IC11) && ((ic2src == LL_RCC_ICCLKSOURCE_PLL1) ||
695                                                                   (ic6src == LL_RCC_ICCLKSOURCE_PLL1) ||
696                                                                   (ic11src == LL_RCC_ICCLKSOURCE_PLL1)))
697       {
698         return HAL_ERROR;
699       }
700       /* PLL1 is not used, it can be configured */
701       if (RCC_PLL_Config(RCC_PLL1_CONFIG, &(pRCC_OscInitStruct->PLL1)) != HAL_OK)
702       {
703         return HAL_ERROR;
704       }
705     }
706     else if ((pRCC_OscInitStruct->PLL1.PLLState == RCC_PLL_ON) && (pll1_ready == 0U))
707     {
708       if (RCC_PLL_Enable(RCC_PLL1_CONFIG) != HAL_OK)
709       {
710         return HAL_ERROR;
711       }
712     }
713     else
714     {
715       /* Nothing to do */
716     }
717   }
718 
719   /*-------------------------------- PLL2 Configuration ----------------------*/
720   /* Check the parameters */
721   assert_param(IS_RCC_PLL(pRCC_OscInitStruct->PLL2.PLLState));
722 
723   if (pRCC_OscInitStruct->PLL2.PLLState != RCC_PLL_NONE)
724   {
725     uint32_t new_pll_config = RCC_PLL_IsNewConfig(RCC_PLL2_CONFIG, &(pRCC_OscInitStruct->PLL2));
726     uint32_t pll2_ready = LL_RCC_PLL2_IsReady();
727     if (new_pll_config == 1U)
728     {
729       uint32_t ic1src = LL_RCC_IC1_GetSource();
730       uint32_t ic2src = LL_RCC_IC2_GetSource();
731       uint32_t ic6src = LL_RCC_IC6_GetSource();
732       uint32_t ic11src = LL_RCC_IC11_GetSource();
733       /* PLL2 should not be disabled / reconfigured if used for IC1 (cpuclksrc) - return HAL_ERROR */
734       if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_IC1) && (ic1src == LL_RCC_ICCLKSOURCE_PLL2))
735       {
736         return HAL_ERROR;
737       }
738 
739       /* PLL2 should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc) - return HAL_ERROR  */
740       if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_IC2_IC6_IC11) && ((ic2src == LL_RCC_ICCLKSOURCE_PLL2) ||
741                                                                   (ic6src == LL_RCC_ICCLKSOURCE_PLL2) ||
742                                                                   (ic11src == LL_RCC_ICCLKSOURCE_PLL2)))
743       {
744         return HAL_ERROR;
745       }
746       /* PLL2 is not used, it can be configured */
747       if (RCC_PLL_Config(RCC_PLL2_CONFIG, &(pRCC_OscInitStruct->PLL2)) != HAL_OK)
748       {
749         return HAL_ERROR;
750       }
751     }
752     else if ((pRCC_OscInitStruct->PLL2.PLLState == RCC_PLL_ON) && (pll2_ready == 0U))
753     {
754       if (RCC_PLL_Enable(RCC_PLL2_CONFIG) != HAL_OK)
755       {
756         return HAL_ERROR;
757       }
758     }
759     else
760     {
761       /* Nothing to do */
762     }
763   }
764 
765   /*-------------------------------- PLL3 Configuration ----------------------*/
766   /* Check the parameters */
767   assert_param(IS_RCC_PLL(pRCC_OscInitStruct->PLL3.PLLState));
768 
769   if (pRCC_OscInitStruct->PLL3.PLLState != RCC_PLL_NONE)
770   {
771     uint32_t new_pll_config = RCC_PLL_IsNewConfig(RCC_PLL3_CONFIG, &(pRCC_OscInitStruct->PLL3));
772     uint32_t pll3_ready = LL_RCC_PLL1_IsReady();
773     if (new_pll_config == 1U)
774     {
775       uint32_t ic1src = LL_RCC_IC1_GetSource();
776       uint32_t ic2src = LL_RCC_IC2_GetSource();
777       uint32_t ic6src = LL_RCC_IC6_GetSource();
778       uint32_t ic11src = LL_RCC_IC11_GetSource();
779       /* PLL3 should not be disabled / reconfigured if used for IC1 (cpuclksrc) - return HAL_ERROR */
780       if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_IC1) && (ic1src == LL_RCC_ICCLKSOURCE_PLL3))
781       {
782         return HAL_ERROR;
783       }
784       /* PLL3 should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc) - return HAL_ERROR  */
785       if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_IC2_IC6_IC11) && ((ic2src == LL_RCC_ICCLKSOURCE_PLL3) ||
786                                                                   (ic6src == LL_RCC_ICCLKSOURCE_PLL3) ||
787                                                                   (ic11src == LL_RCC_ICCLKSOURCE_PLL3)))
788       {
789         return HAL_ERROR;
790       }
791       /* PLL3 is not used, it can be configured */
792       if (RCC_PLL_Config(RCC_PLL3_CONFIG, &(pRCC_OscInitStruct->PLL3)) != HAL_OK)
793       {
794         return HAL_ERROR;
795       }
796     }
797     else if ((pRCC_OscInitStruct->PLL3.PLLState == RCC_PLL_ON) && (pll3_ready == 0U))
798     {
799       if (RCC_PLL_Enable(RCC_PLL3_CONFIG) != HAL_OK)
800       {
801         return HAL_ERROR;
802       }
803     }
804     else
805     {
806       /* Nothing to do */
807     }
808   }
809 
810   /*-------------------------------- PLL4 Configuration ----------------------*/
811   /* Check the parameters */
812   assert_param(IS_RCC_PLL(pRCC_OscInitStruct->PLL4.PLLState));
813 
814   if (pRCC_OscInitStruct->PLL4.PLLState != RCC_PLL_NONE)
815   {
816     uint32_t new_pll_config = RCC_PLL_IsNewConfig(RCC_PLL4_CONFIG, &(pRCC_OscInitStruct->PLL4));
817     uint32_t pll4_ready = LL_RCC_PLL4_IsReady();
818 
819     if (new_pll_config == 1U)
820     {
821       uint32_t ic1src = LL_RCC_IC1_GetSource();
822       uint32_t ic2src = LL_RCC_IC2_GetSource();
823       uint32_t ic6src = LL_RCC_IC6_GetSource();
824       uint32_t ic11src = LL_RCC_IC11_GetSource();
825       /* PLL4 should not be disabled / reconfigured if used for IC1 (cpuclksrc) - return HAL_ERROR */
826       if ((cpuclksrc == RCC_CPUCLKSOURCE_STATUS_IC1) && (ic1src == LL_RCC_ICCLKSOURCE_PLL4))
827       {
828         return HAL_ERROR;
829       }
830       /* PLL4 should not be disabled / reconfigured if used for IC2, IC6 or IC11 (sysclksrc) - return HAL_ERROR  */
831       if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_IC2_IC6_IC11) && ((ic2src == LL_RCC_ICCLKSOURCE_PLL4) ||
832                                                                   (ic6src == LL_RCC_ICCLKSOURCE_PLL4) ||
833                                                                   (ic11src == LL_RCC_ICCLKSOURCE_PLL4)))
834       {
835         return HAL_ERROR;
836       }
837       /* PLL4 is not used, it can be configured */
838       if (RCC_PLL_Config(RCC_PLL4_CONFIG, &(pRCC_OscInitStruct->PLL4)) != HAL_OK)
839       {
840         return HAL_ERROR;
841       }
842     }
843     else if ((pRCC_OscInitStruct->PLL4.PLLState == RCC_PLL_ON) && (pll4_ready == 0U))
844     {
845       if (RCC_PLL_Enable(RCC_PLL4_CONFIG) != HAL_OK)
846       {
847         return HAL_ERROR;
848       }
849     }
850     else
851     {
852       /* Nothing to do */
853     }
854   }
855 
856   return HAL_OK;
857 }
858 
859 /**
860   * @brief  Initializes the CPU, System AXI, AHB, APB buses clocks according to the specified
861   *         parameters in the RCC_ClkInitStruct.
862   * @param  pRCC_ClkInitStruct  Pointer to an RCC_OscInitTypeDef structure that
863   *         contains the configuration information for the RCC peripheral.
864   *
865   * @note   The SystemCoreClock CMSIS variable is used to store System Core Clock Frequency
866   *         and updated by HAL_InitTick() function called within this function.
867   *
868   * @note   The HSI is used (enabled by hardware) as system clock source after
869   *         start-up from Reset, wake-up from STOP (unless MSI is selected) and STANDBY mode,
870   *         or in case of failure of the HSE used directly or indirectly as system clock
871   *         (if the Clock Security System CSS is enabled).
872   *
873   * @note   A switch from one clock source to another occurs only if the target
874   *         clock source is ready (clock stable after start-up delay or PLL locked).
875   *         If a clock source which is not yet ready is selected, the switch will
876   *         occur when the clock source will be ready.
877   *         You can use HAL_RCC_GetClockConfig() function to know which clock is
878   *         currently used as system clock source.
879   * @retval None
880   */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * pRCC_ClkInitStruct)881 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef  *pRCC_ClkInitStruct)
882 {
883   uint32_t tickstart;
884 
885   /* Check Null pointer */
886   if (pRCC_ClkInitStruct == NULL)
887   {
888     return HAL_ERROR;
889   }
890 
891   /* Check the parameters */
892   assert_param(IS_RCC_CLOCKTYPE(pRCC_ClkInitStruct->ClockType));
893 
894   /* Increasing the BUS frequency divider ? */
895 
896   /*-------------------------- PCLK1 Configuration ---------------------------*/
897   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
898   {
899     assert_param(IS_RCC_PCLK1(pRCC_ClkInitStruct->APB1CLKDivider));
900     if ((pRCC_ClkInitStruct->APB1CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE1))
901     {
902       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, (pRCC_ClkInitStruct->APB1CLKDivider));
903     }
904   }
905 
906   /*-------------------------- PCLK2 Configuration ---------------------------*/
907   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
908   {
909     assert_param(IS_RCC_PCLK2(pRCC_ClkInitStruct->APB2CLKDivider));
910     if ((pRCC_ClkInitStruct->APB2CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE2))
911     {
912       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, (pRCC_ClkInitStruct->APB2CLKDivider));
913     }
914   }
915 
916   /*-------------------------- PCLK4 Configuration ---------------------------*/
917   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK4) == RCC_CLOCKTYPE_PCLK4)
918   {
919     assert_param(IS_RCC_PCLK4(pRCC_ClkInitStruct->APB4CLKDivider));
920     if ((pRCC_ClkInitStruct->APB4CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE4))
921     {
922       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE4, (pRCC_ClkInitStruct->APB4CLKDivider));
923     }
924   }
925 
926   /*-------------------------- PCLK5 Configuration ---------------------------*/
927   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK5) == RCC_CLOCKTYPE_PCLK5)
928   {
929     assert_param(IS_RCC_PCLK5(pRCC_ClkInitStruct->APB5CLKDivider));
930     if ((pRCC_ClkInitStruct->APB5CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE5))
931     {
932       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE5, (pRCC_ClkInitStruct->APB5CLKDivider));
933     }
934   }
935 
936   /*-------------------------- HCLK Configuration --------------------------*/
937   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
938   {
939     assert_param(IS_RCC_HCLK(pRCC_ClkInitStruct->AHBCLKDivider));
940     if ((pRCC_ClkInitStruct->AHBCLKDivider) > (RCC->CFGR2 & RCC_CFGR2_HPRE))
941     {
942       /* Set the new HCLK clock divider */
943       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pRCC_ClkInitStruct->AHBCLKDivider);
944     }
945   }
946 
947   /*------------------------- CPUCLK Configuration -------------------------*/
948   if ((pRCC_ClkInitStruct->ClockType & RCC_CLOCKTYPE_CPUCLK) == RCC_CLOCKTYPE_CPUCLK)
949   {
950     assert_param(IS_RCC_CPUCLKSOURCE(pRCC_ClkInitStruct->CPUCLKSource));
951 
952     /* HSE is selected as CPU Clock Source */
953     if (pRCC_ClkInitStruct->CPUCLKSource == RCC_CPUCLKSOURCE_HSE)
954     {
955       /* Check the HSE ready flag */
956       if (LL_RCC_HSE_IsReady() == 0U)
957       {
958         return HAL_ERROR;
959       }
960     }
961     /* PLL is selected as CPU Clock Source */
962     else if (pRCC_ClkInitStruct->CPUCLKSource == RCC_CPUCLKSOURCE_IC1)
963     {
964       /* Check parameters */
965       assert_param(IS_RCC_ICCLKSOURCE(pRCC_ClkInitStruct->IC1Selection.ClockSelection));
966       assert_param(IS_RCC_ICCLKDIVIDER(pRCC_ClkInitStruct->IC1Selection.ClockDivider));
967 
968       /* ICx clock switch requires both origin and destination clock source to be active */
969       /* Check IC1 origin and target clock sources availability */
970       if (RCC_IC_CheckPLLSources(LL_RCC_IC1_GetSource(), pRCC_ClkInitStruct->IC1Selection.ClockSelection) != 1U)
971       {
972         return HAL_ERROR;
973       }
974 
975       /* Configure IC1 source and divider */
976       WRITE_REG(RCC->IC1CFGR, pRCC_ClkInitStruct->IC1Selection.ClockSelection | \
977                 ((pRCC_ClkInitStruct->IC1Selection.ClockDivider - 1U) << RCC_IC1CFGR_IC1INT_Pos));
978 
979       /* Enable IC1 */
980       LL_RCC_IC1_Enable();
981     }
982     /* MSI is selected as CPU Clock Source */
983     else if (pRCC_ClkInitStruct->CPUCLKSource == RCC_CPUCLKSOURCE_MSI)
984     {
985       /* Check the MSI ready flag */
986       if (LL_RCC_MSI_IsReady() == 0U)
987       {
988         return HAL_ERROR;
989       }
990     }
991     /* HSI is selected as CPU Clock Source */
992     else
993     {
994       /* Check the HSI ready flag */
995       if (LL_RCC_HSI_IsReady() == 0U)
996       {
997         return HAL_ERROR;
998       }
999     }
1000 
1001     /* Switch the CPU clock */
1002     MODIFY_REG(RCC->CFGR1, RCC_CFGR1_CPUSW, pRCC_ClkInitStruct->CPUCLKSource);
1003 
1004     /* Get Start Tick*/
1005     tickstart = HAL_GetTick();
1006 
1007     while (__HAL_RCC_GET_CPUCLK_SOURCE() != (pRCC_ClkInitStruct->CPUCLKSource << 4U))
1008     {
1009       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
1010       {
1011         return HAL_TIMEOUT;
1012       }
1013     }
1014 
1015     /* Update the SystemCoreClock global variable with CPU clock */
1016     SystemCoreClock = HAL_RCC_GetCpuClockFreq();
1017 
1018   }
1019 
1020   /*------------------------- SYSCLK Configuration -------------------------*/
1021   if ((pRCC_ClkInitStruct->ClockType & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1022   {
1023     assert_param(IS_RCC_SYSCLKSOURCE(pRCC_ClkInitStruct->SYSCLKSource));
1024 
1025     /* HSE is selected as System bus clock source */
1026     if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1027     {
1028       /* Check the HSE ready flag */
1029       if (LL_RCC_HSE_IsReady() == 0U)
1030       {
1031         return HAL_ERROR;
1032       }
1033     }
1034     /* PLL output is selected as System bus clock source */
1035     else if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_IC2_IC6_IC11)
1036     {
1037       /* Check parameters */
1038       assert_param(IS_RCC_ICCLKSOURCE(pRCC_ClkInitStruct->IC2Selection.ClockSelection));
1039       assert_param(IS_RCC_ICCLKDIVIDER(pRCC_ClkInitStruct->IC2Selection.ClockDivider));
1040       assert_param(IS_RCC_ICCLKSOURCE(pRCC_ClkInitStruct->IC6Selection.ClockSelection));
1041       assert_param(IS_RCC_ICCLKDIVIDER(pRCC_ClkInitStruct->IC6Selection.ClockDivider));
1042       assert_param(IS_RCC_ICCLKSOURCE(pRCC_ClkInitStruct->IC11Selection.ClockSelection));
1043       assert_param(IS_RCC_ICCLKDIVIDER(pRCC_ClkInitStruct->IC11Selection.ClockDivider));
1044 
1045       /* ICx clock switch requires both origin and destination clock source to be active */
1046       /* Check IC2/IC6/IC11 origin and target clock sources availability */
1047       if (RCC_IC_CheckPLLSources(LL_RCC_IC2_GetSource(), pRCC_ClkInitStruct->IC2Selection.ClockSelection) != 1U)
1048       {
1049         return HAL_ERROR;
1050       }
1051       if (RCC_IC_CheckPLLSources(LL_RCC_IC6_GetSource(), pRCC_ClkInitStruct->IC6Selection.ClockSelection) != 1U)
1052       {
1053         return HAL_ERROR;
1054       }
1055       if (RCC_IC_CheckPLLSources(LL_RCC_IC11_GetSource(), pRCC_ClkInitStruct->IC11Selection.ClockSelection) != 1U)
1056       {
1057         return HAL_ERROR;
1058       }
1059 
1060       /* Configure IC2, IC6 and IC11 sources and dividers */
1061       WRITE_REG(RCC->IC2CFGR, pRCC_ClkInitStruct->IC2Selection.ClockSelection | \
1062                 ((pRCC_ClkInitStruct->IC2Selection.ClockDivider - 1U) << RCC_IC2CFGR_IC2INT_Pos));
1063       WRITE_REG(RCC->IC6CFGR, pRCC_ClkInitStruct->IC6Selection.ClockSelection | \
1064                 ((pRCC_ClkInitStruct->IC6Selection.ClockDivider - 1U) << RCC_IC6CFGR_IC6INT_Pos));
1065       WRITE_REG(RCC->IC11CFGR, pRCC_ClkInitStruct->IC11Selection.ClockSelection | \
1066                 ((pRCC_ClkInitStruct->IC11Selection.ClockDivider - 1U) << RCC_IC11CFGR_IC11INT_Pos));
1067 
1068       /* Require to have IC2, IC6 and IC11 outputs enabled */
1069       WRITE_REG(RCC->DIVENSR, RCC_DIVENSR_IC2ENS | RCC_DIVENSR_IC6ENS | RCC_DIVENSR_IC11ENS);
1070     }
1071     /* HSI is selected as System bus clock source */
1072     else if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
1073     {
1074       /* Check the HSI ready flag */
1075       if (LL_RCC_HSI_IsReady() == 0U)
1076       {
1077         return HAL_ERROR;
1078       }
1079     }
1080     /* MSI is selected as System bus clock source */
1081     else
1082     {
1083       /* Check the MSI ready flag */
1084       if (LL_RCC_MSI_IsReady() == 0U)
1085       {
1086         return HAL_ERROR;
1087       }
1088     }
1089 
1090     /* Switch the system bus clocks */
1091     MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SYSSW, pRCC_ClkInitStruct->SYSCLKSource);
1092 
1093     /* Get Start Tick*/
1094     tickstart = HAL_GetTick();
1095 
1096     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (pRCC_ClkInitStruct->SYSCLKSource << 4U))
1097     {
1098       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
1099       {
1100         return HAL_TIMEOUT;
1101       }
1102     }
1103   }
1104 
1105   /* Decreasing the BUS frequency divider ? */
1106 
1107   /*-------------------------- HCLK Configuration --------------------------*/
1108   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1109   {
1110     assert_param(IS_RCC_HCLK(pRCC_ClkInitStruct->AHBCLKDivider));
1111     if ((pRCC_ClkInitStruct->AHBCLKDivider) < (RCC->CFGR2 & RCC_CFGR2_HPRE))
1112     {
1113       /* Set the new HCLK clock divider */
1114       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pRCC_ClkInitStruct->AHBCLKDivider);
1115     }
1116   }
1117 
1118   /*-------------------------- PCLK1 Configuration ---------------------------*/
1119   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1120   {
1121     assert_param(IS_RCC_PCLK1(pRCC_ClkInitStruct->APB1CLKDivider));
1122     if ((pRCC_ClkInitStruct->APB1CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1123     {
1124       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, (pRCC_ClkInitStruct->APB1CLKDivider));
1125     }
1126   }
1127 
1128   /*-------------------------- PCLK2 Configuration ---------------------------*/
1129   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1130   {
1131     assert_param(IS_RCC_PCLK2(pRCC_ClkInitStruct->APB2CLKDivider));
1132     if ((pRCC_ClkInitStruct->APB2CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE2))
1133     {
1134       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, (pRCC_ClkInitStruct->APB2CLKDivider));
1135     }
1136   }
1137 
1138   /*-------------------------- PCLK4 Configuration ---------------------------*/
1139   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK4) == RCC_CLOCKTYPE_PCLK4)
1140   {
1141     assert_param(IS_RCC_PCLK4(pRCC_ClkInitStruct->APB4CLKDivider));
1142     if ((pRCC_ClkInitStruct->APB4CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE4))
1143     {
1144       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE4, (pRCC_ClkInitStruct->APB4CLKDivider));
1145     }
1146   }
1147 
1148   /*-------------------------- PCLK5 Configuration ---------------------------*/
1149   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK5) == RCC_CLOCKTYPE_PCLK5)
1150   {
1151     assert_param(IS_RCC_PCLK5(pRCC_ClkInitStruct->APB5CLKDivider));
1152     if ((pRCC_ClkInitStruct->APB5CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE5))
1153     {
1154       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE5, (pRCC_ClkInitStruct->APB5CLKDivider));
1155     }
1156   }
1157 
1158   /* Configure the source of time base considering new system clocks settings*/
1159   return HAL_InitTick(uwTickPrio);
1160 }
1161 
1162 /**
1163   * @}
1164   */
1165 
1166 /** @defgroup RCC_Group2 Peripheral Control functions
1167   *  @brief   RCC clocks control functions
1168   *
1169 @verbatim
1170  ===============================================================================
1171                       ##### Peripheral Control functions #####
1172  ===============================================================================
1173     [..]
1174     This subsection provides a set of functions allowing to control the RCC Clocks
1175     frequencies.
1176 
1177 @endverbatim
1178   * @{
1179   */
1180 
1181 /**
1182   * @brief  Selects the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9).
1183   * @note   PWR VDDIO4 Input Independent I/O supply 4 shall be previously set up for PC9
1184   *         with HAL_PWREx_EnableVddIO4()
1185   * @note   The MCO switch to the new clock source only occurs when the previous clock source is active
1186   *         (dynamic switch).
1187   * @param  RCC_MCOx specifies the output direction for the clock source.
1188   *          This parameter can be one of the following values:
1189   *            @arg RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1190   *            @arg RCC_MCO2 Clock source to output on MCO2 pin(PC9).
1191   * @param  RCC_MCOSource specifies the clock source to output.
1192   *          This parameter can be one of the following values:
1193   *            @arg RCC_MCO1SOURCE_LSI LSI clock selected as MCO1 source
1194   *            @arg RCC_MCO1SOURCE_LSE LSE clock selected as MCO1 source
1195   *            @arg RCC_MCO1SOURCE_MSI MSI clock selected as MCO1 source
1196   *            @arg RCC_MCO1SOURCE_HSI HSI clock selected as MCO1 source
1197   *            @arg RCC_MCO1SOURCE_HSE HSE clock selected as MCO1 source
1198   *            @arg RCC_MCO1SOURCE_IC5 IC5 clock selected as MCO1 source
1199   *            @arg RCC_MCO1SOURCE_IC10 IC10 clock selected as MCO1 source
1200   *            @arg RCC_MCO1SOURCE_SYSA CPU clock (SYSA) selected as MCO1 source
1201   *            @arg RCC_MCO2SOURCE_LSI LSI clock selected as MCO2 source
1202   *            @arg RCC_MCO2SOURCE_LSE LSE clock selected as MCO2 source
1203   *            @arg RCC_MCO2SOURCE_MSI MSI clock selected as MCO2 source
1204   *            @arg RCC_MCO2SOURCE_HSI HSI clock selected as MCO2 source
1205   *            @arg RCC_MCO2SOURCE_HSE HSE clock selected as MCO2 source
1206   *            @arg RCC_MCO2SOURCE_IC15 IC15 clock selected as MCO2 source
1207   *            @arg RCC_MCO2SOURCE_IC20 IC20 clock selected as MCO2 source
1208   *            @arg RCC_MCO2SOURCE_SYSB Bus clock (SYSB) selected as MCO2 source
1209   * @param  RCC_MCODiv specifies the MCOx pre-scaler.
1210   *          This parameter can be one of the following values:
1211   *            @arg RCC_MCODIV_1 up to RCC_MCODIV_16  : divider applied to MCOx clock
1212   * @retval None
1213   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1214 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1215 {
1216   GPIO_InitTypeDef GPIO_InitStruct;
1217 
1218   /* Check the parameters */
1219   assert_param(IS_RCC_MCO(RCC_MCOx));
1220   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1221 
1222   /* RCC_MCO1 */
1223   if (RCC_MCOx == RCC_MCO1)
1224   {
1225     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1226 
1227     /* MCO1 Clock Enable */
1228     RCC_MCO1_CLK_ENABLE();
1229 
1230     /* Configure the MCO1 pin in alternate function mode */
1231     GPIO_InitStruct.Pin = RCC_MCO1_PIN;
1232     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1233     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1234     GPIO_InitStruct.Pull = GPIO_NOPULL;
1235     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1236     HAL_GPIO_Init(RCC_MCO1_GPIO_PORT, &GPIO_InitStruct);
1237 
1238     /* Configure MCO1 */
1239     LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
1240 
1241     /* Enable IC5 if requested as source to MCO1 */
1242     if (RCC_MCOSource == RCC_MCO1SOURCE_IC5)
1243     {
1244       LL_RCC_IC5_Enable();
1245     }
1246     /* Enable IC10 if requested as source to MCO1 */
1247     else if (RCC_MCOSource == RCC_MCO1SOURCE_IC10)
1248     {
1249       LL_RCC_IC10_Enable();
1250     }
1251     else
1252     {
1253       /* Nothing to do as not ICx source */
1254     }
1255     /* Enable MC01 output */
1256     LL_RCC_EnableMCO(LL_RCC_MCO1);
1257   }
1258   else
1259   {
1260     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
1261 
1262     /* MCO2 Clock Enable */
1263     RCC_MCO2_CLK_ENABLE();
1264 
1265     /* Configure the MCO2 pin in alternate function mode */
1266     GPIO_InitStruct.Pin = RCC_MCO2_PIN;
1267     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1268     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1269     GPIO_InitStruct.Pull = GPIO_NOPULL;
1270     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1271     HAL_GPIO_Init(RCC_MCO2_GPIO_PORT, &GPIO_InitStruct);
1272 
1273     /* Configure MCO2 */
1274     LL_RCC_ConfigMCO(RCC_MCOSource, ((RCC_CCIPR5_MCO2PRE << 16U) | ((RCC_MCODiv & RCC_CCIPR5_MCO1PRE) << 8U)));
1275 
1276     /* Enable IC15 if requested as source to MCO2 */
1277     if (RCC_MCOSource == RCC_MCO2SOURCE_IC15)
1278     {
1279       LL_RCC_IC15_Enable();
1280     }
1281     /* Enable IC20 if requested as source to MCO2 */
1282     else if (RCC_MCOSource == RCC_MCO2SOURCE_IC20)
1283     {
1284       LL_RCC_IC20_Enable();
1285     }
1286     else
1287     {
1288       /* Nothing to do as not ICx source */
1289     }
1290     /* Enable MC02 output */
1291     LL_RCC_EnableMCO(LL_RCC_MCO2);
1292   }
1293 }
1294 
1295 /**
1296   * @brief  Enable the HSE Clock Security System.
1297   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1298   *         is automatically disabled and an interrupt is generated to inform the
1299   *         software about the failure (Clock Security System Interrupt, CSSI),
1300   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1301   *         the Cortex-M NMI (Non-Mask-able Interrupt) exception vector.
1302   * @note   The HSE Clock Security System may be enabled even if the HSE is not enabled
1303   *         but will be activated when the HSE is enabled and ready.
1304   * @note   It is not possible to disable the HSE Clock Security System.
1305   * @retval None
1306   */
HAL_RCC_EnableCSS(void)1307 void HAL_RCC_EnableCSS(void)
1308 {
1309   LL_RCC_HSE_EnableCSS();
1310 }
1311 
1312 /**
1313   * @brief  Returns the CPU clock (sysa_ck) frequency
1314   *
1315   * @note   The CPU clock frequency computed by this function may be not the real
1316   *         frequency in the chip. It is calculated based on the predefined
1317   *         constant and the selected clock source:
1318   * @note     If CPUCLK source is HSI, function returns values based on HSI_VALUE(**)
1319   * @note     If CPUCLK source is MSI, function returns values based on MSI_VALUE(*)
1320   * @note     If CPUCLK source is HSE, function returns values based on HSE_VALUE(***)
1321   * @note     If CPUCLK source is IC1, function returns values based on HSI_VALUE(*),
1322   *           MSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
1323   * @note     (*) HSI_VALUE is a constant defined in stm32n6xx_hal_conf.h file (default value
1324   *               64 MHz) but the real value may vary depending on the variations
1325   *               in voltage and temperature.
1326   * @note     (**) MSI_VALUE is a constant defined in stm32n6xx_hal_conf.h file (default value
1327   *               4 MHz) but the real value may vary depending on the variations
1328   *               in voltage and temperature.
1329   * @note     (***) HSE_VALUE is a constant defined in stm32n6xx_hal_conf.h file (default value
1330   *                25 MHz), user has to ensure that HSE_VALUE is same as the real
1331   *                frequency of the crystal used. Otherwise, this function may
1332   *                have wrong result.
1333   *
1334   * @note   The result of this function could be not correct when using fractional
1335   *         value for HSE crystal.
1336   *
1337   * @note   This function can be used by the user application to compute the
1338   *         baud rate for the communication peripherals or configure other parameters.
1339   *
1340   * @note   Each time CPUCLK changes, this function must be called by the user application
1341   *         to update the CPUCLK value. Otherwise, any configuration based on this function
1342   *         will be incorrect.
1343   *
1344   * @retval CPUCLK frequency
1345   */
HAL_RCC_GetCpuClockFreq(void)1346 uint32_t HAL_RCC_GetCpuClockFreq(void)
1347 {
1348   uint32_t frequency = 0U;
1349   uint32_t ic_divider;
1350 
1351   /* Get CPUCLK source -------------------------------------------------------*/
1352   switch (LL_RCC_GetCpuClkSource())
1353   {
1354     /* No check on Ready: Won't be selected by hardware if not */
1355     case LL_RCC_CPU_CLKSOURCE_STATUS_HSI:
1356       frequency = HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_HSICFGR_HSIDIV_Pos);
1357       break;
1358 
1359     case LL_RCC_CPU_CLKSOURCE_STATUS_MSI:
1360       if (LL_RCC_MSI_GetFrequency() == LL_RCC_MSI_FREQ_4MHZ)
1361       {
1362         frequency = MSI_VALUE;
1363       }
1364       else
1365       {
1366         frequency = 16000000UL;
1367       }
1368       break;
1369 
1370     case LL_RCC_CPU_CLKSOURCE_STATUS_HSE:
1371       frequency = HSE_VALUE;
1372       break;
1373 
1374     case LL_RCC_CPU_CLKSOURCE_STATUS_IC1:
1375       ic_divider = LL_RCC_IC1_GetDivider();
1376       switch (LL_RCC_IC1_GetSource())
1377       {
1378         case LL_RCC_ICCLKSOURCE_PLL1:
1379           frequency = HAL_RCCEx_GetPLL1CLKFreq();
1380           frequency = frequency / ic_divider;
1381           break;
1382         case LL_RCC_ICCLKSOURCE_PLL2:
1383           frequency = HAL_RCCEx_GetPLL2CLKFreq();
1384           frequency = frequency / ic_divider;
1385           break;
1386         case LL_RCC_ICCLKSOURCE_PLL3:
1387           frequency = HAL_RCCEx_GetPLL3CLKFreq();
1388           frequency = frequency / ic_divider;
1389           break;
1390         case LL_RCC_ICCLKSOURCE_PLL4:
1391           frequency = HAL_RCCEx_GetPLL4CLKFreq();
1392           frequency = frequency / ic_divider;
1393           break;
1394         default:
1395           /* Unexpected case */
1396           break;
1397       }
1398       break;
1399 
1400     default:
1401       /* Unexpected case */
1402       break;
1403   }
1404 
1405   return frequency;
1406 }
1407 
1408 /**
1409   * @brief  Returns the SYSCLK bus (sysb_ck) frequency
1410   *
1411   * @note   The system bus frequency computed by this function may be not the real
1412   *         frequency in the chip. It is calculated based on the predefined
1413   *         constant and the selected clock source:
1414   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
1415   * @note     If SYSCLK source is MSI, function returns values based on MSI_VALUE(*)
1416   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
1417   * @note     If SYSCLK source is IC2, function returns values based on HSI_VALUE(*),
1418   *           MSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
1419   * @note     (*) HSI_VALUE is a constant defined in stm32n6xx_hal_conf.h file (default value
1420   *               64 MHz) but the real value may vary depending on the variations
1421   *               in voltage and temperature.
1422   * @note     (**) MSI_VALUE is a constant defined in stm32n6xx_hal_conf.h file (default value
1423   *               4 MHz) but the real value may vary depending on the variations
1424   *               in voltage and temperature.
1425   * @note     (***) HSE_VALUE is a constant defined in stm32n6xx_hal_conf.h file (default value
1426   *                25 MHz), user has to ensure that HSE_VALUE is same as the real
1427   *                frequency of the crystal used. Otherwise, this function may
1428   *                have wrong result.
1429   *
1430   * @note   The result of this function could be not correct when using fractional
1431   *         value for HSE crystal.
1432   *
1433   * @note   This function can be used by the user application to compute the
1434   *         baud rate for the communication peripherals or configure other parameters.
1435   *
1436   * @note   Each time SYSCLK changes, this function must be called by the user application
1437   *         to update the SYSCLK value. Otherwise, any configuration based on this function
1438   *         will be incorrect.
1439   *
1440   * @retval SYSCLK frequency
1441   */
HAL_RCC_GetSysClockFreq(void)1442 uint32_t HAL_RCC_GetSysClockFreq(void)
1443 {
1444   uint32_t frequency = 0U;
1445   uint32_t ic_divider;
1446 
1447   /* Get SYSCLK source -------------------------------------------------------*/
1448   switch (LL_RCC_GetSysClkSource())
1449   {
1450     /* No check on Ready: Won't be selected by hardware if not */
1451     case LL_RCC_SYS_CLKSOURCE_STATUS_HSI:
1452       frequency = HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_HSICFGR_HSIDIV_Pos);
1453       break;
1454 
1455     case LL_RCC_SYS_CLKSOURCE_STATUS_MSI:
1456       if (LL_RCC_MSI_GetFrequency() == LL_RCC_MSI_FREQ_4MHZ)
1457       {
1458         frequency = MSI_VALUE;
1459       }
1460       else
1461       {
1462         frequency = 16000000UL;
1463       }
1464       break;
1465 
1466     case LL_RCC_SYS_CLKSOURCE_STATUS_HSE:
1467       frequency = HSE_VALUE;
1468       break;
1469 
1470     case LL_RCC_SYS_CLKSOURCE_STATUS_IC2_IC6_IC11:
1471       ic_divider = LL_RCC_IC2_GetDivider();
1472       switch (LL_RCC_IC2_GetSource())
1473       {
1474         case LL_RCC_ICCLKSOURCE_PLL1:
1475           frequency = HAL_RCCEx_GetPLL1CLKFreq();
1476           frequency = frequency / ic_divider;
1477           break;
1478         case LL_RCC_ICCLKSOURCE_PLL2:
1479           frequency = HAL_RCCEx_GetPLL2CLKFreq();
1480           frequency = frequency / ic_divider;
1481           break;
1482         case LL_RCC_ICCLKSOURCE_PLL3:
1483           frequency = HAL_RCCEx_GetPLL3CLKFreq();
1484           frequency = frequency / ic_divider;
1485           break;
1486         case LL_RCC_ICCLKSOURCE_PLL4:
1487           frequency = HAL_RCCEx_GetPLL4CLKFreq();
1488           frequency = frequency / ic_divider;
1489           break;
1490         default:
1491           /* Unexpected case */
1492           break;
1493       }
1494       break;
1495 
1496     default:
1497       /* Unexpected case */
1498       break;
1499   }
1500 
1501   return frequency;
1502 }
1503 
1504 /**
1505   * @brief  Return the HCLK frequency.
1506   * @retval HCLK frequency in Hz
1507   */
HAL_RCC_GetHCLKFreq(void)1508 uint32_t HAL_RCC_GetHCLKFreq(void)
1509 {
1510   return LL_RCC_CALC_HCLK_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler());
1511 }
1512 
1513 /**
1514   * @brief  Return the PCLK1 frequency.
1515   * @note   Each time PCLK1 changes, this function must be called to update the
1516   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1517   * @retval PCLK1 frequency in Hz
1518   */
HAL_RCC_GetPCLK1Freq(void)1519 uint32_t HAL_RCC_GetPCLK1Freq(void)
1520 {
1521   return LL_RCC_CALC_PCLK1_FREQ(LL_RCC_CALC_HCLK_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler()),
1522                                 LL_RCC_GetAPB1Prescaler());
1523 }
1524 
1525 /**
1526   * @brief  Return the PCLK2 frequency.
1527   * @note   Each time PCLK2 changes, this function must be called to update the
1528   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1529   * @retval PCLK2 frequency in Hz
1530   */
HAL_RCC_GetPCLK2Freq(void)1531 uint32_t HAL_RCC_GetPCLK2Freq(void)
1532 {
1533   return LL_RCC_CALC_PCLK2_FREQ(LL_RCC_CALC_HCLK_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler()),
1534                                 LL_RCC_GetAPB2Prescaler());
1535 }
1536 
1537 /**
1538   * @brief  Return the PCLK4 frequency.
1539   * @note   Each time PCLK4 changes, this function must be called to update the
1540   *         right PCLK4 value. Otherwise, any configuration based on this function will be incorrect.
1541   * @retval PCLK4 frequency in Hz
1542   */
HAL_RCC_GetPCLK4Freq(void)1543 uint32_t HAL_RCC_GetPCLK4Freq(void)
1544 {
1545   return LL_RCC_CALC_PCLK4_FREQ(LL_RCC_CALC_HCLK_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler()),
1546                                 LL_RCC_GetAPB4Prescaler());
1547 }
1548 
1549 /**
1550   * @brief  Return the PCLK5 frequency.
1551   * @note   Each time PCLK5 changes, this function must be called to update the
1552   *         right PCLK5 value. Otherwise, any configuration based on this function will be incorrect.
1553   * @retval PCLK5 frequency in Hz
1554   */
HAL_RCC_GetPCLK5Freq(void)1555 uint32_t HAL_RCC_GetPCLK5Freq(void)
1556 {
1557   return LL_RCC_CALC_PCLK5_FREQ(LL_RCC_CALC_HCLK_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler()),
1558                                 LL_RCC_GetAPB5Prescaler());
1559 }
1560 
1561 /**
1562   * @brief  Get the oscillators status configuration in RCC_OscInitStruct according to
1563   *         the internal RCC configuration registers.
1564   * @param  pRCC_OscInitStruct  Pointer to an RCC_OscInitTypeDef structure that
1565   *         will return the configuration.
1566   * @retval None
1567   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * pRCC_OscInitStruct)1568 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *pRCC_OscInitStruct)
1569 {
1570   uint32_t sr_value;
1571   uint32_t cfgr_value;
1572 
1573   /* Get the status register value */
1574   sr_value = RCC->SR;
1575 
1576   /* Set all possible values for the Oscillator type parameters --------------*/
1577   pRCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1578                                        RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1579 
1580   /* Get the HSE configuration -----------------------------------------------*/
1581   if ((sr_value & RCC_SR_HSERDY) != 0UL)
1582   {
1583     cfgr_value = RCC->HSECFGR;
1584     if ((cfgr_value & (RCC_HSECFGR_HSEBYP | RCC_HSECFGR_HSEEXT)) == RCC_HSECFGR_HSEBYP)
1585     {
1586       pRCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1587     }
1588     else if ((cfgr_value & (RCC_HSECFGR_HSEBYP | RCC_HSECFGR_HSEEXT)) == (RCC_HSECFGR_HSEBYP | RCC_HSECFGR_HSEEXT))
1589     {
1590       pRCC_OscInitStruct->HSEState = RCC_HSE_BYPASS_DIGITAL;
1591     }
1592     else
1593     {
1594       pRCC_OscInitStruct->HSEState = RCC_HSE_ON;
1595     }
1596   }
1597   else
1598   {
1599     pRCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1600   }
1601 
1602   /* Get the MSI configuration -----------------------------------------------*/
1603   if ((sr_value & RCC_SR_MSIRDY) != 0UL)
1604   {
1605     pRCC_OscInitStruct->MSIState = RCC_MSI_ON;
1606   }
1607   else
1608   {
1609     pRCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1610   }
1611 
1612   cfgr_value = RCC->MSICFGR;
1613   pRCC_OscInitStruct->MSIFrequency = (cfgr_value & RCC_MSICFGR_MSIFREQSEL);
1614   pRCC_OscInitStruct->MSICalibrationValue = ((cfgr_value & RCC_MSICFGR_MSITRIM) >> RCC_MSICFGR_MSITRIM_Pos);
1615 
1616   /* Get the HSI configuration -----------------------------------------------*/
1617   if ((sr_value & RCC_SR_HSIRDY) != 0UL)
1618   {
1619     pRCC_OscInitStruct->HSIState = RCC_HSI_ON;
1620   }
1621   else
1622   {
1623     pRCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1624   }
1625 
1626   cfgr_value = RCC->HSICFGR;
1627   pRCC_OscInitStruct->HSIDiv = (cfgr_value & RCC_HSICFGR_HSIDIV);
1628   pRCC_OscInitStruct->HSICalibrationValue = ((cfgr_value & RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos);
1629 
1630   /* Get the LSE configuration -----------------------------------------------*/
1631   if ((sr_value & RCC_SR_LSERDY) != 0UL)
1632   {
1633     cfgr_value = RCC->LSECFGR;
1634     if ((cfgr_value & (RCC_LSECFGR_LSEBYP | RCC_LSECFGR_LSEEXT)) == RCC_LSECFGR_LSEBYP)
1635     {
1636       pRCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1637     }
1638     else if ((cfgr_value & (RCC_LSECFGR_LSEBYP | RCC_LSECFGR_LSEEXT)) == (RCC_LSECFGR_LSEBYP | RCC_LSECFGR_LSEEXT))
1639     {
1640       pRCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_DIGITAL;
1641     }
1642     else
1643     {
1644       pRCC_OscInitStruct->LSEState = RCC_LSE_ON;
1645     }
1646   }
1647   else
1648   {
1649     pRCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1650   }
1651 
1652   /* Get the LSI configuration -----------------------------------------------*/
1653   if ((sr_value & RCC_SR_LSIRDY) != 0UL)
1654   {
1655     pRCC_OscInitStruct->LSIState = RCC_LSI_ON;
1656   }
1657   else
1658   {
1659     pRCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1660   }
1661 
1662   /* Get the PLL1 configuration -----------------------------------------------*/
1663   if ((sr_value & RCC_SR_PLL1RDY) != 0UL)
1664   {
1665     cfgr_value = RCC->PLL1CFGR1;
1666     pRCC_OscInitStruct->PLL1.PLLState = RCC_PLL_ON;
1667     pRCC_OscInitStruct->PLL1.PLLSource = (cfgr_value & RCC_PLL1CFGR1_PLL1SEL);
1668     pRCC_OscInitStruct->PLL1.PLLM = ((cfgr_value & RCC_PLL1CFGR1_PLL1DIVM) >> RCC_PLL1CFGR1_PLL1DIVM_Pos);
1669     pRCC_OscInitStruct->PLL1.PLLN = ((cfgr_value & RCC_PLL1CFGR1_PLL1DIVN) >> RCC_PLL1CFGR1_PLL1DIVN_Pos);
1670     pRCC_OscInitStruct->PLL1.PLLFractional = (READ_BIT(RCC->PLL1CFGR2, RCC_PLL1CFGR2_PLL1DIVNFRAC) >> \
1671                                               RCC_PLL1CFGR2_PLL1DIVNFRAC_Pos);
1672     cfgr_value = RCC->PLL1CFGR3;
1673     pRCC_OscInitStruct->PLL1.PLLP1 = ((cfgr_value & RCC_PLL1CFGR3_PLL1PDIV1) >> RCC_PLL1CFGR3_PLL1PDIV1_Pos);
1674     pRCC_OscInitStruct->PLL1.PLLP2 = ((cfgr_value & RCC_PLL1CFGR3_PLL1PDIV2) >> RCC_PLL1CFGR3_PLL1PDIV2_Pos);
1675   }
1676   else
1677   {
1678     cfgr_value = RCC->PLL1CFGR1;
1679     if ((cfgr_value & RCC_PLL1CFGR1_PLL1BYP) != 0UL)
1680     {
1681       pRCC_OscInitStruct->PLL1.PLLState = RCC_PLL_BYPASS;
1682     }
1683     else
1684     {
1685       pRCC_OscInitStruct->PLL1.PLLState = RCC_PLL_OFF;
1686     }
1687   }
1688 
1689   /* Get the PLL2 configuration -----------------------------------------------*/
1690   if ((sr_value & RCC_SR_PLL2RDY) != 0UL)
1691   {
1692     cfgr_value = RCC->PLL2CFGR1;
1693     pRCC_OscInitStruct->PLL2.PLLState = RCC_PLL_ON;
1694     pRCC_OscInitStruct->PLL2.PLLSource = (cfgr_value & RCC_PLL2CFGR1_PLL2SEL);
1695     pRCC_OscInitStruct->PLL2.PLLM = ((cfgr_value & RCC_PLL2CFGR1_PLL2DIVM) >> RCC_PLL2CFGR1_PLL2DIVM_Pos);
1696     pRCC_OscInitStruct->PLL2.PLLN = ((cfgr_value & RCC_PLL2CFGR1_PLL2DIVN) >> RCC_PLL2CFGR1_PLL2DIVN_Pos);
1697     pRCC_OscInitStruct->PLL2.PLLFractional = (READ_BIT(RCC->PLL2CFGR2, RCC_PLL2CFGR2_PLL2DIVNFRAC) >> \
1698                                               RCC_PLL2CFGR2_PLL2DIVNFRAC_Pos);
1699     cfgr_value = RCC->PLL2CFGR3;
1700     pRCC_OscInitStruct->PLL2.PLLP1 = ((cfgr_value & RCC_PLL2CFGR3_PLL2PDIV1) >> RCC_PLL2CFGR3_PLL2PDIV1_Pos);
1701     pRCC_OscInitStruct->PLL2.PLLP2 = ((cfgr_value & RCC_PLL2CFGR3_PLL2PDIV2) >> RCC_PLL2CFGR3_PLL2PDIV2_Pos);
1702   }
1703   else
1704   {
1705     cfgr_value = RCC->PLL2CFGR1;
1706     if ((cfgr_value & RCC_PLL2CFGR1_PLL2BYP) != 0UL)
1707     {
1708       pRCC_OscInitStruct->PLL2.PLLState = RCC_PLL_BYPASS;
1709     }
1710     else
1711     {
1712       pRCC_OscInitStruct->PLL2.PLLState = RCC_PLL_OFF;
1713     }
1714   }
1715 
1716   /* Get the PLL3 configuration -----------------------------------------------*/
1717   if ((sr_value & RCC_SR_PLL3RDY) != 0UL)
1718   {
1719     cfgr_value = RCC->PLL3CFGR1;
1720     pRCC_OscInitStruct->PLL3.PLLState = RCC_PLL_ON;
1721     pRCC_OscInitStruct->PLL3.PLLSource = (cfgr_value & RCC_PLL3CFGR1_PLL3SEL);
1722     pRCC_OscInitStruct->PLL3.PLLM = ((cfgr_value & RCC_PLL3CFGR1_PLL3DIVM) >> RCC_PLL3CFGR1_PLL3DIVM_Pos);
1723     pRCC_OscInitStruct->PLL3.PLLN = ((cfgr_value & RCC_PLL3CFGR1_PLL3DIVN) >> RCC_PLL3CFGR1_PLL3DIVN_Pos);
1724     pRCC_OscInitStruct->PLL3.PLLFractional = (READ_BIT(RCC->PLL3CFGR2, RCC_PLL3CFGR2_PLL3DIVNFRAC) >> \
1725                                               RCC_PLL3CFGR2_PLL3DIVNFRAC_Pos);
1726     cfgr_value = RCC->PLL3CFGR3;
1727     pRCC_OscInitStruct->PLL3.PLLP1 = ((cfgr_value & RCC_PLL3CFGR3_PLL3PDIV1) >> RCC_PLL3CFGR3_PLL3PDIV1_Pos);
1728     pRCC_OscInitStruct->PLL3.PLLP2 = ((cfgr_value & RCC_PLL3CFGR3_PLL3PDIV2) >> RCC_PLL3CFGR3_PLL3PDIV2_Pos);
1729   }
1730   else
1731   {
1732     cfgr_value = RCC->PLL3CFGR1;
1733     if ((cfgr_value & RCC_PLL3CFGR1_PLL3BYP) != 0UL)
1734     {
1735       pRCC_OscInitStruct->PLL3.PLLState = RCC_PLL_BYPASS;
1736     }
1737     else
1738     {
1739       pRCC_OscInitStruct->PLL3.PLLState = RCC_PLL_OFF;
1740     }
1741   }
1742 
1743   /* Get the PLL4 configuration -----------------------------------------------*/
1744   if ((sr_value & RCC_SR_PLL4RDY) != 0UL)
1745   {
1746     cfgr_value = RCC->PLL4CFGR1;
1747     pRCC_OscInitStruct->PLL4.PLLState = RCC_PLL_ON;
1748     pRCC_OscInitStruct->PLL4.PLLSource = (cfgr_value & RCC_PLL4CFGR1_PLL4SEL);
1749     pRCC_OscInitStruct->PLL4.PLLM = ((cfgr_value & RCC_PLL4CFGR1_PLL4DIVM) >> RCC_PLL4CFGR1_PLL4DIVM_Pos);
1750     pRCC_OscInitStruct->PLL4.PLLN = ((cfgr_value & RCC_PLL4CFGR1_PLL4DIVN) >> RCC_PLL4CFGR1_PLL4DIVN_Pos);
1751     pRCC_OscInitStruct->PLL4.PLLFractional = (READ_BIT(RCC->PLL4CFGR2, RCC_PLL4CFGR2_PLL4DIVNFRAC) >> \
1752                                               RCC_PLL4CFGR2_PLL4DIVNFRAC_Pos);
1753     cfgr_value = RCC->PLL4CFGR3;
1754     pRCC_OscInitStruct->PLL4.PLLP1 = ((cfgr_value & RCC_PLL4CFGR3_PLL4PDIV1) >> RCC_PLL4CFGR3_PLL4PDIV1_Pos);
1755     pRCC_OscInitStruct->PLL4.PLLP2 = ((cfgr_value & RCC_PLL4CFGR3_PLL4PDIV2) >> RCC_PLL4CFGR3_PLL4PDIV2_Pos);
1756   }
1757   else
1758   {
1759     cfgr_value = RCC->PLL4CFGR1;
1760     if ((cfgr_value & RCC_PLL4CFGR1_PLL4BYP) != 0UL)
1761     {
1762       pRCC_OscInitStruct->PLL4.PLLState = RCC_PLL_BYPASS;
1763     }
1764     else
1765     {
1766       pRCC_OscInitStruct->PLL4.PLLState = RCC_PLL_OFF;
1767     }
1768   }
1769 }
1770 
1771 /**
1772   * @brief  Get the clocks status configuration in RCC_ClkInitStruct according to
1773   *         the internal RCC configuration registers.
1774   * @param  pRCC_ClkInitStruct  Pointer to an RCC_ClkInitTypeDef structure that
1775   *         will return the configuration.
1776   * @retval None
1777   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * pRCC_ClkInitStruct)1778 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *pRCC_ClkInitStruct)
1779 {
1780   uint32_t cfgr_value;
1781 
1782   /* Set all possible values for the Clock type parameter --------------------*/
1783   pRCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_CPUCLK | RCC_CLOCKTYPE_SYSCLK | \
1784                                   RCC_CLOCKTYPE_HCLK   | \
1785                                   RCC_CLOCKTYPE_PCLK1  | RCC_CLOCKTYPE_PCLK2 | \
1786                                   RCC_CLOCKTYPE_PCLK4  | RCC_CLOCKTYPE_PCLK5;
1787 
1788   /* Get the configuration register 1 value */
1789   cfgr_value = RCC->CFGR1;
1790 
1791   /* Get the active CPU source -----------------------------------------------*/
1792   pRCC_ClkInitStruct->CPUCLKSource = (cfgr_value & RCC_CFGR1_CPUSWS) >> 4U;
1793 
1794   /* Get the active SYSCLK bus source ----------------------------------------*/
1795   pRCC_ClkInitStruct->SYSCLKSource = (cfgr_value & RCC_CFGR1_SYSSWS) >> 4U;
1796 
1797   /* Get the configuration register 2 value */
1798   cfgr_value = RCC->CFGR2;
1799 
1800   /* Get the HCLK configuration ----------------------------------------------*/
1801   pRCC_ClkInitStruct->AHBCLKDivider = (cfgr_value & RCC_CFGR2_HPRE);
1802 
1803   /* Get the APB1 configuration ----------------------------------------------*/
1804   pRCC_ClkInitStruct->APB1CLKDivider = (cfgr_value & RCC_CFGR2_PPRE1);
1805 
1806   /* Get the APB2 configuration ----------------------------------------------*/
1807   pRCC_ClkInitStruct->APB2CLKDivider = (cfgr_value & RCC_CFGR2_PPRE2);
1808 
1809   /* Get the APB4 configuration ----------------------------------------------*/
1810   pRCC_ClkInitStruct->APB4CLKDivider = (cfgr_value & RCC_CFGR2_PPRE4);
1811 
1812   /* Get the APB5 configuration ----------------------------------------------*/
1813   pRCC_ClkInitStruct->APB5CLKDivider = (cfgr_value & RCC_CFGR2_PPRE5);
1814 
1815   /* Get the IC1 configuration -----------------------------------------------*/
1816   cfgr_value = RCC->IC1CFGR;
1817   pRCC_ClkInitStruct->IC1Selection.ClockSelection = cfgr_value & RCC_IC1CFGR_IC1SEL;
1818   pRCC_ClkInitStruct->IC1Selection.ClockDivider = ((cfgr_value & RCC_IC1CFGR_IC1INT) >> RCC_IC1CFGR_IC1INT_Pos) + 1U;
1819 
1820   /* Get the IC2 configuration -----------------------------------------------*/
1821   cfgr_value = RCC->IC2CFGR;
1822   pRCC_ClkInitStruct->IC2Selection.ClockSelection = cfgr_value & RCC_IC2CFGR_IC2SEL;
1823   pRCC_ClkInitStruct->IC2Selection.ClockDivider = ((cfgr_value & RCC_IC2CFGR_IC2INT) >> RCC_IC2CFGR_IC2INT_Pos) + 1U;
1824 
1825   /* Get the IC6 configuration -----------------------------------------------*/
1826   cfgr_value = RCC->IC6CFGR;
1827   pRCC_ClkInitStruct->IC6Selection.ClockSelection = cfgr_value & RCC_IC6CFGR_IC6SEL;
1828   pRCC_ClkInitStruct->IC6Selection.ClockDivider = ((cfgr_value & RCC_IC6CFGR_IC6INT) >> RCC_IC6CFGR_IC6INT_Pos) + 1U;
1829 
1830   /* Get the IC11 configuration ----------------------------------------------*/
1831   cfgr_value = RCC->IC11CFGR;
1832   pRCC_ClkInitStruct->IC11Selection.ClockSelection = cfgr_value & RCC_IC11CFGR_IC11SEL;
1833   pRCC_ClkInitStruct->IC11Selection.ClockDivider = ((cfgr_value & RCC_IC11CFGR_IC11INT) >> RCC_IC11CFGR_IC11INT_Pos) + 1U;
1834 }
1835 
1836 /**
1837   * @brief This function handles the RCC HSE CSS interrupt request.
1838   * @note This API should be called under the NMI_Handler().
1839   * @retval None
1840   */
HAL_RCC_NMI_IRQHandler(void)1841 void HAL_RCC_NMI_IRQHandler(void)
1842 {
1843   /* Check RCC HCECSSF interrupt flag  */
1844   if (LL_RCC_IsActiveFlag_HSECSS() == 1U)
1845   {
1846     /* Clear RCC HSE Clock Security System pending flag */
1847     LL_RCC_ClearFlag_HSECSS();
1848 
1849     /* RCC HSE Clock Security System interrupt user callback */
1850     HAL_RCC_CSSCallback();
1851   }
1852 }
1853 
1854 /**
1855   * @brief  RCC HSE Clock Security System interrupt callback
1856   * @retval none
1857   */
HAL_RCC_CSSCallback(void)1858 __weak void HAL_RCC_CSSCallback(void)
1859 {
1860   /* NOTE : This function should not be modified, when the callback is needed,
1861             the HAL_RCC_CSSCallback could be implemented in the user file
1862    */
1863 }
1864 
1865 /**
1866   * @}
1867   */
1868 
1869 
1870 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1871   *  @brief Attributes management functions.
1872   *
1873 @verbatim
1874  ===============================================================================
1875                        ##### RCC attributes functions #####
1876  ===============================================================================
1877     [..]
1878     This subsection provides a set of functions allowing to:
1879 
1880     (+) Configure the RCC item(s) attribute(s).
1881     (+) Get the attribute of an RCC item.
1882 
1883 @endverbatim
1884   * @{
1885   */
1886 
1887 /**
1888   * @brief  Configure the RCC item(s) attribute(s).
1889   * @note   Available attributes are to control the secure, privileged, public and lock access rights of items.
1890   *         Default access rights are non-secure, unprivileged, non-public and unlocked.
1891   * @note   Secure/non-secure, privileged/unprivileged and public/non-public attributes can be set and reset
1892   *         from the secure/privileged state only.
1893   * @note   Lock Item attribute can be set from the secure/privileged state only.
1894   * @param  Item Item(s) to set attributes on.
1895   *         This parameter can be a one value or a combination of @ref RCC_items belonging to the same group of items
1896   *         (eg. RCC_ITEM_GROUP_OSC)
1897   * @param  Attributes specifies the RCC secure/privilege/public attributes.
1898   *         This parameter can be a combination of @ref RCC_attributes
1899   * @retval None
1900   *
1901   */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1902 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1903 {
1904   /* Check the parameters */
1905   assert_param(IS_RCC_ATTRIBUTES(Attributes));
1906   assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1907 
1908   /* Check then configure items groups */
1909   /* Oscillators group */
1910   if ((Item & RCC_ITEM_GROUP_OSC) == RCC_ITEM_GROUP_OSC)
1911   {
1912     RCC_ATTR_ConfigItemGroup(RCC_ITEM_GROUP_IDX_OSC, Item & RCC_ITEM_GROUP_OSC_MASK, Attributes);
1913   }
1914 
1915   /* PLLs group */
1916   if ((Item & RCC_ITEM_GROUP_PLL) == RCC_ITEM_GROUP_PLL)
1917   {
1918     RCC_ATTR_ConfigItemGroup(RCC_ITEM_GROUP_IDX_PLL, Item & RCC_ITEM_GROUP_PLL_MASK, Attributes);
1919   }
1920 
1921   /* ICxs group */
1922   if ((Item & RCC_ITEM_GROUP_IC) == RCC_ITEM_GROUP_IC)
1923   {
1924     RCC_ATTR_ConfigItemGroup(RCC_ITEM_GROUP_IDX_IC, Item & RCC_ITEM_GROUP_IC_MASK, Attributes);
1925   }
1926 
1927   /* System configs group */
1928   if ((Item & RCC_ITEM_GROUP_SYSCFG) == RCC_ITEM_GROUP_SYSCFG)
1929   {
1930     RCC_ATTR_ConfigItemGroup(RCC_ITEM_GROUP_IDX_SYSCFG, Item & RCC_ITEM_GROUP_SYSCFG_MASK, Attributes);
1931   }
1932 
1933   /* Buses group */
1934   if ((Item & RCC_ITEM_GROUP_BUS) == RCC_ITEM_GROUP_BUS)
1935   {
1936     RCC_ATTR_ConfigItemGroup(RCC_ITEM_GROUP_IDX_BUS, Item & RCC_ITEM_GROUP_BUS_MASK, Attributes);
1937   }
1938 
1939   /* Memories group */
1940   if ((Item & RCC_ITEM_GROUP_MEM) == RCC_ITEM_GROUP_MEM)
1941   {
1942     RCC_ATTR_ConfigItemGroup(RCC_ITEM_GROUP_IDX_MEM, Item & RCC_ITEM_GROUP_MEM_MASK, Attributes);
1943   }
1944 }
1945 
1946 /**
1947   * @brief  Get the attributes of an RCC item.
1948   * @note   Secured items are available from non-secure state when set as public
1949   * @param  Item A single item to get secure/non-secure, public/non-public, privilege/non-privilege and locked
1950         attributes from. This parameter can be a value of RCC_items.
1951   * @param  pAttributes pointer to return the attributes (this is a combination of @ref RCC_attributes).
1952   * @retval HAL Status.
1953   *
1954   */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1955 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1956 {
1957   uint32_t attributes = 0UL;
1958 
1959   /* Check null pointer */
1960   if (pAttributes == NULL)
1961   {
1962     return HAL_ERROR;
1963   }
1964 
1965   /* Check the parameters */
1966   assert_param(IS_RCC_SINGLE_ITEM_ATTRIBUTES(Item));
1967 
1968   /* Get the item group index and compute the attribute base register address*/
1969   uint32_t ItemGroup = (Item & RCC_ITEM_GROUP_MASK) >> RCC_ITEM_GROUP_POS;
1970   uint32_t ItemGroupIdx = 0UL;
1971   while ((ItemGroup >> ItemGroupIdx) != 1UL)
1972   {
1973     ItemGroupIdx++;
1974   }
1975 
1976   __IO const uint32_t *p_rcc_reg = &(RCC->SECCFGR0) + (0x4UL * ItemGroupIdx);
1977 
1978   if ((Item & RCC_ITEM_GROUP_MASK) != RCC_ITEM_GROUP_MEM)
1979   {
1980     /* Get secure attribute */
1981     attributes |= ((p_rcc_reg[0] & Item) == 0U) ? RCC_ATTR_NSEC : RCC_ATTR_SEC;
1982 
1983     /* Get privilege attribute */
1984     attributes |= ((p_rcc_reg[1] & Item) == 0U) ? RCC_ATTR_NPRIV : RCC_ATTR_PRIV;
1985 
1986     /* Get lock attribute */
1987     attributes |= ((p_rcc_reg[2] & Item) == 0U) ? RCC_ATTR_NLOCK : RCC_ATTR_LOCK;
1988 
1989     /* Get public attribute */
1990     attributes |= ((p_rcc_reg[3] & Item) == 0U) ? RCC_ATTR_NPUB : RCC_ATTR_PUB;
1991   }
1992   else
1993   {
1994     /* For memory group, only public attribute is available */
1995     attributes |= ((*p_rcc_reg & Item) == 0U) ? RCC_ATTR_NPUB : RCC_ATTR_PUB;
1996   }
1997 
1998   /* Return value */
1999   *pAttributes = attributes;
2000 
2001   return HAL_OK;
2002 }
2003 
2004 /**
2005   * @}
2006   */
2007 
2008 /**
2009   * @}
2010   */
2011 
2012 /** @defgroup RCC_Private_functions RCC Private Functions
2013   * @{
2014   */
2015 /**
2016   * @brief  Configure the requested PLL
2017   * @param  PLLnumber PLL number to configure
2018   * @param  pPLLInit Pointer to an RCC_PLLInitTypeDef structure that
2019   *                  contains the configuration parameters.
2020   * @note   PLL is temporary disabled to apply new parameters
2021   *
2022   * @retval HAL status
2023   */
RCC_PLL_Config(uint32_t PLLnumber,const RCC_PLLInitTypeDef * pPLLInit)2024 static HAL_StatusTypeDef RCC_PLL_Config(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit)
2025 {
2026   __IO uint32_t *p_rcc_pll_cfgr1_reg;
2027   __IO uint32_t *p_rcc_pll_cfgr2_reg;
2028   __IO uint32_t *p_rcc_pll_cfgr3_reg;
2029   HAL_StatusTypeDef ret = HAL_OK;
2030   uint32_t tickstart;
2031 
2032   p_rcc_pll_cfgr1_reg = &(RCC->PLL1CFGR1) + (((uint32_t)0x4) * PLLnumber);
2033   p_rcc_pll_cfgr2_reg = &(RCC->PLL1CFGR2) + (((uint32_t)0x4) * PLLnumber);
2034   p_rcc_pll_cfgr3_reg = &(RCC->PLL1CFGR3) + (((uint32_t)0x4) * PLLnumber);
2035 
2036   /* !!! WARNING: ONLY INTEGER AND FRACTIONAL MODES MANAGED TODAY !!! */
2037   if (pPLLInit->PLLState == RCC_PLL_ON)
2038   {
2039     /* Check the parameters */
2040     assert_param(IS_RCC_PLLSOURCE(pPLLInit->PLLSource));
2041     assert_param(IS_RCC_PLLFRACN_VALUE(pPLLInit->PLLFractional));
2042     assert_param(IS_RCC_PLLM_VALUE(pPLLInit->PLLM));
2043     assert_param(IS_RCC_PLLN_VALUE(pPLLInit->PLLN));
2044     assert_param(IS_RCC_PLLP_VALUE(pPLLInit->PLLP1));
2045     assert_param(IS_RCC_PLLP_VALUE(pPLLInit->PLLP2));
2046 
2047     /* Ensure PLLx is disabled */
2048     WRITE_REG(RCC->CCR, RCC_CCR_PLL1ONC << PLLnumber);
2049 
2050     /* Get Start Tick*/
2051     tickstart = HAL_GetTick();
2052 
2053     /* Wait till PLLx is disabled */
2054     while (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY << PLLnumber)) == (RCC_SR_PLL1RDY << PLLnumber))
2055     {
2056       if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
2057       {
2058         return HAL_TIMEOUT;
2059       }
2060     }
2061 
2062     /* Ensure PLLxMODSSDIS='1' */
2063     SET_BIT(*p_rcc_pll_cfgr3_reg, RCC_PLL1CFGR3_PLL1MODSSDIS);
2064 
2065     /* Clear bypass mode */
2066     CLEAR_BIT(*p_rcc_pll_cfgr1_reg, RCC_PLL1CFGR1_PLL1BYP);
2067 
2068     /* Configure the PLLx clock source, multiplication and division factors. */
2069     MODIFY_REG(*p_rcc_pll_cfgr1_reg, (RCC_PLL1CFGR1_PLL1SEL | RCC_PLL1CFGR1_PLL1DIVM | RCC_PLL1CFGR1_PLL1DIVN), \
2070                (pPLLInit->PLLSource | (pPLLInit->PLLM << RCC_PLL1CFGR1_PLL1DIVM_Pos) \
2071                 | (pPLLInit->PLLN << RCC_PLL1CFGR1_PLL1DIVN_Pos)));
2072     MODIFY_REG(*p_rcc_pll_cfgr3_reg, (RCC_PLL1CFGR3_PLL1PDIV1 | RCC_PLL1CFGR3_PLL1PDIV2), \
2073                ((pPLLInit->PLLP1 << RCC_PLL1CFGR3_PLL1PDIV1_Pos) | (pPLLInit->PLLP2 << RCC_PLL1CFGR3_PLL1PDIV2_Pos)));
2074 
2075     /* Configure PLLx DIVNFRAC */
2076     MODIFY_REG(*p_rcc_pll_cfgr2_reg, RCC_PLL1CFGR2_PLL1DIVNFRAC, \
2077                pPLLInit->PLLFractional << RCC_PLL1CFGR2_PLL1DIVNFRAC_Pos);
2078 
2079     /* Clear PLLxMODDSEN (Also clear in Fractional Mode to ensure the latch of updated FRAC value when set again) */
2080     CLEAR_BIT(*p_rcc_pll_cfgr3_reg, RCC_PLL1CFGR3_PLL1MODDSEN);
2081 
2082     /* Fractional Mode specificities Management */
2083     if (pPLLInit->PLLFractional != 0U)
2084     {
2085       /* Set PLLxMODDSEN and DACEN */
2086       SET_BIT(*p_rcc_pll_cfgr3_reg, (RCC_PLL1CFGR3_PLL1MODDSEN | RCC_PLL1CFGR3_PLL1DACEN));
2087     }
2088 
2089     /* Ensure PLLxMODSSRST='1' and Enable PLLx post divider output */
2090     SET_BIT(*p_rcc_pll_cfgr3_reg, (RCC_PLL1CFGR3_PLL1MODSSRST | RCC_PLL1CFGR3_PLL1PDIVEN));
2091 
2092     /* Enable the PLLx */
2093     WRITE_REG(RCC->CSR, RCC_CSR_PLL1ONS << PLLnumber);
2094 
2095     /* Get Start Tick*/
2096     tickstart = HAL_GetTick();
2097 
2098     /* Wait till PLLx is ready */
2099     while (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY << PLLnumber)) == 0U)
2100     {
2101       if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
2102       {
2103         return HAL_TIMEOUT;
2104       }
2105     }
2106   }
2107   else if (pPLLInit->PLLState == RCC_PLL_BYPASS)
2108   {
2109     assert_param(IS_RCC_PLLSOURCE(pPLLInit->PLLSource));
2110 
2111     /* Check selected source is ready */
2112     if (RCC_PLL_Source_IsReady(pPLLInit->PLLSource) == 1U)
2113     {
2114       /* Ensure PLLx is disabled */
2115       WRITE_REG(RCC->CCR, RCC_CCR_PLL1ONC << PLLnumber);
2116 
2117       /* Get Start Tick*/
2118       tickstart = HAL_GetTick();
2119 
2120       /* Wait till PLLx is disabled */
2121       while (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY << PLLnumber)) == (RCC_SR_PLL1RDY << PLLnumber))
2122       {
2123         if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
2124         {
2125           return HAL_TIMEOUT;
2126         }
2127       }
2128 
2129       /* Set bypass mode with selected source */
2130       MODIFY_REG(*p_rcc_pll_cfgr1_reg, (RCC_PLL1CFGR1_PLL1BYP | RCC_PLL1CFGR1_PLL1SEL), \
2131                  (RCC_PLL1CFGR1_PLL1BYP | pPLLInit->PLLSource));
2132     }
2133     else
2134     {
2135       ret = HAL_ERROR;
2136     }
2137   }
2138   else if (pPLLInit->PLLState == RCC_PLL_OFF)
2139   {
2140     /* Disable PLLx post divider output */
2141     CLEAR_BIT(*p_rcc_pll_cfgr3_reg, RCC_PLL1CFGR3_PLL1PDIVEN);
2142 
2143     /* Ensure PLLx is disabled */
2144     WRITE_REG(RCC->CCR, RCC_CCR_PLL1ONC << PLLnumber);
2145 
2146     /* Get Start Tick*/
2147     tickstart = HAL_GetTick();
2148 
2149     /* Wait till PLLx is disabled */
2150     while (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY << PLLnumber)) == (RCC_SR_PLL1RDY << PLLnumber))
2151     {
2152       if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
2153       {
2154         return HAL_TIMEOUT;
2155       }
2156     }
2157 
2158     /* Clear bypass mode */
2159     CLEAR_BIT(*p_rcc_pll_cfgr1_reg, RCC_PLL1CFGR1_PLL1BYP);
2160   }
2161   else
2162   {
2163     /* Nothing to do */
2164   }
2165 
2166   return ret;
2167 }
2168 
2169 /**
2170   * @brief  Enable the requested PLL
2171   * @param  PLLnumber PLL number to enable
2172   *
2173   * @retval HAL status
2174   */
RCC_PLL_Enable(uint32_t PLLnumber)2175 static HAL_StatusTypeDef RCC_PLL_Enable(uint32_t PLLnumber)
2176 {
2177   HAL_StatusTypeDef ret = HAL_OK;
2178   uint32_t tickstart;
2179 
2180   /* Enable the PLLx */
2181   WRITE_REG(RCC->CSR, RCC_CSR_PLL1ONS << PLLnumber);
2182 
2183   /* Get Start Tick*/
2184   tickstart = HAL_GetTick();
2185 
2186   /* Wait till PLLx is ready */
2187   while (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY << PLLnumber)) == 0U)
2188   {
2189     if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
2190     {
2191       return HAL_TIMEOUT;
2192     }
2193   }
2194 
2195   return ret;
2196 }
2197 
2198 /**
2199   * @brief  Check for a new PLL configuration
2200   * @param  PLLnumber PLL number
2201   * @param  pPLLInit Pointer to an RCC_PLLInitTypeDef structure that
2202   *                  contains the configuration parameters.  *
2203   * @retval 1 if success else 0
2204   */
RCC_PLL_IsNewConfig(uint32_t PLLnumber,const RCC_PLLInitTypeDef * pPLLInit)2205 static uint32_t RCC_PLL_IsNewConfig(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit)
2206 {
2207   __IO const uint32_t *p_rcc_pll_cfgr1_reg, *p_rcc_pll_cfgr2_reg, *p_rcc_pll_cfgr3_reg;
2208   uint32_t ret = 0U;
2209 
2210   /* No assert since done in calling function */
2211 
2212   p_rcc_pll_cfgr1_reg = &(RCC->PLL1CFGR1) + (((uint32_t)0x4) * PLLnumber);
2213   p_rcc_pll_cfgr2_reg = &(RCC->PLL1CFGR2) + (((uint32_t)0x4) * PLLnumber);
2214   p_rcc_pll_cfgr3_reg = &(RCC->PLL1CFGR3) + (((uint32_t)0x4) * PLLnumber);
2215 
2216   /* !!! WARNING: ONLY INTEGER AND FRACTIONAL MODES MANAGED TODAY !!! */
2217 
2218   /* Check for PLLCFGR1, PLLCFGR2 and PLLCFGR3 parameters updates */
2219   if ((*p_rcc_pll_cfgr1_reg & (RCC_PLL1CFGR1_PLL1SEL | RCC_PLL1CFGR1_PLL1DIVM | RCC_PLL1CFGR1_PLL1DIVN)) != \
2220       (pPLLInit->PLLSource | (pPLLInit->PLLM << RCC_PLL1CFGR1_PLL1DIVM_Pos) \
2221        | (pPLLInit->PLLN << RCC_PLL1CFGR1_PLL1DIVN_Pos)))
2222   {
2223     ret = 1U; /* New PLL configuration */
2224   }
2225   else if ((*p_rcc_pll_cfgr2_reg & RCC_PLL1CFGR2_PLL1DIVNFRAC) != \
2226            (pPLLInit->PLLFractional << RCC_PLL1CFGR2_PLL1DIVNFRAC_Pos))
2227   {
2228     ret = 1U; /* New PLL configuration */
2229   }
2230   else if ((*p_rcc_pll_cfgr3_reg & (RCC_PLL1CFGR3_PLL1PDIV1 | RCC_PLL1CFGR3_PLL1PDIV2)) != \
2231            ((pPLLInit->PLLP1 << RCC_PLL1CFGR3_PLL1PDIV1_Pos) | (pPLLInit->PLLP2 << RCC_PLL1CFGR3_PLL1PDIV2_Pos)))
2232   {
2233     ret = 1U; /* New PLL configuration */
2234   }
2235   else
2236   {
2237     /* Mode change detection*/
2238     uint32_t pllState;
2239 
2240     /* Get current Mode*/
2241     if (READ_BIT(RCC->SR, (RCC_SR_PLL1RDY << PLLnumber)) == (RCC_SR_PLL1RDY << PLLnumber))
2242     {
2243       pllState = RCC_PLL_ON;
2244     }
2245     else
2246     {
2247       if ((*p_rcc_pll_cfgr1_reg & RCC_PLL1CFGR1_PLL1BYP) != 0UL)
2248       {
2249         pllState = RCC_PLL_BYPASS;
2250       }
2251       else
2252       {
2253         pllState = RCC_PLL_OFF;
2254       }
2255     }
2256 
2257     /* Compare with new mode */
2258     if (pllState != pPLLInit->PLLState)
2259     {
2260       ret = 1U; /* New PLL configuration */
2261     }
2262   }
2263 
2264   return ret;
2265 }
2266 
2267 /**
2268   * @brief  Check whether the PLL source is ready
2269   * @param  PLLSource PLL source
2270   * @retval 1 if success else 0
2271   */
RCC_PLL_Source_IsReady(uint32_t PLLSource)2272 static uint32_t RCC_PLL_Source_IsReady(uint32_t PLLSource)
2273 {
2274   uint32_t ret = 1U;
2275 
2276   /* No assert since done in calling function */
2277 
2278   switch (PLLSource)
2279   {
2280     case RCC_PLLSOURCE_HSI:
2281       if (LL_RCC_HSI_IsReady() == 0U)
2282       {
2283         ret = 0U;
2284       }
2285       break;
2286     case RCC_PLLSOURCE_MSI:
2287       if (LL_RCC_MSI_IsReady() == 0U)
2288       {
2289         ret = 0U;
2290       }
2291       break;
2292     case RCC_PLLSOURCE_HSE:
2293       if (LL_RCC_HSE_IsReady() == 0U)
2294       {
2295         ret = 0U;
2296       }
2297       break;
2298     case RCC_PLLSOURCE_PIN:
2299     default:
2300       break;
2301   }
2302 
2303   return ret;
2304 }
2305 
2306 /**
2307   * @brief  Check whether PLL sources are available
2308   * @param  PLLSource1 First PLL source
2309   * @param  PLLSource2 Second PLL source
2310   * @retval 1 if success else 0
2311   */
RCC_IC_CheckPLLSources(uint32_t PLLSource1,uint32_t PLLSource2)2312 static uint32_t RCC_IC_CheckPLLSources(uint32_t PLLSource1, uint32_t PLLSource2)
2313 {
2314   uint32_t ret = 1U;
2315 
2316   /* No assert since done in calling function */
2317 
2318   /* Check PLLSource1 clock source */
2319   switch (PLLSource1)
2320   {
2321     case LL_RCC_ICCLKSOURCE_PLL1:
2322       if (LL_RCC_PLL1_IsReady() == 0U)
2323       {
2324         if (LL_RCC_PLL1_IsEnabledBypass() == 0U)
2325         {
2326           ret = 0U;
2327         }
2328       }
2329       break;
2330     case LL_RCC_ICCLKSOURCE_PLL2:
2331       if (LL_RCC_PLL2_IsReady() == 0U)
2332       {
2333         if (LL_RCC_PLL2_IsEnabledBypass() == 0U)
2334         {
2335           ret = 0U;
2336         }
2337       }
2338       break;
2339     case LL_RCC_ICCLKSOURCE_PLL3:
2340       if (LL_RCC_PLL3_IsReady() == 0U)
2341       {
2342         if (LL_RCC_PLL3_IsEnabledBypass() == 0U)
2343         {
2344           ret = 0U;
2345         }
2346       }
2347       break;
2348     case LL_RCC_ICCLKSOURCE_PLL4:
2349       if (LL_RCC_PLL4_IsReady() == 0U)
2350       {
2351         if (LL_RCC_PLL4_IsEnabledBypass() == 0U)
2352         {
2353           ret = 0U;
2354         }
2355       }
2356       break;
2357     default:
2358       /* Unexpected */
2359       ret = 0U;
2360       break;
2361   }
2362 
2363   /* Check PLLSource2 clock source */
2364   switch (PLLSource2)
2365   {
2366     case LL_RCC_ICCLKSOURCE_PLL1:
2367       if (LL_RCC_PLL1_IsReady() == 0U)
2368       {
2369         if (LL_RCC_PLL1_IsEnabledBypass() == 0U)
2370         {
2371           ret = 0U;
2372         }
2373       }
2374       break;
2375     case LL_RCC_ICCLKSOURCE_PLL2:
2376       if (LL_RCC_PLL2_IsReady() == 0U)
2377       {
2378         if (LL_RCC_PLL2_IsEnabledBypass() == 0U)
2379         {
2380           ret = 0U;
2381         }
2382       }
2383       break;
2384     case LL_RCC_ICCLKSOURCE_PLL3:
2385       if (LL_RCC_PLL3_IsReady() == 0U)
2386       {
2387         if (LL_RCC_PLL3_IsEnabledBypass() == 0U)
2388         {
2389           ret = 0U;
2390         }
2391       }
2392       break;
2393     case LL_RCC_ICCLKSOURCE_PLL4:
2394       if (LL_RCC_PLL4_IsReady() == 0U)
2395       {
2396         if (LL_RCC_PLL4_IsEnabledBypass() == 0U)
2397         {
2398           ret = 0U;
2399         }
2400       }
2401       break;
2402     default:
2403       /* Unexpected */
2404       ret = 0U;
2405       break;
2406   }
2407 
2408   return ret;
2409 }
2410 
2411 /**
2412   * @brief  Attribute configuration of a group of Items.
2413   * @param  ItemGroupIdx the Item group Index to configure
2414   * @param  Item Item(s) to set attributes on.
2415   *         This parameter can be a one or a combination of @ref RCC_items, masked with RCC_ITEM_MASK
2416   * @param  Attributes specifies the RCC secure/privilege/public/lock attributes.
2417   *         This parameter can be a combination of @ref RCC_attributes
2418   * @retval None
2419   */
RCC_ATTR_ConfigItemGroup(uint32_t ItemGroupIdx,uint32_t Item,uint32_t Attributes)2420 static void RCC_ATTR_ConfigItemGroup(uint32_t ItemGroupIdx, uint32_t Item, uint32_t Attributes)
2421 {
2422   __IO uint32_t *p_rcc_reg = &(RCC->SECCFGR0) + (0x4UL * ItemGroupIdx);
2423 
2424   if (ItemGroupIdx != RCC_ITEM_GROUP_IDX_MEM)
2425   {
2426 #if defined (CPU_IN_SECURE_STATE)
2427     /* Check item security attribute management */
2428     if ((Attributes & RCC_ATTR_SEC_MASK) == RCC_ATTR_SEC_MASK)
2429     {
2430       /* Configure item security attribute */
2431       if ((Attributes & RCC_ATTR_SEC) == RCC_ATTR_SEC)
2432       {
2433         SET_BIT(p_rcc_reg[0], Item);
2434       }
2435       else
2436       {
2437         CLEAR_BIT(p_rcc_reg[0], Item);
2438       }
2439     }
2440 #endif /* CPU_IN_SECURE_STATE */
2441 
2442     /* Check item privilege attribute management */
2443     if ((Attributes & RCC_ATTR_PRIV_MASK) == RCC_ATTR_PRIV_MASK)
2444     {
2445       /* Configure item privilege attribute */
2446       if ((Attributes & RCC_ATTR_PRIV) == RCC_ATTR_PRIV)
2447       {
2448         SET_BIT(p_rcc_reg[1], Item);
2449       }
2450       else
2451       {
2452         CLEAR_BIT(p_rcc_reg[1], Item);
2453       }
2454     }
2455 
2456 #if defined (CPU_IN_SECURE_STATE)
2457     /* Check item lock attribute management */
2458     if ((Attributes & RCC_ATTR_LOCK_MASK) == RCC_ATTR_LOCK_MASK)
2459     {
2460       /* Configure item lock attribute */
2461       if ((Attributes & RCC_ATTR_LOCK) == RCC_ATTR_LOCK)
2462       {
2463         SET_BIT(p_rcc_reg[2], Item);
2464       }
2465     }
2466 
2467     /* Check item public attribute management */
2468     if ((Attributes & RCC_ATTR_PUB_MASK) == RCC_ATTR_PUB_MASK)
2469     {
2470       /* Configure item public attribute */
2471       if ((Attributes & RCC_ATTR_PUB) == RCC_ATTR_PUB)
2472       {
2473         SET_BIT(p_rcc_reg[3], Item);
2474       }
2475       else
2476       {
2477         CLEAR_BIT(p_rcc_reg[3], Item);
2478       }
2479     }
2480 #endif /* CPU_IN_SECURE_STATE */
2481   }
2482   else
2483   {
2484     /* For memory group, only public attribute is available */
2485 #if defined (CPU_IN_SECURE_STATE)
2486     /* Check item public attribute management */
2487     if ((Attributes & RCC_ATTR_PUB_MASK) == RCC_ATTR_PUB_MASK)
2488     {
2489       /* Configure item public attribute */
2490       if ((Attributes & RCC_ATTR_PUB) == RCC_ATTR_PUB)
2491       {
2492         SET_BIT(*(p_rcc_reg), Item);
2493       }
2494       else
2495       {
2496         CLEAR_BIT(*(p_rcc_reg), Item);
2497       }
2498     }
2499 #endif /* CPU_IN_SECURE_STATE */
2500   }
2501 }
2502 
2503 /**
2504   * @}
2505   */
2506 
2507 #endif /* HAL_RCC_MODULE_ENABLED */
2508 
2509 /**
2510   * @}
2511   */
2512 
2513 /**
2514   * @}
2515   */
2516