Subversion Repositories LedShow

Rev

Rev 2 | Details | Compare with Previous | 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.
9 mjames 6
  *          This file provides firmware functions to manage the following
2 mjames 7
  *          functionalities RCC extension peripheral:
8
  *           + Extended Peripheral Control functions
9 mjames 9
  *
2 mjames 10
  ******************************************************************************
11
  * @attention
12
  *
9 mjames 13
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
14
  * All rights reserved.</center></h2>
2 mjames 15
  *
9 mjames 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
2 mjames 20
  *
9 mjames 21
  ******************************************************************************
22
  */
2 mjames 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
 
9 mjames 63
/** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
64
  *  @brief  Extended Peripheral Control functions
2 mjames 65
  *
9 mjames 66
@verbatim
2 mjames 67
 ===============================================================================
68
                ##### Extended Peripheral Control functions  #####
9 mjames 69
 ===============================================================================
2 mjames 70
    [..]
9 mjames 71
    This subsection provides a set of functions allowing to control the RCC Clocks
2 mjames 72
    frequencies.
9 mjames 73
    [..]
2 mjames 74
    (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
9 mjames 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
2 mjames 77
        the backup registers) are set to their reset values.
9 mjames 78
 
2 mjames 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
  *
9 mjames 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
2 mjames 92
  *         the backup registers) are set to their reset values.
93
  *
9 mjames 94
  * @note   In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
2 mjames 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));
9 mjames 109
 
110
  /*------------------------------- RTC/LCD Configuration ------------------------*/
2 mjames 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
 
9 mjames 118
    /* As soon as function is called to change RTC clock source, activation of the
2 mjames 119
       power domain is done. */
120
    /* Requires to enable write access to Backup Domain of necessary */
9 mjames 121
    if (__HAL_RCC_PWR_IS_CLK_DISABLED())
2 mjames 122
    {
9 mjames 123
      __HAL_RCC_PWR_CLK_ENABLE();
2 mjames 124
      pwrclkchanged = SET;
125
    }
9 mjames 126
 
127
    if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
2 mjames 128
    {
129
      /* Enable write access to Backup domain */
130
      SET_BIT(PWR->CR, PWR_CR_DBP);
9 mjames 131
 
2 mjames 132
      /* Wait for Backup domain Write protection disable */
133
      tickstart = HAL_GetTick();
9 mjames 134
 
135
      while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
2 mjames 136
      {
9 mjames 137
        if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
2 mjames 138
        {
139
          return HAL_TIMEOUT;
140
        }
141
      }
142
    }
9 mjames 143
 
144
    /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
2 mjames 145
    temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
9 mjames 146
    if ((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
2 mjames 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();
9 mjames 161
 
162
        /* Wait till LSE is ready */
163
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
2 mjames 164
        {
9 mjames 165
          if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
2 mjames 166
          {
167
            return HAL_TIMEOUT;
9 mjames 168
          }
169
        }
2 mjames 170
      }
171
    }
9 mjames 172
    __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
2 mjames 173
 
174
    /* Require to disable power clock if necessary */
9 mjames 175
    if (pwrclkchanged == SET)
2 mjames 176
    {
177
      __HAL_RCC_PWR_CLK_DISABLE();
178
    }
179
  }
180
 
9 mjames 181
  /*------------------------------ ADC clock Configuration ------------------*/
182
  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
2 mjames 183
  {
184
    /* Check the parameters */
185
    assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
9 mjames 186
 
2 mjames 187
    /* Configure the ADC clock source */
188
    __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
189
  }
190
 
191
#if defined(STM32F105xC) || defined(STM32F107xC)
9 mjames 192
  /*------------------------------ I2S2 Configuration ------------------------*/
193
  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
2 mjames 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
 
9 mjames 202
  /*------------------------------ I2S3 Configuration ------------------------*/
203
  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
2 mjames 204
  {
205
    /* Check the parameters */
206
    assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
9 mjames 207
 
2 mjames 208
    /* Configure the I2S3 clock source */
209
    __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
210
  }
211
 
9 mjames 212
  /*------------------------------ PLL I2S Configuration ----------------------*/
2 mjames 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 */
9 mjames 232
      if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \
233
          (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
2 mjames 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);
9 mjames 243
 
2 mjames 244
      /* Enable the main PLLI2S. */
245
      __HAL_RCC_PLLI2S_ENABLE();
9 mjames 246
 
2 mjames 247
      /* Get Start Tick*/
248
      tickstart = HAL_GetTick();
9 mjames 249
 
2 mjames 250
      /* Wait till PLLI2S is ready */
9 mjames 251
      while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
2 mjames 252
      {
9 mjames 253
        if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
2 mjames 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
      {
9 mjames 264
        return HAL_ERROR;
2 mjames 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)
9 mjames 273
  /*------------------------------ USB clock Configuration ------------------*/
274
  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
2 mjames 275
  {
276
    /* Check the parameters */
277
    assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
9 mjames 278
 
2 mjames 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.
9 mjames 290
  * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
2 mjames 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;
9 mjames 297
 
2 mjames 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));
9 mjames 407
 
2 mjames 408
  switch (PeriphClk)
