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