Subversion Repositories DashDisplay

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
  * @version V1.0.1
6
  * @date    31-July-2015
7
  * @brief   Extended RCC HAL module driver.
8
  *          This file provides firmware functions to manage the following
9
  *          functionalities RCC extension peripheral:
10
  *           + Extended Peripheral Control functions
11
  *  
12
  ******************************************************************************
13
  * @attention
14
  *
15
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
16
  *
17
  * Redistribution and use in source and binary forms, with or without modification,
18
  * are permitted provided that the following conditions are met:
19
  *   1. Redistributions of source code must retain the above copyright notice,
20
  *      this list of conditions and the following disclaimer.
21
  *   2. Redistributions in binary form must reproduce the above copyright notice,
22
  *      this list of conditions and the following disclaimer in the documentation
23
  *      and/or other materials provided with the distribution.
24
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
25
  *      may be used to endorse or promote products derived from this software
26
  *      without specific prior written permission.
27
  *
28
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
  *
39
  ******************************************************************************  
40
  */
41
 
42
/* Includes ------------------------------------------------------------------*/
43
#include "stm32f1xx_hal.h"
44
 
45
/** @addtogroup STM32F1xx_HAL_Driver
46
  * @{
47
  */
48
 
49
#ifdef HAL_RCC_MODULE_ENABLED
50
 
51
/** @defgroup RCCEx RCCEx
52
  * @brief RCC Extension HAL module driver.
53
  * @{
54
  */
55
 