409
  {
410
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
411
 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
412
 || defined(STM32F105xC) || defined(STM32F107xC)
9 mjames 413
    case RCC_PERIPHCLK_USB:
2 mjames 414
    {
415
      /* Get RCC configuration ------------------------------------------------------*/
416
      temp_reg = RCC->CFGR;
9 mjames 417
 
2 mjames 418
      /* Check if PLL is enabled */
9 mjames 419
      if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLON))
2 mjames 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)
9 mjames 432
          if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
2 mjames 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
          }
9 mjames 445
 
2 mjames 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
          {
9 mjames 450
            pllclk = pllclk / 2;
2 mjames 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
        {
9 mjames 471
          /* Prescaler of 2 selected for USB */
2 mjames 472
          frequency = pllclk;
473
        }
474
        else
475
        {
9 mjames 476
          /* Prescaler of 3 selected for USB */
2 mjames 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
        {
9 mjames 488
          /* Prescaler of 1.5 selected for USB */
2 mjames 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)
9 mjames 497
    case RCC_PERIPHCLK_I2S2:
2 mjames 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
      {
9 mjames 510
        /* Check if PLLI2S is enabled */
2 mjames 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
    }
9 mjames 522
    case RCC_PERIPHCLK_I2S3:
2 mjames 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
      {
9 mjames 535
        /* Check if PLLI2S is enabled */
2 mjames 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 */
9 mjames 548
    case RCC_PERIPHCLK_RTC:
2 mjames 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
      {
9 mjames 570
        /* nothing to do: frequency already initialized to 0U */
2 mjames 571
      }
572
      break;
573
    }
9 mjames 574
    case RCC_PERIPHCLK_ADC:
2 mjames 575
    {
576
      frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) + 1) * 2);
577
      break;
578
    }
9 mjames 579
    default:
2 mjames 580
    {
581
      break;
582
    }
583
  }
9 mjames 584
  return (frequency);
2 mjames 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
  *
9 mjames 595
@verbatim
2 mjames 596
 ===============================================================================
597
                ##### Extended PLLI2S Management functions  #####
9 mjames 598
 ===============================================================================
2 mjames 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 */
9 mjames 626
    if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \
627
        (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
2 mjames 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();
9 mjames 637
 
638
    /* Wait till PLLI2S is ready */
639
    while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
2 mjames 640
    {
9 mjames 641
      if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
2 mjames 642
      {
643
        return HAL_TIMEOUT;
644
      }
645
    }
646
 
647
    /* Configure the HSE prediv2 factor --------------------------------*/
648
    __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
649
 
9 mjames 650
 
2 mjames 651
    /* Configure the main PLLI2S multiplication factors. */
652
    __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
9 mjames 653
 
2 mjames 654
    /* Enable the main PLLI2S. */
655
    __HAL_RCC_PLLI2S_ENABLE();
9 mjames 656
 
2 mjames 657
    /* Get Start Tick*/
658
    tickstart = HAL_GetTick();
9 mjames 659
 
2 mjames 660
    /* Wait till PLLI2S is ready */
9 mjames 661
    while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
2 mjames 662
    {
9 mjames 663
      if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
2 mjames 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();
9 mjames 695
 
696
    /* Wait till PLLI2S is ready */
697
    while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
2 mjames 698
    {
9 mjames 699
      if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
2 mjames 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
  }
9 mjames 710
 
2 mjames 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
  *
9 mjames 721
@verbatim
2 mjames 722
 ===============================================================================
723
                ##### Extended PLL2 Management functions  #####
9 mjames 724
 ===============================================================================
2 mjames 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
 
9 mjames 743
  /* This bit can not be cleared if the PLL2 clock is used indirectly as system
2 mjames 744
    clock (i.e. it is used as PLL clock entry that is used as system clock). */
9 mjames 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))
2 mjames 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 */
9 mjames 759
    if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \
760
        (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
2 mjames 761
    {
762
      return HAL_ERROR;
763
    }
764
 
765
    /* Disable the main PLL2. */
766
    __HAL_RCC_PLL2_DISABLE();
9 mjames 767
 
2 mjames 768
    /* Get Start Tick*/
769
    tickstart = HAL_GetTick();
9 mjames 770
 
2 mjames 771
    /* Wait till PLL2 is disabled */
9 mjames 772
    while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
2 mjames 773
    {
9 mjames 774
      if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
2 mjames 775
      {
776
        return HAL_TIMEOUT;
777
      }
778
    }
9 mjames 779
 
2 mjames 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);
9 mjames 785
 
2 mjames 786
    /* Enable the main PLL2. */
787
    __HAL_RCC_PLL2_ENABLE();
9 mjames 788
 
2 mjames 789
    /* Get Start Tick*/
790
    tickstart = HAL_GetTick();
9 mjames 791
 
2 mjames 792
    /* Wait till PLL2 is ready */
9 mjames 793
    while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  == RESET)
2 mjames 794
    {
9 mjames 795
      if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
2 mjames 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
 
9 mjames 814
  /* This bit can not be cleared if the PLL2 clock is used indirectly as system
2 mjames 815
    clock (i.e. it is used as PLL clock entry that is used as system clock). */
9 mjames 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))
2 mjames 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();
9 mjames 829
 
830
    /* Wait till PLL2 is disabled */
831
    while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  != RESET)
2 mjames 832
    {
9 mjames 833
      if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
2 mjames 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