Subversion Repositories dashGPS

Rev

Go to most recent revision | 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
  * <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
  */
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
    /* check for RTC Parameters used to output RTCCLK */
114
    assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
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 */
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
  */
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
  */
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). */
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
  */
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