56
/* Private typedef -----------------------------------------------------------*/
57
/* Private define ------------------------------------------------------------*/
58
/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
59
 * @{
60
 */
61
/**
62
  * @}
63
  */
64
 
65
/* Private macro -------------------------------------------------------------*/
66
/** @defgroup RCCEx_Private_Macros RCCEx Private Macros
67
 * @{
68
 */
69
/**
70
  * @}
71
  */
72
 
73
/* Private variables ---------------------------------------------------------*/
74
/* Private function prototypes -----------------------------------------------*/
75
/* Private functions ---------------------------------------------------------*/
76
 
77
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
78
  * @{
79
  */
80
 
81
/** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
82
 *  @brief  Extended Peripheral Control functions  
83
 *
84
@verbatim  
85
 ===============================================================================
86
                ##### Extended Peripheral Control functions  #####
87
 ===============================================================================  
88
    [..]
89
    This subsection provides a set of functions allowing to control the RCC Clocks
90
    frequencies.
91
    [..]
92
    (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
93
        select the RTC clock source; in this case the Backup domain will be reset in  
94
        order to modify the RTC Clock source, as consequence RTC registers (including
95
        the backup registers) and RCC_BDCR register are set to their reset values.
96
 
97
@endverbatim
98
  * @{
99
  */
100
 
101
/**
102
  * @brief  Initializes the RCC extended peripherals clocks according to the specified parameters in the
103
  *         RCC_PeriphCLKInitTypeDef.
104
  * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
105
  *         contains the configuration information for the Extended Peripherals clocks(RTC clock).
106
  *
107
  * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
108
  *         the RTC clock source; in this case the Backup domain will be reset in  
109
  *         order to modify the RTC Clock source, as consequence RTC registers (including
110
  *         the backup registers) are set to their reset values.
111
  *
112
  * @note   In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
113
  *         one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
114
  *         manually disable it.
115
  *
116
  * @retval HAL status
117
  */
118
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
119
{
120
  uint32_t tickstart = 0, temp_reg = 0;
121
#if defined(STM32F105xC) || defined(STM32F107xC)
122
  uint32_t  pllactive = 0;
123
#endif /* STM32F105xC || STM32F107xC */
124
 
125
  /* Check the parameters */
126
  assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
127
 
128
  /*------------------------------- RTC/LCD Configuration ------------------------*/
129
  if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
130
  {
131
    /* check for RTC Parameters used to output RTCCLK */
132
    assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
133
 
134
    /* Enable Power Clock*/
135
    __HAL_RCC_PWR_CLK_ENABLE();
136
 
137
    /* Enable write access to Backup domain */
138
    SET_BIT(PWR->CR, PWR_CR_DBP);
139
 
140
    /* Wait for Backup domain Write protection disable */
141
    tickstart = HAL_GetTick();
142
 
143
    while((PWR->CR & PWR_CR_DBP) == RESET)
144
    {
145
      if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
146
      {
147
        return HAL_TIMEOUT;
148
      }      
149
    }
150
 
151
    /* Reset the Backup domain only if the RTC Clock source selection is modified */
152
    if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
153
    {
154
      /* Store the content of BDCR register before the reset of Backup Domain */
155
      temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
156
      /* RTC Clock selection can be changed only if the Backup Domain is reset */
157
      __HAL_RCC_BACKUPRESET_FORCE();
158
      __HAL_RCC_BACKUPRESET_RELEASE();
159
      /* Restore the Content of BDCR register */
160
      RCC->BDCR = temp_reg;
161
 
162
      /* Wait for LSERDY if LSE was enabled */
163
      if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY))
164
      {
165
        /* Get timeout */
166
        tickstart = HAL_GetTick();
167
 
168
        /* Wait till LSE is ready */  
169
        while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
170
        {
171
          if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
172
          {
173
            return HAL_TIMEOUT;
174
          }      
175
        }  
176
      }
177
      __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
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 = 0;
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 RCC_PERIPHCLK_RTC  RTC peripheral clock
347
  *            @arg RCC_PERIPHCLK_ADC  ADC peripheral clock
348
  *            @arg RCC_PERIPHCLK_I2S2 I2S2 peripheral clock (STM32F103xE, STM32F103xG, STM32F105xC & STM32F107xC)
349
  *            @arg RCC_PERIPHCLK_I2S3 I2S3 peripheral clock (STM32F103xE, STM32F103xG, STM32F105xC & STM32F107xC)
350
  *            @arg RCC_PERIPHCLK_USB USB peripheral clock (STM32F102xx, STM32F103xx, STM32F105xC & STM32F107xC)
351
  * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
352
  */
353
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
354
{
355
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
356
 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
357
 || defined(STM32F105xC) || defined(STM32F107xC)
358
#if defined(STM32F105xC) || defined(STM32F107xC)
359
  const uint8_t aPLLMULFactorTable[12] = {0, 0, 4,  5,  6,  7,  8,  9, 0, 0, 0, 13};
360
  const uint8_t aPredivFactorTable[16] = { 1, 2,  3,  4,  5,  6,  7,  8, 9,10, 11, 12, 13, 14, 15, 16};
361
#else
362
  const uint8_t aPLLMULFactorTable[16] = { 2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 16};
363
  const uint8_t aPredivFactorTable[2] = { 1, 2};
364
#endif
365
#endif
366
  uint32_t temp_reg = 0, frequency = 0;
367
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
368
 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
369
 || defined(STM32F105xC) || defined(STM32F107xC)
370
  uint32_t prediv1 = 0, pllclk = 0, pllmul = 0;
371
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
372
#if defined(STM32F105xC) || defined(STM32F107xC)
373
  uint32_t pll2mul = 0, pll3mul = 0, prediv2 = 0;
374
#endif /* STM32F105xC || STM32F107xC */
375
 
376
  /* Check the parameters */
377
  assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
378
 
379
  switch (PeriphClk)
380
  {
381
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
382
 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
383
 || defined(STM32F105xC) || defined(STM32F107xC)
384
  case RCC_PERIPHCLK_USB:  
385
    {
386
      /* Get RCC configuration ------------------------------------------------------*/
387
      temp_reg = RCC->CFGR;
388
 
389
      /* Check if PLL is enabled */
390
      if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLLON))
391
      {
392
        pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> POSITION_VAL(RCC_CFGR_PLLMULL)];
393
        if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
394
        {
395
#if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
396
 || defined(STM32F100xE)
397
          prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> POSITION_VAL(RCC_CFGR2_PREDIV1)];
398
#else
399
          prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> POSITION_VAL(RCC_CFGR_PLLXTPRE)];
400
#endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
401
 
402
#if defined(STM32F105xC) || defined(STM32F107xC)
403
          if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
404
          {
405
            /* PLL2 selected as Prediv1 source */
406
            /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
407
            prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
408
            pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> POSITION_VAL(RCC_CFGR2_PLL2MUL)) + 2;
409
            pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
410
          }
411
          else
412
          {
413
            /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
414
            pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
415
          }
416
 
417
          /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
418
          /* In this case need to divide pllclk by 2 */
419
          if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> POSITION_VAL(RCC_CFGR_PLLMULL)])
