1 /**
2 ******************************************************************************
3 * @file stm32f1xx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extended RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extension peripheral:
8 * + Extended Peripheral Control functions
9 *
10 ******************************************************************************
11 * @attention
12 *
13 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
14 * All rights reserved.</center></h2>
15 *
16 * This software component is licensed by ST under BSD 3-Clause license,
17 * the "License"; You may not use this file except in compliance with the
18 * License. You may obtain a copy of the License at:
19 * opensource.org/licenses/BSD-3-Clause
20 *
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32f1xx_hal.h"
26
27 /** @addtogroup STM32F1xx_HAL_Driver
28 * @{
29 */
30
31 #ifdef HAL_RCC_MODULE_ENABLED
32
33 /** @defgroup RCCEx RCCEx
34 * @brief RCC Extension HAL module driver.
35 * @{
36 */
37
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private define ------------------------------------------------------------*/
40 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
41 * @{
42 */
43 /**
44 * @}
45 */
46
47 /* Private macro -------------------------------------------------------------*/
48 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
49 * @{
50 */
51 /**
52 * @}
53 */
54
55 /* Private variables ---------------------------------------------------------*/
56 /* Private function prototypes -----------------------------------------------*/
57 /* Private functions ---------------------------------------------------------*/
58
59 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
60 * @{
61 */
62
63 /** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
64 * @brief Extended Peripheral Control functions
65 *
66 @verbatim
67 ===============================================================================
68 ##### Extended Peripheral Control functions #####
69 ===============================================================================
70 [..]
71 This subsection provides a set of functions allowing to control the RCC Clocks
72 frequencies.
73 [..]
74 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
75 select the RTC clock source; in this case the Backup domain will be reset in
76 order to modify the RTC Clock source, as consequence RTC registers (including
77 the backup registers) are set to their reset values.
78
79 @endverbatim
80 * @{
81 */
82
83 /**
84 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
85 * RCC_PeriphCLKInitTypeDef.
86 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
87 * contains the configuration information for the Extended Peripherals clocks(RTC clock).
88 *
89 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
90 * the RTC clock source; in this case the Backup domain will be reset in
91 * order to modify the RTC Clock source, as consequence RTC registers (including
92 * the backup registers) are set to their reset values.
93 *
94 * @note In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
95 * one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
96 * manually disable it.
97 *
98 * @retval HAL status
99 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)100 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
101 {
102 uint32_t tickstart = 0U, temp_reg = 0U;
103 #if defined(STM32F105xC) || defined(STM32F107xC)
104 uint32_t pllactive = 0U;
105 #endif /* STM32F105xC || STM32F107xC */
106
107 /* Check the parameters */
108 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
109
110 /*------------------------------- RTC/LCD Configuration ------------------------*/
111 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
112 {
113 FlagStatus pwrclkchanged = RESET;
114
115 /* check for RTC Parameters used to output RTCCLK */
116 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
117
118 /* As soon as function is called to change RTC clock source, activation of the
119 power domain is done. */
120 /* Requires to enable write access to Backup Domain of necessary */
121 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
122 {
123 __HAL_RCC_PWR_CLK_ENABLE();
124 pwrclkchanged = SET;
125 }
126
127 if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
128 {
129 /* Enable write access to Backup domain */
130 SET_BIT(PWR->CR, PWR_CR_DBP);
131
132 /* Wait for Backup domain Write protection disable */
133 tickstart = HAL_GetTick();
134
135 while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
136 {
137 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
138 {
139 return HAL_TIMEOUT;
140 }
141 }
142 }
143
144 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
145 temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
146 if ((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
147 {
148 /* Store the content of BDCR register before the reset of Backup Domain */
149 temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
150 /* RTC Clock selection can be changed only if the Backup Domain is reset */
151 __HAL_RCC_BACKUPRESET_FORCE();
152 __HAL_RCC_BACKUPRESET_RELEASE();
153 /* Restore the Content of BDCR register */
154 RCC->BDCR = temp_reg;
155
156 /* Wait for LSERDY if LSE was enabled */
157 if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
158 {
159 /* Get Start Tick */
160 tickstart = HAL_GetTick();
161
162 /* Wait till LSE is ready */
163 while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
164 {
165 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
166 {
167 return HAL_TIMEOUT;
168 }
169 }
170 }
171 }
172 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
173
174 /* Require to disable power clock if necessary */
175 if (pwrclkchanged == SET)
176 {
177 __HAL_RCC_PWR_CLK_DISABLE();
178 }
179 }
180
181 /*------------------------------ ADC clock Configuration ------------------*/
182 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
183 {
184 /* Check the parameters */
185 assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
186
187 /* Configure the ADC clock source */
188 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
189 }
190
191 #if defined(STM32F105xC) || defined(STM32F107xC)
192 /*------------------------------ I2S2 Configuration ------------------------*/
193 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
194 {
195 /* Check the parameters */
196 assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
197
198 /* Configure the I2S2 clock source */
199 __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
200 }
201
202 /*------------------------------ I2S3 Configuration ------------------------*/
203 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
204 {
205 /* Check the parameters */
206 assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
207
208 /* Configure the I2S3 clock source */
209 __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
210 }
211
212 /*------------------------------ PLL I2S Configuration ----------------------*/
213 /* Check that PLLI2S need to be enabled */
214 if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
215 {
216 /* Update flag to indicate that PLL I2S should be active */
217 pllactive = 1;
218 }
219
220 /* Check if PLL I2S need to be enabled */
221 if (pllactive == 1)
222 {
223 /* Enable PLL I2S only if not active */
224 if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON))
225 {
226 /* Check the parameters */
227 assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL));
228 assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value));
229
230 /* Prediv2 can be written only when the PLL2 is disabled. */
231 /* Return an error only if new value is different from the programmed value */
232 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \
233 (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
234 {
235 return HAL_ERROR;
236 }
237
238 /* Configure the HSE prediv2 factor --------------------------------*/
239 __HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value);
240
241 /* Configure the main PLLI2S multiplication factors. */
242 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL);
243
244 /* Enable the main PLLI2S. */
245 __HAL_RCC_PLLI2S_ENABLE();
246
247 /* Get Start Tick*/
248 tickstart = HAL_GetTick();
249
250 /* Wait till PLLI2S is ready */
251 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
252 {
253 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
254 {
255 return HAL_TIMEOUT;
256 }
257 }
258 }
259 else
260 {
261 /* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */
262 if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL)
263 {
264 return HAL_ERROR;
265 }
266 }
267 }
268 #endif /* STM32F105xC || STM32F107xC */
269
270 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
271 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
272 || defined(STM32F105xC) || defined(STM32F107xC)
273 /*------------------------------ USB clock Configuration ------------------*/
274 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
275 {
276 /* Check the parameters */
277 assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
278
279 /* Configure the USB clock source */
280 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
281 }
282 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
283
284 return HAL_OK;
285 }
286
287 /**
288 * @brief Get the PeriphClkInit according to the internal
289 * RCC configuration registers.
290 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
291 * returns the configuration information for the Extended Peripherals clocks(RTC, I2S, ADC clocks).
292 * @retval None
293 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)294 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
295 {
296 uint32_t srcclk = 0U;
297
298 /* Set all possible values for the extended clock type parameter------------*/
299 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC;
300
301 /* Get the RTC configuration -----------------------------------------------*/
302 srcclk = __HAL_RCC_GET_RTC_SOURCE();
303 /* Source clock is LSE or LSI*/
304 PeriphClkInit->RTCClockSelection = srcclk;
305
306 /* Get the ADC clock configuration -----------------------------------------*/
307 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC;
308 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
309
310 #if defined(STM32F105xC) || defined(STM32F107xC)
311 /* Get the I2S2 clock configuration -----------------------------------------*/
312 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
313 PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
314
315 /* Get the I2S3 clock configuration -----------------------------------------*/
316 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
317 PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE();
318
319 #endif /* STM32F105xC || STM32F107xC */
320
321 #if defined(STM32F103xE) || defined(STM32F103xG)
322 /* Get the I2S2 clock configuration -----------------------------------------*/
323 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
324 PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK;
325
326 /* Get the I2S3 clock configuration -----------------------------------------*/
327 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
328 PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK;
329
330 #endif /* STM32F103xE || STM32F103xG */
331
332 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
333 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
334 || defined(STM32F105xC) || defined(STM32F107xC)
335 /* Get the USB clock configuration -----------------------------------------*/
336 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
337 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
338 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
339 }
340
341 /**
342 * @brief Returns the peripheral clock frequency
343 * @note Returns 0 if peripheral clock is unknown
344 * @param PeriphClk Peripheral clock identifier
345 * This parameter can be one of the following values:
346 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
347 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
348 @if STM32F103xE
349 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
350 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
351 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
352 @endif
353 @if STM32F103xG
354 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
355 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
356 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
357 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
358 @endif
359 @if STM32F105xC
360 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
361 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
362 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
363 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
364 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
365 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
366 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
367 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
368 @endif
369 @if STM32F107xC
370 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
371 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
372 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
373 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
374 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
375 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
376 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
377 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
378 @endif
379 @if STM32F102xx
380 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
381 @endif
382 @if STM32F103xx
383 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
384 @endif
385 * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
386 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)387 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
388 {
389 #if defined(STM32F105xC) || defined(STM32F107xC)
390 const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
391 const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
392
393 uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
394 uint32_t pll2mul = 0U, pll3mul = 0U, prediv2 = 0U;
395 #endif /* STM32F105xC || STM32F107xC */
396 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || \
397 defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)
398 const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
399 const uint8_t aPredivFactorTable[2] = {1, 2};
400
401 uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
402 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG */
403 uint32_t temp_reg = 0U, frequency = 0U;
404
405 /* Check the parameters */
406 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
407
408 switch (PeriphClk)
409 {
410 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
411 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
412 || defined(STM32F105xC) || defined(STM32F107xC)
413 case RCC_PERIPHCLK_USB:
414 {
415 /* Get RCC configuration ------------------------------------------------------*/
416 temp_reg = RCC->CFGR;
417
418 /* Check if PLL is enabled */
419 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLON))
420 {
421 pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
422 if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
423 {
424 #if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
425 || defined(STM32F100xE)
426 prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
427 #else
428 prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
429 #endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
430
431 #if defined(STM32F105xC) || defined(STM32F107xC)
432 if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
433 {
434 /* PLL2 selected as Prediv1 source */
435 /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
436 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
437 pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
438 pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
439 }
440 else
441 {
442 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
443 pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
444 }
445
446 /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
447 /* In this case need to divide pllclk by 2 */
448 if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
449 {
450 pllclk = pllclk / 2;
451 }
452 #else
453 if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
454 {
455 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
456 pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
457 }
458 #endif /* STM32F105xC || STM32F107xC */
459 }
460 else
461 {
462 /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
463 pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
464 }
465
466 /* Calcul of the USB frequency*/
467 #if defined(STM32F105xC) || defined(STM32F107xC)
468 /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
469 if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
470 {
471 /* Prescaler of 2 selected for USB */
472 frequency = pllclk;
473 }
474 else
475 {
476 /* Prescaler of 3 selected for USB */
477 frequency = (2 * pllclk) / 3;
478 }
479 #else
480 /* USBCLK = PLLCLK / USB prescaler */
481 if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
482 {
483 /* No prescaler selected for USB */
484 frequency = pllclk;
485 }
486 else
487 {
488 /* Prescaler of 1.5 selected for USB */
489 frequency = (pllclk * 2) / 3;
490 }
491 #endif
492 }
493 break;
494 }
495 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
496 #if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
497 case RCC_PERIPHCLK_I2S2:
498 {
499 #if defined(STM32F103xE) || defined(STM32F103xG)
500 /* SYSCLK used as source clock for I2S2 */
501 frequency = HAL_RCC_GetSysClockFreq();
502 #else
503 if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
504 {
505 /* SYSCLK used as source clock for I2S2 */
506 frequency = HAL_RCC_GetSysClockFreq();
507 }
508 else
509 {
510 /* Check if PLLI2S is enabled */
511 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
512 {
513 /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
514 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
515 pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
516 frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
517 }
518 }
519 #endif /* STM32F103xE || STM32F103xG */
520 break;
521 }
522 case RCC_PERIPHCLK_I2S3:
523 {
524 #if defined(STM32F103xE) || defined(STM32F103xG)
525 /* SYSCLK used as source clock for I2S3 */
526 frequency = HAL_RCC_GetSysClockFreq();
527 #else
528 if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
529 {
530 /* SYSCLK used as source clock for I2S3 */
531 frequency = HAL_RCC_GetSysClockFreq();
532 }
533 else
534 {
535 /* Check if PLLI2S is enabled */
536 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
537 {
538 /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
539 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
540 pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
541 frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
542 }
543 }
544 #endif /* STM32F103xE || STM32F103xG */
545 break;
546 }
547 #endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
548 case RCC_PERIPHCLK_RTC:
549 {
550 /* Get RCC BDCR configuration ------------------------------------------------------*/
551 temp_reg = RCC->BDCR;
552
553 /* Check if LSE is ready if RTC clock selection is LSE */
554 if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
555 {
556 frequency = LSE_VALUE;
557 }
558 /* Check if LSI is ready if RTC clock selection is LSI */
559 else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
560 {
561 frequency = LSI_VALUE;
562 }
563 else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
564 {
565 frequency = HSE_VALUE / 128U;
566 }
567 /* Clock not enabled for RTC*/
568 else
569 {
570 /* nothing to do: frequency already initialized to 0U */
571 }
572 break;
573 }
574 case RCC_PERIPHCLK_ADC:
575 {
576 frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) + 1) * 2);
577 break;
578 }
579 default:
580 {
581 break;
582 }
583 }
584 return (frequency);
585 }
586
587 /**
588 * @}
589 */
590
591 #if defined(STM32F105xC) || defined(STM32F107xC)
592 /** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
593 * @brief PLLI2S Management functions
594 *
595 @verbatim
596 ===============================================================================
597 ##### Extended PLLI2S Management functions #####
598 ===============================================================================
599 [..]
600 This subsection provides a set of functions allowing to control the PLLI2S
601 activation or deactivation
602 @endverbatim
603 * @{
604 */
605
606 /**
607 * @brief Enable PLLI2S
608 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
609 * contains the configuration information for the PLLI2S
610 * @note The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
611 * @retval HAL status
612 */
HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef * PLLI2SInit)613 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
614 {
615 uint32_t tickstart = 0U;
616
617 /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
618 if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
619 {
620 /* Check the parameters */
621 assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
622 assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
623
624 /* Prediv2 can be written only when the PLL2 is disabled. */
625 /* Return an error only if new value is different from the programmed value */
626 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \
627 (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
628 {
629 return HAL_ERROR;
630 }
631
632 /* Disable the main PLLI2S. */
633 __HAL_RCC_PLLI2S_DISABLE();
634
635 /* Get Start Tick*/
636 tickstart = HAL_GetTick();
637
638 /* Wait till PLLI2S is ready */
639 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
640 {
641 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
642 {
643 return HAL_TIMEOUT;
644 }
645 }
646
647 /* Configure the HSE prediv2 factor --------------------------------*/
648 __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
649
650
651 /* Configure the main PLLI2S multiplication factors. */
652 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
653
654 /* Enable the main PLLI2S. */
655 __HAL_RCC_PLLI2S_ENABLE();
656
657 /* Get Start Tick*/
658 tickstart = HAL_GetTick();
659
660 /* Wait till PLLI2S is ready */
661 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
662 {
663 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
664 {
665 return HAL_TIMEOUT;
666 }
667 }
668 }
669 else
670 {
671 /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
672 return HAL_ERROR;
673 }
674
675 return HAL_OK;
676 }
677
678 /**
679 * @brief Disable PLLI2S
680 * @note PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
681 * @retval HAL status
682 */
HAL_RCCEx_DisablePLLI2S(void)683 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
684 {
685 uint32_t tickstart = 0U;
686
687 /* Disable PLL I2S as not requested by I2S2 or I2S3*/
688 if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
689 {
690 /* Disable the main PLLI2S. */
691 __HAL_RCC_PLLI2S_DISABLE();
692
693 /* Get Start Tick*/
694 tickstart = HAL_GetTick();
695
696 /* Wait till PLLI2S is ready */
697 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
698 {
699 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
700 {
701 return HAL_TIMEOUT;
702 }
703 }
704 }
705 else
706 {
707 /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
708 return HAL_ERROR;
709 }
710
711 return HAL_OK;
712 }
713
714 /**
715 * @}
716 */
717
718 /** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
719 * @brief PLL2 Management functions
720 *
721 @verbatim
722 ===============================================================================
723 ##### Extended PLL2 Management functions #####
724 ===============================================================================
725 [..]
726 This subsection provides a set of functions allowing to control the PLL2
727 activation or deactivation
728 @endverbatim
729 * @{
730 */
731
732 /**
733 * @brief Enable PLL2
734 * @param PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
735 * contains the configuration information for the PLL2
736 * @note The PLL2 configuration not modified if used indirectly as system clock.
737 * @retval HAL status
738 */
HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef * PLL2Init)739 HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init)
740 {
741 uint32_t tickstart = 0U;
742
743 /* This bit can not be cleared if the PLL2 clock is used indirectly as system
744 clock (i.e. it is used as PLL clock entry that is used as system clock). */
745 if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
746 (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
747 ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
748 {
749 return HAL_ERROR;
750 }
751 else
752 {
753 /* Check the parameters */
754 assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
755 assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
756
757 /* Prediv2 can be written only when the PLLI2S is disabled. */
758 /* Return an error only if new value is different from the programmed value */
759 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \
760 (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
761 {
762 return HAL_ERROR;
763 }
764
765 /* Disable the main PLL2. */
766 __HAL_RCC_PLL2_DISABLE();
767
768 /* Get Start Tick*/
769 tickstart = HAL_GetTick();
770
771 /* Wait till PLL2 is disabled */
772 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
773 {
774 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
775 {
776 return HAL_TIMEOUT;
777 }
778 }
779
780 /* Configure the HSE prediv2 factor --------------------------------*/
781 __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
782
783 /* Configure the main PLL2 multiplication factors. */
784 __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
785
786 /* Enable the main PLL2. */
787 __HAL_RCC_PLL2_ENABLE();
788
789 /* Get Start Tick*/
790 tickstart = HAL_GetTick();
791
792 /* Wait till PLL2 is ready */
793 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
794 {
795 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
796 {
797 return HAL_TIMEOUT;
798 }
799 }
800 }
801
802 return HAL_OK;
803 }
804
805 /**
806 * @brief Disable PLL2
807 * @note PLL2 is not disabled if used indirectly as system clock.
808 * @retval HAL status
809 */
HAL_RCCEx_DisablePLL2(void)810 HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
811 {
812 uint32_t tickstart = 0U;
813
814 /* This bit can not be cleared if the PLL2 clock is used indirectly as system
815 clock (i.e. it is used as PLL clock entry that is used as system clock). */
816 if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
817 (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
818 ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
819 {
820 return HAL_ERROR;
821 }
822 else
823 {
824 /* Disable the main PLL2. */
825 __HAL_RCC_PLL2_DISABLE();
826
827 /* Get Start Tick*/
828 tickstart = HAL_GetTick();
829
830 /* Wait till PLL2 is disabled */
831 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
832 {
833 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
834 {
835 return HAL_TIMEOUT;
836 }
837 }
838 }
839
840 return HAL_OK;
841 }
842
843 /**
844 * @}
845 */
846 #endif /* STM32F105xC || STM32F107xC */
847
848 /**
849 * @}
850 */
851
852 /**
853 * @}
854 */
855
856 #endif /* HAL_RCC_MODULE_ENABLED */
857
858 /**
859 * @}
860 */
861
862 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
863
864