1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_rcc_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended RCC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities RCC extension peripheral:
8   *           + Extended Peripheral Control functions
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
14   * All rights reserved.</center></h2>
15   *
16   * This software component is licensed by ST under BSD 3-Clause license,
17   * the "License"; You may not use this file except in compliance with the
18   * License. You may obtain a copy of the License at:
19   *                        opensource.org/licenses/BSD-3-Clause
20   *
21   ******************************************************************************
22   */
23 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32h7xx_hal.h"
26 
27 /** @addtogroup STM32H7xx_HAL_Driver
28   * @{
29   */
30 
31 /** @defgroup RCCEx  RCCEx
32   * @brief RCC HAL module driver
33   * @{
34   */
35 
36 #ifdef HAL_RCC_MODULE_ENABLED
37 
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private defines -----------------------------------------------------------*/
40 /** @defgroup RCCEx_Private_defines Private Defines
41  * @{
42  */
43 #define PLL2_TIMEOUT_VALUE         PLL_TIMEOUT_VALUE    /* 2 ms */
44 #define PLL3_TIMEOUT_VALUE         PLL_TIMEOUT_VALUE    /* 2 ms */
45 
46 #define DIVIDER_P_UPDATE          0U
47 #define DIVIDER_Q_UPDATE          1U
48 #define DIVIDER_R_UPDATE          2U
49 /**
50   * @}
51   */
52 
53 /* Private macros ------------------------------------------------------------*/
54 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
55  * @{
56  */
57 /**
58   * @}
59   */
60 
61 /* Private variables ---------------------------------------------------------*/
62 /* Private function prototypes -----------------------------------------------*/
63 static HAL_StatusTypeDef RCCEx_PLL2_Config(RCC_PLL2InitTypeDef *pll2, uint32_t Divider);
64 static HAL_StatusTypeDef RCCEx_PLL3_Config(RCC_PLL3InitTypeDef *pll3, uint32_t Divider);
65 
66 
67 /* Exported functions --------------------------------------------------------*/
68 
69 /** @defgroup RCCEx_Exported_Functions Exported Functions
70   * @{
71   */
72 
73 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
74  *  @brief  Extended Peripheral Control functions
75  *
76 @verbatim
77  ===============================================================================
78                 ##### Extended Peripheral Control functions  #####
79  ===============================================================================
80     [..]
81     This subsection provides a set of functions allowing to control the RCC Clocks
82     frequencies.
83     [..]
84     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
85         select the RTC clock source; in this case the Backup domain will be reset in
86         order to modify the RTC Clock source, as consequence RTC registers (including
87         the backup registers) and RCC_BDCR register are set to their reset values.
88 
89 @endverbatim
90   * @{
91   */
92 /**
93   * @brief  Initializes the RCC extended peripherals clocks according to the specified
94   *         parameters in the RCC_PeriphCLKInitTypeDef.
95   * @param  PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
96   *         contains the configuration information for the Extended Peripherals
97   *         clocks(SDMMC, CKPER, FMC, QSPI, DSI, SPI45, SPDIF, DFSDM1, FDCAN, SWPMI,SAI23, SAI1, SPI123,
98   *         USART234578, USART16, RNG, HRTIM1, I2C123, USB,CEC, LPTIM1, LPUART1, I2C4, LPTIM2, LPTIM345, ADC,
99   *         SAI4A,SAI4B,SPI6,RTC).
100   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
101   *         the RTC clock source; in this case the Backup domain will be reset in
102   *         order to modify the RTC Clock source, as consequence RTC registers (including
103   *         the backup registers) are set to their reset values.
104   *
105   * @retval HAL status
106   */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)107 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
108 {
109   uint32_t tmpreg;
110   uint32_t tickstart;
111   HAL_StatusTypeDef ret = HAL_OK;      /* Intermediate status */
112   HAL_StatusTypeDef status = HAL_OK;   /* Final status */
113 
114   /*---------------------------- SPDIFRX configuration -------------------------------*/
115 
116   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
117   {
118 
119     switch(PeriphClkInit->SpdifrxClockSelection)
120     {
121     case RCC_SPDIFRXCLKSOURCE_PLL:      /* PLL is used as clock source for SPDIFRX*/
122       /* Enable SAI Clock output generated form System PLL . */
123       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
124 
125       /* SAI1 clock source configuration done later after clock selection check */
126       break;
127 
128     case RCC_SPDIFRXCLKSOURCE_PLL2: /* PLL2 is used as clock source for SPDIFRX*/
129 
130       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_R_UPDATE);
131 
132       /* SAI1 clock source configuration done later after clock selection check */
133       break;
134 
135     case RCC_SPDIFRXCLKSOURCE_PLL3:  /* PLL3 is used as clock source for SPDIFRX*/
136       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE);
137 
138       /* SAI1 clock source configuration done later after clock selection check */
139       break;
140 
141     case RCC_SPDIFRXCLKSOURCE_HSI:
142       /* Internal OSC clock is used as source of SPDIFRX clock*/
143       /* SPDIFRX clock source configuration done later after clock selection check */
144       break;
145 
146     default:
147       ret = HAL_ERROR;
148       break;
149     }
150 
151     if(ret == HAL_OK)
152     {
153       /* Set the source of SPDIFRX clock*/
154       __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifrxClockSelection);
155     }
156     else
157     {
158       /* set overall return value */
159       status = ret;
160     }
161   }
162 
163   /*---------------------------- SAI1 configuration -------------------------------*/
164   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)
165   {
166     switch(PeriphClkInit->Sai1ClockSelection)
167     {
168     case RCC_SAI1CLKSOURCE_PLL:      /* PLL is used as clock source for SAI1*/
169       /* Enable SAI Clock output generated form System PLL . */
170       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
171 
172       /* SAI1 clock source configuration done later after clock selection check */
173       break;
174 
175     case RCC_SAI1CLKSOURCE_PLL2: /* PLL2 is used as clock source for SAI1*/
176 
177       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
178 
179       /* SAI1 clock source configuration done later after clock selection check */
180       break;
181 
182     case RCC_SAI1CLKSOURCE_PLL3:  /* PLL3 is used as clock source for SAI1*/
183       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_P_UPDATE);
184 
185       /* SAI1 clock source configuration done later after clock selection check */
186       break;
187 
188     case RCC_SAI1CLKSOURCE_PIN:
189       /* External clock is used as source of SAI1 clock*/
190       /* SAI1 clock source configuration done later after clock selection check */
191       break;
192 
193     case RCC_SAI1CLKSOURCE_CLKP:
194       /* HSI, HSE, or CSI oscillator is used as source of SAI1 clock */
195       /* SAI1 clock source configuration done later after clock selection check */
196       break;
197 
198     default:
199       ret = HAL_ERROR;
200       break;
201     }
202 
203     if(ret == HAL_OK)
204     {
205       /* Set the source of SAI1 clock*/
206       __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
207     }
208     else
209     {
210       /* set overall return value */
211       status = ret;
212     }
213   }
214 
215   /*---------------------------- SAI2/3 configuration -------------------------------*/
216   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI23) == RCC_PERIPHCLK_SAI23)
217   {
218     switch(PeriphClkInit->Sai23ClockSelection)
219     {
220     case RCC_SAI23CLKSOURCE_PLL:      /* PLL is used as clock source for SAI2/3 */
221       /* Enable SAI Clock output generated form System PLL . */
222       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
223 
224       /* SAI2/3 clock source configuration done later after clock selection check */
225       break;
226 
227     case RCC_SAI23CLKSOURCE_PLL2: /* PLL2 is used as clock source for SAI2/3 */
228 
229       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
230 
231       /* SAI2/3 clock source configuration done later after clock selection check */
232       break;
233 
234     case RCC_SAI23CLKSOURCE_PLL3:  /* PLL3 is used as clock source for SAI2/3 */
235       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_P_UPDATE);
236 
237       /* SAI2/3 clock source configuration done later after clock selection check */
238       break;
239 
240     case RCC_SAI23CLKSOURCE_PIN:
241       /* External clock is used as source of SAI2/3 clock*/
242       /* SAI2/3 clock source configuration done later after clock selection check */
243       break;
244 
245     case RCC_SAI23CLKSOURCE_CLKP:
246       /* HSI, HSE, or CSI oscillator is used as source of SAI2/3 clock */
247       /* SAI2/3 clock source configuration done later after clock selection check */
248       break;
249 
250     default:
251       ret = HAL_ERROR;
252       break;
253     }
254 
255     if(ret == HAL_OK)
256     {
257       /* Set the source of SAI2/3 clock*/
258       __HAL_RCC_SAI23_CONFIG(PeriphClkInit->Sai23ClockSelection);
259     }
260     else
261     {
262       /* set overall return value */
263       status = ret;
264     }
265   }
266 
267   /*---------------------------- SAI4A configuration -------------------------------*/
268   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI4A) == RCC_PERIPHCLK_SAI4A)
269   {
270     switch(PeriphClkInit->Sai4AClockSelection)
271     {
272     case RCC_SAI4ACLKSOURCE_PLL:      /* PLL is used as clock source for SAI2*/
273       /* Enable SAI Clock output generated form System PLL . */
274       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
275 
276       /* SAI1 clock source configuration done later after clock selection check */
277       break;
278 
279     case RCC_SAI4ACLKSOURCE_PLL2: /* PLL2 is used as clock source for SAI2*/
280 
281       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
282 
283       /* SAI2 clock source configuration done later after clock selection check */
284       break;
285 
286     case RCC_SAI4ACLKSOURCE_PLL3:  /* PLL3 is used as clock source for SAI2*/
287       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_P_UPDATE);
288 
289       /* SAI1 clock source configuration done later after clock selection check */
290       break;
291 
292     case RCC_SAI4ACLKSOURCE_PIN:
293       /* External clock is used as source of SAI2 clock*/
294       /* SAI2 clock source configuration done later after clock selection check */
295       break;
296 
297     case RCC_SAI4ACLKSOURCE_CLKP:
298       /* HSI, HSE, or CSI oscillator is used as source of SAI2 clock */
299       /* SAI1 clock source configuration done later after clock selection check */
300       break;
301 
302     default:
303       ret = HAL_ERROR;
304       break;
305     }
306 
307     if(ret == HAL_OK)
308     {
309       /* Set the source of SAI2 clock*/
310       __HAL_RCC_SAI4A_CONFIG(PeriphClkInit->Sai4AClockSelection);
311     }
312     else
313     {
314       /* set overall return value */
315       status = ret;
316     }
317   }
318   /*---------------------------- SAI4B configuration -------------------------------*/
319   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI4B) == RCC_PERIPHCLK_SAI4B)
320   {
321     switch(PeriphClkInit->Sai4BClockSelection)
322     {
323     case RCC_SAI4BCLKSOURCE_PLL:      /* PLL is used as clock source for SAI2*/
324       /* Enable SAI Clock output generated form System PLL . */
325       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
326 
327       /* SAI1 clock source configuration done later after clock selection check */
328       break;
329 
330     case RCC_SAI4BCLKSOURCE_PLL2: /* PLL2 is used as clock source for SAI2*/
331 
332       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
333 
334       /* SAI2 clock source configuration done later after clock selection check */
335       break;
336 
337     case RCC_SAI4BCLKSOURCE_PLL3:  /* PLL3 is used as clock source for SAI2*/
338       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3), DIVIDER_P_UPDATE);
339 
340       /* SAI1 clock source configuration done later after clock selection check */
341       break;
342 
343     case RCC_SAI4BCLKSOURCE_PIN:
344       /* External clock is used as source of SAI2 clock*/
345       /* SAI2 clock source configuration done later after clock selection check */
346       break;
347 
348     case RCC_SAI4BCLKSOURCE_CLKP:
349       /* HSI, HSE, or CSI oscillator is used as source of SAI2 clock */
350       /* SAI1 clock source configuration done later after clock selection check */
351       break;
352 
353     default:
354       ret = HAL_ERROR;
355       break;
356     }
357 
358     if(ret == HAL_OK)
359     {
360       /* Set the source of SAI2 clock*/
361       __HAL_RCC_SAI4B_CONFIG(PeriphClkInit->Sai4BClockSelection);
362     }
363     else
364     {
365       /* set overall return value */
366       status = ret;
367     }
368   }
369   /*---------------------------- QSPI configuration -------------------------------*/
370   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_QSPI) == RCC_PERIPHCLK_QSPI)
371   {
372     switch(PeriphClkInit->QspiClockSelection)
373     {
374     case RCC_QSPICLKSOURCE_PLL:      /* PLL is used as clock source for QSPI*/
375       /* Enable QSPI Clock output generated form System PLL . */
376       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
377 
378       /* QSPI clock source configuration done later after clock selection check */
379       break;
380 
381     case RCC_QSPICLKSOURCE_PLL2: /* PLL2 is used as clock source for QSPI*/
382 
383       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_R_UPDATE);
384 
385       /* QSPI clock source configuration done later after clock selection check */
386       break;
387 
388 
389     case RCC_QSPICLKSOURCE_CLKP:
390       /* HSI, HSE, or CSI oscillator is used as source of QSPI clock */
391       /* QSPI clock source configuration done later after clock selection check */
392       break;
393 
394     case RCC_QSPICLKSOURCE_D1HCLK:
395       /* Domain1 HCLK  clock selected as QSPI kernel peripheral clock */
396       break;
397 
398     default:
399       ret = HAL_ERROR;
400       break;
401     }
402 
403     if(ret == HAL_OK)
404     {
405       /* Set the source of QSPI clock*/
406       __HAL_RCC_QSPI_CONFIG(PeriphClkInit->QspiClockSelection);
407     }
408     else
409     {
410       /* set overall return value */
411       status = ret;
412     }
413   }
414 
415   /*---------------------------- SPI1/2/3 configuration -------------------------------*/
416   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI123) == RCC_PERIPHCLK_SPI123)
417   {
418     switch(PeriphClkInit->Spi123ClockSelection)
419     {
420     case RCC_SPI123CLKSOURCE_PLL:      /* PLL is used as clock source for SPI1/2/3 */
421       /* Enable SPI Clock output generated form System PLL . */
422       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
423 
424       /* SPI1/2/3 clock source configuration done later after clock selection check */
425       break;
426 
427     case RCC_SPI123CLKSOURCE_PLL2: /* PLL2 is used as clock source for SPI1/2/3 */
428       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
429 
430       /* SPI1/2/3 clock source configuration done later after clock selection check */
431       break;
432 
433     case RCC_SPI123CLKSOURCE_PLL3:  /* PLL3 is used as clock source for SPI1/2/3 */
434       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_P_UPDATE);
435 
436       /* SPI1/2/3 clock source configuration done later after clock selection check */
437       break;
438 
439     case RCC_SPI123CLKSOURCE_PIN:
440       /* External clock is used as source of SPI1/2/3 clock*/
441       /* SPI1/2/3 clock source configuration done later after clock selection check */
442       break;
443 
444     case RCC_SPI123CLKSOURCE_CLKP:
445       /* HSI, HSE, or CSI oscillator is used as source of SPI1/2/3 clock */
446       /* SPI1/2/3 clock source configuration done later after clock selection check */
447       break;
448 
449     default:
450       ret = HAL_ERROR;
451       break;
452     }
453 
454     if(ret == HAL_OK)
455     {
456       /* Set the source of SPI1/2/3 clock*/
457       __HAL_RCC_SPI123_CONFIG(PeriphClkInit->Spi123ClockSelection);
458     }
459     else
460     {
461       /* set overall return value */
462       status = ret;
463     }
464   }
465 
466   /*---------------------------- SPI4/5 configuration -------------------------------*/
467   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI45) == RCC_PERIPHCLK_SPI45)
468   {
469     switch(PeriphClkInit->Spi45ClockSelection)
470     {
471     case RCC_SPI45CLKSOURCE_D2PCLK1:      /* D2PCLK1 as clock source for SPI4/5 */
472       /* SPI4/5 clock source configuration done later after clock selection check */
473       break;
474 
475     case RCC_SPI45CLKSOURCE_PLL2: /* PLL2 is used as clock source for SPI4/5 */
476 
477       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
478 
479       /* SPI4/5 clock source configuration done later after clock selection check */
480       break;
481     case RCC_SPI45CLKSOURCE_PLL3:  /* PLL3 is used as clock source for SPI4/5 */
482       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_Q_UPDATE);
483       /* SPI4/5 clock source configuration done later after clock selection check */
484       break;
485 
486     case RCC_SPI45CLKSOURCE_HSI:
487       /* HSI oscillator clock is used as source of SPI4/5 clock*/
488       /* SPI4/5 clock source configuration done later after clock selection check */
489       break;
490 
491     case RCC_SPI45CLKSOURCE_CSI:
492       /*  CSI oscillator clock is used as source of SPI4/5 clock */
493       /* SPI4/5 clock source configuration done later after clock selection check */
494       break;
495 
496     case RCC_SPI45CLKSOURCE_HSE:
497       /* HSE,  oscillator is used as source of SPI4/5 clock */
498       /* SPI4/5 clock source configuration done later after clock selection check */
499       break;
500 
501     default:
502       ret = HAL_ERROR;
503       break;
504     }
505 
506     if(ret == HAL_OK)
507     {
508       /* Set the source of SPI4/5 clock*/
509       __HAL_RCC_SPI45_CONFIG(PeriphClkInit->Spi45ClockSelection);
510     }
511     else
512     {
513       /* set overall return value */
514       status = ret;
515     }
516   }
517 
518   /*---------------------------- SPI6 configuration -------------------------------*/
519   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI6) == RCC_PERIPHCLK_SPI6)
520   {
521     switch(PeriphClkInit->Spi6ClockSelection)
522     {
523     case RCC_SPI6CLKSOURCE_D3PCLK1:      /* D3PCLK1 as clock source for SPI6*/
524       /* SPI6 clock source configuration done later after clock selection check */
525       break;
526 
527     case RCC_SPI6CLKSOURCE_PLL2: /* PLL2 is used as clock source for SPI6*/
528 
529       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
530 
531       /* SPI6 clock source configuration done later after clock selection check */
532       break;
533     case RCC_SPI6CLKSOURCE_PLL3:  /* PLL3 is used as clock source for SPI6*/
534       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_Q_UPDATE);
535       /* SPI6 clock source configuration done later after clock selection check */
536       break;
537 
538     case RCC_SPI6CLKSOURCE_HSI:
539       /* HSI oscillator clock is used as source of SPI6 clock*/
540       /* SPI6 clock source configuration done later after clock selection check */
541       break;
542 
543     case RCC_SPI6CLKSOURCE_CSI:
544       /*  CSI oscillator clock is used as source of SPI6 clock */
545       /* SPI6 clock source configuration done later after clock selection check */
546       break;
547 
548     case RCC_SPI6CLKSOURCE_HSE:
549       /* HSE,  oscillator is used as source of SPI6 clock */
550       /* SPI6 clock source configuration done later after clock selection check */
551       break;
552 
553     default:
554       ret = HAL_ERROR;
555       break;
556     }
557 
558     if(ret == HAL_OK)
559     {
560       /* Set the source of SPI6 clock*/
561       __HAL_RCC_SPI6_CONFIG(PeriphClkInit->Spi6ClockSelection);
562     }
563     else
564     {
565       /* set overall return value */
566       status = ret;
567     }
568   }
569 
570 #if defined(DSI)
571   /*---------------------------- DSI configuration -------------------------------*/
572   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DSI) == RCC_PERIPHCLK_DSI)
573   {
574     switch(PeriphClkInit->DsiClockSelection)
575     {
576 
577     case RCC_DSICLKSOURCE_PLL2: /* PLL2 is used as clock source for DSI*/
578 
579       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
580 
581       /* DSI clock source configuration done later after clock selection check */
582       break;
583 
584     case RCC_DSICLKSOURCE_PHY:
585       /* PHY is used as clock source for DSI*/
586       /* DSI clock source configuration done later after clock selection check */
587       break;
588 
589     default:
590       ret = HAL_ERROR;
591       break;
592     }
593 
594     if(ret == HAL_OK)
595     {
596       /* Set the source of DSI clock*/
597       __HAL_RCC_DSI_CONFIG(PeriphClkInit->DsiClockSelection);
598     }
599     else
600     {
601       /* set overall return value */
602       status = ret;
603     }
604   }
605 #endif /*DSI*/
606 
607 #if defined(FDCAN1) || defined(FDCAN2)
608   /*---------------------------- FDCAN configuration -------------------------------*/
609   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FDCAN) == RCC_PERIPHCLK_FDCAN)
610   {
611     switch(PeriphClkInit->FdcanClockSelection)
612     {
613     case RCC_FDCANCLKSOURCE_PLL:      /* PLL is used as clock source for FDCAN*/
614       /* Enable FDCAN Clock output generated form System PLL . */
615       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
616 
617       /* FDCAN clock source configuration done later after clock selection check */
618       break;
619 
620     case RCC_FDCANCLKSOURCE_PLL2: /* PLL2 is used as clock source for FDCAN*/
621 
622       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
623 
624       /* FDCAN clock source configuration done later after clock selection check */
625       break;
626 
627     case RCC_FDCANCLKSOURCE_HSE:
628       /* HSE is used as clock source for FDCAN*/
629       /* FDCAN clock source configuration done later after clock selection check */
630       break;
631 
632     default:
633       ret = HAL_ERROR;
634       break;
635     }
636 
637     if(ret == HAL_OK)
638     {
639       /* Set the source of FDCAN clock*/
640       __HAL_RCC_FDCAN_CONFIG(PeriphClkInit->FdcanClockSelection);
641     }
642     else
643     {
644       /* set overall return value */
645       status = ret;
646     }
647   }
648 
649 #endif /*FDCAN1 || FDCAN2*/
650   /*---------------------------- FMC configuration -------------------------------*/
651   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMC) == RCC_PERIPHCLK_FMC)
652   {
653     switch(PeriphClkInit->FmcClockSelection)
654     {
655     case RCC_FMCCLKSOURCE_PLL:      /* PLL is used as clock source for FMC*/
656       /* Enable FMC Clock output generated form System PLL . */
657       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
658 
659       /* FMC clock source configuration done later after clock selection check */
660       break;
661 
662     case RCC_FMCCLKSOURCE_PLL2: /* PLL2 is used as clock source for FMC*/
663 
664       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_R_UPDATE);
665 
666       /* FMC clock source configuration done later after clock selection check */
667       break;
668 
669 
670     case RCC_FMCCLKSOURCE_CLKP:
671       /* HSI, HSE, or CSI oscillator is used as source of FMC clock */
672       /* FMC clock source configuration done later after clock selection check */
673       break;
674 
675     case RCC_FMCCLKSOURCE_D1HCLK:
676       /* Domain1 HCLK  clock selected as QSPI kernel peripheral clock */
677       break;
678 
679     default:
680       ret = HAL_ERROR;
681       break;
682     }
683 
684     if(ret == HAL_OK)
685     {
686       /* Set the source of FMC clock*/
687       __HAL_RCC_FMC_CONFIG(PeriphClkInit->FmcClockSelection);
688     }
689     else
690     {
691       /* set overall return value */
692       status = ret;
693     }
694   }
695 
696   /*---------------------------- RTC configuration -------------------------------*/
697   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
698   {
699     /* check for RTC Parameters used to output RTCCLK */
700     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
701 
702     /* Enable write access to Backup domain */
703     SET_BIT(PWR->CR1, PWR_CR1_DBP);
704 
705     /* Wait for Backup domain Write protection disable */
706     tickstart = HAL_GetTick();
707 
708     while((PWR->CR1 & PWR_CR1_DBP) == 0U)
709     {
710       if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
711       {
712         ret = HAL_TIMEOUT;
713         break;
714       }
715     }
716 
717     if(ret == HAL_OK)
718     {
719       /* Reset the Backup domain only if the RTC Clock source selection is modified */
720       if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
721       {
722         /* Store the content of BDCR register before the reset of Backup Domain */
723         tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
724         /* RTC Clock selection can be changed only if the Backup Domain is reset */
725         __HAL_RCC_BACKUPRESET_FORCE();
726         __HAL_RCC_BACKUPRESET_RELEASE();
727         /* Restore the Content of BDCR register */
728         RCC->BDCR = tmpreg;
729       }
730 
731       /* If LSE is selected as RTC clock source, wait for LSE reactivation */
732       if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
733       {
734         /* Get Start Tick*/
735         tickstart = HAL_GetTick();
736 
737         /* Wait till LSE is ready */
738         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == 0U)
739         {
740           if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
741           {
742             ret = HAL_TIMEOUT;
743             break;
744           }
745         }
746       }
747 
748       if(ret == HAL_OK)
749       {
750         __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
751       }
752       else
753       {
754         /* set overall return value */
755         status = ret;
756       }
757     }
758     else
759     {
760       /* set overall return value */
761       status = ret;
762     }
763   }
764 
765 
766   /*-------------------------- USART1/6 configuration --------------------------*/
767   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART16) == RCC_PERIPHCLK_USART16)
768   {
769     switch(PeriphClkInit->Usart16ClockSelection)
770     {
771     case RCC_USART16CLKSOURCE_D2PCLK2: /* D2PCLK2 as clock source for USART1/6 */
772       /* USART1/6 clock source configuration done later after clock selection check */
773       break;
774 
775     case RCC_USART16CLKSOURCE_PLL2: /* PLL2 is used as clock source for USART1/6 */
776       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
777       /* USART1/6 clock source configuration done later after clock selection check */
778       break;
779 
780     case RCC_USART16CLKSOURCE_PLL3: /* PLL3 is used as clock source for USART1/6 */
781       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_Q_UPDATE);
782       /* USART1/6 clock source configuration done later after clock selection check */
783       break;
784 
785     case RCC_USART16CLKSOURCE_HSI:
786       /* HSI oscillator clock is used as source of USART1/6 clock */
787       /* USART1/6 clock source configuration done later after clock selection check */
788       break;
789 
790     case RCC_USART16CLKSOURCE_CSI:
791       /* CSI oscillator clock is used as source of USART1/6 clock */
792       /* USART1/6 clock source configuration done later after clock selection check */
793       break;
794 
795     case RCC_USART16CLKSOURCE_LSE:
796       /* LSE,  oscillator is used as source of USART1/6 clock */
797       /* USART1/6 clock source configuration done later after clock selection check */
798       break;
799 
800     default:
801       ret = HAL_ERROR;
802       break;
803     }
804 
805     if(ret == HAL_OK)
806     {
807       /* Set the source of USART1/6 clock */
808       __HAL_RCC_USART16_CONFIG(PeriphClkInit->Usart16ClockSelection);
809     }
810     else
811     {
812       /* set overall return value */
813       status = ret;
814     }
815   }
816 
817   /*-------------------------- USART2/3/4/5/7/8 Configuration --------------------------*/
818   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART234578) == RCC_PERIPHCLK_USART234578)
819   {
820     switch(PeriphClkInit->Usart234578ClockSelection)
821     {
822     case RCC_USART234578CLKSOURCE_D2PCLK1: /* D2PCLK1 as clock source for USART2/3/4/5/7/8 */
823       /* USART2/3/4/5/7/8 clock source configuration done later after clock selection check */
824       break;
825 
826     case RCC_USART234578CLKSOURCE_PLL2: /* PLL2 is used as clock source for USART2/3/4/5/7/8 */
827       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
828       /* USART2/3/4/5/7/8 clock source configuration done later after clock selection check */
829       break;
830 
831     case RCC_USART234578CLKSOURCE_PLL3: /* PLL3 is used as clock source for USART2/3/4/5/7/8 */
832       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_Q_UPDATE);
833       /* USART2/3/4/5/7/8 clock source configuration done later after clock selection check */
834       break;
835 
836     case RCC_USART234578CLKSOURCE_HSI:
837       /* HSI oscillator clock is used as source of USART2/3/4/5/7/8 clock */
838       /* USART2/3/4/5/7/8 clock source configuration done later after clock selection check */
839       break;
840 
841     case RCC_USART234578CLKSOURCE_CSI:
842       /* CSI oscillator clock is used as source of USART2/3/4/5/7/8 clock */
843       /* USART2/3/4/5/7/8 clock source configuration done later after clock selection check */
844       break;
845 
846     case RCC_USART234578CLKSOURCE_LSE:
847       /* LSE,  oscillator is used as source of USART2/3/4/5/7/8 clock */
848       /* USART2/3/4/5/7/8 clock source configuration done later after clock selection check */
849       break;
850 
851     default:
852       ret = HAL_ERROR;
853       break;
854     }
855 
856     if(ret == HAL_OK)
857     {
858       /* Set the source of USART2/3/4/5/7/8 clock */
859       __HAL_RCC_USART234578_CONFIG(PeriphClkInit->Usart234578ClockSelection);
860     }
861     else
862     {
863       /* set overall return value */
864       status = ret;
865     }
866   }
867 
868   /*-------------------------- LPUART1 Configuration -------------------------*/
869   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
870   {
871     switch(PeriphClkInit->Lpuart1ClockSelection)
872     {
873     case RCC_LPUART1CLKSOURCE_D3PCLK1: /* D3PCLK1 as clock source for LPUART1 */
874       /* LPUART1 clock source configuration done later after clock selection check */
875       break;
876 
877     case RCC_LPUART1CLKSOURCE_PLL2: /* PLL2 is used as clock source for LPUART1 */
878       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_Q_UPDATE);
879       /* LPUART1 clock source configuration done later after clock selection check */
880       break;
881 
882     case RCC_LPUART1CLKSOURCE_PLL3: /* PLL3 is used as clock source for LPUART1 */
883       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_Q_UPDATE);
884       /* LPUART1 clock source configuration done later after clock selection check */
885       break;
886 
887     case RCC_LPUART1CLKSOURCE_HSI:
888       /* HSI oscillator clock is used as source of LPUART1 clock */
889       /* LPUART1 clock source configuration done later after clock selection check */
890       break;
891 
892     case RCC_LPUART1CLKSOURCE_CSI:
893       /* CSI oscillator clock is used as source of LPUART1 clock */
894       /* LPUART1 clock source configuration done later after clock selection check */
895       break;
896 
897     case RCC_LPUART1CLKSOURCE_LSE:
898       /* LSE,  oscillator is used as source of LPUART1 clock */
899       /* LPUART1 clock source configuration done later after clock selection check */
900       break;
901 
902     default:
903       ret = HAL_ERROR;
904       break;
905     }
906 
907     if(ret == HAL_OK)
908     {
909       /* Set the source of LPUART1 clock */
910       __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
911     }
912     else
913     {
914       /* set overall return value */
915       status = ret;
916     }
917   }
918 
919   /*---------------------------- LPTIM1 configuration -------------------------------*/
920   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
921   {
922     switch(PeriphClkInit->Lptim1ClockSelection)
923     {
924     case RCC_LPTIM1CLKSOURCE_D2PCLK1:      /* D2PCLK1 as clock source for LPTIM1*/
925       /* LPTIM1 clock source configuration done later after clock selection check */
926       break;
927 
928     case RCC_LPTIM1CLKSOURCE_PLL2: /* PLL2 is used as clock source for LPTIM1*/
929 
930       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
931 
932       /* LPTIM1 clock source configuration done later after clock selection check */
933       break;
934 
935     case RCC_LPTIM1CLKSOURCE_PLL3:  /* PLL3 is used as clock source for LPTIM1*/
936       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE);
937 
938       /* LPTIM1 clock source configuration done later after clock selection check */
939       break;
940 
941     case RCC_LPTIM1CLKSOURCE_LSE:
942       /* External low speed OSC clock is used as source of LPTIM1 clock*/
943       /* LPTIM1 clock source configuration done later after clock selection check */
944       break;
945 
946     case RCC_LPTIM1CLKSOURCE_LSI:
947       /* Internal  low speed OSC clock is used  as source of LPTIM1 clock*/
948       /* LPTIM1 clock source configuration done later after clock selection check */
949       break;
950     case RCC_LPTIM1CLKSOURCE_CLKP:
951       /* HSI, HSE, or CSI oscillator is used as source of LPTIM1 clock */
952       /* LPTIM1 clock source configuration done later after clock selection check */
953       break;
954 
955     default:
956       ret = HAL_ERROR;
957       break;
958     }
959 
960     if(ret == HAL_OK)
961     {
962       /* Set the source of LPTIM1 clock*/
963       __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
964     }
965     else
966     {
967       /* set overall return value */
968       status = ret;
969     }
970   }
971 
972   /*---------------------------- LPTIM2 configuration -------------------------------*/
973   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == RCC_PERIPHCLK_LPTIM2)
974   {
975     switch(PeriphClkInit->Lptim2ClockSelection)
976     {
977     case RCC_LPTIM2CLKSOURCE_D3PCLK1:      /* D3PCLK1 as clock source for LPTIM2*/
978       /* LPTIM2 clock source configuration done later after clock selection check */
979       break;
980 
981     case RCC_LPTIM2CLKSOURCE_PLL2: /* PLL2 is used as clock source for LPTIM2*/
982 
983       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
984 
985       /* LPTIM2 clock source configuration done later after clock selection check */
986       break;
987 
988     case RCC_LPTIM2CLKSOURCE_PLL3:  /* PLL3 is used as clock source for LPTIM2*/
989       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE);
990 
991       /* LPTIM2 clock source configuration done later after clock selection check */
992       break;
993 
994     case RCC_LPTIM2CLKSOURCE_LSE:
995       /* External low speed OSC clock is used as source of LPTIM2 clock*/
996       /* LPTIM2 clock source configuration done later after clock selection check */
997       break;
998 
999     case RCC_LPTIM2CLKSOURCE_LSI:
1000       /* Internal  low speed OSC clock is used  as source of LPTIM2 clock*/
1001       /* LPTIM2 clock source configuration done later after clock selection check */
1002       break;
1003     case RCC_LPTIM2CLKSOURCE_CLKP:
1004       /* HSI, HSE, or CSI oscillator is used as source of LPTIM2 clock */
1005       /* LPTIM2 clock source configuration done later after clock selection check */
1006       break;
1007 
1008     default:
1009       ret = HAL_ERROR;
1010       break;
1011     }
1012 
1013     if(ret == HAL_OK)
1014     {
1015       /* Set the source of LPTIM2 clock*/
1016       __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
1017     }
1018     else
1019     {
1020       /* set overall return value */
1021       status = ret;
1022     }
1023   }
1024 
1025   /*---------------------------- LPTIM345 configuration -------------------------------*/
1026   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM345) == RCC_PERIPHCLK_LPTIM345)
1027   {
1028     switch(PeriphClkInit->Lptim345ClockSelection)
1029     {
1030 
1031     case RCC_LPTIM345CLKSOURCE_D3PCLK1:      /* D3PCLK1 as clock source for LPTIM3/4/5 */
1032       /* LPTIM3/4/5 clock source configuration done later after clock selection check */
1033       break;
1034 
1035     case RCC_LPTIM345CLKSOURCE_PLL2: /* PLL2 is used as clock source for LPTIM3/4/5 */
1036       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
1037 
1038       /* LPTIM3/4/5 clock source configuration done later after clock selection check */
1039       break;
1040 
1041     case RCC_LPTIM345CLKSOURCE_PLL3:  /* PLL3 is used as clock source for LPTIM3/4/5 */
1042       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE);
1043 
1044       /* LPTIM3/4/5 clock source configuration done later after clock selection check */
1045       break;
1046 
1047     case RCC_LPTIM345CLKSOURCE_LSE:
1048       /* External low speed OSC clock is used as source of LPTIM3/4/5 clock */
1049       /* LPTIM3/4/5 clock source configuration done later after clock selection check */
1050       break;
1051 
1052     case RCC_LPTIM345CLKSOURCE_LSI:
1053       /* Internal  low speed OSC clock is used  as source of LPTIM3/4/5 clock */
1054       /* LPTIM3/4/5 clock source configuration done later after clock selection check */
1055       break;
1056     case RCC_LPTIM345CLKSOURCE_CLKP:
1057       /* HSI, HSE, or CSI oscillator is used as source of LPTIM3/4/5 clock */
1058       /* LPTIM3/4/5 clock source configuration done later after clock selection check */
1059       break;
1060 
1061     default:
1062       ret = HAL_ERROR;
1063       break;
1064     }
1065 
1066     if(ret == HAL_OK)
1067     {
1068       /* Set the source of LPTIM3/4/5 clock */
1069       __HAL_RCC_LPTIM345_CONFIG(PeriphClkInit->Lptim345ClockSelection);
1070     }
1071     else
1072     {
1073       /* set overall return value */
1074       status = ret;
1075     }
1076   }
1077 
1078   /*------------------------------ I2C1/2/3 Configuration ------------------------*/
1079   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C123) == RCC_PERIPHCLK_I2C123)
1080   {
1081     /* Check the parameters */
1082     assert_param(IS_RCC_I2C123CLKSOURCE(PeriphClkInit->I2c123ClockSelection));
1083 
1084     if ((PeriphClkInit->I2c123ClockSelection )== RCC_I2C123CLKSOURCE_PLL3 )
1085     {
1086         if(RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE)!= HAL_OK)
1087         {
1088           status = HAL_ERROR;
1089         }
1090     }
1091 
1092     else
1093     {
1094       __HAL_RCC_I2C123_CONFIG(PeriphClkInit->I2c123ClockSelection);
1095     }
1096 
1097   }
1098 
1099   /*------------------------------ I2C4 Configuration ------------------------*/
1100   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
1101   {
1102     /* Check the parameters */
1103     assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
1104 
1105     if ((PeriphClkInit->I2c4ClockSelection) == RCC_I2C4CLKSOURCE_PLL3 )
1106     {
1107       if(RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE)!= HAL_OK)
1108       {
1109         status = HAL_ERROR;
1110       }
1111     }
1112 
1113     else
1114     {
1115       __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
1116     }
1117   }
1118 
1119   /*---------------------------- ADC configuration -------------------------------*/
1120   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
1121   {
1122     switch(PeriphClkInit->AdcClockSelection)
1123     {
1124 
1125     case RCC_ADCCLKSOURCE_PLL2: /* PLL2 is used as clock source for ADC*/
1126 
1127       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);
1128 
1129       /* ADC clock source configuration done later after clock selection check */
1130       break;
1131 
1132     case RCC_ADCCLKSOURCE_PLL3:  /* PLL3 is used as clock source for ADC*/
1133       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE);
1134 
1135       /* ADC clock source configuration done later after clock selection check */
1136       break;
1137 
1138     case RCC_ADCCLKSOURCE_CLKP:
1139       /* HSI, HSE, or CSI oscillator is used as source of ADC clock */
1140       /* ADC clock source configuration done later after clock selection check */
1141       break;
1142 
1143     default:
1144       ret = HAL_ERROR;
1145       break;
1146     }
1147 
1148     if(ret == HAL_OK)
1149     {
1150       /* Set the source of ADC clock*/
1151       __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
1152     }
1153     else
1154     {
1155       /* set overall return value */
1156       status = ret;
1157     }
1158   }
1159 
1160   /*------------------------------ USB Configuration -------------------------*/
1161   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
1162   {
1163 
1164     switch(PeriphClkInit->UsbClockSelection)
1165     {
1166     case RCC_USBCLKSOURCE_PLL:      /* PLL is used as clock source for USB*/
1167       /* Enable USB Clock output generated form System USB . */
1168       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
1169 
1170       /* USB clock source configuration done later after clock selection check */
1171       break;
1172 
1173     case RCC_USBCLKSOURCE_PLL3: /* PLL3 is used as clock source for USB*/
1174 
1175       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_Q_UPDATE);
1176 
1177       /* USB clock source configuration done later after clock selection check */
1178       break;
1179 
1180     case RCC_USBCLKSOURCE_HSI48:
1181       /* HSI48 oscillator is used as source of USB clock */
1182       /* USB clock source configuration done later after clock selection check */
1183       break;
1184 
1185     default:
1186       ret = HAL_ERROR;
1187       break;
1188     }
1189 
1190     if(ret == HAL_OK)
1191     {
1192       /* Set the source of USB clock*/
1193       __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
1194     }
1195     else
1196     {
1197       /* set overall return value */
1198       status = ret;
1199     }
1200 
1201   }
1202 
1203   /*------------------------------------- SDMMC Configuration ------------------------------------*/
1204   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC) == RCC_PERIPHCLK_SDMMC)
1205   {
1206     /* Check the parameters */
1207     assert_param(IS_RCC_SDMMC(PeriphClkInit->SdmmcClockSelection));
1208 
1209     switch(PeriphClkInit->SdmmcClockSelection)
1210     {
1211     case RCC_SDMMCCLKSOURCE_PLL:      /* PLL is used as clock source for SDMMC*/
1212       /* Enable SDMMC Clock output generated form System PLL . */
1213       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
1214 
1215       /* SDMMC clock source configuration done later after clock selection check */
1216       break;
1217 
1218     case RCC_SDMMCCLKSOURCE_PLL2: /* PLL2 is used as clock source for SDMMC*/
1219 
1220       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_R_UPDATE);
1221 
1222       /* SDMMC clock source configuration done later after clock selection check */
1223       break;
1224 
1225     default:
1226       ret = HAL_ERROR;
1227       break;
1228     }
1229 
1230     if(ret == HAL_OK)
1231     {
1232       /* Set the source of SDMMC clock*/
1233       __HAL_RCC_SDMMC_CONFIG(PeriphClkInit->SdmmcClockSelection);
1234     }
1235     else
1236     {
1237       /* set overall return value */
1238       status = ret;
1239     }
1240   }
1241 
1242 #if defined(LTDC)
1243   /*-------------------------------------- LTDC Configuration -----------------------------------*/
1244   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)
1245   {
1246     if(RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE)!=HAL_OK)
1247     {
1248       status=HAL_ERROR;
1249     }
1250   }
1251 #endif /* LTDC */
1252 
1253   /*------------------------------ RNG Configuration -------------------------*/
1254   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == RCC_PERIPHCLK_RNG)
1255   {
1256 
1257     switch(PeriphClkInit->RngClockSelection)
1258     {
1259     case RCC_RNGCLKSOURCE_PLL:     /* PLL is used as clock source for RNG*/
1260       /* Enable RNG Clock output generated form System RNG . */
1261       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ);
1262 
1263       /* RNG clock source configuration done later after clock selection check */
1264       break;
1265 
1266     case RCC_RNGCLKSOURCE_LSE: /* LSE is used as clock source for RNG*/
1267 
1268       /* RNG clock source configuration done later after clock selection check */
1269       break;
1270 
1271     case RCC_RNGCLKSOURCE_LSI: /* LSI is used as clock source for RNG*/
1272 
1273       /* RNG clock source configuration done later after clock selection check */
1274       break;
1275     case RCC_RNGCLKSOURCE_HSI48:
1276       /* HSI48 oscillator is used as source of RNG clock */
1277       /* RNG clock source configuration done later after clock selection check */
1278       break;
1279 
1280     default:
1281       ret = HAL_ERROR;
1282       break;
1283     }
1284 
1285     if(ret == HAL_OK)
1286     {
1287       /* Set the source of RNG clock*/
1288       __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
1289     }
1290     else
1291     {
1292       /* set overall return value */
1293       status = ret;
1294     }
1295 
1296   }
1297 
1298   /*------------------------------ SWPMI1 Configuration ------------------------*/
1299   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SWPMI1) == RCC_PERIPHCLK_SWPMI1)
1300   {
1301     /* Check the parameters */
1302     assert_param(IS_RCC_SWPMI1CLKSOURCE(PeriphClkInit->Swpmi1ClockSelection));
1303 
1304     /* Configure the SWPMI1 interface clock source */
1305     __HAL_RCC_SWPMI1_CONFIG(PeriphClkInit->Swpmi1ClockSelection);
1306   }
1307 
1308   /*------------------------------ HRTIM1 clock Configuration ----------------*/
1309   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_HRTIM1) == RCC_PERIPHCLK_HRTIM1)
1310   {
1311     /* Check the parameters */
1312     assert_param(IS_RCC_HRTIM1CLKSOURCE(PeriphClkInit->Hrtim1ClockSelection));
1313 
1314     /* Configure the HRTIM1 clock source */
1315     __HAL_RCC_HRTIM1_CONFIG(PeriphClkInit->Hrtim1ClockSelection);
1316   }
1317 
1318   /*------------------------------ DFSDM1 Configuration ------------------------*/
1319   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
1320   {
1321     /* Check the parameters */
1322     assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
1323 
1324     /* Configure the DFSDM1 interface clock source */
1325     __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
1326   }
1327 
1328   /*------------------------------------ TIM configuration --------------------------------------*/
1329   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == RCC_PERIPHCLK_TIM)
1330   {
1331     /* Check the parameters */
1332     assert_param(IS_RCC_TIMPRES(PeriphClkInit->TIMPresSelection));
1333 
1334     /* Configure Timer Prescaler */
1335     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
1336   }
1337 
1338   /*------------------------------------ CKPER configuration --------------------------------------*/
1339   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CKPER) == RCC_PERIPHCLK_CKPER)
1340   {
1341     /* Check the parameters */
1342     assert_param(IS_RCC_CLKPSOURCE(PeriphClkInit->CkperClockSelection));
1343 
1344     /* Configure the CKPER clock source */
1345     __HAL_RCC_CLKP_CONFIG(PeriphClkInit->CkperClockSelection);
1346   }
1347 
1348   if (status == HAL_OK)
1349   {
1350     return HAL_OK;
1351   }
1352   return HAL_ERROR;
1353 }
1354 
1355 /**
1356   * @brief  Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
1357   * @param  PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
1358 *         returns the configuration information for the Extended Peripherals clocks :
1359   *         (SDMMC, CKPER, FMC, QSPI, DSI, SPI45, SPDIF, DFSDM1, FDCAN, SWPMI,SAI23, SAI1, SPI123,
1360   *         USART234578, USART16, RNG,HRTIM1, I2C123, USB,CEC, LPTIM1, LPUART1, I2C4, LPTIM2, LPTIM345, ADC,
1361 *         SAI4A,SAI4B,SPI6,RTC,TIM).
1362   * @retval None
1363   */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)1364 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
1365 {
1366   /* Set all possible values for the extended clock type parameter------------*/
1367   PeriphClkInit->PeriphClockSelection =
1368                  RCC_PERIPHCLK_USART16 | RCC_PERIPHCLK_USART234578 | RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C123   |
1369                  RCC_PERIPHCLK_I2C4    | RCC_PERIPHCLK_LPTIM1      | RCC_PERIPHCLK_LPTIM2  | RCC_PERIPHCLK_LPTIM345 |
1370                  RCC_PERIPHCLK_SAI1    | RCC_PERIPHCLK_SAI23       | RCC_PERIPHCLK_SAI4A   | RCC_PERIPHCLK_SAI4B    |
1371                  RCC_PERIPHCLK_SPI123  | RCC_PERIPHCLK_SPI45       | RCC_PERIPHCLK_SPI6    | RCC_PERIPHCLK_FDCAN    |
1372                  RCC_PERIPHCLK_SDMMC   | RCC_PERIPHCLK_RNG         | RCC_PERIPHCLK_USB     | RCC_PERIPHCLK_ADC      |
1373                  RCC_PERIPHCLK_SWPMI1  | RCC_PERIPHCLK_DFSDM1      | RCC_PERIPHCLK_RTC     | RCC_PERIPHCLK_CEC      |
1374                  RCC_PERIPHCLK_FMC     | RCC_PERIPHCLK_QSPI        | RCC_PERIPHCLK_DSI     | RCC_PERIPHCLK_SPDIFRX  |
1375                  RCC_PERIPHCLK_HRTIM1  | RCC_PERIPHCLK_TIM         | RCC_PERIPHCLK_CKPER;
1376 
1377 #if defined(LTDC)
1378   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LTDC;
1379 #endif /* LTDC */
1380 
1381   /* Get the PLL3 Clock configuration -----------------------------------------------*/
1382   PeriphClkInit->PLL3.PLL3M = (uint32_t)((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM3)>> RCC_PLLCKSELR_DIVM3_Pos);
1383   PeriphClkInit->PLL3.PLL3N = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_N3) >> RCC_PLL3DIVR_N3_Pos)+ 1U;
1384   PeriphClkInit->PLL3.PLL3R = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_R3) >> RCC_PLL3DIVR_R3_Pos)+ 1U;
1385   PeriphClkInit->PLL3.PLL3P = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_P3) >> RCC_PLL3DIVR_P3_Pos)+ 1U;
1386   PeriphClkInit->PLL3.PLL3Q = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_Q3) >> RCC_PLL3DIVR_Q3_Pos)+ 1U;
1387   PeriphClkInit->PLL3.PLL3RGE = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLL3RGE) >> RCC_PLLCFGR_PLL3RGE_Pos);
1388   PeriphClkInit->PLL3.PLL3VCOSEL = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLL3VCOSEL) >> RCC_PLLCFGR_PLL3VCOSEL_Pos);
1389 
1390   /* Get the PLL2 Clock configuration -----------------------------------------------*/
1391   PeriphClkInit->PLL2.PLL2M = (uint32_t)((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM2)>> RCC_PLLCKSELR_DIVM2_Pos);
1392   PeriphClkInit->PLL2.PLL2N = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_N2) >> RCC_PLL2DIVR_N2_Pos)+ 1U;
1393   PeriphClkInit->PLL2.PLL2R = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_R2) >> RCC_PLL2DIVR_R2_Pos)+ 1U;
1394   PeriphClkInit->PLL2.PLL2P = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_P2) >> RCC_PLL2DIVR_P2_Pos)+ 1U;
1395   PeriphClkInit->PLL2.PLL2Q = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_Q2) >> RCC_PLL2DIVR_Q2_Pos)+ 1U;
1396   PeriphClkInit->PLL2.PLL2RGE = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLL2RGE) >> RCC_PLLCFGR_PLL2RGE_Pos);
1397   PeriphClkInit->PLL2.PLL2VCOSEL = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLL2VCOSEL) >> RCC_PLLCFGR_PLL2VCOSEL_Pos);
1398 
1399   /* Get the USART1 configuration --------------------------------------------*/
1400   PeriphClkInit->Usart16ClockSelection      = __HAL_RCC_GET_USART16_SOURCE();
1401   /* Get the USART2/3/4/5/7/8 clock source -----------------------------------*/
1402   PeriphClkInit->Usart234578ClockSelection  = __HAL_RCC_GET_USART234578_SOURCE();
1403   /* Get the LPUART1 clock source --------------------------------------------*/
1404   PeriphClkInit->Lpuart1ClockSelection      = __HAL_RCC_GET_LPUART1_SOURCE();
1405   /* Get the I2C1/2/3 clock source -------------------------------------------*/
1406   PeriphClkInit->I2c123ClockSelection       = __HAL_RCC_GET_I2C1_SOURCE();
1407   /* Get the LPTIM1 clock source ---------------------------------------------*/
1408   PeriphClkInit->Lptim1ClockSelection       = __HAL_RCC_GET_LPTIM1_SOURCE();
1409   /* Get the LPTIM2 clock source ---------------------------------------------*/
1410   PeriphClkInit->Lptim2ClockSelection       = __HAL_RCC_GET_LPTIM2_SOURCE();
1411   /* Get the LPTIM3/4/5 clock source -----------------------------------------*/
1412   PeriphClkInit->Lptim345ClockSelection     = __HAL_RCC_GET_LPTIM345_SOURCE();
1413   /* Get the SAI1 clock source -----------------------------------------------*/
1414   PeriphClkInit->Sai1ClockSelection         = __HAL_RCC_GET_SAI1_SOURCE();
1415   /* Get the SAI2/3 clock source ---------------------------------------------*/
1416   PeriphClkInit->Sai23ClockSelection        = __HAL_RCC_GET_SAI23_SOURCE();
1417   /* Get the SAI4A clock source ----------------------------------------------*/
1418   PeriphClkInit->Sai4AClockSelection        = __HAL_RCC_GET_SAI4A_SOURCE();
1419   /* Get the SAI4B clock source ----------------------------------------------*/
1420   PeriphClkInit->Sai4BClockSelection        = __HAL_RCC_GET_SAI4B_SOURCE();
1421   /* Get the RTC clock source ------------------------------------------------*/
1422   PeriphClkInit->RTCClockSelection          = __HAL_RCC_GET_RTC_SOURCE();
1423   /* Get the USB clock source ------------------------------------------------*/
1424   PeriphClkInit->UsbClockSelection          = __HAL_RCC_GET_USB_SOURCE();
1425   /* Get the SDMMC clock source ----------------------------------------------*/
1426   PeriphClkInit->SdmmcClockSelection        = __HAL_RCC_GET_SDMMC_SOURCE();
1427   /* Get the RNG clock source ------------------------------------------------*/
1428   PeriphClkInit->RngClockSelection          = __HAL_RCC_GET_RNG_SOURCE();
1429   /* Get the HRTIM1 clock source ---------------------------------------------*/
1430   PeriphClkInit->Hrtim1ClockSelection       = __HAL_RCC_GET_HRTIM1_SOURCE();
1431   /* Get the ADC clock source ------------------------------------------------*/
1432   PeriphClkInit->AdcClockSelection          = __HAL_RCC_GET_ADC_SOURCE();
1433   /* Get the SWPMI1 clock source ---------------------------------------------*/
1434   PeriphClkInit->Swpmi1ClockSelection       = __HAL_RCC_GET_SWPMI1_SOURCE();
1435   /* Get the DFSDM1 clock source ---------------------------------------------*/
1436   PeriphClkInit->Dfsdm1ClockSelection       = __HAL_RCC_GET_DFSDM1_SOURCE();
1437   /* Get the SPDIFRX clock source --------------------------------------------*/
1438   PeriphClkInit->SpdifrxClockSelection      = __HAL_RCC_GET_SPDIFRX_SOURCE();
1439   /* Get the SPI1/2/3 clock source -------------------------------------------*/
1440   PeriphClkInit->Spi123ClockSelection       = __HAL_RCC_GET_SPI123_SOURCE();
1441   /* Get the SPI4/5 clock source ---------------------------------------------*/
1442   PeriphClkInit->Spi45ClockSelection        = __HAL_RCC_GET_SPI45_SOURCE();
1443   /* Get the SPI6 clock source -----------------------------------------------*/
1444   PeriphClkInit->Spi6ClockSelection         = __HAL_RCC_GET_SPI6_SOURCE();
1445   /* Get the FDCAN clock source ----------------------------------------------*/
1446   PeriphClkInit->FdcanClockSelection        = __HAL_RCC_GET_FDCAN_SOURCE();
1447   /* Get the CEC clock source ------------------------------------------------*/
1448   PeriphClkInit->CecClockSelection          = __HAL_RCC_GET_CEC_SOURCE();
1449   /* Get the FMC clock source ------------------------------------------------*/
1450   PeriphClkInit->FmcClockSelection          = __HAL_RCC_GET_FMC_SOURCE();
1451   /* Get the QSPI clock source -----------------------------------------------*/
1452   PeriphClkInit->QspiClockSelection         = __HAL_RCC_GET_QSPI_SOURCE();
1453 
1454 #if defined(DSI)
1455   /* Get the DSI clock source ------------------------------------------------*/
1456   PeriphClkInit->DsiClockSelection          = __HAL_RCC_GET_DSI_SOURCE();
1457 #endif /*DSI*/
1458 
1459   /* Get the CKPER clock source ----------------------------------------------*/
1460   PeriphClkInit->CkperClockSelection        = __HAL_RCC_GET_CLKP_SOURCE();
1461 
1462   /* Get the TIM Prescaler configuration -------------------------------------*/
1463   if ((RCC->CFGR & RCC_CFGR_TIMPRE) == 0U)
1464   {
1465     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
1466   }
1467   else
1468   {
1469     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
1470   }
1471 }
1472 
1473 /**
1474   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..)
1475   * @note   Return 0 if peripheral clock identifier not managed by this API
1476   * @param  PeriphClk: Peripheral clock identifier
1477   *         This parameter can be one of the following values:
1478   *            @arg RCC_PERIPHCLK_SAI1  : SAI1 peripheral clock
1479   *            @arg RCC_PERIPHCLK_SAI23 : SAI2/3 peripheral clock
1480   *            @arg RCC_PERIPHCLK_SAI4A : SAI4A peripheral clock
1481   *            @arg RCC_PERIPHCLK_SAI4B : SAI4B peripheral clock
1482   *            @arg RCC_PERIPHCLK_SPI123: SPI1/2/3 peripheral clock
1483   * @retval Frequency in KHz
1484   */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)1485 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
1486 {
1487   PLL1_ClocksTypeDef pll1_clocks;
1488   PLL2_ClocksTypeDef pll2_clocks;
1489   PLL3_ClocksTypeDef pll3_clocks;
1490 
1491   /* This variable is used to store the SAI clock frequency (value in Hz) */
1492   uint32_t frequency;
1493   /* This variable is used to store the SAI and CKP clock source */
1494   uint32_t saiclocksource;
1495   uint32_t ckpclocksource;
1496   uint32_t srcclk;
1497 
1498   if (PeriphClk == RCC_PERIPHCLK_SAI1)
1499     {
1500 
1501       saiclocksource= __HAL_RCC_GET_SAI1_SOURCE();
1502 
1503       switch (saiclocksource)
1504       {
1505       case 0: /* PLL1 is the clock source for SAI1 */
1506         {
1507           HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
1508           frequency = pll1_clocks.PLL1_Q_Frequency;
1509           break;
1510         }
1511       case RCC_D2CCIP1R_SAI1SEL_0: /* PLLI2 is the clock source for SAI1 */
1512         {
1513           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1514           frequency = pll2_clocks.PLL2_P_Frequency;
1515           break;
1516         }
1517 
1518       case RCC_D2CCIP1R_SAI1SEL_1: /* PLLI3 is the clock source for SAI1 */
1519         {
1520           HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1521           frequency = pll3_clocks.PLL3_P_Frequency;
1522           break;
1523         }
1524 
1525       case RCC_D2CCIP1R_SAI1SEL_2: /* CKPER is the clock source for SAI1*/
1526         {
1527 
1528           ckpclocksource= __HAL_RCC_GET_CLKP_SOURCE();
1529 
1530           if(ckpclocksource== 0U)
1531           {
1532             /* In Case the CKPER Source is HSI */
1533             frequency = HSI_VALUE;
1534           }
1535 
1536           else if(ckpclocksource== RCC_D1CCIPR_CKPERSEL_0)
1537           {
1538             /* In Case the CKPER Source is CSI */
1539             frequency = CSI_VALUE;
1540           }
1541 
1542           else if (ckpclocksource== RCC_D1CCIPR_CKPERSEL_1)
1543           {
1544             /* In Case the CKPER Source is HSE */
1545             frequency = HSE_VALUE;
1546           }
1547 
1548           else
1549           {
1550             /* In Case the CKPER is disabled*/
1551             frequency = 0;
1552           }
1553 
1554           break;
1555         }
1556 
1557       case (RCC_D2CCIP1R_SAI1SEL_0 | RCC_D2CCIP1R_SAI1SEL_1 ): /* External clock is the clock source for SAI1 */
1558         {
1559           frequency = EXTERNAL_CLOCK_VALUE;
1560           break;
1561         }
1562       default :
1563         {
1564           frequency = 0;
1565           break;
1566         }
1567       }
1568     }
1569 
1570   else if (PeriphClk == RCC_PERIPHCLK_SAI23)
1571     {
1572 
1573       saiclocksource= __HAL_RCC_GET_SAI23_SOURCE();
1574 
1575       switch (saiclocksource)
1576       {
1577       case 0: /* PLL1 is the clock source for SAI2/3 */
1578         {
1579           HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
1580           frequency = pll1_clocks.PLL1_Q_Frequency;
1581           break;
1582         }
1583       case RCC_D2CCIP1R_SAI23SEL_0: /* PLLI2 is the clock source for SAI2/3 */
1584         {
1585           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1586           frequency = pll2_clocks.PLL2_P_Frequency;
1587           break;
1588         }
1589 
1590       case RCC_D2CCIP1R_SAI23SEL_1: /* PLLI3 is the clock source for SAI2/3 */
1591         {
1592           HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1593           frequency = pll3_clocks.PLL3_P_Frequency;
1594           break;
1595         }
1596 
1597       case RCC_D2CCIP1R_SAI23SEL_2: /* CKPER is the clock source for SAI2/3 */
1598         {
1599 
1600           ckpclocksource= __HAL_RCC_GET_CLKP_SOURCE();
1601 
1602           if(ckpclocksource== 0U)
1603           {
1604             /* In Case the CKPER Source is HSI */
1605             frequency = HSI_VALUE;
1606           }
1607 
1608           else if(ckpclocksource== RCC_D1CCIPR_CKPERSEL_0)
1609           {
1610             /* In Case the CKPER Source is CSI */
1611             frequency = CSI_VALUE;
1612           }
1613 
1614           else if (ckpclocksource== RCC_D1CCIPR_CKPERSEL_1)
1615           {
1616             /* In Case the CKPER Source is HSE */
1617             frequency = HSE_VALUE;
1618           }
1619 
1620           else
1621           {
1622             /* In Case the CKPER is disabled*/
1623             frequency = 0;
1624           }
1625 
1626           break;
1627         }
1628 
1629       case (RCC_D2CCIP1R_SAI23SEL_0 | RCC_D2CCIP1R_SAI23SEL_1 ): /* External clock is the clock source for SAI2/3 */
1630         {
1631           frequency = EXTERNAL_CLOCK_VALUE;
1632           break;
1633         }
1634       default :
1635         {
1636           frequency = 0;
1637           break;
1638         }
1639       }
1640     }
1641 
1642   else if (PeriphClk == RCC_PERIPHCLK_SAI4A)
1643     {
1644 
1645       saiclocksource= __HAL_RCC_GET_SAI4A_SOURCE();
1646 
1647       switch (saiclocksource)
1648       {
1649       case 0: /* PLL1 is the clock source for SAI4A */
1650         {
1651           HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
1652           frequency = pll1_clocks.PLL1_Q_Frequency;
1653           break;
1654         }
1655       case RCC_D3CCIPR_SAI4ASEL_0: /* PLLI2 is the clock source for SAI4A */
1656         {
1657           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1658           frequency = pll2_clocks.PLL2_P_Frequency;
1659           break;
1660         }
1661 
1662       case RCC_D3CCIPR_SAI4ASEL_1: /* PLLI3 is the clock source for SAI4A */
1663         {
1664           HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1665           frequency = pll3_clocks.PLL3_P_Frequency;
1666           break;
1667         }
1668 
1669       case RCC_D3CCIPR_SAI4ASEL_2: /* CKPER is the clock source for SAI4A*/
1670         {
1671 
1672           ckpclocksource= __HAL_RCC_GET_CLKP_SOURCE();
1673 
1674           if(ckpclocksource== 0U)
1675           {
1676             /* In Case the CKPER Source is HSI */
1677             frequency = HSI_VALUE;
1678           }
1679 
1680           else if(ckpclocksource== RCC_D1CCIPR_CKPERSEL_0)
1681           {
1682             /* In Case the CKPER Source is CSI */
1683             frequency = CSI_VALUE;
1684           }
1685 
1686           else if (ckpclocksource== RCC_D1CCIPR_CKPERSEL_1)
1687           {
1688             /* In Case the CKPER Source is HSE */
1689             frequency = HSE_VALUE;
1690           }
1691 
1692           else
1693           {
1694             /* In Case the CKPER is disabled*/
1695             frequency = 0;
1696           }
1697 
1698           break;
1699         }
1700 
1701       case (RCC_D3CCIPR_SAI4ASEL_0 | RCC_D3CCIPR_SAI4ASEL_1 ): /* External clock is the clock source for SAI4A */
1702         {
1703           frequency = EXTERNAL_CLOCK_VALUE;
1704           break;
1705         }
1706 
1707       default :
1708         {
1709           frequency = 0;
1710           break;
1711         }
1712       }
1713     }
1714 
1715   else if (PeriphClk == RCC_PERIPHCLK_SAI4B)
1716     {
1717 
1718       saiclocksource= __HAL_RCC_GET_SAI4B_SOURCE();
1719 
1720       switch (saiclocksource)
1721       {
1722       case 0: /* PLL1 is the clock source for SAI4B */
1723         {
1724           HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
1725           frequency = pll1_clocks.PLL1_Q_Frequency;
1726           break;
1727         }
1728       case RCC_D3CCIPR_SAI4BSEL_0: /* PLLI2 is the clock source for SAI4B */
1729         {
1730           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1731           frequency = pll2_clocks.PLL2_P_Frequency;
1732           break;
1733         }
1734 
1735       case RCC_D3CCIPR_SAI4BSEL_1: /* PLLI3 is the clock source for SAI4B */
1736         {
1737           HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1738           frequency = pll3_clocks.PLL3_P_Frequency;
1739           break;
1740         }
1741 
1742       case RCC_D3CCIPR_SAI4BSEL_2: /* CKPER is the clock source for SAI4B*/
1743         {
1744 
1745           ckpclocksource= __HAL_RCC_GET_CLKP_SOURCE();
1746 
1747           if(ckpclocksource== 0U)
1748           {
1749             /* In Case the CKPER Source is HSI */
1750             frequency = HSI_VALUE;
1751           }
1752 
1753           else if(ckpclocksource== RCC_D1CCIPR_CKPERSEL_0)
1754           {
1755             /* In Case the CKPER Source is CSI */
1756             frequency = CSI_VALUE;
1757           }
1758 
1759           else if (ckpclocksource== RCC_D1CCIPR_CKPERSEL_1)
1760           {
1761             /* In Case the CKPER Source is HSE */
1762             frequency = HSE_VALUE;
1763           }
1764 
1765           else
1766           {
1767             /* In Case the CKPER is disabled*/
1768             frequency = 0;
1769           }
1770 
1771           break;
1772         }
1773 
1774       case (RCC_D3CCIPR_SAI4BSEL_0 | RCC_D3CCIPR_SAI4BSEL_1 ): /* External clock is the clock source for SAI4B */
1775         {
1776           frequency = EXTERNAL_CLOCK_VALUE;
1777           break;
1778         }
1779 
1780       default :
1781         {
1782           frequency = 0;
1783           break;
1784         }
1785       }
1786     }
1787 
1788   else if (PeriphClk == RCC_PERIPHCLK_SPI123)
1789     {
1790       /* Get SPI1/2/3 clock source */
1791       srcclk= __HAL_RCC_GET_SPI123_SOURCE();
1792 
1793       switch (srcclk)
1794       {
1795       case 0: /* PLL1 is the clock source for I2S */
1796         {
1797           HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
1798           frequency = pll1_clocks.PLL1_Q_Frequency;
1799           break;
1800         }
1801       case RCC_D2CCIP1R_SPI123SEL_0: /* PLL2 is the clock source for I2S */
1802         {
1803           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1804           frequency = pll2_clocks.PLL2_P_Frequency;
1805           break;
1806         }
1807 
1808       case RCC_D2CCIP1R_SPI123SEL_1: /* PLL3 is the clock source for I2S */
1809         {
1810           HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1811           frequency = pll3_clocks.PLL3_P_Frequency;
1812           break;
1813         }
1814 
1815       case RCC_D2CCIP1R_SPI123SEL_2: /* CKPER is the clock source for I2S */
1816         {
1817 
1818           ckpclocksource= __HAL_RCC_GET_CLKP_SOURCE();
1819 
1820           if(ckpclocksource== RCC_CLKPSOURCE_HSI)
1821           {
1822             /* In Case the CKPER Source is HSI */
1823             frequency = HSI_VALUE;
1824           }
1825 
1826           else if(ckpclocksource== RCC_CLKPSOURCE_CSI)
1827           {
1828             /* In Case the CKPER Source is CSI */
1829             frequency = CSI_VALUE;
1830           }
1831 
1832           else if (ckpclocksource== RCC_CLKPSOURCE_HSE)
1833           {
1834             /* In Case the CKPER Source is HSE */
1835             frequency = HSE_VALUE;
1836           }
1837 
1838           else
1839           {
1840             /* In Case the CKPER is disabled*/
1841             frequency = 0;
1842           }
1843 
1844           break;
1845         }
1846 
1847       case (RCC_D2CCIP1R_SPI123SEL_0 | RCC_D2CCIP1R_SPI123SEL_1): /* External clock is the clock source for I2S */
1848         {
1849           frequency = EXTERNAL_CLOCK_VALUE;
1850           break;
1851         }
1852       default :
1853         {
1854           frequency = 0;
1855           break;
1856         }
1857       }
1858     }
1859   else if (PeriphClk == RCC_PERIPHCLK_ADC)
1860     {
1861       /* Get ADC clock source */
1862       srcclk= __HAL_RCC_GET_ADC_SOURCE();
1863 
1864       switch (srcclk)
1865       {
1866       case RCC_ADCCLKSOURCE_PLL2:
1867         {
1868           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1869           frequency = pll2_clocks.PLL2_P_Frequency;
1870           break;
1871         }
1872       case RCC_ADCCLKSOURCE_PLL3:
1873         {
1874           HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks);
1875           frequency = pll3_clocks.PLL3_R_Frequency;
1876           break;
1877         }
1878 
1879       case RCC_ADCCLKSOURCE_CLKP:
1880         {
1881 
1882           ckpclocksource= __HAL_RCC_GET_CLKP_SOURCE();
1883 
1884           if(ckpclocksource== RCC_CLKPSOURCE_HSI)
1885           {
1886             /* In Case the CKPER Source is HSI */
1887             frequency = HSI_VALUE;
1888           }
1889 
1890           else if(ckpclocksource== RCC_CLKPSOURCE_CSI)
1891           {
1892             /* In Case the CKPER Source is CSI */
1893             frequency = CSI_VALUE;
1894           }
1895 
1896           else if (ckpclocksource== RCC_CLKPSOURCE_HSE)
1897           {
1898             /* In Case the CKPER Source is HSE */
1899             frequency = HSE_VALUE;
1900           }
1901 
1902           else
1903           {
1904             /* In Case the CKPER is disabled*/
1905             frequency = 0;
1906           }
1907 
1908           break;
1909         }
1910 
1911       default :
1912         {
1913           frequency = 0;
1914           break;
1915         }
1916       }
1917     }
1918   else if (PeriphClk == RCC_PERIPHCLK_SDMMC)
1919     {
1920       /* Get SDMMC clock source */
1921       srcclk= __HAL_RCC_GET_SDMMC_SOURCE();
1922 
1923       switch (srcclk)
1924       {
1925       case RCC_SDMMCCLKSOURCE_PLL: /* PLL1 is the clock source for SDMMC */
1926         {
1927           HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
1928           frequency = pll1_clocks.PLL1_Q_Frequency;
1929           break;
1930         }
1931       case RCC_SDMMCCLKSOURCE_PLL2: /* PLL2 is the clock source for SDMMC */
1932         {
1933           HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks);
1934           frequency = pll2_clocks.PLL2_R_Frequency;
1935           break;
1936         }
1937 
1938       default :
1939         {
1940           frequency = 0;
1941           break;
1942         }
1943       }
1944     }
1945   else
1946     {
1947       frequency = 0;
1948     }
1949 
1950   return frequency;
1951 }
1952 
1953 
1954 /**
1955   * @brief  Returns the D1PCLK1 frequency
1956   * @note   Each time D1PCLK1 changes, this function must be called to update the
1957   *         right D1PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1958   * @retval D1PCLK1 frequency
1959   */
HAL_RCCEx_GetD1PCLK1Freq(void)1960 uint32_t HAL_RCCEx_GetD1PCLK1Freq(void)
1961 {
1962   /* Get HCLK source and Compute D1PCLK1 frequency ---------------------------*/
1963   return (HAL_RCC_GetHCLKFreq() >> (D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1PPRE)>> RCC_D1CFGR_D1PPRE_Pos] & 0x1FU));
1964 }
1965 
1966 /**
1967   * @brief  Returns the D3PCLK1 frequency
1968   * @note   Each time D3PCLK1 changes, this function must be called to update the
1969   *         right D3PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1970   * @retval D3PCLK1 frequency
1971   */
HAL_RCCEx_GetD3PCLK1Freq(void)1972 uint32_t HAL_RCCEx_GetD3PCLK1Freq(void)
1973 {
1974   /* Get HCLK source and Compute D3PCLK1 frequency ---------------------------*/
1975   return (HAL_RCC_GetHCLKFreq() >> (D1CorePrescTable[(RCC->D3CFGR & RCC_D3CFGR_D3PPRE)>> RCC_D3CFGR_D3PPRE_Pos] & 0x1FU));
1976 }
1977 /**
1978 * @brief  Returns the PLL2 clock frequencies :PLL2_P_Frequency,PLL2_R_Frequency and PLL2_Q_Frequency
1979   * @note   The PLL2 clock frequencies computed by this function is not the real
1980   *         frequency in the chip. It is calculated based on the predefined
1981   *         constant and the selected clock source:
1982   * @note     The function returns values based on HSE_VALUE, HSI_VALUE or CSI Value multiplied/divided by the PLL factors.
1983   * @note   This function can be used by the user application to compute the
1984   *         baud-rate for the communication peripherals or configure other parameters.
1985   *
1986   * @note   Each time PLL2CLK changes, this function must be called to update the
1987   *         right PLL2CLK value. Otherwise, any configuration based on this function will be incorrect.
1988   * @param  PLL2_Clocks structure.
1989   * @retval None
1990   */
HAL_RCCEx_GetPLL2ClockFreq(PLL2_ClocksTypeDef * PLL2_Clocks)1991 void HAL_RCCEx_GetPLL2ClockFreq(PLL2_ClocksTypeDef* PLL2_Clocks)
1992 {
1993   uint32_t  pllsource, pll2m,  pll2fracen, hsivalue;
1994   float_t fracn2, pll2vco;
1995 
1996   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLL2M) * PLL2N
1997      PLL2xCLK = PLL2_VCO / PLL2x
1998   */
1999   pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
2000   pll2m = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM2)>> 12)  ;
2001   pll2fracen = RCC->PLLCFGR & RCC_PLLCFGR_PLL2FRACEN;
2002   fracn2 =(float_t)(uint32_t)(pll2fracen* ((RCC->PLL2FRACR & RCC_PLL2FRACR_FRACN2)>> 3));
2003 
2004   if (pll2m != 0U)
2005   {
2006     switch (pllsource)
2007     {
2008 
2009     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
2010 
2011       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2012       {
2013         hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER()>> 3));
2014         pll2vco = ( (float_t)hsivalue / (float_t)pll2m) * ((float_t)(uint32_t)(RCC->PLL2DIVR & RCC_PLL2DIVR_N2) + (fracn2/(float_t)0x2000) +(float_t)1 );
2015       }
2016       else
2017       {
2018         pll2vco = ((float_t)HSI_VALUE / (float_t)pll2m) * ((float_t)(uint32_t)(RCC->PLL2DIVR & RCC_PLL2DIVR_N2) + (fracn2/(float_t)0x2000) +(float_t)1 );
2019       }
2020       break;
2021 
2022     case RCC_PLLSOURCE_CSI:  /* CSI used as PLL clock source */
2023       pll2vco = ((float_t)CSI_VALUE / (float_t)pll2m) * ((float_t)(uint32_t)(RCC->PLL2DIVR & RCC_PLL2DIVR_N2) + (fracn2/(float_t)0x2000) +(float_t)1 );
2024       break;
2025 
2026     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
2027       pll2vco = ((float_t)HSE_VALUE / (float_t)pll2m) * ((float_t)(uint32_t)(RCC->PLL2DIVR & RCC_PLL2DIVR_N2) + (fracn2/(float_t)0x2000) +(float_t)1 );
2028       break;
2029 
2030     default:
2031       pll2vco = ((float_t)CSI_VALUE / (float_t)pll2m) * ((float_t)(uint32_t)(RCC->PLL2DIVR & RCC_PLL2DIVR_N2) + (fracn2/(float_t)0x2000) +(float_t)1 );
2032       break;
2033     }
2034     PLL2_Clocks->PLL2_P_Frequency = (uint32_t)(float_t)(pll2vco/((float_t)(uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_P2) >>9)  + (float_t)1 )) ;
2035     PLL2_Clocks->PLL2_Q_Frequency = (uint32_t)(float_t)(pll2vco/((float_t)(uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_Q2) >>16) + (float_t)1 )) ;
2036     PLL2_Clocks->PLL2_R_Frequency = (uint32_t)(float_t)(pll2vco/((float_t)(uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_R2) >>24) + (float_t)1 )) ;
2037   }
2038   else
2039   {
2040     PLL2_Clocks->PLL2_P_Frequency = 0U;
2041     PLL2_Clocks->PLL2_Q_Frequency = 0U;
2042     PLL2_Clocks->PLL2_R_Frequency = 0U;
2043   }
2044 }
2045 
2046 /**
2047 * @brief  Returns the PLL3 clock frequencies :PLL3_P_Frequency,PLL3_R_Frequency and PLL3_Q_Frequency
2048   * @note   The PLL3 clock frequencies computed by this function is not the real
2049   *         frequency in the chip. It is calculated based on the predefined
2050   *         constant and the selected clock source:
2051   * @note     The function returns values based on HSE_VALUE, HSI_VALUE or CSI Value multiplied/divided by the PLL factors.
2052   * @note   This function can be used by the user application to compute the
2053   *         baud-rate for the communication peripherals or configure other parameters.
2054   *
2055   * @note   Each time PLL3CLK changes, this function must be called to update the
2056   *         right PLL3CLK value. Otherwise, any configuration based on this function will be incorrect.
2057   * @param  PLL3_Clocks structure.
2058   * @retval None
2059   */
HAL_RCCEx_GetPLL3ClockFreq(PLL3_ClocksTypeDef * PLL3_Clocks)2060 void HAL_RCCEx_GetPLL3ClockFreq(PLL3_ClocksTypeDef* PLL3_Clocks)
2061 {
2062   uint32_t pllsource, pll3m, pll3fracen, hsivalue;
2063   float_t fracn3, pll3vco;
2064 
2065   /* PLL3_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLL3M) * PLL3N
2066      PLL3xCLK = PLL3_VCO / PLLxR
2067   */
2068   pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
2069   pll3m = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM3)>> 20)  ;
2070   pll3fracen = RCC->PLLCFGR & RCC_PLLCFGR_PLL3FRACEN;
2071   fracn3 = (float_t)(uint32_t)(pll3fracen* ((RCC->PLL3FRACR & RCC_PLL3FRACR_FRACN3)>> 3));
2072 
2073   if (pll3m != 0U)
2074   {
2075     switch (pllsource)
2076     {
2077     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
2078 
2079       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2080       {
2081         hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER()>> 3));
2082         pll3vco = ((float_t)hsivalue / (float_t)pll3m) * ((float_t)(uint32_t)(RCC->PLL3DIVR & RCC_PLL3DIVR_N3) + (fracn3/(float_t)0x2000) +(float_t)1 );
2083       }
2084       else
2085       {
2086         pll3vco = ((float_t)HSI_VALUE / (float_t)pll3m) * ((float_t)(uint32_t)(RCC->PLL3DIVR & RCC_PLL3DIVR_N3) + (fracn3/(float_t)0x2000) +(float_t)1 );
2087       }
2088       break;
2089     case RCC_PLLSOURCE_CSI:  /* CSI used as PLL clock source */
2090       pll3vco = ((float_t)CSI_VALUE / (float_t)pll3m) * ((float_t)(uint32_t)(RCC->PLL3DIVR & RCC_PLL3DIVR_N3) + (fracn3/(float_t)0x2000) +(float_t)1 );
2091       break;
2092 
2093     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
2094       pll3vco = ((float_t)HSE_VALUE / (float_t)pll3m) * ((float_t)(uint32_t)(RCC->PLL3DIVR & RCC_PLL3DIVR_N3) + (fracn3/(float_t)0x2000) +(float_t)1 );
2095       break;
2096 
2097     default:
2098       pll3vco = ((float_t)CSI_VALUE / (float_t)pll3m) * ((float_t)(uint32_t)(RCC->PLL3DIVR & RCC_PLL3DIVR_N3) + (fracn3/(float_t)0x2000) +(float_t)1 );
2099       break;
2100     }
2101     PLL3_Clocks->PLL3_P_Frequency = (uint32_t)(float_t)(pll3vco/((float_t)(uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_P3) >>9)  + (float_t)1 )) ;
2102     PLL3_Clocks->PLL3_Q_Frequency = (uint32_t)(float_t)(pll3vco/((float_t)(uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_Q3) >>16) + (float_t)1 )) ;
2103     PLL3_Clocks->PLL3_R_Frequency = (uint32_t)(float_t)(pll3vco/((float_t)(uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_R3) >>24) + (float_t)1 )) ;
2104   }
2105   else
2106   {
2107     PLL3_Clocks->PLL3_P_Frequency = 0U;
2108     PLL3_Clocks->PLL3_Q_Frequency = 0U;
2109     PLL3_Clocks->PLL3_R_Frequency = 0U;
2110   }
2111 
2112 }
2113 
2114 /**
2115 * @brief  Returns the PLL1 clock frequencies :PLL1_P_Frequency,PLL1_R_Frequency and PLL1_Q_Frequency
2116   * @note   The PLL1 clock frequencies computed by this function is not the real
2117   *         frequency in the chip. It is calculated based on the predefined
2118   *         constant and the selected clock source:
2119   * @note     The function returns values based on HSE_VALUE, HSI_VALUE or CSI Value multiplied/divided by the PLL factors.
2120   * @note   This function can be used by the user application to compute the
2121   *         baud-rate for the communication peripherals or configure other parameters.
2122   *
2123   * @note   Each time PLL1CLK changes, this function must be called to update the
2124   *         right PLL1CLK value. Otherwise, any configuration based on this function will be incorrect.
2125   * @param  PLL1_Clocks structure.
2126   * @retval None
2127   */
HAL_RCCEx_GetPLL1ClockFreq(PLL1_ClocksTypeDef * PLL1_Clocks)2128 void HAL_RCCEx_GetPLL1ClockFreq(PLL1_ClocksTypeDef* PLL1_Clocks)
2129 {
2130   uint32_t pllsource, pll1m, pll1fracen, hsivalue;
2131   float_t fracn1, pll1vco;
2132 
2133   pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
2134   pll1m = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4);
2135   pll1fracen = RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN;
2136   fracn1 = (float_t)(uint32_t)(pll1fracen * ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3));
2137 
2138   if (pll1m != 0U)
2139   {
2140     switch (pllsource)
2141     {
2142 
2143     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
2144 
2145       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U)
2146       {
2147         hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER()>> 3));
2148         pll1vco = ((float_t)hsivalue / (float_t)pll1m) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
2149       }
2150       else
2151       {
2152         pll1vco = ((float_t)HSI_VALUE / (float_t)pll1m) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
2153       }
2154       break;
2155     case RCC_PLLSOURCE_CSI:  /* CSI used as PLL clock source */
2156       pll1vco = ((float_t)CSI_VALUE / (float_t)pll1m) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
2157       break;
2158 
2159     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
2160       pll1vco = ((float_t)HSE_VALUE / (float_t)pll1m) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
2161       break;
2162 
2163     default:
2164       pll1vco = ((float_t)CSI_VALUE / (float_t)pll1m) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 );
2165       break;
2166     }
2167 
2168     PLL1_Clocks->PLL1_P_Frequency = (uint32_t)(float_t)(pll1vco/((float_t)(uint32_t)((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9)  + (float_t)1 )) ;
2169     PLL1_Clocks->PLL1_Q_Frequency = (uint32_t)(float_t)(pll1vco/((float_t)(uint32_t)((RCC->PLL1DIVR & RCC_PLL1DIVR_Q1) >>16) + (float_t)1 )) ;
2170     PLL1_Clocks->PLL1_R_Frequency = (uint32_t)(float_t)(pll1vco/((float_t)(uint32_t)((RCC->PLL1DIVR & RCC_PLL1DIVR_R1) >>24) + (float_t)1 )) ;
2171   }
2172   else
2173   {
2174     PLL1_Clocks->PLL1_P_Frequency = 0U;
2175     PLL1_Clocks->PLL1_Q_Frequency = 0U;
2176     PLL1_Clocks->PLL1_R_Frequency = 0U;
2177   }
2178 
2179 }
2180 
2181 /**
2182   * @brief  Returns the main Core frequency
2183   * @note   Each time core clock changes, this function must be called to update the
2184   *         right system core clock value. Otherwise, any configuration based on this function will be incorrect.
2185   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
2186   *         and updated within this function
2187   * @retval HCLK frequency
2188   */
HAL_RCCEx_GetD1SysClockFreq(void)2189 uint32_t HAL_RCCEx_GetD1SysClockFreq(void)
2190 {
2191   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos] & 0x1FU);
2192   return SystemCoreClock;
2193 }
2194 
2195 /**
2196   * @brief  Enables the LSE Clock Security System.
2197   * @note   Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
2198   *         with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
2199   *         clock with HAL_RCCEx_PeriphCLKConfig().
2200   * @retval None
2201   */
HAL_RCCEx_EnableLSECSS(void)2202 void HAL_RCCEx_EnableLSECSS(void)
2203 {
2204   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
2205 }
2206 
2207 /**
2208   * @brief  Disables the LSE Clock Security System.
2209   * @note   LSE Clock Security System can only be disabled after a LSE failure detection.
2210   * @retval None
2211   */
HAL_RCCEx_DisableLSECSS(void)2212 void HAL_RCCEx_DisableLSECSS(void)
2213 {
2214   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
2215   /* Disable LSE CSS IT if any */
2216   __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
2217 }
2218 
2219 /**
2220   * @brief  Configure the oscillator clock source for wakeup from Stop and CSS backup clock
2221   * @param  WakeUpClk: Wakeup clock
2222   *         This parameter can be one of the following values:
2223   *            @arg RCC_STOP_WAKEUPCLOCK_CSI: CSI oscillator selection
2224   *            @arg RCC_STOP_WAKEUPCLOCK_HSI: HSI oscillator selection
2225   * @note   This function shall not be called after the Clock Security System on HSE has been
2226   *         enabled.
2227   * @retval None
2228   */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)2229 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
2230 {
2231   assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
2232 
2233   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
2234 }
2235 
2236 /**
2237   * @brief  Configure the oscillator Kernel clock source for wakeup from Stop
2238   * @param  WakeUpClk: Kernel Wakeup clock
2239   *         This parameter can be one of the following values:
2240   *            @arg RCC_STOP_KERWAKEUPCLOCK_CSI: CSI oscillator selection
2241   *            @arg RCC_STOP_KERWAKEUPCLOCK_HSI: HSI oscillator selection
2242   * @retval None
2243   */
HAL_RCCEx_KerWakeUpStopCLKConfig(uint32_t WakeUpClk)2244 void HAL_RCCEx_KerWakeUpStopCLKConfig(uint32_t WakeUpClk)
2245 {
2246   assert_param(IS_RCC_STOP_KERWAKEUPCLOCK(WakeUpClk));
2247 
2248   __HAL_RCC_KERWAKEUPSTOP_CLK_CONFIG(WakeUpClk);
2249 }
2250 
2251 #if defined(DUAL_CORE)
2252 /**
2253   * @brief  Enable COREx boot independently of CMx_B option byte value
2254   * @param  RCC_BootCx: Boot Core to be enabled
2255   *         This parameter can be one of the following values:
2256   *            @arg RCC_BOOT_C1: CM7 core selection
2257   *            @arg RCC_BOOT_C2: CM4 core selection
2258   * @note   This bit can be set by software but is cleared by hardware after a system reset or STANDBY
2259   *
2260   * @retval None
2261   */
HAL_RCCEx_EnableBootCore(uint32_t RCC_BootCx)2262 void HAL_RCCEx_EnableBootCore(uint32_t RCC_BootCx)
2263 {
2264   assert_param(IS_RCC_BOOT_CORE(RCC_BootCx));
2265   SET_BIT(RCC->GCR, RCC_BootCx) ;
2266 }
2267 
2268 #endif /*DUAL_CORE*/
2269 
2270 #if defined(DUAL_CORE)
2271 /**
2272   * @brief  Configure WWDGx to generate a system reset not only CPUx reset(default) when a time-out occurs
2273   * @param  RCC_WWDGx: WWDGx to be configured
2274   *         This parameter can be one of the following values:
2275   *            @arg RCC_WWDG1: WWDG1 generates system reset
2276   *            @arg RCC_WWDG2: WWDG2 generates system reset
2277   * @note   This bit can be set by software but is cleared by hardware during a system reset
2278   *
2279   * @retval None
2280   */
HAL_RCCEx_WWDGxSysResetConfig(uint32_t RCC_WWDGx)2281 void HAL_RCCEx_WWDGxSysResetConfig(uint32_t RCC_WWDGx)
2282 {
2283   assert_param(IS_RCC_SCOPE_WWDG(RCC_WWDGx));
2284   SET_BIT(RCC->GCR, RCC_WWDGx) ;
2285 }
2286 
2287 #else
2288 
2289 /**
2290   * @brief  Configure WWDG1 to generate a system reset not only CPU reset(default) when a time-out occurs
2291   * @param  RCC_WWDGx: WWDGx to be configured
2292   *         This parameter can be one of the following values:
2293   *            @arg RCC_WWDG1: WWDG1 generates system reset
2294   * @note   This bit can be set by software but is cleared by hardware during a system reset
2295   *
2296   * @retval None
2297   */
HAL_RCCEx_WWDGxSysResetConfig(uint32_t RCC_WWDGx)2298 void HAL_RCCEx_WWDGxSysResetConfig(uint32_t RCC_WWDGx)
2299 {
2300   assert_param(IS_RCC_SCOPE_WWDG(RCC_WWDGx));
2301   SET_BIT(RCC->GCR, RCC_WWDGx) ;
2302 }
2303 
2304 #endif /*DUAL_CORE*/
2305 
2306 
2307 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
2308  *  @brief  Extended Clock Recovery System Control functions
2309  *
2310 @verbatim
2311  ===============================================================================
2312                 ##### Extended Clock Recovery System Control functions  #####
2313  ===============================================================================
2314     [..]
2315       For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
2316 
2317       (#) In System clock config, HSI48 needs to be enabled
2318 
2319       (#) Enable CRS clock in IP MSP init which will use CRS functions
2320 
2321       (#) Call CRS functions as follows:
2322           (##) Prepare synchronization configuration necessary for HSI48 calibration
2323               (+++) Default values can be set for frequency Error Measurement (reload and error limit)
2324                         and also HSI48 oscillator smooth trimming.
2325               (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
2326                         directly reload value with target and synchronization frequencies values
2327           (##) Call function HAL_RCCEx_CRSConfig which
2328               (+++) Resets CRS registers to their default values.
2329               (+++) Configures CRS registers with synchronization configuration
2330               (+++) Enables automatic calibration and frequency error counter feature
2331            Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
2332            periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
2333            provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
2334            precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
2335            should be used as SYNC signal.
2336 
2337           (##) A polling function is provided to wait for complete synchronization
2338               (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
2339               (+++) According to CRS status, user can decide to adjust again the calibration or continue
2340                         application if synchronization is OK
2341 
2342       (#) User can retrieve information related to synchronization in calling function
2343             HAL_RCCEx_CRSGetSynchronizationInfo()
2344 
2345       (#) Regarding synchronization status and synchronization information, user can try a new calibration
2346            in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
2347            Note: When the SYNC event is detected during the down-counting phase (before reaching the zero value),
2348            it means that the actual frequency is lower than the target (and so, that the TRIM value should be
2349            incremented), while when it is detected during the up-counting phase it means that the actual frequency
2350            is higher (and that the TRIM value should be decremented).
2351 
2352       (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
2353           through CRS Handler (CRS_IRQn/CRS_IRQHandler)
2354               (++) Call function HAL_RCCEx_CRSConfig()
2355               (++) Enable CRS_IRQn (thanks to NVIC functions)
2356               (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
2357               (++) Implement CRS status management in the following user callbacks called from
2358                    HAL_RCCEx_CRS_IRQHandler():
2359                    (+++) HAL_RCCEx_CRS_SyncOkCallback()
2360                    (+++) HAL_RCCEx_CRS_SyncWarnCallback()
2361                    (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
2362                    (+++) HAL_RCCEx_CRS_ErrorCallback()
2363 
2364       (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
2365           This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
2366 
2367 @endverbatim
2368  * @{
2369  */
2370 
2371 /**
2372   * @brief  Start automatic synchronization for polling mode
2373   * @param  pInit Pointer on RCC_CRSInitTypeDef structure
2374   * @retval None
2375   */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)2376 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
2377 {
2378   uint32_t value;
2379 
2380   /* Check the parameters */
2381   assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
2382   assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
2383   assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
2384   assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
2385   assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
2386   assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
2387 
2388   /* CONFIGURATION */
2389 
2390   /* Before configuration, reset CRS registers to their default values*/
2391   __HAL_RCC_CRS_FORCE_RESET();
2392   __HAL_RCC_CRS_RELEASE_RESET();
2393 
2394   /* Set the SYNCDIV[2:0] bits according to Pre-scaler value */
2395   /* Set the SYNCSRC[1:0] bits according to Source value */
2396   /* Set the SYNCSPOL bit according to Polarity value */
2397   if ((HAL_GetREVID() <= REV_ID_Y) && (pInit->Source == RCC_CRS_SYNC_SOURCE_USB2))
2398   {
2399     /* Use Rev.Y value of USB2 */
2400     value = (pInit->Prescaler | RCC_CRS_SYNC_SOURCE_PIN | pInit->Polarity);
2401   }
2402   else
2403   {
2404     value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
2405   }
2406   /* Set the RELOAD[15:0] bits according to ReloadValue value */
2407   value |= pInit->ReloadValue;
2408   /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
2409   value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
2410   WRITE_REG(CRS->CFGR, value);
2411 
2412   /* Adjust HSI48 oscillator smooth trimming */
2413   /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
2414   MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
2415 
2416   /* START AUTOMATIC SYNCHRONIZATION*/
2417 
2418   /* Enable Automatic trimming & Frequency error counter */
2419   SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
2420 }
2421 
2422 /**
2423   * @brief  Generate the software synchronization event
2424   * @retval None
2425   */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)2426 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
2427 {
2428   SET_BIT(CRS->CR, CRS_CR_SWSYNC);
2429 }
2430 
2431 /**
2432   * @brief  Return synchronization info
2433   * @param  pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
2434   * @retval None
2435   */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)2436 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
2437 {
2438   /* Check the parameter */
2439   assert_param(pSynchroInfo != (void *)NULL);
2440 
2441   /* Get the reload value */
2442   pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
2443 
2444   /* Get HSI48 oscillator smooth trimming */
2445   pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
2446 
2447   /* Get Frequency error capture */
2448   pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
2449 
2450   /* Get Frequency error direction */
2451   pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
2452 }
2453 
2454 /**
2455 * @brief Wait for CRS Synchronization status.
2456 * @param Timeout  Duration of the time-out
2457 * @note  Timeout is based on the maximum time to receive a SYNC event based on synchronization
2458 *        frequency.
2459 * @note    If Time-out set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
2460 * @retval Combination of Synchronization status
2461 *          This parameter can be a combination of the following values:
2462 *            @arg @ref RCC_CRS_TIMEOUT
2463 *            @arg @ref RCC_CRS_SYNCOK
2464 *            @arg @ref RCC_CRS_SYNCWARN
2465 *            @arg @ref RCC_CRS_SYNCERR
2466 *            @arg @ref RCC_CRS_SYNCMISS
2467 *            @arg @ref RCC_CRS_TRIMOVF
2468 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)2469 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
2470 {
2471   uint32_t crsstatus = RCC_CRS_NONE;
2472   uint32_t tickstart;
2473 
2474   /* Get time-out */
2475   tickstart = HAL_GetTick();
2476 
2477   /* Wait for CRS flag or time-out detection */
2478   do
2479   {
2480     if(Timeout != HAL_MAX_DELAY)
2481     {
2482       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2483       {
2484         crsstatus = RCC_CRS_TIMEOUT;
2485       }
2486     }
2487     /* Check CRS SYNCOK flag  */
2488     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
2489     {
2490       /* CRS SYNC event OK */
2491       crsstatus |= RCC_CRS_SYNCOK;
2492 
2493       /* Clear CRS SYNC event OK bit */
2494       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
2495     }
2496 
2497     /* Check CRS SYNCWARN flag  */
2498     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
2499     {
2500       /* CRS SYNC warning */
2501       crsstatus |= RCC_CRS_SYNCWARN;
2502 
2503       /* Clear CRS SYNCWARN bit */
2504       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
2505     }
2506 
2507     /* Check CRS TRIM overflow flag  */
2508     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
2509     {
2510       /* CRS SYNC Error */
2511       crsstatus |= RCC_CRS_TRIMOVF;
2512 
2513       /* Clear CRS Error bit */
2514       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
2515     }
2516 
2517     /* Check CRS Error flag  */
2518     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
2519     {
2520       /* CRS SYNC Error */
2521       crsstatus |= RCC_CRS_SYNCERR;
2522 
2523       /* Clear CRS Error bit */
2524       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
2525     }
2526 
2527     /* Check CRS SYNC Missed flag  */
2528     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
2529     {
2530       /* CRS SYNC Missed */
2531       crsstatus |= RCC_CRS_SYNCMISS;
2532 
2533       /* Clear CRS SYNC Missed bit */
2534       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
2535     }
2536 
2537     /* Check CRS Expected SYNC flag  */
2538     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
2539     {
2540       /* frequency error counter reached a zero value */
2541       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
2542     }
2543   } while(RCC_CRS_NONE == crsstatus);
2544 
2545   return crsstatus;
2546 }
2547 
2548 /**
2549   * @brief Handle the Clock Recovery System interrupt request.
2550   * @retval None
2551   */
HAL_RCCEx_CRS_IRQHandler(void)2552 void HAL_RCCEx_CRS_IRQHandler(void)
2553 {
2554   uint32_t crserror = RCC_CRS_NONE;
2555   /* Get current IT flags and IT sources values */
2556   uint32_t itflags = READ_REG(CRS->ISR);
2557   uint32_t itsources = READ_REG(CRS->CR);
2558 
2559   /* Check CRS SYNCOK flag  */
2560   if(((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
2561   {
2562     /* Clear CRS SYNC event OK flag */
2563     WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
2564 
2565     /* user callback */
2566     HAL_RCCEx_CRS_SyncOkCallback();
2567   }
2568   /* Check CRS SYNCWARN flag  */
2569   else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
2570   {
2571     /* Clear CRS SYNCWARN flag */
2572     WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
2573 
2574     /* user callback */
2575     HAL_RCCEx_CRS_SyncWarnCallback();
2576   }
2577   /* Check CRS Expected SYNC flag  */
2578   else if(((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
2579   {
2580     /* frequency error counter reached a zero value */
2581     WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
2582 
2583     /* user callback */
2584     HAL_RCCEx_CRS_ExpectedSyncCallback();
2585   }
2586   /* Check CRS Error flags  */
2587   else
2588   {
2589     if(((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
2590     {
2591       if((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
2592       {
2593         crserror |= RCC_CRS_SYNCERR;
2594       }
2595       if((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
2596       {
2597         crserror |= RCC_CRS_SYNCMISS;
2598       }
2599       if((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
2600       {
2601         crserror |= RCC_CRS_TRIMOVF;
2602       }
2603 
2604       /* Clear CRS Error flags */
2605       WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
2606 
2607       /* user error callback */
2608       HAL_RCCEx_CRS_ErrorCallback(crserror);
2609     }
2610   }
2611 }
2612 
2613 /**
2614   * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
2615   * @retval none
2616   */
HAL_RCCEx_CRS_SyncOkCallback(void)2617 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
2618 {
2619   /* NOTE : This function should not be modified, when the callback is needed,
2620             the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
2621    */
2622 }
2623 
2624 /**
2625   * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
2626   * @retval none
2627   */
HAL_RCCEx_CRS_SyncWarnCallback(void)2628 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
2629 {
2630   /* NOTE : This function should not be modified, when the callback is needed,
2631             the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
2632    */
2633 }
2634 
2635 /**
2636   * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
2637   * @retval none
2638   */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)2639 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
2640 {
2641   /* NOTE : This function should not be modified, when the callback is needed,
2642             the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
2643    */
2644 }
2645 
2646 /**
2647   * @brief  RCCEx Clock Recovery System Error interrupt callback.
2648   * @param  Error Combination of Error status.
2649   *         This parameter can be a combination of the following values:
2650   *           @arg @ref RCC_CRS_SYNCERR
2651   *           @arg @ref RCC_CRS_SYNCMISS
2652   *           @arg @ref RCC_CRS_TRIMOVF
2653   * @retval none
2654   */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)2655 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
2656 {
2657   /* Prevent unused argument(s) compilation warning */
2658   UNUSED(Error);
2659 
2660   /* NOTE : This function should not be modified, when the callback is needed,
2661             the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
2662    */
2663 }
2664 
2665 
2666 /**
2667   * @}
2668   */
2669 
2670 /**
2671   * @}
2672   */
2673 
2674 /** @defgroup RCCEx_Private_functions Private Functions
2675  * @{
2676  */
2677 
2678 
2679 
2680 /**
2681   * @brief  Configure the PLL2 VCI,VCO ranges, multiplication and division factors and enable it
2682   * @param  pll2: Pointer to an RCC_PLL2InitTypeDef structure that
2683   *         contains the configuration parameters  as well as VCI, VCO clock ranges.
2684   * @param  Divider  divider parameter to be updated
2685   * @note   PLL2 is temporary disable to apply new parameters
2686   *
2687   * @retval HAL status
2688   */
RCCEx_PLL2_Config(RCC_PLL2InitTypeDef * pll2,uint32_t Divider)2689 static HAL_StatusTypeDef RCCEx_PLL2_Config(RCC_PLL2InitTypeDef *pll2, uint32_t Divider)
2690 {
2691 
2692   uint32_t tickstart;
2693   HAL_StatusTypeDef status = HAL_OK;
2694   assert_param(IS_RCC_PLL2M_VALUE(pll2->PLL2M));
2695   assert_param(IS_RCC_PLL2N_VALUE(pll2->PLL2N));
2696   assert_param(IS_RCC_PLL2P_VALUE(pll2->PLL2P));
2697   assert_param(IS_RCC_PLL2R_VALUE(pll2->PLL2R));
2698   assert_param(IS_RCC_PLL2Q_VALUE(pll2->PLL2Q));
2699   assert_param(IS_RCC_PLL2RGE_VALUE(pll2->PLL2RGE));
2700   assert_param(IS_RCC_PLL2VCO_VALUE(pll2->PLL2VCOSEL));
2701   assert_param(IS_RCC_PLLFRACN_VALUE(pll2->PLL2FRACN));
2702 
2703   /* Check that PLL2 OSC clock source is already set */
2704   if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_NONE)
2705   {
2706     return HAL_ERROR;
2707   }
2708 
2709 
2710   else
2711   {
2712     /* Disable  PLL2. */
2713     __HAL_RCC_PLL2_DISABLE();
2714 
2715     /* Get Start Tick*/
2716     tickstart = HAL_GetTick();
2717 
2718     /* Wait till PLL is ready */
2719     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != 0U)
2720     {
2721       if( (HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
2722       {
2723         return HAL_TIMEOUT;
2724       }
2725     }
2726 
2727     /* Configure PLL2 multiplication and division factors. */
2728     __HAL_RCC_PLL2_CONFIG(pll2->PLL2M,
2729                           pll2->PLL2N,
2730                           pll2->PLL2P,
2731                           pll2->PLL2Q,
2732                           pll2->PLL2R);
2733 
2734     /* Select PLL2 input reference frequency range: VCI */
2735     __HAL_RCC_PLL2_VCIRANGE(pll2->PLL2RGE) ;
2736 
2737     /* Select PLL2 output frequency range : VCO */
2738     __HAL_RCC_PLL2_VCORANGE(pll2->PLL2VCOSEL) ;
2739 
2740     /* Disable PLL2FRACN . */
2741     __HAL_RCC_PLL2FRACN_DISABLE();
2742 
2743     /* Configures PLL2 clock Fractional Part Of The Multiplication Factor */
2744     __HAL_RCC_PLL2FRACN_CONFIG(pll2->PLL2FRACN);
2745 
2746     /* Enable PLL2FRACN . */
2747     __HAL_RCC_PLL2FRACN_ENABLE();
2748 
2749     /* Enable the PLL2 clock output */
2750     if(Divider == DIVIDER_P_UPDATE)
2751     {
2752       __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL2_DIVP);
2753     }
2754     else if(Divider == DIVIDER_Q_UPDATE)
2755     {
2756       __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL2_DIVQ);
2757     }
2758     else
2759     {
2760       __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL2_DIVR);
2761     }
2762 
2763     /* Enable  PLL2. */
2764     __HAL_RCC_PLL2_ENABLE();
2765 
2766     /* Get Start Tick*/
2767     tickstart = HAL_GetTick();
2768 
2769     /* Wait till PLL2 is ready */
2770     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == 0U)
2771     {
2772       if( (HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
2773       {
2774         return HAL_TIMEOUT;
2775       }
2776     }
2777 
2778   }
2779 
2780 
2781   return status;
2782 }
2783 
2784 
2785 /**
2786   * @brief  Configure the PLL3 VCI,VCO ranges, multiplication and division factors and enable it
2787   * @param  pll3: Pointer to an RCC_PLL3InitTypeDef structure that
2788   *         contains the configuration parameters  as well as VCI, VCO clock ranges.
2789   * @param  Divider  divider parameter to be updated
2790   * @note   PLL3 is temporary disable to apply new parameters
2791   *
2792   * @retval HAL status
2793   */
RCCEx_PLL3_Config(RCC_PLL3InitTypeDef * pll3,uint32_t Divider)2794 static HAL_StatusTypeDef RCCEx_PLL3_Config(RCC_PLL3InitTypeDef *pll3, uint32_t Divider)
2795 {
2796   uint32_t tickstart;
2797   HAL_StatusTypeDef status = HAL_OK;
2798   assert_param(IS_RCC_PLL3M_VALUE(pll3->PLL3M));
2799   assert_param(IS_RCC_PLL3N_VALUE(pll3->PLL3N));
2800   assert_param(IS_RCC_PLL3P_VALUE(pll3->PLL3P));
2801   assert_param(IS_RCC_PLL3R_VALUE(pll3->PLL3R));
2802   assert_param(IS_RCC_PLL3Q_VALUE(pll3->PLL3Q));
2803   assert_param(IS_RCC_PLL3RGE_VALUE(pll3->PLL3RGE));
2804   assert_param(IS_RCC_PLL3VCO_VALUE(pll3->PLL3VCOSEL));
2805   assert_param(IS_RCC_PLLFRACN_VALUE(pll3->PLL3FRACN));
2806 
2807   /* Check that PLL3 OSC clock source is already set */
2808   if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_NONE)
2809   {
2810     return HAL_ERROR;
2811   }
2812 
2813 
2814   else
2815   {
2816     /* Disable  PLL3. */
2817     __HAL_RCC_PLL3_DISABLE();
2818 
2819     /* Get Start Tick*/
2820     tickstart = HAL_GetTick();
2821     /* Wait till PLL3 is ready */
2822     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY) != 0U)
2823     {
2824       if( (HAL_GetTick() - tickstart ) > PLL3_TIMEOUT_VALUE)
2825       {
2826         return HAL_TIMEOUT;
2827       }
2828     }
2829 
2830     /* Configure the PLL3  multiplication and division factors. */
2831     __HAL_RCC_PLL3_CONFIG(pll3->PLL3M,
2832                           pll3->PLL3N,
2833                           pll3->PLL3P,
2834                           pll3->PLL3Q,
2835                           pll3->PLL3R);
2836 
2837     /* Select PLL3 input reference frequency range: VCI */
2838     __HAL_RCC_PLL3_VCIRANGE(pll3->PLL3RGE) ;
2839 
2840     /* Select PLL3 output frequency range : VCO */
2841     __HAL_RCC_PLL3_VCORANGE(pll3->PLL3VCOSEL) ;
2842 
2843     /* Disable PLL3FRACN . */
2844     __HAL_RCC_PLL3FRACN_DISABLE();
2845 
2846     /* Configures PLL3 clock Fractional Part Of The Multiplication Factor */
2847     __HAL_RCC_PLL3FRACN_CONFIG(pll3->PLL3FRACN);
2848 
2849     /* Enable PLL3FRACN . */
2850     __HAL_RCC_PLL3FRACN_ENABLE();
2851 
2852     /* Enable the PLL3 clock output */
2853     if(Divider == DIVIDER_P_UPDATE)
2854     {
2855       __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL3_DIVP);
2856     }
2857     else if(Divider == DIVIDER_Q_UPDATE)
2858     {
2859       __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL3_DIVQ);
2860     }
2861     else
2862     {
2863       __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL3_DIVR);
2864     }
2865 
2866     /* Enable  PLL3. */
2867     __HAL_RCC_PLL3_ENABLE();
2868 
2869     /* Get Start Tick*/
2870     tickstart = HAL_GetTick();
2871 
2872     /* Wait till PLL3 is ready */
2873     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY) == 0U)
2874     {
2875       if( (HAL_GetTick() - tickstart ) > PLL3_TIMEOUT_VALUE)
2876       {
2877         return HAL_TIMEOUT;
2878       }
2879     }
2880 
2881   }
2882 
2883 
2884   return status;
2885 }
2886 
2887 
2888 
2889 
2890 /**
2891   * @}
2892   */
2893 
2894 /**
2895   * @}
2896   */
2897 
2898 #endif /* HAL_RCC_MODULE_ENABLED */
2899 /**
2900   * @}
2901   */
2902 
2903 /**
2904   * @}
2905   */
2906 
2907 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2908