420
          {
421
              pllclk = pllclk / 2;
422
          }
423
#else
424
          if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
425
          {
426
            /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
427
            pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
428
          }
429
#endif /* STM32F105xC || STM32F107xC */
430
        }
431
        else
432
        {
433
          /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
434
          pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
435
        }
436
 
437
        /* Calcul of the USB frequency*/
438
#if defined(STM32F105xC) || defined(STM32F107xC)
439
        /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
440
        if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
441
        {
442
          /* Prescaler of 2 selected for USB */
443
          frequency = pllclk;
444
        }
445
        else
446
        {
447
          /* Prescaler of 3 selected for USB */
448
          frequency = (2 * pllclk) / 3;
449
        }
450
#else
451
        /* USBCLK = PLLCLK / USB prescaler */
452
        if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
453
        {
454
          /* No prescaler selected for USB */
455
          frequency = pllclk;
456
        }
457
        else
458
        {
459
          /* Prescaler of 1.5 selected for USB */
460
          frequency = (pllclk * 2) / 3;
461
        }
462
#endif
463
      }
464
      break;
465
    }
466
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
467
#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC)\
468
 || defined(STM32F107xC)
469
  case RCC_PERIPHCLK_I2S2:  
470
    {
471
#if defined(STM32F103xE) || defined(STM32F103xG)
472
      /* SYSCLK used as source clock for I2S2 */
473
      frequency = HAL_RCC_GetSysClockFreq();
474
#else
475
      if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
476
      {
477
        /* SYSCLK used as source clock for I2S2 */
478
        frequency = HAL_RCC_GetSysClockFreq();
479
      }
480
      else
481
      {
482
         /* Check if PLLI2S is enabled */
483
        if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
484
        {
485
          /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
486
          prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
487
          pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> POSITION_VAL(RCC_CFGR2_PLL3MUL)) + 2;
488
          frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
489
        }
490
      }
491
#endif /* STM32F103xE || STM32F103xG */
492
      break;
493
    }
494
  case RCC_PERIPHCLK_I2S3:
495
    {
496
#if defined(STM32F103xE) || defined(STM32F103xG)
497
      /* SYSCLK used as source clock for I2S3 */
498
      frequency = HAL_RCC_GetSysClockFreq();
499
#else
500
      if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
501
      {
502
        /* SYSCLK used as source clock for I2S3 */
503
        frequency = HAL_RCC_GetSysClockFreq();
504
      }
505
      else
506
      {
507
         /* Check if PLLI2S is enabled */
508
        if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
509
        {
510
          /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
511
          prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
512
          pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> POSITION_VAL(RCC_CFGR2_PLL3MUL)) + 2;
513
          frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
514
        }
515
      }
516
#endif /* STM32F103xE || STM32F103xG */
517
      break;
518
    }
519
#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
520
  case RCC_PERIPHCLK_RTC:  
