Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

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