1 /**
2 ******************************************************************************
3 * @file stm32l5xx_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 extended peripheral:
8 * + Extended Peripheral Control functions
9 * + Extended Clock management functions
10 * + Extended Clock Recovery System Control functions
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2019 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file in
19 * the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32l5xx_hal.h"
26
27 /** @addtogroup STM32L5xx_HAL_Driver
28 * @{
29 */
30
31 /** @defgroup RCCEx RCCEx
32 * @brief RCC Extended HAL module driver
33 * @{
34 */
35
36 #ifdef HAL_RCC_MODULE_ENABLED
37
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private defines -----------------------------------------------------------*/
40 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
41 * @{
42 */
43 #define PLLSAI1_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
44 #define PLLSAI2_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
45 #define PLL_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
46
47 #define DIVIDER_P_UPDATE 0U
48 #define DIVIDER_Q_UPDATE 1U
49 #define DIVIDER_R_UPDATE 2U
50
51 #define PLLSAI1CFGR_PLLSAI1SRC_NONE 0U
52 #define PLLSAI1CFGR_PLLSAI1SRC_MSI RCC_PLLSAI1CFGR_PLLSAI1SRC_0
53 #define PLLSAI1CFGR_PLLSAI1SRC_HSI RCC_PLLSAI1CFGR_PLLSAI1SRC_1
54 #define PLLSAI1CFGR_PLLSAI1SRC_HSE (RCC_PLLSAI1CFGR_PLLSAI1SRC_1 | RCC_PLLSAI1CFGR_PLLSAI1SRC_0)
55
56 #define PLLSAI2CFGR_PLLSAI2SRC_NONE 0U
57 #define PLLSAI2CFGR_PLLSAI2SRC_MSI RCC_PLLSAI2CFGR_PLLSAI2SRC_0
58 #define PLLSAI2CFGR_PLLSAI2SRC_HSI RCC_PLLSAI2CFGR_PLLSAI2SRC_1
59 #define PLLSAI2CFGR_PLLSAI2SRC_HSE (RCC_PLLSAI2CFGR_PLLSAI2SRC_1 | RCC_PLLSAI2CFGR_PLLSAI2SRC_0)
60
61 #define __LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
62 #define LSCO_GPIO_PORT GPIOA
63 #define LSCO_PIN GPIO_PIN_2
64 /**
65 * @}
66 */
67
68 /* Private macros ------------------------------------------------------------*/
69 /* Private variables ---------------------------------------------------------*/
70 /* Private function prototypes -----------------------------------------------*/
71 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
72 * @{
73 */
74 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource);
75 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *pPllSai1, uint32_t Divider);
76 static uint32_t RCCEx_PLLSAI1_GetVCOFreq(void);
77 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *pPllSai2, uint32_t Divider);
78 static uint32_t RCCEx_PLLSAI2_GetVCOFreq(void);
79 static uint32_t RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk, uint32_t InputFrequency);
80
81 /**
82 * @}
83 */
84
85 /* Exported functions --------------------------------------------------------*/
86
87 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
88 * @{
89 */
90
91 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
92 * @brief Extended Peripheral Control functions
93 *
94 @verbatim
95 ===============================================================================
96 ##### Extended Peripheral Control functions #####
97 ===============================================================================
98 [..]
99 This subsection provides a set of functions allowing to control the RCC Clocks
100 frequencies.
101 [..]
102 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
103 select the RTC clock source; in this case the Backup domain will be reset in
104 order to modify the RTC Clock source, as consequence RTC registers (including
105 the backup registers) are set to their reset values.
106
107 @endverbatim
108 * @{
109 */
110 /**
111 * @brief Initialize the RCC extended peripherals clocks according to the specified
112 * parameters in the RCC_PeriphCLKInitTypeDef.
113 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
114 * contains a field PeriphClockSelection which can be a combination of the following values:
115 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
116 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
117 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock
118 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
119 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock
120 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
121 * @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock
122 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
123 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
124 * @arg @ref RCC_PERIPHCLK_LPTIM3 LPTIM3 peripheral clock
125 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
126 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
127 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
128 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock
129 * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock
130 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
131 * @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock
132 * @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock
133 * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock
134 * @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock
135 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
136 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral kernel clock
137 * @arg @ref RCC_PERIPHCLK_DFSDM1AUDIO DFSDM1 peripheral audio clock
138 * @arg @ref RCC_PERIPHCLK_OSPI OctoSPI peripheral clock
139 * @arg @ref RCC_PERIPHCLK_FDCAN FDCAN peripheral clock
140 *
141 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
142 * the RTC clock source: in this case the access to Backup domain is enabled.
143 *
144 * @retval HAL status
145 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)146 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
147 {
148 HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
149 HAL_StatusTypeDef status = HAL_OK; /* Final status */
150 uint32_t tmpregister;
151 uint32_t tickstart;
152
153 /* Check the parameters */
154 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
155
156 /*-------------------------- SAI1 clock source configuration ---------------------*/
157 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
158 {
159 /* Check the parameters */
160 assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
161
162 switch (PeriphClkInit->Sai1ClockSelection)
163 {
164 case RCC_SAI1CLKSOURCE_PLL: /* PLL is used as clock source for SAI1*/
165 /* Enable SAI Clock output generated from System PLL . */
166 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
167 /* SAI1 clock source config set later after clock selection check */
168 break;
169
170 case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1*/
171 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
172 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
173 /* SAI1 clock source config set later after clock selection check */
174 break;
175
176 case RCC_SAI1CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI1*/
177 /* PLLSAI2 input clock, parameters M, N & P configuration clock output (PLLSAI2ClockOut) */
178 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
179 /* SAI1 clock source config set later after clock selection check */
180 break;
181
182 case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock*/
183 case RCC_SAI1CLKSOURCE_HSI: /* HSI is used as source of SAI1 clock*/
184 /* SAI1 clock source config set later after clock selection check */
185 break;
186
187 default:
188 ret = HAL_ERROR;
189 break;
190 }
191
192 if (ret == HAL_OK)
193 {
194 /* Set the source of SAI1 clock*/
195 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
196 }
197 else
198 {
199 /* set overall return value */
200 status = ret;
201 }
202 }
203
204 /*-------------------------- SAI2 clock source configuration ---------------------*/
205 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2))
206 {
207 /* Check the parameters */
208 assert_param(IS_RCC_SAI2CLK(PeriphClkInit->Sai2ClockSelection));
209
210 switch (PeriphClkInit->Sai2ClockSelection)
211 {
212 case RCC_SAI2CLKSOURCE_PLL: /* PLL is used as clock source for SAI2*/
213 /* Enable SAI Clock output generated from System PLL . */
214 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
215 /* SAI2 clock source config set later after clock selection check */
216 break;
217
218 case RCC_SAI2CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI2*/
219 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
220 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
221 /* SAI2 clock source config set later after clock selection check */
222 break;
223
224 case RCC_SAI2CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI2*/
225 /* PLLSAI2 input clock, parameters M, N & P configuration and clock output (PLLSAI2ClockOut) */
226 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
227 /* SAI2 clock source config set later after clock selection check */
228 break;
229
230 case RCC_SAI2CLKSOURCE_PIN: /* External clock is used as source of SAI2 clock*/
231 case RCC_SAI2CLKSOURCE_HSI: /* HSI is used as source of SAI2 clock*/
232 /* SAI2 clock source config set later after clock selection check */
233 break;
234
235 default:
236 ret = HAL_ERROR;
237 break;
238 }
239
240 if (ret == HAL_OK)
241 {
242 /* Set the source of SAI2 clock*/
243 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
244 }
245 else
246 {
247 /* set overall return value */
248 status = ret;
249 }
250 }
251
252 /*-------------------------- RTC clock source configuration ----------------------*/
253 if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
254 {
255 FlagStatus pwrclkchanged = RESET;
256
257 /* Check for RTC Parameters used to output RTCCLK */
258 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
259
260 /* Enable Power Clock */
261 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
262 {
263 __HAL_RCC_PWR_CLK_ENABLE();
264 pwrclkchanged = SET;
265 }
266
267 /* Enable write access to Backup domain */
268 SET_BIT(PWR->CR1, PWR_CR1_DBP);
269
270 /* Wait for Backup domain Write protection disable */
271 tickstart = HAL_GetTick();
272
273 while ((PWR->CR1 & PWR_CR1_DBP) == 0U)
274 {
275 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
276 {
277 /* New check to avoid false timeout detection in case of preemption */
278 if ((PWR->CR1 & PWR_CR1_DBP) == 0U)
279 {
280 ret = HAL_TIMEOUT;
281 }
282 break;
283 }
284 }
285
286 if (ret == HAL_OK)
287 {
288 /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
289 tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
290
291 if ((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
292 {
293 /* Store the content of BDCR register before the reset of Backup Domain */
294 tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
295 /* RTC Clock selection can be changed only if the Backup Domain is reset */
296 __HAL_RCC_BACKUPRESET_FORCE();
297 __HAL_RCC_BACKUPRESET_RELEASE();
298 /* Restore the Content of BDCR register */
299 RCC->BDCR = tmpregister;
300 }
301
302 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
303 if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
304 {
305 /* Get Start Tick*/
306 tickstart = HAL_GetTick();
307
308 /* Wait till LSE is ready */
309 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
310 {
311 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
312 {
313 /* New check to avoid false timeout detection in case of preemption */
314 if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
315 {
316 ret = HAL_TIMEOUT;
317 }
318 break;
319 }
320 }
321 }
322
323 if (ret == HAL_OK)
324 {
325 /* Apply new RTC clock source selection */
326 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
327 }
328 else
329 {
330 /* set overall return value */
331 status = ret;
332 }
333 }
334 else
335 {
336 /* set overall return value */
337 status = ret;
338 }
339
340 /* Restore clock configuration if changed */
341 if (pwrclkchanged == SET)
342 {
343 __HAL_RCC_PWR_CLK_DISABLE();
344 }
345 }
346
347 /*-------------------------- USART1 clock source configuration -------------------*/
348 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
349 {
350 /* Check the parameters */
351 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
352
353 /* Configure the USART1 clock source */
354 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
355 }
356
357 /*-------------------------- USART2 clock source configuration -------------------*/
358 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
359 {
360 /* Check the parameters */
361 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
362
363 /* Configure the USART2 clock source */
364 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
365 }
366
367 /*-------------------------- USART3 clock source configuration -------------------*/
368 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
369 {
370 /* Check the parameters */
371 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
372
373 /* Configure the USART3 clock source */
374 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
375 }
376
377 /*-------------------------- UART4 clock source configuration --------------------*/
378 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
379 {
380 /* Check the parameters */
381 assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
382
383 /* Configure the UART4 clock source */
384 __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
385 }
386
387 /*-------------------------- UART5 clock source configuration --------------------*/
388 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
389 {
390 /* Check the parameters */
391 assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
392
393 /* Configure the UART5 clock source */
394 __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
395 }
396
397 /*-------------------------- LPUART1 clock source configuration ------------------*/
398 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
399 {
400 /* Check the parameters */
401 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
402
403 /* Configure the LPUART1 clock source */
404 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
405 }
406
407 /*-------------------------- LPTIM1 clock source configuration -------------------*/
408 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
409 {
410 /* Check the parameters */
411 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
412
413 /* Configure the LPTIM1 clock source */
414 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
415 }
416
417 /*-------------------------- LPTIM2 clock source configuration -------------------*/
418 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
419 {
420 /* Check the parameters */
421 assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
422
423 /* Configure the LPTIM2 clock source */
424 __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
425 }
426
427 /*-------------------------- LPTIM3 clock source configuration -------------------*/
428 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM3) == (RCC_PERIPHCLK_LPTIM3))
429 {
430 /* Check the parameters */
431 assert_param(IS_RCC_LPTIM3CLK(PeriphClkInit->Lptim3ClockSelection));
432
433 /* Configure the LPTIM3 clock source */
434 __HAL_RCC_LPTIM3_CONFIG(PeriphClkInit->Lptim3ClockSelection);
435 }
436
437 /*-------------------------- FDCAN kernel clock source configuration -------------*/
438 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FDCAN) == (RCC_PERIPHCLK_FDCAN))
439 {
440 /* Check the parameters */
441 assert_param(IS_RCC_FDCANCLK(PeriphClkInit->FdcanClockSelection));
442
443 /* Configure the FDCAN kernel clock source */
444 switch (PeriphClkInit->FdcanClockSelection)
445 {
446 case RCC_FDCANCLKSOURCE_HSE: /* HSE is used as source of FDCAN kernel clock*/
447 /* FDCAN kernel clock source config set later after clock selection check */
448 break;
449
450 case RCC_FDCANCLKSOURCE_PLL: /* PLL is used as clock source for FDCAN kernel clock*/
451 /* Enable PLL48M1CLK output clock generated from System PLL . */
452 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
453 /* FDCAN kernel clock source config set later after clock selection check */
454 break;
455
456 case RCC_FDCANCLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for FDCAN kernel clock*/
457 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
458 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
459 /* FDCAN kernel clock source config set later after clock selection check */
460 break;
461
462 default:
463 ret = HAL_ERROR;
464 break;
465 }
466
467 if (ret == HAL_OK)
468 {
469 /* Set the source of FDCAN kernel clock*/
470 __HAL_RCC_FDCAN_CONFIG(PeriphClkInit->FdcanClockSelection);
471 }
472 else
473 {
474 /* set overall return value */
475 status = ret;
476 }
477 }
478
479 /*-------------------------- I2C1 clock source configuration ---------------------*/
480 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
481 {
482 /* Check the parameters */
483 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
484
485 /* Configure the I2C1 clock source */
486 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
487 }
488
489 /*-------------------------- I2C2 clock source configuration ---------------------*/
490 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
491 {
492 /* Check the parameters */
493 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
494
495 /* Configure the I2C2 clock source */
496 __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
497 }
498
499 /*-------------------------- I2C3 clock source configuration ---------------------*/
500 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
501 {
502 /* Check the parameters */
503 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
504
505 /* Configure the I2C3 clock source */
506 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
507 }
508
509 /*-------------------------- I2C4 clock source configuration ---------------------*/
510 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
511 {
512 /* Check the parameters */
513 assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
514
515 /* Configure the I2C4 clock source */
516 __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
517 }
518
519 #if defined(USB)
520
521 /*-------------------------- USB clock source configuration ----------------------*/
522 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
523 {
524 /* Check the parameters */
525 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
526
527 /* Configure the USB clock source */
528 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
529
530 if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
531 {
532 /* Enable PLL48M1CLK output clock */
533 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
534 }
535 else
536 {
537 if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
538 {
539 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
540 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
541
542 if (ret != HAL_OK)
543 {
544 /* set overall return value */
545 status = ret;
546 }
547 }
548 }
549 }
550
551 #endif /* USB */
552
553 /*-------------------------- SDMMC1 clock source configuration -------------------*/
554 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1))
555 {
556 /* Check the parameters */
557 assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
558
559 /* Configure the SDMMC1 clock source */
560 __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
561
562 if (PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1)
563 {
564 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
565 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
566
567 if (ret != HAL_OK)
568 {
569 /* set overall return value */
570 status = ret;
571 }
572 }
573 else if (PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL)
574 {
575 /* Enable PLL48M1CLK output clock */
576 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
577 }
578 else if (PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLP)
579 {
580 /* Enable PLLSAI3CLK output clock */
581 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
582 }
583 else
584 {
585 /* Nothing to do */
586 }
587 }
588
589 /*-------------------------- RNG clock source configuration ----------------------*/
590 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
591 {
592 /* Check the parameters */
593 assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
594
595 /* Configure the RNG clock source */
596 __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
597
598 if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
599 {
600 /* Enable PLL48M1CLK output clock */
601 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
602 }
603 else if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1)
604 {
605 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
606 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
607
608 if (ret != HAL_OK)
609 {
610 /* set overall return value */
611 status = ret;
612 }
613 }
614 else
615 {
616 /* Nothing to do */
617 }
618 }
619
620 /*-------------------------- ADC clock source configuration ----------------------*/
621 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
622 {
623 /* Check the parameters */
624 assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
625
626 /* Configure the ADC interface clock source */
627 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
628
629 if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
630 {
631 /* PLLSAI1 input clock, parameters M, N & R configuration and clock output (PLLSAI1ClockOut) */
632 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE);
633
634 if (ret != HAL_OK)
635 {
636 /* set overall return value */
637 status = ret;
638 }
639 }
640 }
641
642 /*-------------------------- DFSDM1 clock source configuration -------------------*/
643 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
644 {
645 /* Check the parameters */
646 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
647
648 /* Configure the DFSDM1 interface clock source */
649 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
650 }
651
652 /*-------------------------- DFSDM1 audio clock source configuration -------------*/
653 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1AUDIO) == RCC_PERIPHCLK_DFSDM1AUDIO)
654 {
655 /* Check the parameters */
656 assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
657
658 /* Configure the DFSDM1 interface audio clock source */
659 __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
660 }
661
662 /*-------------------------- OctoSPIx clock source configuration ----------------*/
663 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_OSPI) == RCC_PERIPHCLK_OSPI)
664 {
665 /* Check the parameters */
666 assert_param(IS_RCC_OSPICLKSOURCE(PeriphClkInit->OspiClockSelection));
667
668 /* Configure the OctoSPI clock source */
669 __HAL_RCC_OSPI_CONFIG(PeriphClkInit->OspiClockSelection);
670
671 if (PeriphClkInit->OspiClockSelection == RCC_OSPICLKSOURCE_PLL)
672 {
673 /* Enable PLL48M1CLK output clock */
674 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
675 }
676 }
677
678 return status;
679 }
680
681 /**
682 * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
683 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
684 * returns the configuration information for the Extended Peripherals
685 * clocks(SAI1, SAI2, LPTIM1, LPTIM2, LPTIM3, I2C1, I2C2, I2C3, I2C4, LPUART1,
686 * USART1, USART2, USART3, UART4, UART5, RTC, ADCx, DFSDMx, USB, SDMMC1, RNG and FDCAN).
687 * @retval None
688 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)689 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
690 {
691 /* Set all possible values for the extended clock type parameter------------*/
692 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
693 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
694 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_LPTIM3 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \
695 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB | RCC_PERIPHCLK_DFSDM1 | \
696 RCC_PERIPHCLK_DFSDM1AUDIO | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_OSPI | RCC_PERIPHCLK_FDCAN;
697
698 /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
699 PeriphClkInit->PLLSAI1.PLLSAI1Source = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1SRC) >> RCC_PLLSAI1CFGR_PLLSAI1SRC_Pos);
700 PeriphClkInit->PLLSAI1.PLLSAI1M = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U;
701 PeriphClkInit->PLLSAI1.PLLSAI1N = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos);
702 PeriphClkInit->PLLSAI1.PLLSAI1P = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1P) >> RCC_PLLSAI1CFGR_PLLSAI1P_Pos) << 4U) + 7U;
703 PeriphClkInit->PLLSAI1.PLLSAI1Q = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) * 2U;
704 PeriphClkInit->PLLSAI1.PLLSAI1R = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U;
705
706 /* Get the PLLSAI2 Clock configuration -----------------------------------------------*/
707 PeriphClkInit->PLLSAI2.PLLSAI2Source = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2SRC) >> RCC_PLLSAI2CFGR_PLLSAI2SRC_Pos);
708 PeriphClkInit->PLLSAI2.PLLSAI2M = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U;
709 PeriphClkInit->PLLSAI2.PLLSAI2N = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos);
710 PeriphClkInit->PLLSAI2.PLLSAI2P = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2P) >> RCC_PLLSAI2CFGR_PLLSAI2P_Pos) << 4U) + 7U;
711
712 /* Get the USART1 clock source ---------------------------------------------*/
713 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
714
715 /* Get the USART2 clock source ---------------------------------------------*/
716 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
717
718 /* Get the USART3 clock source ---------------------------------------------*/
719 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
720
721 /* Get the UART4 clock source ----------------------------------------------*/
722 PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
723
724 /* Get the UART5 clock source ----------------------------------------------*/
725 PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
726
727 /* Get the LPUART1 clock source --------------------------------------------*/
728 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
729
730 /* Get the I2C1 clock source -----------------------------------------------*/
731 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
732
733 /* Get the I2C2 clock source ----------------------------------------------*/
734 PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
735
736 /* Get the I2C3 clock source -----------------------------------------------*/
737 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
738
739 /* Get the I2C4 clock source -----------------------------------------------*/
740 PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE();
741
742 /* Get the LPTIM1 clock source ---------------------------------------------*/
743 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
744
745 /* Get the LPTIM2 clock source ---------------------------------------------*/
746 PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE();
747
748 /* Get the LPTIM3 clock source ---------------------------------------------*/
749 PeriphClkInit->Lptim3ClockSelection = __HAL_RCC_GET_LPTIM3_SOURCE();
750
751 /* Get the FDCAN kernel clock source ---------------------------------------*/
752 PeriphClkInit->FdcanClockSelection = __HAL_RCC_GET_FDCAN_SOURCE();
753
754 /* Get the SAI1 clock source -----------------------------------------------*/
755 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
756
757 /* Get the SAI2 clock source -----------------------------------------------*/
758 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
759
760 /* Get the RTC clock source ------------------------------------------------*/
761 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
762
763 #if defined(USB)
764 /* Get the USB clock source ------------------------------------------------*/
765 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
766 #endif /* USB */
767
768 /* Get the SDMMC1 clock source ---------------------------------------------*/
769 PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
770
771 /* Get the RNG clock source ------------------------------------------------*/
772 PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE();
773
774 /* Get the ADC clock source ------------------------------------------------*/
775 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
776
777 /* Get the DFSDM1 clock source ---------------------------------------------*/
778 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
779
780 /* Get the DFSDM1 audio clock source ---------------------------------------*/
781 PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
782
783 /* Get the OctoSPIclock source --------------------------------------------*/
784 PeriphClkInit->OspiClockSelection = __HAL_RCC_GET_OSPI_SOURCE();
785 }
786
787 /**
788 * @brief Return the peripheral clock frequency for peripherals with clock source from PLLSAIs
789 * @note Return 0 if peripheral clock identifier not managed by this API
790 * @param PeriphClk Peripheral clock identifier
791 * This parameter can be one of the following values:
792 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
793 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
794 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock
795 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
796 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock
797 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
798 * @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock
799 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
800 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
801 * @arg @ref RCC_PERIPHCLK_LPTIM3 LPTIM3 peripheral clock
802 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
803 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
804 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
805 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock
806 * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock
807 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
808 * @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock
809 * @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock
810 * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock
811 * @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock
812 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
813 * @arg @ref RCC_PERIPHCLK_FDCAN FDCAN peripheral clock
814 * @retval Frequency in Hz
815 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)816 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
817 {
818 uint32_t frequency = 0U; /* Default is 0 */
819 uint32_t srcclk;
820 uint32_t pllvco, plln, pllp;
821 uint32_t pll_oscsource;
822
823 /* Check the parameters */
824 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
825
826 if (PeriphClk == RCC_PERIPHCLK_RTC)
827 {
828 /* Get the current RTC source */
829 srcclk = __HAL_RCC_GET_RTC_SOURCE();
830
831 switch (srcclk)
832 {
833 case RCC_RTCCLKSOURCE_LSE:
834 /* Check if LSE is ready */
835 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
836 {
837 frequency = LSE_VALUE;
838 }
839 break;
840 case RCC_RTCCLKSOURCE_LSI:
841 /* Check if LSI is ready */
842 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
843 {
844 frequency = LSI_VALUE;
845 }
846 break;
847 case RCC_RTCCLKSOURCE_HSE_DIV32:
848 /* Check if HSE is ready */
849 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
850 {
851 frequency = HSE_VALUE / 32U;
852 }
853 break;
854 default:
855 /* No clock source, frequency default init at 0 */
856 break;
857 }
858 }
859 else
860 {
861 /* Other external peripheral clock source than RTC */
862 pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
863
864 /* Compute PLL clock input */
865 switch (pll_oscsource)
866 {
867 case RCC_PLLSOURCE_MSI: /* MSI ? */
868 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
869 {
870 /*MSI frequency range in HZ*/
871 pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
872 }
873 else
874 {
875 pllvco = 0U;
876 }
877 break;
878 case RCC_PLLSOURCE_HSI: /* HSI ? */
879 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
880 {
881 pllvco = HSI_VALUE;
882 }
883 else
884 {
885 pllvco = 0U;
886 }
887 break;
888 case RCC_PLLSOURCE_HSE: /* HSE ? */
889 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
890 {
891 pllvco = HSE_VALUE;
892 }
893 else
894 {
895 pllvco = 0U;
896 }
897 break;
898 default:
899 /* No source */
900 pllvco = 0U;
901 break;
902 }
903
904 switch (PeriphClk)
905 {
906 case RCC_PERIPHCLK_SAI1:
907 frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco);
908 break;
909
910 case RCC_PERIPHCLK_SAI2:
911 frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI2, pllvco);
912 break;
913
914 #if defined(USB)
915
916 case RCC_PERIPHCLK_USB:
917
918 #endif /* USB */
919
920 case RCC_PERIPHCLK_RNG:
921
922 srcclk = READ_BIT(RCC->CCIPR1, RCC_CCIPR1_CLK48MSEL);
923
924 switch (srcclk)
925 {
926 case RCC_CCIPR1_CLK48MSEL: /* MSI ? */
927 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
928 {
929 /*MSI frequency range in HZ*/
930 frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
931 }
932 break;
933 case RCC_CCIPR1_CLK48MSEL_1: /* PLL "Q" ? */
934 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
935 {
936 if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
937 {
938 /* f(PLL Source) / PLLM */
939 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
940 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
941 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
942 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
943 }
944 }
945 break;
946 case RCC_CCIPR1_CLK48MSEL_0: /* PLLSAI1 ? */
947 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY))
948 {
949 if (HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
950 {
951 /* Get f(PLLSAI1 source) */
952 pllvco = RCCEx_PLLSAI1_GetVCOFreq();
953 /* f(PLLSAI1 Source) / PLLSAI1M */
954 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
955 /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */
956 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
957 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U);
958 }
959 }
960 break;
961 case 0U:
962 if (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */
963 {
964 frequency = HSI48_VALUE;
965 }
966 break;
967 default:
968 /* No clock source, frequency default init at 0 */
969 break;
970 } /* switch(srcclk) */
971
972 break;
973
974 case RCC_PERIPHCLK_SDMMC1:
975
976 if (HAL_IS_BIT_SET(RCC->CCIPR2, RCC_CCIPR2_SDMMCSEL)) /* PLLP ? */
977 {
978 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
979 {
980 if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN))
981 {
982 /* f(PLL Source) / PLLM */
983 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
984 /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
985 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
986 pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
987 if (pllp == 0U)
988 {
989 if (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
990 {
991 pllp = 17U;
992 }
993 else
994 {
995 pllp = 7U;
996 }
997 }
998 frequency = (pllvco * plln) / pllp;
999 }
1000 }
1001 }
1002 else /* 48MHz from MSI or PLLSAI1Q or PLLQ or HSI48 */
1003 {
1004 srcclk = READ_BIT(RCC->CCIPR1, RCC_CCIPR1_CLK48MSEL);
1005
1006 switch (srcclk)
1007 {
1008 case RCC_CCIPR1_CLK48MSEL: /* MSI ? */
1009 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
1010 {
1011 /*MSI frequency range in HZ*/
1012 frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
1013 }
1014 break;
1015 case RCC_CCIPR1_CLK48MSEL_1: /* PLL "Q" ? */
1016 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
1017 {
1018 if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
1019 {
1020 /* f(PLL Source) / PLLM */
1021 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
1022 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
1023 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1024 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1025 }
1026 }
1027 break;
1028 case RCC_CCIPR1_CLK48MSEL_0: /* PLLSAI1 ? */
1029 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY))
1030 {
1031 if (HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
1032 {
1033 /* Get f(PLLSAI1 source) */
1034 pllvco = RCCEx_PLLSAI1_GetVCOFreq();
1035 /* f(PLLSAI1 Source) / PLLSAI1M */
1036 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
1037 /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */
1038 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
1039 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U);
1040 }
1041 }
1042 break;
1043 case 0U:
1044 if (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */
1045 {
1046 frequency = HSI48_VALUE;
1047 }
1048 break;
1049 default:
1050 /* No clock source, frequency default init at 0 */
1051 break;
1052 } /* switch(srcclk) */
1053 }
1054
1055 break;
1056
1057 case RCC_PERIPHCLK_USART1:
1058
1059 /* Get the current USART1 source */
1060 srcclk = __HAL_RCC_GET_USART1_SOURCE();
1061
1062 switch (srcclk)
1063 {
1064 case RCC_USART1CLKSOURCE_PCLK2:
1065 frequency = HAL_RCC_GetPCLK2Freq();
1066 break;
1067 case RCC_USART1CLKSOURCE_SYSCLK:
1068 frequency = HAL_RCC_GetSysClockFreq();
1069 break;
1070 case RCC_USART1CLKSOURCE_HSI:
1071 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1072 {
1073 frequency = HSI_VALUE;
1074 }
1075 break;
1076 case RCC_USART1CLKSOURCE_LSE:
1077 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1078 {
1079 frequency = LSE_VALUE;
1080 }
1081 break;
1082 default:
1083 /* No clock source, frequency default init at 0 */
1084 break;
1085 }
1086
1087 break;
1088
1089 case RCC_PERIPHCLK_USART2:
1090
1091 /* Get the current USART2 source */
1092 srcclk = __HAL_RCC_GET_USART2_SOURCE();
1093
1094 switch (srcclk)
1095 {
1096 case RCC_USART2CLKSOURCE_PCLK1:
1097 frequency = HAL_RCC_GetPCLK1Freq();
1098 break;
1099 case RCC_USART2CLKSOURCE_SYSCLK:
1100 frequency = HAL_RCC_GetSysClockFreq();
1101 break;
1102 case RCC_USART2CLKSOURCE_HSI:
1103 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1104 {
1105 frequency = HSI_VALUE;
1106 }
1107 break;
1108 case RCC_USART2CLKSOURCE_LSE:
1109 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1110 {
1111 frequency = LSE_VALUE;
1112 }
1113 break;
1114 default:
1115 /* No clock source, frequency default init at 0 */
1116 break;
1117 }
1118
1119 break;
1120
1121 case RCC_PERIPHCLK_USART3:
1122
1123 /* Get the current USART3 source */
1124 srcclk = __HAL_RCC_GET_USART3_SOURCE();
1125
1126 switch (srcclk)
1127 {
1128 case RCC_USART3CLKSOURCE_PCLK1:
1129 frequency = HAL_RCC_GetPCLK1Freq();
1130 break;
1131 case RCC_USART3CLKSOURCE_SYSCLK:
1132 frequency = HAL_RCC_GetSysClockFreq();
1133 break;
1134 case RCC_USART3CLKSOURCE_HSI:
1135 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1136 {
1137 frequency = HSI_VALUE;
1138 }
1139 break;
1140 case RCC_USART3CLKSOURCE_LSE:
1141 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1142 {
1143 frequency = LSE_VALUE;
1144 }
1145 break;
1146 default:
1147 /* No clock source, frequency default init at 0 */
1148 break;
1149 }
1150
1151 break;
1152
1153 case RCC_PERIPHCLK_UART4:
1154
1155 /* Get the current UART4 source */
1156 srcclk = __HAL_RCC_GET_UART4_SOURCE();
1157
1158 switch (srcclk)
1159 {
1160 case RCC_UART4CLKSOURCE_PCLK1:
1161 frequency = HAL_RCC_GetPCLK1Freq();
1162 break;
1163 case RCC_UART4CLKSOURCE_SYSCLK:
1164 frequency = HAL_RCC_GetSysClockFreq();
1165 break;
1166 case RCC_UART4CLKSOURCE_HSI:
1167 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1168 {
1169 frequency = HSI_VALUE;
1170 }
1171 break;
1172 case RCC_UART4CLKSOURCE_LSE:
1173 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1174 {
1175 frequency = LSE_VALUE;
1176 }
1177 break;
1178 default:
1179 /* No clock source, frequency default init at 0 */
1180 break;
1181 }
1182
1183 break;
1184
1185 case RCC_PERIPHCLK_UART5:
1186
1187 /* Get the current UART5 source */
1188 srcclk = __HAL_RCC_GET_UART5_SOURCE();
1189
1190 switch (srcclk)
1191 {
1192 case RCC_UART5CLKSOURCE_PCLK1:
1193 frequency = HAL_RCC_GetPCLK1Freq();
1194 break;
1195 case RCC_UART5CLKSOURCE_SYSCLK:
1196 frequency = HAL_RCC_GetSysClockFreq();
1197 break;
1198 case RCC_UART5CLKSOURCE_HSI:
1199 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1200 {
1201 frequency = HSI_VALUE;
1202 }
1203 break;
1204 case RCC_UART5CLKSOURCE_LSE:
1205 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1206 {
1207 frequency = LSE_VALUE;
1208 }
1209 break;
1210 default:
1211 /* No clock source, frequency default init at 0 */
1212 break;
1213 }
1214
1215 break;
1216
1217 case RCC_PERIPHCLK_LPUART1:
1218
1219 /* Get the current LPUART1 source */
1220 srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
1221
1222 switch (srcclk)
1223 {
1224 case RCC_LPUART1CLKSOURCE_PCLK1:
1225 frequency = HAL_RCC_GetPCLK1Freq();
1226 break;
1227 case RCC_LPUART1CLKSOURCE_SYSCLK:
1228 frequency = HAL_RCC_GetSysClockFreq();
1229 break;
1230 case RCC_LPUART1CLKSOURCE_HSI:
1231 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1232 {
1233 frequency = HSI_VALUE;
1234 }
1235 break;
1236 case RCC_LPUART1CLKSOURCE_LSE:
1237 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1238 {
1239 frequency = LSE_VALUE;
1240 }
1241 break;
1242 default:
1243 /* No clock source, frequency default init at 0 */
1244 break;
1245 }
1246
1247 break;
1248
1249 case RCC_PERIPHCLK_ADC:
1250
1251 /* Get the current ADC source */
1252 srcclk = __HAL_RCC_GET_ADC_SOURCE();
1253
1254 switch (srcclk)
1255 {
1256 case RCC_ADCCLKSOURCE_SYSCLK:
1257 frequency = HAL_RCC_GetSysClockFreq();
1258 break;
1259 case RCC_ADCCLKSOURCE_PLLSAI1:
1260 if (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != 0U)
1261 {
1262 /* Get f(PLLSAI1 source) */
1263 pllvco = RCCEx_PLLSAI1_GetVCOFreq();
1264 /* f(PLLSAI1 Source) / PLLSAI1M */
1265 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
1266 /* f(PLLADC1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1R */
1267 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
1268 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U);
1269 }
1270 break;
1271 default:
1272 /* No clock source, frequency default init at 0 */
1273 break;
1274 }
1275
1276 break;
1277
1278 case RCC_PERIPHCLK_DFSDM1:
1279
1280 /* Get the current DFSDM1 source */
1281 srcclk = __HAL_RCC_GET_DFSDM1_SOURCE();
1282
1283 if (srcclk == RCC_DFSDM1CLKSOURCE_PCLK2)
1284 {
1285 frequency = HAL_RCC_GetPCLK2Freq();
1286 }
1287 else
1288 {
1289 frequency = HAL_RCC_GetSysClockFreq();
1290 }
1291
1292 break;
1293
1294 case RCC_PERIPHCLK_DFSDM1AUDIO:
1295
1296 /* Get the current DFSDM1 audio source */
1297 srcclk = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
1298
1299 switch (srcclk)
1300 {
1301 case RCC_DFSDM1AUDIOCLKSOURCE_SAI1:
1302 frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco);
1303 break;
1304 case RCC_DFSDM1AUDIOCLKSOURCE_MSI:
1305 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
1306 {
1307 /*MSI frequency range in HZ*/
1308 frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
1309 }
1310 break;
1311 case RCC_DFSDM1AUDIOCLKSOURCE_HSI:
1312 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1313 {
1314 frequency = HSI_VALUE;
1315 }
1316 break;
1317 default:
1318 /* No clock source, frequency default init at 0 */
1319 break;
1320 }
1321
1322 break;
1323
1324 case RCC_PERIPHCLK_I2C1:
1325
1326 /* Get the current I2C1 source */
1327 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
1328
1329 switch (srcclk)
1330 {
1331 case RCC_I2C1CLKSOURCE_PCLK1:
1332 frequency = HAL_RCC_GetPCLK1Freq();
1333 break;
1334 case RCC_I2C1CLKSOURCE_SYSCLK:
1335 frequency = HAL_RCC_GetSysClockFreq();
1336 break;
1337 case RCC_I2C1CLKSOURCE_HSI:
1338 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1339 {
1340 frequency = HSI_VALUE;
1341 }
1342 break;
1343 default:
1344 /* No clock source, frequency default init at 0 */
1345 break;
1346 }
1347
1348 break;
1349
1350 case RCC_PERIPHCLK_I2C2:
1351
1352 /* Get the current I2C2 source */
1353 srcclk = __HAL_RCC_GET_I2C2_SOURCE();
1354
1355 switch (srcclk)
1356 {
1357 case RCC_I2C2CLKSOURCE_PCLK1:
1358 frequency = HAL_RCC_GetPCLK1Freq();
1359 break;
1360 case RCC_I2C2CLKSOURCE_SYSCLK:
1361 frequency = HAL_RCC_GetSysClockFreq();
1362 break;
1363 case RCC_I2C2CLKSOURCE_HSI:
1364 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1365 {
1366 frequency = HSI_VALUE;
1367 }
1368 break;
1369 default:
1370 /* No clock source, frequency default init at 0 */
1371 break;
1372 }
1373
1374 break;
1375
1376 case RCC_PERIPHCLK_I2C3:
1377
1378 /* Get the current I2C3 source */
1379 srcclk = __HAL_RCC_GET_I2C3_SOURCE();
1380
1381 switch (srcclk)
1382 {
1383 case RCC_I2C3CLKSOURCE_PCLK1:
1384 frequency = HAL_RCC_GetPCLK1Freq();
1385 break;
1386 case RCC_I2C3CLKSOURCE_SYSCLK:
1387 frequency = HAL_RCC_GetSysClockFreq();
1388 break;
1389 case RCC_I2C3CLKSOURCE_HSI:
1390 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1391 {
1392 frequency = HSI_VALUE;
1393 }
1394 break;
1395 default:
1396 /* No clock source, frequency default init at 0 */
1397 break;
1398 }
1399 break;
1400
1401 case RCC_PERIPHCLK_I2C4:
1402
1403 /* Get the current I2C4 source */
1404 srcclk = __HAL_RCC_GET_I2C4_SOURCE();
1405
1406 switch (srcclk)
1407 {
1408 case RCC_I2C4CLKSOURCE_PCLK1:
1409 frequency = HAL_RCC_GetPCLK1Freq();
1410 break;
1411 case RCC_I2C4CLKSOURCE_SYSCLK:
1412 frequency = HAL_RCC_GetSysClockFreq();
1413 break;
1414 case RCC_I2C4CLKSOURCE_HSI:
1415 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1416 {
1417 frequency = HSI_VALUE;
1418 }
1419 break;
1420 default:
1421 /* No clock source, frequency default init at 0 */
1422 break;
1423 }
1424
1425 break;
1426
1427 case RCC_PERIPHCLK_LPTIM1:
1428
1429 /* Get the current LPTIM1 source */
1430 srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
1431
1432 switch (srcclk)
1433 {
1434 case RCC_LPTIM1CLKSOURCE_PCLK1:
1435 frequency = HAL_RCC_GetPCLK1Freq();
1436 break;
1437 case RCC_LPTIM1CLKSOURCE_LSI:
1438 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
1439 {
1440 frequency = LSI_VALUE;
1441 }
1442 break;
1443 case RCC_LPTIM1CLKSOURCE_HSI:
1444 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1445 {
1446 frequency = HSI_VALUE;
1447 }
1448 break;
1449 case RCC_LPTIM1CLKSOURCE_LSE:
1450 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1451 {
1452 frequency = LSE_VALUE;
1453 }
1454 break;
1455 default:
1456 /* No clock source, frequency default init at 0 */
1457 break;
1458 }
1459
1460 break;
1461
1462 case RCC_PERIPHCLK_LPTIM2:
1463
1464 /* Get the current LPTIM2 source */
1465 srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
1466
1467 switch (srcclk)
1468 {
1469 case RCC_LPTIM2CLKSOURCE_PCLK1:
1470 frequency = HAL_RCC_GetPCLK1Freq();
1471 break;
1472 case RCC_LPTIM2CLKSOURCE_LSI:
1473 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
1474 {
1475 frequency = LSI_VALUE;
1476 }
1477 break;
1478 case RCC_LPTIM2CLKSOURCE_HSI:
1479 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1480 {
1481 frequency = HSI_VALUE;
1482 }
1483 break;
1484 case RCC_LPTIM2CLKSOURCE_LSE:
1485 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1486 {
1487 frequency = LSE_VALUE;
1488 }
1489 break;
1490 default:
1491 /* No clock source, frequency default init at 0 */
1492 break;
1493 }
1494
1495 break;
1496
1497 case RCC_PERIPHCLK_LPTIM3:
1498
1499 /* Get the current LPTIM3 source */
1500 srcclk = __HAL_RCC_GET_LPTIM3_SOURCE();
1501
1502 switch (srcclk)
1503 {
1504 case RCC_LPTIM3CLKSOURCE_PCLK1:
1505 frequency = HAL_RCC_GetPCLK1Freq();
1506 break;
1507 case RCC_LPTIM3CLKSOURCE_LSI:
1508 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
1509 {
1510 frequency = LSI_VALUE;
1511 }
1512 break;
1513 case RCC_LPTIM3CLKSOURCE_HSI:
1514 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1515 {
1516 frequency = HSI_VALUE;
1517 }
1518 break;
1519 case RCC_LPTIM3CLKSOURCE_LSE:
1520 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1521 {
1522 frequency = LSE_VALUE;
1523 }
1524 break;
1525 default:
1526 /* No clock source, frequency default init at 0 */
1527 break;
1528 }
1529
1530 break;
1531
1532 case RCC_PERIPHCLK_FDCAN:
1533
1534 /* Get the current FDCAN kernel source */
1535 srcclk = __HAL_RCC_GET_FDCAN_SOURCE();
1536
1537 switch (srcclk)
1538 {
1539 case RCC_FDCANCLKSOURCE_HSE:
1540 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
1541 {
1542 frequency = HSE_VALUE;
1543 }
1544 break;
1545
1546 case RCC_FDCANCLKSOURCE_PLL:
1547 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
1548 {
1549 if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
1550 {
1551 /* f(PLL Source) / PLLM */
1552 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
1553 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
1554 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1555 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1556 }
1557 }
1558 break;
1559
1560 case RCC_FDCANCLKSOURCE_PLLSAI1:
1561 if (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U)
1562 {
1563 /* Get f(PLLSAI1 source) */
1564 pllvco = RCCEx_PLLSAI1_GetVCOFreq();
1565 /* f(PLLSAI1 Source) / PLLSAI1M */
1566 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
1567 /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
1568 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
1569 pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos;
1570 if (pllp == 0U)
1571 {
1572 if (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U)
1573 {
1574 pllp = 17U;
1575 }
1576 else
1577 {
1578 pllp = 7U;
1579 }
1580 }
1581 frequency = (pllvco * plln) / pllp;
1582 }
1583 break;
1584
1585 default:
1586 /* No clock source, frequency default init at 0 */
1587 break;
1588 }
1589
1590 break;
1591
1592 default:
1593 /* Unexpected case, frequency default init at 0 */
1594 break;
1595 }
1596 }
1597
1598 return (frequency);
1599 }
1600
1601 /**
1602 * @}
1603 */
1604
1605 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
1606 * @brief Extended Clock management functions
1607 *
1608 @verbatim
1609 ===============================================================================
1610 ##### Extended clock management functions #####
1611 ===============================================================================
1612 [..]
1613 This subsection provides a set of functions allowing to control the
1614 activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI2, CSS on LSE,
1615 low speed clock output and clock after wake-up from STOP mode.
1616 @endverbatim
1617 * @{
1618 */
1619
1620 /**
1621 * @brief Enable PLLSAI1.
1622 * @param PLLSAI1Init pointer to an RCC_PLLSAI1InitTypeDef structure that
1623 * contains the configuration information for the PLLSAI1
1624 * @retval HAL status
1625 */
HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef * PLLSAI1Init)1626 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef *PLLSAI1Init)
1627 {
1628 HAL_StatusTypeDef status = HAL_OK;
1629 uint32_t tickstart;
1630
1631 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1632 assert_param(IS_RCC_PLLSAI1SOURCE(PLLSAI1Init->PLLSAI1Source));
1633 assert_param(IS_RCC_PLLSAI1M_VALUE(PLLSAI1Init->PLLSAI1M));
1634 assert_param(IS_RCC_PLLSAI1N_VALUE(PLLSAI1Init->PLLSAI1N));
1635 assert_param(IS_RCC_PLLSAI1P_VALUE(PLLSAI1Init->PLLSAI1P));
1636 assert_param(IS_RCC_PLLSAI1Q_VALUE(PLLSAI1Init->PLLSAI1Q));
1637 assert_param(IS_RCC_PLLSAI1R_VALUE(PLLSAI1Init->PLLSAI1R));
1638 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
1639
1640 /* Disable the PLLSAI1 */
1641 __HAL_RCC_PLLSAI1_DISABLE();
1642
1643 /* Get Start Tick*/
1644 tickstart = HAL_GetTick();
1645
1646 /* Wait till PLLSAI1 is ready to be updated */
1647 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1648 {
1649 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1650 {
1651 /* New check to avoid false timeout detection in case of preemption */
1652 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1653 {
1654 status = HAL_TIMEOUT;
1655 }
1656 break;
1657 }
1658 }
1659
1660 if (status == HAL_OK)
1661 {
1662 /* Make sure PLLSAI1Source is ready */
1663 status = RCCEx_PLLSource_Enable(PLLSAI1Init->PLLSAI1Source);
1664
1665 if (status == HAL_OK)
1666 {
1667 /* Configure the PLLSAI1 clock source, multiplication factor N, */
1668 /* and division factors M, P, Q and R */
1669 __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1Source, PLLSAI1Init->PLLSAI1M, PLLSAI1Init->PLLSAI1N,
1670 PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R);
1671 /* Configure the PLLSAI1 Clock output(s) */
1672 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
1673
1674 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
1675 __HAL_RCC_PLLSAI1_ENABLE();
1676
1677 /* Get Start Tick*/
1678 tickstart = HAL_GetTick();
1679
1680 /* Wait till PLLSAI1 is ready */
1681 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
1682 {
1683 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1684 {
1685 /* New check to avoid false timeout detection in case of preemption */
1686 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
1687 {
1688 status = HAL_TIMEOUT;
1689 }
1690 break;
1691 }
1692 }
1693 }
1694 }
1695
1696 return status;
1697 }
1698
1699 /**
1700 * @brief Disable PLLSAI1.
1701 * @retval HAL status
1702 */
HAL_RCCEx_DisablePLLSAI1(void)1703 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
1704 {
1705 HAL_StatusTypeDef status = HAL_OK;
1706 uint32_t tickstart;
1707
1708 /* Disable the PLLSAI1 */
1709 __HAL_RCC_PLLSAI1_DISABLE();
1710
1711 /* Get Start Tick*/
1712 tickstart = HAL_GetTick();
1713
1714 /* Wait till PLLSAI1 is ready */
1715 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1716 {
1717 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1718 {
1719 /* New check to avoid false timeout detection in case of preemption */
1720 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1721 {
1722 status = HAL_TIMEOUT;
1723 }
1724 break;
1725 }
1726 }
1727
1728 /* To save power disable the PLLSAI1 Source and Clock outputs */
1729 CLEAR_BIT(RCC->PLLSAI1CFGR,
1730 RCC_PLLSAI1CFGR_PLLSAI1PEN | RCC_PLLSAI1CFGR_PLLSAI1QEN | RCC_PLLSAI1CFGR_PLLSAI1REN | RCC_PLLSAI1CFGR_PLLSAI1SRC);
1731
1732 return status;
1733 }
1734
1735 /**
1736 * @brief Enable PLLSAI2.
1737 * @param PLLSAI2Init pointer to an RCC_PLLSAI2InitTypeDef structure that
1738 * contains the configuration information for the PLLSAI2
1739 * @retval HAL status
1740 */
HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef * PLLSAI2Init)1741 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef *PLLSAI2Init)
1742 {
1743 HAL_StatusTypeDef status = HAL_OK;
1744 uint32_t tickstart;
1745
1746 /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
1747 assert_param(IS_RCC_PLLSAI2SOURCE(PLLSAI2Init->PLLSAI2Source));
1748 assert_param(IS_RCC_PLLSAI2M_VALUE(PLLSAI2Init->PLLSAI2M));
1749 assert_param(IS_RCC_PLLSAI2N_VALUE(PLLSAI2Init->PLLSAI2N));
1750 assert_param(IS_RCC_PLLSAI2P_VALUE(PLLSAI2Init->PLLSAI2P));
1751 assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PLLSAI2Init->PLLSAI2ClockOut));
1752
1753 /* Disable the PLLSAI2 */
1754 __HAL_RCC_PLLSAI2_DISABLE();
1755
1756 /* Get Start Tick*/
1757 tickstart = HAL_GetTick();
1758
1759 /* Wait till PLLSAI2 is ready to be updated */
1760 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1761 {
1762 if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
1763 {
1764 /* New check to avoid false timeout detection in case of preemption */
1765 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1766 {
1767 status = HAL_TIMEOUT;
1768 }
1769 break;
1770 }
1771 }
1772
1773 if (status == HAL_OK)
1774 {
1775 /* Make sure PLLSAI2Source is ready */
1776 status = RCCEx_PLLSource_Enable(PLLSAI2Init->PLLSAI2Source);
1777
1778 if (status == HAL_OK)
1779 {
1780 /* Configure the PLLSAI2 clock source, multiplication factor N, */
1781 /* and division factors M and P */
1782 __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2Source, PLLSAI2Init->PLLSAI2M, PLLSAI2Init->PLLSAI2N,
1783 PLLSAI2Init->PLLSAI2P);
1784 /* Configure the PLLSAI2 Clock output(s) */
1785 __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut);
1786
1787 /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
1788 __HAL_RCC_PLLSAI2_ENABLE();
1789
1790 /* Get Start Tick*/
1791 tickstart = HAL_GetTick();
1792
1793 /* Wait till PLLSAI2 is ready */
1794 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
1795 {
1796 if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
1797 {
1798 /* New check to avoid false timeout detection in case of preemption */
1799 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
1800 {
1801 status = HAL_TIMEOUT;
1802 }
1803 break;
1804 }
1805 }
1806 }
1807 }
1808
1809 return status;
1810 }
1811
1812 /**
1813 * @brief Disable PLLISAI2.
1814 * @retval HAL status
1815 */
HAL_RCCEx_DisablePLLSAI2(void)1816 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI2(void)
1817 {
1818 HAL_StatusTypeDef status = HAL_OK;
1819 uint32_t tickstart;
1820
1821 /* Disable the PLLSAI2 */
1822 __HAL_RCC_PLLSAI2_DISABLE();
1823
1824 /* Get Start Tick*/
1825 tickstart = HAL_GetTick();
1826
1827 /* Wait till PLLSAI2 is ready */
1828 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1829 {
1830 if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
1831 {
1832 /* New check to avoid false timeout detection in case of preemption */
1833 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1834 {
1835 status = HAL_TIMEOUT;
1836 }
1837 break;
1838 }
1839 }
1840
1841 /* To save power disable the PLLSAI2 Source and Clock outputs */
1842 CLEAR_BIT(RCC->PLLSAI2CFGR,
1843 RCC_PLLSAI2CFGR_PLLSAI2PEN | RCC_PLLSAI2CFGR_PLLSAI2SRC);
1844
1845 return status;
1846 }
1847
1848 /**
1849 * @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
1850 * @param WakeUpClk Wakeup clock
1851 * This parameter can be one of the following values:
1852 * @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI oscillator selection
1853 * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection
1854 * @note This function shall not be called after the Clock Security System on HSE has been
1855 * enabled.
1856 * @retval None
1857 */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)1858 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
1859 {
1860 assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
1861
1862 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
1863 }
1864
1865 /**
1866 * @brief Configure the MSI range after standby mode.
1867 * @note After Standby its frequency can be selected between 4 possible values (1, 2, 4 or 8 MHz).
1868 * @param MSIRange MSI range
1869 * This parameter can be one of the following values:
1870 * @arg @ref RCC_MSIRANGE_4 Range 4 around 1 MHz
1871 * @arg @ref RCC_MSIRANGE_5 Range 5 around 2 MHz
1872 * @arg @ref RCC_MSIRANGE_6 Range 6 around 4 MHz (reset value)
1873 * @arg @ref RCC_MSIRANGE_7 Range 7 around 8 MHz
1874 * @retval None
1875 */
HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)1876 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
1877 {
1878 assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
1879
1880 __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
1881 }
1882
1883 /**
1884 * @brief Enable the Clock Security System on LSE.
1885 * @note Prior to enable the Clock Security System on LSE, LSE oscillator is to be enabled
1886 * with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
1887 * clock with HAL_RCCEx_PeriphCLKConfig().
1888 * @retval None
1889 */
HAL_RCCEx_EnableLSECSS(void)1890 void HAL_RCCEx_EnableLSECSS(void)
1891 {
1892 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON);
1893 }
1894
1895 /**
1896 * @brief Disable the Clock Security System on LSE.
1897 * @note LSE Clock Security System can only be disabled after a LSE failure detection.
1898 * @retval None
1899 */
HAL_RCCEx_DisableLSECSS(void)1900 void HAL_RCCEx_DisableLSECSS(void)
1901 {
1902 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON);
1903 }
1904
1905 /**
1906 * @brief Handle the RCC Clock Security System on LSE interrupt request.
1907 * @retval None
1908 */
HAL_RCCEx_LSECSS_IRQHandler(void)1909 void HAL_RCCEx_LSECSS_IRQHandler(void)
1910 {
1911 /* Check RCC LSECSSD flag */
1912 if (READ_BIT(RCC->BDCR, RCC_BDCR_LSECSSD) != 0U)
1913 {
1914 /* RCC LSE Clock Security System interrupt user callback */
1915 HAL_RCCEx_LSECSS_Callback();
1916 }
1917 }
1918
1919 /**
1920 * @brief RCCEx Clock Security System on LSE interrupt callback.
1921 * @retval none
1922 */
HAL_RCCEx_LSECSS_Callback(void)1923 __weak void HAL_RCCEx_LSECSS_Callback(void)
1924 {
1925 /* NOTE : This function should not be modified, when the callback is needed,
1926 the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
1927 */
1928 }
1929
1930 /**
1931 * @brief Select the Low Speed clock source to output on LSCO pin (PA2).
1932 * @param LSCOSource specifies the Low Speed clock source to output.
1933 * This parameter can be one of the following values:
1934 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
1935 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
1936 * @retval None
1937 */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1938 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1939 {
1940 GPIO_InitTypeDef GPIO_InitStruct;
1941 FlagStatus pwrclkchanged = RESET;
1942 FlagStatus backupchanged = RESET;
1943
1944 /* Check the parameters */
1945 assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1946
1947 /* LSCO Pin Clock Enable */
1948 __LSCO_CLK_ENABLE();
1949
1950 /* Configure the LSCO pin in analog mode */
1951 GPIO_InitStruct.Pin = LSCO_PIN;
1952 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
1953 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1954 GPIO_InitStruct.Pull = GPIO_NOPULL;
1955 HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
1956
1957 /* Update LSCOSEL clock source in Backup Domain control register */
1958 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1959 {
1960 __HAL_RCC_PWR_CLK_ENABLE();
1961 pwrclkchanged = SET;
1962 }
1963 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1964 {
1965 HAL_PWR_EnableBkUpAccess();
1966 backupchanged = SET;
1967 }
1968
1969 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
1970
1971 if (backupchanged == SET)
1972 {
1973 HAL_PWR_DisableBkUpAccess();
1974 }
1975 if (pwrclkchanged == SET)
1976 {
1977 __HAL_RCC_PWR_CLK_DISABLE();
1978 }
1979 }
1980
1981 /**
1982 * @brief Disable the Low Speed clock output.
1983 * @retval None
1984 */
HAL_RCCEx_DisableLSCO(void)1985 void HAL_RCCEx_DisableLSCO(void)
1986 {
1987 FlagStatus pwrclkchanged = RESET;
1988 FlagStatus backupchanged = RESET;
1989
1990 /* Update LSCOEN bit in Backup Domain control register */
1991 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1992 {
1993 __HAL_RCC_PWR_CLK_ENABLE();
1994 pwrclkchanged = SET;
1995 }
1996 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1997 {
1998 /* Enable access to the backup domain */
1999 HAL_PWR_EnableBkUpAccess();
2000 backupchanged = SET;
2001 }
2002
2003 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
2004
2005 /* Restore previous configuration */
2006 if (backupchanged == SET)
2007 {
2008 /* Disable access to the backup domain */
2009 HAL_PWR_DisableBkUpAccess();
2010 }
2011 if (pwrclkchanged == SET)
2012 {
2013 __HAL_RCC_PWR_CLK_DISABLE();
2014 }
2015 }
2016
2017 /**
2018 * @brief Enable the PLL-mode of the MSI.
2019 * @note Prior to enable the PLL-mode of the MSI for automatic hardware
2020 * calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
2021 * @retval None
2022 */
HAL_RCCEx_EnableMSIPLLMode(void)2023 void HAL_RCCEx_EnableMSIPLLMode(void)
2024 {
2025 SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
2026 }
2027
2028 /**
2029 * @brief Disable the PLL-mode of the MSI.
2030 * @note PLL-mode of the MSI is automatically reset when LSE oscillator is disabled
2031 * of after a LSE failure.
2032 * @retval None
2033 */
HAL_RCCEx_DisableMSIPLLMode(void)2034 void HAL_RCCEx_DisableMSIPLLMode(void)
2035 {
2036 CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
2037 }
2038
2039 /**
2040 * @}
2041 */
2042
2043 #if defined(CRS)
2044
2045 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
2046 * @brief Extended Clock Recovery System Control functions
2047 *
2048 @verbatim
2049 ===============================================================================
2050 ##### Extended Clock Recovery System Control functions #####
2051 ===============================================================================
2052 [..]
2053 For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
2054
2055 (#) In System clock config, HSI48 needs to be enabled
2056
2057 (#) Enable CRS clock
2058
2059 (#) Call CRS functions as follows:
2060 (##) Prepare synchronization configuration necessary for HSI48 calibration
2061 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
2062 and also HSI48 oscillator smooth trimming.
2063 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
2064 directly reload value with target and synchronization frequencies values
2065 (##) Call function HAL_RCCEx_CRSConfig which
2066 (+++) Resets CRS registers to their default values.
2067 (+++) Configures CRS registers with synchronization configuration
2068 (+++) Enables automatic calibration and frequency error counter feature
2069 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
2070 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
2071 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
2072 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
2073 should be used as SYNC signal.
2074
2075 (##) A polling function is provided to wait for complete synchronization
2076 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
2077 (+++) According to CRS status, user can decide to adjust again the calibration or continue
2078 application if synchronization is OK
2079
2080 (#) User can retrieve information related to synchronization in calling function
2081 HAL_RCCEx_CRSGetSynchronizationInfo()
2082
2083 (#) Regarding synchronization status and synchronization information, user can try a new calibration
2084 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
2085 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
2086 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
2087 incremented), while when it is detected during the upcounting phase it means that the actual frequency
2088 is higher (and that the TRIM value should be decremented).
2089
2090 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
2091 through CRS Handler (CRS_IRQn/CRS_IRQHandler)
2092 (++) Call function HAL_RCCEx_CRSConfig()
2093 (++) Enable CRS_IRQn (thanks to NVIC functions)
2094 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
2095 (++) Implement CRS status management in the following user callbacks called from
2096 HAL_RCCEx_CRS_IRQHandler():
2097 (+++) HAL_RCCEx_CRS_SyncOkCallback()
2098 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
2099 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
2100 (+++) HAL_RCCEx_CRS_ErrorCallback()
2101
2102 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
2103 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
2104
2105 @endverbatim
2106 * @{
2107 */
2108
2109 /**
2110 * @brief Start automatic synchronization for polling mode.
2111 * @param pInit Pointer on RCC_CRSInitTypeDef structure
2112 * @retval None
2113 */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)2114 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
2115 {
2116 uint32_t value;
2117
2118 /* Check the parameters */
2119 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
2120 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
2121 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
2122 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
2123 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
2124 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
2125
2126 /* CONFIGURATION */
2127
2128 /* Before configuration, reset CRS registers to their default values*/
2129 __HAL_RCC_CRS_FORCE_RESET();
2130 __HAL_RCC_CRS_RELEASE_RESET();
2131
2132 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
2133 /* Set the SYNCSRC[1:0] bits according to Source value */
2134 /* Set the SYNCSPOL bit according to Polarity value */
2135 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
2136 /* Set the RELOAD[15:0] bits according to ReloadValue value */
2137 value |= pInit->ReloadValue;
2138 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
2139 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
2140 WRITE_REG(CRS->CFGR, value);
2141
2142 /* Adjust HSI48 oscillator smooth trimming */
2143 /* Set the TRIM[6:0] bits according to RCC_CRS_HSI48CalibrationValue value */
2144 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
2145
2146 /* START AUTOMATIC SYNCHRONIZATION*/
2147
2148 /* Enable Automatic trimming & Frequency error counter */
2149 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
2150 }
2151
2152 /**
2153 * @brief Generate the software synchronization event.
2154 * @retval None
2155 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)2156 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
2157 {
2158 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
2159 }
2160
2161 /**
2162 * @brief Return synchronization info.
2163 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
2164 * @retval None
2165 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)2166 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
2167 {
2168 /* Check the parameter */
2169 assert_param(pSynchroInfo != (void *)NULL);
2170
2171 /* Get the reload value */
2172 pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
2173
2174 /* Get HSI48 oscillator smooth trimming */
2175 pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
2176
2177 /* Get Frequency error capture */
2178 pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
2179
2180 /* Get Frequency error direction */
2181 pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
2182 }
2183
2184 /**
2185 * @brief Wait for CRS Synchronization status.
2186 * @param Timeout Duration of the timeout
2187 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
2188 * frequency.
2189 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
2190 * @retval Combination of Synchronization status
2191 * This parameter can be a combination of the following values:
2192 * @arg @ref RCC_CRS_TIMEOUT
2193 * @arg @ref RCC_CRS_SYNCOK
2194 * @arg @ref RCC_CRS_SYNCWARN
2195 * @arg @ref RCC_CRS_SYNCERR
2196 * @arg @ref RCC_CRS_SYNCMISS
2197 * @arg @ref RCC_CRS_TRIMOVF
2198 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)2199 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
2200 {
2201 uint32_t crsstatus = RCC_CRS_NONE;
2202 uint32_t tickstart;
2203 HAL_StatusTypeDef status = HAL_OK;
2204
2205 /* Get timeout */
2206 tickstart = HAL_GetTick();
2207
2208 /* Wait for CRS flag or timeout detection */
2209 do
2210 {
2211 if (Timeout != HAL_MAX_DELAY)
2212 {
2213 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2214 {
2215 status = HAL_TIMEOUT;
2216 }
2217 }
2218 /* Check CRS SYNCOK flag */
2219 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
2220 {
2221 /* CRS SYNC event OK */
2222 crsstatus |= RCC_CRS_SYNCOK;
2223
2224 /* Clear CRS SYNC event OK bit */
2225 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
2226 }
2227
2228 /* Check CRS SYNCWARN flag */
2229 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
2230 {
2231 /* CRS SYNC warning */
2232 crsstatus |= RCC_CRS_SYNCWARN;
2233
2234 /* Clear CRS SYNCWARN bit */
2235 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
2236 }
2237
2238 /* Check CRS TRIM overflow flag */
2239 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
2240 {
2241 /* CRS SYNC Error */
2242 crsstatus |= RCC_CRS_TRIMOVF;
2243
2244 /* Clear CRS Error bit */
2245 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
2246 }
2247
2248 /* Check CRS Error flag */
2249 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
2250 {
2251 /* CRS SYNC Error */
2252 crsstatus |= RCC_CRS_SYNCERR;
2253
2254 /* Clear CRS Error bit */
2255 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
2256 }
2257
2258 /* Check CRS SYNC Missed flag */
2259 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
2260 {
2261 /* CRS SYNC Missed */
2262 crsstatus |= RCC_CRS_SYNCMISS;
2263
2264 /* Clear CRS SYNC Missed bit */
2265 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
2266 }
2267
2268 /* Check CRS Expected SYNC flag */
2269 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
2270 {
2271 /* frequency error counter reached a zero value */
2272 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
2273 }
2274 } while ((crsstatus == RCC_CRS_NONE) && (status == HAL_OK));
2275
2276 if (crsstatus == RCC_CRS_NONE)
2277 {
2278 crsstatus = RCC_CRS_TIMEOUT;
2279 }
2280
2281 return crsstatus;
2282 }
2283
2284 /**
2285 * @brief Handle the Clock Recovery System interrupt request.
2286 * @retval None
2287 */
HAL_RCCEx_CRS_IRQHandler(void)2288 void HAL_RCCEx_CRS_IRQHandler(void)
2289 {
2290 uint32_t crserror = RCC_CRS_NONE;
2291 /* Get current IT flags and IT sources values */
2292 uint32_t itflags = READ_REG(CRS->ISR);
2293 uint32_t itsources = READ_REG(CRS->CR);
2294
2295 /* Check CRS SYNCOK flag */
2296 if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
2297 {
2298 /* Clear CRS SYNC event OK flag */
2299 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
2300
2301 /* user callback */
2302 HAL_RCCEx_CRS_SyncOkCallback();
2303 }
2304 /* Check CRS SYNCWARN flag */
2305 else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
2306 {
2307 /* Clear CRS SYNCWARN flag */
2308 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
2309
2310 /* user callback */
2311 HAL_RCCEx_CRS_SyncWarnCallback();
2312 }
2313 /* Check CRS Expected SYNC flag */
2314 else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
2315 {
2316 /* frequency error counter reached a zero value */
2317 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
2318
2319 /* user callback */
2320 HAL_RCCEx_CRS_ExpectedSyncCallback();
2321 }
2322 /* Check CRS Error flags */
2323 else
2324 {
2325 if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
2326 {
2327 if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
2328 {
2329 crserror |= RCC_CRS_SYNCERR;
2330 }
2331 if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
2332 {
2333 crserror |= RCC_CRS_SYNCMISS;
2334 }
2335 if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
2336 {
2337 crserror |= RCC_CRS_TRIMOVF;
2338 }
2339
2340 /* Clear CRS Error flags */
2341 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
2342
2343 /* user error callback */
2344 HAL_RCCEx_CRS_ErrorCallback(crserror);
2345 }
2346 }
2347 }
2348
2349 /**
2350 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
2351 * @retval none
2352 */
HAL_RCCEx_CRS_SyncOkCallback(void)2353 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
2354 {
2355 /* NOTE : This function should not be modified, when the callback is needed,
2356 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
2357 */
2358 }
2359
2360 /**
2361 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
2362 * @retval none
2363 */
HAL_RCCEx_CRS_SyncWarnCallback(void)2364 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
2365 {
2366 /* NOTE : This function should not be modified, when the callback is needed,
2367 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
2368 */
2369 }
2370
2371 /**
2372 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
2373 * @retval none
2374 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)2375 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
2376 {
2377 /* NOTE : This function should not be modified, when the callback is needed,
2378 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
2379 */
2380 }
2381
2382 /**
2383 * @brief RCCEx Clock Recovery System Error interrupt callback.
2384 * @param Error Combination of Error status.
2385 * This parameter can be a combination of the following values:
2386 * @arg @ref RCC_CRS_SYNCERR
2387 * @arg @ref RCC_CRS_SYNCMISS
2388 * @arg @ref RCC_CRS_TRIMOVF
2389 * @retval none
2390 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)2391 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
2392 {
2393 /* Prevent unused argument(s) compilation warning */
2394 UNUSED(Error);
2395
2396 /* NOTE : This function should not be modified, when the callback is needed,
2397 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
2398 */
2399 }
2400
2401 /**
2402 * @}
2403 */
2404
2405 #endif /* CRS */
2406
2407 /**
2408 * @}
2409 */
2410
2411 /** @addtogroup RCCEx_Private_Functions
2412 * @{
2413 */
2414
RCCEx_PLLSource_Enable(uint32_t PllSource)2415 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource)
2416 {
2417 HAL_StatusTypeDef status = HAL_OK;
2418 uint32_t tickstart;
2419
2420 switch (PllSource)
2421 {
2422 case RCC_PLLSOURCE_MSI:
2423 /* Check whether MSI in not ready and enable it */
2424 if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
2425 {
2426 /* Enable the Internal Multi Speed oscillator (MSI). */
2427 __HAL_RCC_MSI_ENABLE();
2428
2429 /* Get timeout */
2430 tickstart = HAL_GetTick();
2431
2432 /* Wait till MSI is ready */
2433 while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
2434 {
2435 if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
2436 {
2437 /* New check to avoid false timeout detection in case of preemption */
2438 if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
2439 {
2440 status = HAL_TIMEOUT;
2441 }
2442 break;
2443 }
2444 }
2445 }
2446 break;
2447
2448 case RCC_PLLSOURCE_HSI:
2449 /* Check whether HSI in not ready and enable it */
2450 if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
2451 {
2452 /* Enable the Internal High Speed oscillator (HSI). */
2453 __HAL_RCC_HSI_ENABLE();
2454
2455 /* Get timeout */
2456 tickstart = HAL_GetTick();
2457
2458 /* Wait till MSI is ready */
2459 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
2460 {
2461 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
2462 {
2463 /* New check to avoid false timeout detection in case of preemption */
2464 if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
2465 {
2466 status = HAL_TIMEOUT;
2467 }
2468 break;
2469 }
2470 }
2471 }
2472 break;
2473
2474 case RCC_PLLSOURCE_HSE:
2475 /* Check whether HSE in not ready and enable it */
2476 if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
2477 {
2478 /* Enable the External High Speed oscillator (HSE). */
2479 SET_BIT(RCC->CR, RCC_CR_HSEON);
2480
2481 /* Get Start Tick*/
2482 tickstart = HAL_GetTick();
2483
2484 /* Wait till HSE is ready */
2485 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
2486 {
2487 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
2488 {
2489 /* New check to avoid false timeout detection in case of preemption */
2490 if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
2491 {
2492 status = HAL_TIMEOUT;
2493 }
2494 break;
2495 }
2496 }
2497 }
2498 break;
2499
2500 case RCC_PLLSOURCE_NONE:
2501 /* Nothing to do */
2502 break;
2503
2504 default:
2505 status = HAL_ERROR;
2506 break;
2507 }
2508
2509 return status;
2510 }
2511
2512 /**
2513 * @brief Configure the parameters N & P & optionally M of PLLSAI1 and enable PLLSAI1 output clock(s).
2514 * @param pPllSai1 pointer to an RCC_PLLSAI1InitTypeDef structure that
2515 * contains the configuration parameters N & P & optionally M as well as PLLSAI1 output clock(s)
2516 * @param Divider divider parameter to be updated
2517 *
2518 * @note PLLSAI1 is temporary disable to apply new parameters
2519 *
2520 * @retval HAL status
2521 */
RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef * pPllSai1,uint32_t Divider)2522 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *pPllSai1, uint32_t Divider)
2523 {
2524 HAL_StatusTypeDef status = HAL_OK;
2525 uint32_t tickstart;
2526
2527 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
2528 /* P, Q and R dividers are verified in each specific divider case below */
2529 assert_param(IS_RCC_PLLSAI1SOURCE(pPllSai1->PLLSAI1Source));
2530 assert_param(IS_RCC_PLLSAI1M_VALUE(pPllSai1->PLLSAI1M));
2531 assert_param(IS_RCC_PLLSAI1N_VALUE(pPllSai1->PLLSAI1N));
2532 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(pPllSai1->PLLSAI1ClockOut));
2533
2534 /* Check PLLSAI1 clock source availability */
2535 switch (pPllSai1->PLLSAI1Source)
2536 {
2537 case RCC_PLLSOURCE_MSI:
2538 if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
2539 {
2540 status = HAL_ERROR;
2541 }
2542 break;
2543 case RCC_PLLSOURCE_HSI:
2544 if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
2545 {
2546 status = HAL_ERROR;
2547 }
2548 break;
2549 case RCC_PLLSOURCE_HSE:
2550 if (HAL_IS_BIT_CLR(RCC->CR, (RCC_CR_HSERDY | RCC_CR_HSEBYP)))
2551 {
2552 status = HAL_ERROR;
2553 }
2554 break;
2555 default:
2556 status = HAL_ERROR;
2557 break;
2558 }
2559
2560 if (status == HAL_OK)
2561 {
2562 /* Disable the PLLSAI1 */
2563 __HAL_RCC_PLLSAI1_DISABLE();
2564
2565 /* Get Start Tick*/
2566 tickstart = HAL_GetTick();
2567
2568 /* Wait till PLLSAI1 is ready to be updated */
2569 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
2570 {
2571 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2572 {
2573 /* New check to avoid false timeout detection in case of preemption */
2574 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
2575 {
2576 status = HAL_TIMEOUT;
2577 }
2578 break;
2579 }
2580 }
2581
2582 if (status == HAL_OK)
2583 {
2584 if (Divider == DIVIDER_P_UPDATE)
2585 {
2586 assert_param(IS_RCC_PLLSAI1P_VALUE(pPllSai1->PLLSAI1P));
2587
2588 /* Configure the PLLSAI1 Division factor M, P and Multiplication factor N*/
2589 MODIFY_REG(RCC->PLLSAI1CFGR,
2590 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV | RCC_PLLSAI1CFGR_PLLSAI1M | RCC_PLLSAI1CFGR_PLLSAI1SRC,
2591 (pPllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
2592 (pPllSai1->PLLSAI1P << RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos) |
2593 ((pPllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos) |
2594 pPllSai1->PLLSAI1Source);
2595 }
2596 else if (Divider == DIVIDER_Q_UPDATE)
2597 {
2598 assert_param(IS_RCC_PLLSAI1Q_VALUE(pPllSai1->PLLSAI1Q));
2599
2600 /* Configure the PLLSAI1 Division factor M, Q and Multiplication factor N*/
2601 MODIFY_REG(RCC->PLLSAI1CFGR,
2602 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q | RCC_PLLSAI1CFGR_PLLSAI1M | RCC_PLLSAI1CFGR_PLLSAI1SRC,
2603 (pPllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
2604 (((pPllSai1->PLLSAI1Q >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) |
2605 ((pPllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos) |
2606 pPllSai1->PLLSAI1Source);
2607 }
2608 else
2609 {
2610 assert_param(IS_RCC_PLLSAI1R_VALUE(pPllSai1->PLLSAI1R));
2611
2612 /* Configure the PLLSAI1 Division factor M, R and Multiplication factor N*/
2613 MODIFY_REG(RCC->PLLSAI1CFGR,
2614 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R | RCC_PLLSAI1CFGR_PLLSAI1M | RCC_PLLSAI1CFGR_PLLSAI1SRC,
2615 (pPllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
2616 (((pPllSai1->PLLSAI1R >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1R_Pos) |
2617 ((pPllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos) |
2618 pPllSai1->PLLSAI1Source);
2619 }
2620
2621 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
2622 __HAL_RCC_PLLSAI1_ENABLE();
2623
2624 /* Get Start Tick*/
2625 tickstart = HAL_GetTick();
2626
2627 /* Wait till PLLSAI1 is ready */
2628 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
2629 {
2630 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2631 {
2632 /* New check to avoid false timeout detection in case of preemption */
2633 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
2634 {
2635 status = HAL_TIMEOUT;
2636 }
2637 break;
2638 }
2639 }
2640
2641 if (status == HAL_OK)
2642 {
2643 /* Configure the PLLSAI1 Clock output(s) */
2644 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(pPllSai1->PLLSAI1ClockOut);
2645 }
2646 }
2647 }
2648
2649 return status;
2650 }
2651
2652 /**
2653 * @brief Configure the parameters N & P & optionally M of PLLSAI2 and enable PLLSAI2 output clock(s).
2654 * @param pPllSai2 pointer to an RCC_PLLSAI2InitTypeDef structure that
2655 * contains the configuration parameters N & P & optionally M as well as PLLSAI2 output clock(s)
2656 * @param Divider divider parameter to be updated
2657 *
2658 * @note PLLSAI2 is temporary disable to apply new parameters
2659 *
2660 * @retval HAL status
2661 */
RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef * pPllSai2,uint32_t Divider)2662 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *pPllSai2, uint32_t Divider)
2663 {
2664 HAL_StatusTypeDef status = HAL_OK;
2665 uint32_t tickstart;
2666
2667 /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
2668 /* P, Q and R dividers are verified in each specific divider case below */
2669 assert_param(IS_RCC_PLLSAI2SOURCE(pPllSai2->PLLSAI2Source));
2670 assert_param(IS_RCC_PLLSAI2M_VALUE(pPllSai2->PLLSAI2M));
2671 assert_param(IS_RCC_PLLSAI2N_VALUE(pPllSai2->PLLSAI2N));
2672 assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(pPllSai2->PLLSAI2ClockOut));
2673
2674 /* Check PLLSAI2 clock source availability */
2675 switch (pPllSai2->PLLSAI2Source)
2676 {
2677 case RCC_PLLSOURCE_MSI:
2678 if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
2679 {
2680 status = HAL_ERROR;
2681 }
2682 break;
2683 case RCC_PLLSOURCE_HSI:
2684 if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
2685 {
2686 status = HAL_ERROR;
2687 }
2688 break;
2689 case RCC_PLLSOURCE_HSE:
2690 if (HAL_IS_BIT_CLR(RCC->CR, (RCC_CR_HSERDY | RCC_CR_HSEBYP)))
2691 {
2692 status = HAL_ERROR;
2693 }
2694 break;
2695 default:
2696 status = HAL_ERROR;
2697 break;
2698 }
2699
2700 if (status == HAL_OK)
2701 {
2702 /* Disable the PLLSAI2 */
2703 __HAL_RCC_PLLSAI2_DISABLE();
2704
2705 /* Get Start Tick*/
2706 tickstart = HAL_GetTick();
2707
2708 /* Wait till PLLSAI2 is ready to be updated */
2709 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
2710 {
2711 if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
2712 {
2713 /* New check to avoid false timeout detection in case of preemption */
2714 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
2715 {
2716 status = HAL_TIMEOUT;
2717 }
2718 break;
2719 }
2720 }
2721
2722 if (status == HAL_OK)
2723 {
2724 if (Divider == DIVIDER_P_UPDATE)
2725 {
2726 assert_param(IS_RCC_PLLSAI2P_VALUE(pPllSai2->PLLSAI2P));
2727
2728 /* Configure the PLLSAI2 Division factor M, P and Multiplication factor N*/
2729 MODIFY_REG(RCC->PLLSAI2CFGR,
2730 RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2PDIV | RCC_PLLSAI2CFGR_PLLSAI2M | RCC_PLLSAI2CFGR_PLLSAI2SRC,
2731 (pPllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
2732 (pPllSai2->PLLSAI2P << RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos) |
2733 ((pPllSai2->PLLSAI2M - 1U) << RCC_PLLSAI2CFGR_PLLSAI2M_Pos) |
2734 pPllSai2->PLLSAI2Source);
2735
2736 }
2737
2738 /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
2739 __HAL_RCC_PLLSAI2_ENABLE();
2740
2741 /* Get Start Tick*/
2742 tickstart = HAL_GetTick();
2743
2744 /* Wait till PLLSAI2 is ready */
2745 while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
2746 {
2747 if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
2748 {
2749 /* New check to avoid false timeout detection in case of preemption */
2750 if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
2751 {
2752 status = HAL_TIMEOUT;
2753 }
2754 break;
2755 }
2756 }
2757
2758 if (status == HAL_OK)
2759 {
2760 /* Configure the PLLSAI2 Clock output(s) */
2761 __HAL_RCC_PLLSAI2CLKOUT_ENABLE(pPllSai2->PLLSAI2ClockOut);
2762 }
2763 }
2764 }
2765
2766 return status;
2767 }
2768
2769 /**
2770 * @brief Get the PLLSAI1 input VCO frequency.
2771 * @retval pllvco frequency in Hz
2772 */
RCCEx_PLLSAI1_GetVCOFreq(void)2773 static uint32_t RCCEx_PLLSAI1_GetVCOFreq(void)
2774 {
2775 uint32_t pllvco = 0U;
2776
2777 switch (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1SRC))
2778 {
2779 case PLLSAI1CFGR_PLLSAI1SRC_MSI:
2780 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
2781 {
2782 /*MSI frequency range in HZ*/
2783 pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
2784 }
2785 else
2786 {
2787 /* pllvco already set as 0 */
2788 }
2789 break;
2790 case PLLSAI1CFGR_PLLSAI1SRC_HSI:
2791 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
2792 {
2793 pllvco = HSI_VALUE;
2794 }
2795 else
2796 {
2797 /* pllvco already set as 0 */
2798 }
2799 break;
2800 case PLLSAI1CFGR_PLLSAI1SRC_HSE:
2801 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
2802 {
2803 pllvco = HSE_VALUE;
2804 }
2805 else
2806 {
2807 /* pllvco already set as 0 */
2808 }
2809 break;
2810 default:
2811 /* pllvco already set as 0 */
2812 break;
2813 }
2814
2815 return pllvco;
2816 }
2817
2818 /**
2819 * @brief Get the PLLSAI2 input VCO frequency.
2820 * @retval pllvco frequency in Hz
2821 */
RCCEx_PLLSAI2_GetVCOFreq(void)2822 static uint32_t RCCEx_PLLSAI2_GetVCOFreq(void)
2823 {
2824 uint32_t pllvco = 0U;
2825
2826 switch (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2SRC))
2827 {
2828 case PLLSAI2CFGR_PLLSAI2SRC_MSI:
2829 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
2830 {
2831 /*MSI frequency range in HZ*/
2832 pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
2833 }
2834 else
2835 {
2836 /* pllvco already set as 0 */
2837 }
2838 break;
2839 case PLLSAI2CFGR_PLLSAI2SRC_HSI:
2840 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
2841 {
2842 pllvco = HSI_VALUE;
2843 }
2844 else
2845 {
2846 /* pllvco already set as 0 */
2847 }
2848 break;
2849 case PLLSAI2CFGR_PLLSAI2SRC_HSE:
2850 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
2851 {
2852 pllvco = HSE_VALUE;
2853 }
2854 else
2855 {
2856 /* pllvco already set as 0 */
2857 }
2858 break;
2859 default:
2860 /* pllvco already set as 0 */
2861 break;
2862 }
2863
2864 return pllvco;
2865 }
2866
2867 /**
2868 * @brief Get the frequency applied to SAIx peripheral.
2869 * @param PeriphClk Peripheral clock identifier
2870 * This parameter can be one of the following values:
2871 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
2872 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock
2873 * @param InputFrequency pllvco frequency in Hz
2874 * @retval Frequency in Hz
2875 */
RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk,uint32_t InputFrequency)2876 static uint32_t RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk, uint32_t InputFrequency)
2877 {
2878 uint32_t frequency = 0U;
2879 uint32_t srcclk, pllvco, plln, pllp; /* no init needed */
2880
2881 if (PeriphClk == RCC_PERIPHCLK_SAI1)
2882 {
2883 srcclk = __HAL_RCC_GET_SAI1_SOURCE();
2884
2885 if (srcclk == RCC_SAI1CLKSOURCE_PIN)
2886 {
2887 frequency = EXTERNAL_SAI1_CLOCK_VALUE;
2888 }
2889 /* Else, PLL clock output to check below */
2890 }
2891 else /* RCC_PERIPHCLK_SAI2 */
2892 {
2893 srcclk = __HAL_RCC_GET_SAI2_SOURCE();
2894
2895 if (srcclk == RCC_SAI2CLKSOURCE_PIN)
2896 {
2897 frequency = EXTERNAL_SAI2_CLOCK_VALUE;
2898 }
2899 /* Else, PLL clock output to check below */
2900 }
2901
2902 if (frequency == 0U)
2903 {
2904 pllvco = InputFrequency;
2905
2906 if ((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL))
2907 {
2908 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
2909 {
2910 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != 0U)
2911 {
2912 /* f(PLL Source) / PLLM */
2913 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
2914 /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
2915 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
2916 pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
2917 if (pllp == 0U)
2918 {
2919 if (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
2920 {
2921 pllp = 17U;
2922 }
2923 else
2924 {
2925 pllp = 7U;
2926 }
2927 }
2928 frequency = (pllvco * plln) / pllp;
2929 }
2930 }
2931 }
2932 else if ((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI))
2933 {
2934 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
2935 {
2936 frequency = HSI_VALUE;
2937 }
2938 }
2939 else if (srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */
2940 {
2941 if (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U)
2942 {
2943 /* Get f(PLLSAI1 source) */
2944 pllvco = RCCEx_PLLSAI1_GetVCOFreq();
2945 /* f(PLLSAI1 Source) / PLLSAI1M */
2946 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
2947 /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
2948 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
2949 pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos;
2950 if (pllp == 0U)
2951 {
2952 if (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U)
2953 {
2954 pllp = 17U;
2955 }
2956 else
2957 {
2958 pllp = 7U;
2959 }
2960 }
2961 frequency = (pllvco * plln) / pllp;
2962 }
2963 }
2964 else if ((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2))
2965 {
2966 if (__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != 0U)
2967 {
2968 /* Get f(PLLSAI2 source) */
2969 pllvco = RCCEx_PLLSAI2_GetVCOFreq();
2970 /* f(PLLSAI2 Source) / PLLSAI2M */
2971 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U));
2972 /* f(PLLSAI2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2P */
2973 plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos;
2974 pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos;
2975 if (pllp == 0U)
2976 {
2977 if (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != 0U)
2978 {
2979 pllp = 17U;
2980 }
2981 else
2982 {
2983 pllp = 7U;
2984 }
2985 }
2986 frequency = (pllvco * plln) / pllp;
2987 }
2988 }
2989 else
2990 {
2991 /* No clock source, frequency default init at 0 */
2992 }
2993 }
2994
2995 return frequency;
2996 }
2997
2998 /**
2999 * @}
3000 */
3001
3002 #endif /* HAL_RCC_MODULE_ENABLED */
3003
3004 /**
3005 * @}
3006 */
3007
3008 /**
3009 * @}
3010 */
3011
3012
3013