521
    {
522
      /* Get RCC BDCR configuration ------------------------------------------------------*/
523
      temp_reg = RCC->BDCR;
524
 
525
      /* Check if LSE is ready if RTC clock selection is LSE */
526
      if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
527
      {
528
        frequency = LSE_VALUE;
529
      }
530
      /* Check if LSI is ready if RTC clock selection is LSI */
531
      else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
532
      {
533
        frequency = LSI_VALUE;
534
      }
535
      else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
536
      {
537
        frequency = HSE_VALUE / 128;
538
      }
539
      /* Clock not enabled for RTC*/
540
      else
541
      {
542
        frequency = 0;
543
      }
544
      break;
545
    }
546
  case RCC_PERIPHCLK_ADC:  
547
    {
548
      frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> POSITION_VAL(RCC_CFGR_ADCPRE_DIV4)) + 1) * 2);
549
      break;
550
    }
551
  default:
552
    {
553
      break;
554
    }
555
  }
556
  return(frequency);
557
}
558
 
559
/**
560
  * @}
561
  */
562
 
563
#if defined(STM32F105xC) || defined(STM32F107xC)
564
/** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
565
 *  @brief  PLLI2S Management functions
566
 *
567
@verbatim  
568
 ===============================================================================
569
                ##### Extended PLLI2S Management functions  #####
570
 ===============================================================================  
571
    [..]
572
    This subsection provides a set of functions allowing to control the PLLI2S
573
    activation or deactivation
574
@endverbatim
575
  * @{
576
  */
577
 
578
/**
579
  * @brief  Enable PLLI2S
580
  * @param  PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
581
  *         contains the configuration information for the PLLI2S
582
  * @note   The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
583
  * @retval HAL status
584
  */
