DIY Logging Volt/Ampmeter
stm32f1xx_hal_rcc_ex.c
Go to the documentation of this file.
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>&copy; 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  */
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 */
109 
110  /*------------------------------- RTC/LCD Configuration ------------------------*/
111  if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
112  {
113  /* check for RTC Parameters used to output RTCCLK */
115 
116  FlagStatus pwrclkchanged = RESET;
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 */
122  {
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 */
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 */
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  {
178  }
179  }
180 
181  /*------------------------------ ADC clock Configuration ------------------*/
182  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
183  {
184  /* Check the parameters */
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  */
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  */
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  */
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  */
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  */
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). */
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  */
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). */
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 
RCC_CFGR_ADCPRE_Pos
#define RCC_CFGR_ADCPRE_Pos
Definition: stm32f103xb.h:1004
RCC_SYSCLKSOURCE_STATUS_PLLCLK
#define RCC_SYSCLKSOURCE_STATUS_PLLCLK
Definition: stm32f1xx_hal_rcc.h:196
__HAL_RCC_GET_RTC_SOURCE
#define __HAL_RCC_GET_RTC_SOURCE()
Macro to get the RTC clock source.
Definition: stm32f1xx_hal_rcc.h:996
HAL_IS_BIT_CLR
#define HAL_IS_BIT_CLR(REG, BIT)
Definition: stm32f1xx_hal_def.h:60
__HAL_RCC_GET_PLL_OSCSOURCE
#define __HAL_RCC_GET_PLL_OSCSOURCE()
Get oscillator clock selected as PLL input clock.
Definition: stm32f1xx_hal_rcc.h:883
PWR
#define PWR
Definition: stm32f103xb.h:662
HAL_RCCEx_GetPeriphCLKFreq
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
RCC_RTCCLKSOURCE_LSE
#define RCC_RTCCLKSOURCE_LSE
Definition: stm32f1xx_hal_rcc.h:236
__HAL_RCC_PWR_CLK_DISABLE
#define __HAL_RCC_PWR_CLK_DISABLE()
Definition: stm32f1xx_hal_rcc.h:455
__HAL_RCC_ADC_CONFIG
#define __HAL_RCC_ADC_CONFIG(__ADCCLKSOURCE__)
Macro to configure the ADCx clock (x=1 to 3 depending on devices).
Definition: stm32f1xx_hal_rcc_ex.h:1721
RCC_PLLSOURCE_HSI_DIV2
#define RCC_PLLSOURCE_HSI_DIV2
Definition: stm32f1xx_hal_rcc.h:95
stm32f1xx_hal.h
This file contains all the functions prototypes for the HAL module driver.
RCC_DBP_TIMEOUT_VALUE
#define RCC_DBP_TIMEOUT_VALUE
Definition: stm32f1xx_hal_rcc.h:1202
RCC_FLAG_LSERDY
#define RCC_FLAG_LSERDY
Definition: stm32f1xx_hal_rcc.h:300
RCC_PeriphCLKInitTypeDef::PeriphClockSelection
uint32_t PeriphClockSelection
Definition: stm32f1xx_hal_rcc_ex.h:285
HAL_RCC_GetPCLK2Freq
uint32_t HAL_RCC_GetPCLK2Freq(void)
READ_BIT
#define READ_BIT(REG, BIT)
Definition: stm32f1xx.h:182
RCC_CR_HSERDY
#define RCC_CR_HSERDY
Definition: stm32f103xb.h:918
RCC_RTCCLKSOURCE_LSI
#define RCC_RTCCLKSOURCE_LSI
Definition: stm32f1xx_hal_rcc.h:237
RCC_CFGR_PLLMULL
#define RCC_CFGR_PLLMULL
Definition: stm32f103xb.h:1026
RCC_CFGR_PLLXTPRE
#define RCC_CFGR_PLLXTPRE
Definition: stm32f103xb.h:1021
RCC_BDCR_LSERDY
#define RCC_BDCR_LSERDY
Definition: stm32f103xb.h:1368
assert_param
#define assert_param(expr)
Definition: stm32_assert.h:44
LSE_VALUE
#define LSE_VALUE
External Low Speed oscillator (LSE) value. This value is used by the UART, RTC HAL module to compute ...
Definition: stm32f1xx_hal_conf.h:116
LSI_VALUE
#define LSI_VALUE
Internal Low Speed oscillator (LSI) value.
Definition: stm32f1xx_hal_conf.h:106
__HAL_RCC_BACKUPRESET_FORCE
#define __HAL_RCC_BACKUPRESET_FORCE()
Macro to force the Backup domain reset.
Definition: stm32f1xx_hal_rcc.h:1012
HAL_IS_BIT_SET
#define HAL_IS_BIT_SET(REG, BIT)
Definition: stm32f1xx_hal_def.h:59
IS_RCC_PERIPHCLOCK
#define IS_RCC_PERIPHCLOCK(__SELECTION__)
Definition: stm32f1xx_hal_rcc_ex.h:181
RCC_CR_PLLON
#define RCC_CR_PLLON
Definition: stm32f103xb.h:927
__HAL_RCC_GET_ADC_SOURCE
#define __HAL_RCC_GET_ADC_SOURCE()
Macro to get the ADC clock (ADCxCLK, x=1 to 3 depending on devices).
Definition: stm32f1xx_hal_rcc_ex.h:1731
RESET
@ RESET
Definition: stm32f1xx.h:153
HAL_TIMEOUT
@ HAL_TIMEOUT
Definition: stm32f1xx_hal_def.h:44
HAL_OK
@ HAL_OK
Definition: stm32f1xx_hal_def.h:41
RCC_PLLSOURCE_HSE
#define RCC_PLLSOURCE_HSE
Definition: stm32f1xx_hal_rcc.h:96
IS_RCC_ADCPLLCLK_DIV
#define IS_RCC_ADCPLLCLK_DIV(__ADCCLK__)
Definition: stm32f1xx_hal_rcc_ex.h:116
RCC
#define RCC
Definition: stm32f103xb.h:684
__HAL_RCC_PWR_CLK_ENABLE
#define __HAL_RCC_PWR_CLK_ENABLE()
Definition: stm32f1xx_hal_rcc.h:440
RCC_CSR_LSIRDY
#define RCC_CSR_LSIRDY
Definition: stm32f103xb.h:1398
RCC_CFGR_PLLSRC
#define RCC_CFGR_PLLSRC
Definition: stm32f103xb.h:1017
HSE_VALUE
#define HSE_VALUE
Adjust the value of External High Speed oscillator (HSE) used in your application....
Definition: stm32f1xx_hal_conf.h:86
RCC_CFGR_PLLXTPRE_Pos
#define RCC_CFGR_PLLXTPRE_Pos
Definition: stm32f103xb.h:1019
RCC_LSE_TIMEOUT_VALUE
#define RCC_LSE_TIMEOUT_VALUE
Definition: stm32f1xx_hal_rcc.h:1204
HAL_RCCEx_PeriphCLKConfig
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
SET
@ SET
Definition: stm32f1xx.h:154
__HAL_RCC_GET_FLAG
#define __HAL_RCC_GET_FLAG(__FLAG__)
Check RCC flag is set or not.
Definition: stm32f1xx_hal_rcc.h:1131
HSI_VALUE
#define HSI_VALUE
Internal High Speed oscillator (HSI) value. This value is used by the RCC HAL module to compute the s...
Definition: stm32f1xx_hal_conf.h:99
HAL_StatusTypeDef
HAL_StatusTypeDef
HAL Status structures definition.
Definition: stm32f1xx_hal_def.h:39
RCC_BDCR_LSEON
#define RCC_BDCR_LSEON
Definition: stm32f103xb.h:1365
HAL_RCC_GetSysClockFreq
uint32_t HAL_RCC_GetSysClockFreq(void)
FlagStatus
FlagStatus
Definition: stm32f1xx.h:151
__HAL_RCC_BACKUPRESET_RELEASE
#define __HAL_RCC_BACKUPRESET_RELEASE()
Macros to release the Backup domain reset.
Definition: stm32f1xx_hal_rcc.h:1016
IS_RCC_RTCCLKSOURCE
#define IS_RCC_RTCCLKSOURCE(__SOURCE__)
Definition: stm32f1xx_hal_rcc.h:1354
RCC_PERIPHCLK_RTC
#define RCC_PERIPHCLK_RTC
Definition: stm32f1xx_hal_rcc_ex.h:331
__HAL_RCC_GET_SYSCLK_SOURCE
#define __HAL_RCC_GET_SYSCLK_SOURCE()
Macro to get the clock source used as system clock.
Definition: stm32f1xx_hal_rcc.h:911
HAL_GetTick
uint32_t HAL_GetTick(void)
RCC_BDCR_RTCSEL
#define RCC_BDCR_RTCSEL
Definition: stm32f103xb.h:1375
PWR_CR_DBP
#define PWR_CR_DBP
Definition: stm32f103xb.h:780
RCC_PeriphCLKInitTypeDef
RCC extended clocks structure definition.
Definition: stm32f1xx_hal_rcc_ex.h:283
RCC_PeriphCLKInitTypeDef::AdcClockSelection
uint32_t AdcClockSelection
Definition: stm32f1xx_hal_rcc_ex.h:291
SET_BIT
#define SET_BIT(REG, BIT)
Definition: stm32f1xx.h:178
RCC_RTCCLKSOURCE_HSE_DIV128
#define RCC_RTCCLKSOURCE_HSE_DIV128
Definition: stm32f1xx_hal_rcc.h:238
HAL_ERROR
@ HAL_ERROR
Definition: stm32f1xx_hal_def.h:42
RCC_PERIPHCLK_ADC
#define RCC_PERIPHCLK_ADC
Definition: stm32f1xx_hal_rcc_ex.h:332
__HAL_RCC_RTC_CONFIG
#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__)
Macro to configure the RTC clock (RTCCLK).
Definition: stm32f1xx_hal_rcc.h:987
RCC_CFGR_PLLMULL_Pos
#define RCC_CFGR_PLLMULL_Pos
Definition: stm32f103xb.h:1024
HAL_RCCEx_GetPeriphCLKConfig
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
RCC_PeriphCLKInitTypeDef::RTCClockSelection
uint32_t RTCClockSelection
Definition: stm32f1xx_hal_rcc_ex.h:288
__HAL_RCC_PWR_IS_CLK_DISABLED
#define __HAL_RCC_PWR_IS_CLK_DISABLED()
Definition: stm32f1xx_hal_rcc.h:482