585
HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef  *PLLI2SInit)
586
{
587
  uint32_t tickstart = 0;
588
 
589
  /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
590
  if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
591
  {
592
    /* Check the parameters */
593
    assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
594
    assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
595
 
596
    /* Prediv2 can be written only when the PLL2 is disabled. */
597
    /* Return an error only if new value is different from the programmed value */
598
    if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
599
      (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
600
    {
601
      return HAL_ERROR;
602
    }
603
 
604
    /* Disable the main PLLI2S. */
605
    __HAL_RCC_PLLI2S_DISABLE();
606
 
607
    /* Get Start Tick*/
608
    tickstart = HAL_GetTick();
609
 
610
    /* Wait till PLLI2S is ready */  
611
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
612
    {
613
      if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
614
      {
615
        return HAL_TIMEOUT;
616
      }
617
    }
618
 
619
    /* Configure the HSE prediv2 factor --------------------------------*/
620
    __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
621
 
622
 
623
    /* Configure the main PLLI2S multiplication factors. */
624
    __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
625
 
626
    /* Enable the main PLLI2S. */
627
    __HAL_RCC_PLLI2S_ENABLE();
628
 
629
    /* Get Start Tick*/
630
    tickstart = HAL_GetTick();
631
 
632
    /* Wait till PLLI2S is ready */
633
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
634
    {
635
      if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
636
      {
637
        return HAL_TIMEOUT;
638
      }
639
    }
640
  }
641
  else
642
  {
643
    /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
644
    return HAL_ERROR;
645
  }
646
 
647
  return HAL_OK;
648
}
649
 
650
/**
651
  * @brief  Disable PLLI2S
652
  * @note   PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
653
  * @retval HAL status
654
  */
655
HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
656
{
657
  uint32_t tickstart = 0;
658
 
659
  /* Disable PLL I2S as not requested by I2S2 or I2S3*/
660
  if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
661
  {
662
    /* Disable the main PLLI2S. */
663
    __HAL_RCC_PLLI2S_DISABLE();
664
 
665
    /* Get Start Tick*/
666
    tickstart = HAL_GetTick();
667
 
668
    /* Wait till PLLI2S is ready */  
669
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
670
    {
671
      if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
672
      {
673
        return HAL_TIMEOUT;
674
      }
675
    }
676
  }
677
  else
678
  {
679
    /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
680
    return HAL_ERROR;
681
  }
682
 
683
  return HAL_OK;
684
}
685
 
686
/**
687
  * @}
688
  */
689
 
690
/** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
691
 *  @brief  PLL2 Management functions
692
 *
693
@verbatim  
694
 ===============================================================================
695
                ##### Extended PLL2 Management functions  #####
696
 ===============================================================================  
697
    [..]
698
    This subsection provides a set of functions allowing to control the PLL2
699
    activation or deactivation
700
@endverbatim
701
  * @{
702
  */
703
 
704
/**
705
  * @brief  Enable PLL2
706
  * @param  PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
707
  *         contains the configuration information for the PLL2
708
  * @note   The PLL2 configuration not modified if used indirectly as system clock.
709
  * @retval HAL status
710
  */
711
HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef  *PLL2Init)
712
{
713
  uint32_t tickstart = 0;
714
 
715
  /* This bit can not be cleared if the PLL2 clock is used indirectly as system
716
    clock (i.e. it is used as PLL clock entry that is used as system clock). */
717
  if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
718
        (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
719
        ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
720
  {
721
    return HAL_ERROR;
722
  }
723
  else
724
  {
725
    /* Check the parameters */
726
    assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
727
    assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
728
 
729
    /* Prediv2 can be written only when the PLLI2S is disabled. */
730
    /* Return an error only if new value is different from the programmed value */
731
    if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
732
      (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
733
    {
734
      return HAL_ERROR;
735
    }
736
 
737
    /* Disable the main PLL2. */
738
    __HAL_RCC_PLL2_DISABLE();
739
 
740
    /* Get Start Tick*/
741
    tickstart = HAL_GetTick();
742
 
743
    /* Wait till PLL2 is disabled */
744
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
745
    {
746
      if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
747
      {
748
        return HAL_TIMEOUT;
749
      }
750
    }
751
 
752
    /* Configure the HSE prediv2 factor --------------------------------*/
753
    __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
754
 
755
    /* Configure the main PLL2 multiplication factors. */
756
    __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
757
 
758
    /* Enable the main PLL2. */
759
    __HAL_RCC_PLL2_ENABLE();
760
 
761
    /* Get Start Tick*/
762
    tickstart = HAL_GetTick();
763
 
764
    /* Wait till PLL2 is ready */
765
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  == RESET)
766
    {
767
      if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
768
      {
769
        return HAL_TIMEOUT;
770
      }
771
    }
772
  }
773
 
774
  return HAL_OK;
775
}
776
 
777
/**
778
  * @brief  Disable PLL2
779
  * @note   PLL2 is not disabled if used indirectly as system clock.
780
  * @retval HAL status
781
  */
782
HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
783
{
784
  uint32_t tickstart = 0;
785
 
786
  /* This bit can not be cleared if the PLL2 clock is used indirectly as system
787
    clock (i.e. it is used as PLL clock entry that is used as system clock). */
788
  if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
789
        (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
790
        ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
791
  {
792
    return HAL_ERROR;
793
  }
794
  else
795
  {
796
    /* Disable the main PLL2. */
797
    __HAL_RCC_PLL2_DISABLE();
798
 
799
    /* Get Start Tick*/
800
    tickstart = HAL_GetTick();
801
 
802
    /* Wait till PLL2 is disabled */  
803
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  != RESET)
804
    {
805
      if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
806
      {
807
        return HAL_TIMEOUT;
808
      }
809
    }
810
  }
811
 
812
  return HAL_OK;
813
}
814
 
815
/**
816
  * @}
817
  */
818
#endif /* STM32F105xC || STM32F107xC */
819
 
820
/**
821
  * @}
822
  */
823
 
824
/**
825
  * @}
826
  */
827
 
828
#endif /* HAL_RCC_MODULE_ENABLED */
829
 
830
/**
831
  * @}
832
  */
833
 
834
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
835