Subversion Repositories FuelGauge

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f0xx_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
  *           + Extended Clock Recovery System Control functions
10
  *
11
  ******************************************************************************
12
  * @attention
13
  *
14
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
15
  * All rights reserved.</center></h2>
16
  *
17
  * This software component is licensed by ST under BSD 3-Clause license,
18
  * the "License"; You may not use this file except in compliance with the
19
  * License. You may obtain a copy of the License at:
20
  *                        opensource.org/licenses/BSD-3-Clause
21
  *
22
  ******************************************************************************
23
  */
24
 
25
/* Includes ------------------------------------------------------------------*/
26
#include "stm32f0xx_hal.h"
27
 
28
/** @addtogroup STM32F0xx_HAL_Driver
29
  * @{
30
  */
31
 
32
#ifdef HAL_RCC_MODULE_ENABLED
33
 
34
/** @defgroup RCCEx RCCEx
35
  * @brief RCC Extension HAL module driver.
36
  * @{
37
  */
38
 
39
/* Private typedef -----------------------------------------------------------*/
40
/* Private define ------------------------------------------------------------*/
41
#if defined(CRS)
42
/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
43
  * @{
44
  */
45
/* Bit position in register */
46
#define CRS_CFGR_FELIM_BITNUMBER    16
47
#define CRS_CR_TRIM_BITNUMBER       8
48
#define CRS_ISR_FECAP_BITNUMBER     16
49
/**
50
  * @}
51
  */
52
#endif /* CRS */
53
 
54
/* Private macro -------------------------------------------------------------*/
55
/** @defgroup RCCEx_Private_Macros RCCEx Private Macros
56
  * @{
57
  */
58
/**
59
  * @}
60
  */
61
 
62
/* Private variables ---------------------------------------------------------*/
63
/* Private function prototypes -----------------------------------------------*/
64
/* Private functions ---------------------------------------------------------*/
65
 
66
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
67
  * @{
68
  */
69
 
70
/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
71
  * @brief    Extended Peripheral Control functions
72
 *
73
@verbatim
74
 ===============================================================================
75
                ##### Extended Peripheral Control functions  #####
76
 ===============================================================================  
77
    [..]
78
    This subsection provides a set of functions allowing to control the RCC Clocks
79
    frequencies.
80
    [..]
81
    (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
82
        select the RTC clock source; in this case the Backup domain will be reset in  
83
        order to modify the RTC Clock source, as consequence RTC registers (including
84
        the backup registers) are set to their reset values.
85
 
86
@endverbatim
87
  * @{
88
  */
89
 
90
/**
91
  * @brief  Initializes the RCC extended peripherals clocks according to the specified
92
  *         parameters in the RCC_PeriphCLKInitTypeDef.
93
  * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
94
  *         contains the configuration information for the Extended Peripherals clocks
95
  *         (USART, RTC, I2C, CEC and USB).
96
  *
97
  * @note   Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
98
  *         the RTC clock source; in this case the Backup domain will be reset in  
99
  *         order to modify the RTC Clock source, as consequence RTC registers (including
100
  *         the backup registers) and RCC_BDCR register are set to their reset values.
101
  *
102
  * @retval HAL status
103
  */
104
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
105
{
106
  uint32_t tickstart = 0U;
107
  uint32_t temp_reg = 0U;
108
 
109
  /* Check the parameters */
110
  assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
111
 
112
  /*---------------------------- RTC configuration -------------------------------*/
113
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
114
  {
115
    /* check for RTC Parameters used to output RTCCLK */
116
    assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
117
 
118
    FlagStatus       pwrclkchanged = RESET;
119
 
120
    /* As soon as function is called to change RTC clock source, activation of the
121
       power domain is done. */
122
    /* Requires to enable write access to Backup Domain of necessary */
123
    if(__HAL_RCC_PWR_IS_CLK_DISABLED())
124
    {
125
    __HAL_RCC_PWR_CLK_ENABLE();
126
      pwrclkchanged = SET;
127
    }
128
 
129
    if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
130
    {
131
      /* Enable write access to Backup domain */
132
      SET_BIT(PWR->CR, PWR_CR_DBP);
133
 
134
      /* Wait for Backup domain Write protection disable */
135
      tickstart = HAL_GetTick();
136
 
137
      while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
138
      {
139
        if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
140
        {
141
          return HAL_TIMEOUT;
142
        }
143
      }
144
    }
145
 
146
    /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
147
    temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
148
    if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
149
    {
150
      /* Store the content of BDCR register before the reset of Backup Domain */
151
      temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
152
      /* RTC Clock selection can be changed only if the Backup Domain is reset */
153
      __HAL_RCC_BACKUPRESET_FORCE();
154
      __HAL_RCC_BACKUPRESET_RELEASE();
155
      /* Restore the Content of BDCR register */
156
      RCC->BDCR = temp_reg;
157
 
158
      /* Wait for LSERDY if LSE was enabled */
159
      if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
160
      {
161
        /* Get Start Tick */
162
        tickstart = HAL_GetTick();
163
 
164
        /* Wait till LSE is ready */  
165
        while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
166
        {
167
          if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
168
          {
169
            return HAL_TIMEOUT;
170
          }
171
        }
172
      }
173
    }
174
    __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
175
 
176
    /* Require to disable power clock if necessary */
177
    if(pwrclkchanged == SET)
178
    {
179
      __HAL_RCC_PWR_CLK_DISABLE();
180
    }
181
  }
182
 
183
  /*------------------------------- USART1 Configuration ------------------------*/
184
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
185
  {
186
    /* Check the parameters */
187
    assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
188
 
189
    /* Configure the USART1 clock source */
190
    __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
191
  }
192
 
193
#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
194
 || defined(STM32F091xC) || defined(STM32F098xx)
195
  /*----------------------------- USART2 Configuration --------------------------*/
196
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
197
  {
198
    /* Check the parameters */
199
    assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
200
 
201
    /* Configure the USART2 clock source */
202
    __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
203
  }
204
#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
205
       /* STM32F091xC || STM32F098xx */
206
 
207
#if defined(STM32F091xC) || defined(STM32F098xx)
208
  /*----------------------------- USART3 Configuration --------------------------*/
209
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
210
  {
211
    /* Check the parameters */
212
    assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
213
 
214
    /* Configure the USART3 clock source */
215
    __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
216
  }
217
#endif /* STM32F091xC || STM32F098xx */  
218
 
219
  /*------------------------------ I2C1 Configuration ------------------------*/
220
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
221
  {
222
    /* Check the parameters */
223
    assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
224
 
225
    /* Configure the I2C1 clock source */
226
    __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
227
  }
228
 
229
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6)
230
  /*------------------------------ USB Configuration ------------------------*/
231
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
232
  {
233
    /* Check the parameters */
234
    assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
235
 
236
    /* Configure the USB clock source */
237
    __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
238
  }
239
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */
240
 
241
#if defined(STM32F042x6) || defined(STM32F048xx)\
242
 || defined(STM32F051x8) || defined(STM32F058xx)\
243
 || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
244
 || defined(STM32F091xC) || defined(STM32F098xx)
245
  /*------------------------------ CEC clock Configuration -------------------*/
246
  if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
247
  {
248
    /* Check the parameters */
249
    assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
250
 
251
    /* Configure the CEC clock source */
252
    __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
253
  }
254
#endif /* STM32F042x6 || STM32F048xx ||                */
255
       /* STM32F051x8 || STM32F058xx ||                */
256
       /* STM32F071xB || STM32F072xB || STM32F078xx || */
257
       /* STM32F091xC || STM32F098xx */
258
 
259
  return HAL_OK;
260
}
261
 
262
/**
263
  * @brief  Get the RCC_ClkInitStruct according to the internal
264
  * RCC configuration registers.
265
  * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
266
  *         returns the configuration information for the Extended Peripherals clocks
267
  *         (USART, RTC, I2C, CEC and USB).
268
  * @retval None
269
  */
270
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
271
{
272
  /* Set all possible values for the extended clock type parameter------------*/
273
  /* Common part first */
274
  PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1   | RCC_PERIPHCLK_RTC;  
275
  /* Get the RTC configuration --------------------------------------------*/
276
  PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
277
  /* Get the USART1 clock configuration --------------------------------------------*/
278
  PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
279
  /* Get the I2C1 clock source -----------------------------------------------*/
280
  PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
281
 
282
#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
283
 || defined(STM32F091xC) || defined(STM32F098xx)
284
  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART2;
285
  /* Get the USART2 clock source ---------------------------------------------*/
286
  PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
287
#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
288
       /* STM32F091xC || STM32F098xx */
289
 
290
#if defined(STM32F091xC) || defined(STM32F098xx)
291
  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART3;
292
  /* Get the USART3 clock source ---------------------------------------------*/
293
  PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
294
#endif /* STM32F091xC || STM32F098xx */
295
 
296
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6)
297
  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
298
  /* Get the USB clock source ---------------------------------------------*/
299
  PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
300
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */
301
 
302
#if defined(STM32F042x6) || defined(STM32F048xx)\
303
 || defined(STM32F051x8) || defined(STM32F058xx)\
304
 || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
305
 || defined(STM32F091xC) || defined(STM32F098xx)
306
  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC;
307
  /* Get the CEC clock source ------------------------------------------------*/
308
  PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
309
#endif /* STM32F042x6 || STM32F048xx ||                */
310
       /* STM32F051x8 || STM32F058xx ||                */
311
       /* STM32F071xB || STM32F072xB || STM32F078xx || */
312
       /* STM32F091xC || STM32F098xx */
313
 
314
}
315
 
316
/**
317
  * @brief  Returns the peripheral clock frequency
318
  * @note   Returns 0 if peripheral clock is unknown
319
  * @param  PeriphClk Peripheral clock identifier
320
  *         This parameter can be one of the following values:
321
  *            @arg @ref RCC_PERIPHCLK_RTC     RTC peripheral clock
322
  *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
323
  *            @arg @ref RCC_PERIPHCLK_I2C1    I2C1 peripheral clock
324
  @if STM32F042x6
325
  *            @arg @ref RCC_PERIPHCLK_USB     USB peripheral clock
326
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
327
  @endif
328
  @if STM32F048xx
329
  *            @arg @ref RCC_PERIPHCLK_USB     USB peripheral clock
330
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
331
  @endif
332
  @if STM32F051x8
333
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
334
  @endif
335
  @if STM32F058xx
336
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
337
  @endif
338
  @if STM32F070x6
339
  *            @arg @ref RCC_PERIPHCLK_USB     USB peripheral clock
340
  @endif
341
  @if STM32F070xB
342
  *            @arg @ref RCC_PERIPHCLK_USB     USB peripheral clock
343
  @endif
344
  @if STM32F071xB
345
  *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
346
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
347
  @endif
348
  @if STM32F072xB
349
  *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
350
  *            @arg @ref RCC_PERIPHCLK_USB     USB peripheral clock
351
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
352
  @endif
353
  @if STM32F078xx
354
  *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
355
  *            @arg @ref RCC_PERIPHCLK_USB     USB peripheral clock
356
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
357
  @endif
358
  @if STM32F091xC
359
  *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
360
  *            @arg @ref RCC_PERIPHCLK_USART3  USART2 peripheral clock
361
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
362
  @endif
363
  @if STM32F098xx
364
  *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
365
  *            @arg @ref RCC_PERIPHCLK_USART3  USART2 peripheral clock
366
  *            @arg @ref RCC_PERIPHCLK_CEC     CEC peripheral clock
367
  @endif
368
  * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
369
  */
370
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
371
{
372
  /* frequency == 0 : means that no available frequency for the peripheral */
373
  uint32_t frequency = 0U;
374
 
375
  uint32_t srcclk = 0U;
376
#if defined(USB)
377
  uint32_t pllmull = 0U, pllsource = 0U, predivfactor = 0U;
378
#endif /* USB */
379
 
380
  /* Check the parameters */
381
  assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
382
 
383
  switch (PeriphClk)
384
  {
385
  case RCC_PERIPHCLK_RTC:
386
    {
387
      /* Get the current RTC source */
388
      srcclk = __HAL_RCC_GET_RTC_SOURCE();
389
 
390
      /* Check if LSE is ready and if RTC clock selection is LSE */
391
      if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
392
      {
393
        frequency = LSE_VALUE;
394
      }
395
      /* Check if LSI is ready and if RTC clock selection is LSI */
396
      else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
397
      {
398
        frequency = LSI_VALUE;
399
      }
400
      /* Check if HSE is ready  and if RTC clock selection is HSI_DIV32*/
401
      else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIV32) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
402
      {
403
        frequency = HSE_VALUE / 32U;
404
      }
405
      break;
406
    }
407
  case RCC_PERIPHCLK_USART1:
408
    {
409
      /* Get the current USART1 source */
410
      srcclk = __HAL_RCC_GET_USART1_SOURCE();
411
 
412
      /* Check if USART1 clock selection is PCLK1 */
413
      if (srcclk == RCC_USART1CLKSOURCE_PCLK1)
414
      {
415
        frequency = HAL_RCC_GetPCLK1Freq();
416
      }
417
      /* Check if HSI is ready and if USART1 clock selection is HSI */
418
      else if ((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
419
      {
420
        frequency = HSI_VALUE;
421
      }
422
      /* Check if USART1 clock selection is SYSCLK */
423
      else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK)
424
      {
425
        frequency = HAL_RCC_GetSysClockFreq();
426
      }
427
      /* Check if LSE is ready  and if USART1 clock selection is LSE */
428
      else if ((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
429
      {
430
        frequency = LSE_VALUE;
431
      }
432
      break;
433
    }
434
#if defined(RCC_CFGR3_USART2SW)
435
  case RCC_PERIPHCLK_USART2:
436
    {
437
      /* Get the current USART2 source */
438
      srcclk = __HAL_RCC_GET_USART2_SOURCE();
439
 
440
      /* Check if USART2 clock selection is PCLK1 */
441
      if (srcclk == RCC_USART2CLKSOURCE_PCLK1)
442
      {
443
        frequency = HAL_RCC_GetPCLK1Freq();
444
      }
445
      /* Check if HSI is ready and if USART2 clock selection is HSI */
446
      else if ((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
447
      {
448
        frequency = HSI_VALUE;
449
      }
450
      /* Check if USART2 clock selection is SYSCLK */
451
      else if (srcclk == RCC_USART2CLKSOURCE_SYSCLK)
452
      {
453
        frequency = HAL_RCC_GetSysClockFreq();
454
      }
455
      /* Check if LSE is ready  and if USART2 clock selection is LSE */
456
      else if ((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
457
      {
458
        frequency = LSE_VALUE;
459
      }
460
      break;
461
    }
462
#endif /* RCC_CFGR3_USART2SW */
463
#if defined(RCC_CFGR3_USART3SW)
464
  case RCC_PERIPHCLK_USART3:
465
    {
466
      /* Get the current USART3 source */
467
      srcclk = __HAL_RCC_GET_USART3_SOURCE();
468
 
469
      /* Check if USART3 clock selection is PCLK1 */
470
      if (srcclk == RCC_USART3CLKSOURCE_PCLK1)
471
      {
472
        frequency = HAL_RCC_GetPCLK1Freq();
473
      }
474
      /* Check if HSI is ready and if USART3 clock selection is HSI */
475
      else if ((srcclk == RCC_USART3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
476
      {
477
        frequency = HSI_VALUE;
478
      }
479
      /* Check if USART3 clock selection is SYSCLK */
480
      else if (srcclk == RCC_USART3CLKSOURCE_SYSCLK)
481
      {
482
        frequency = HAL_RCC_GetSysClockFreq();
483
      }
484
      /* Check if LSE is ready  and if USART3 clock selection is LSE */
485
      else if ((srcclk == RCC_USART3CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
486
      {
487
        frequency = LSE_VALUE;
488
      }
489
      break;
490
    }
491
#endif /* RCC_CFGR3_USART3SW */
492
  case RCC_PERIPHCLK_I2C1:
493
    {
494
      /* Get the current I2C1 source */
495
      srcclk = __HAL_RCC_GET_I2C1_SOURCE();
496
 
497
      /* Check if HSI is ready and if I2C1 clock selection is HSI */
498
      if ((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
499
      {
500
        frequency = HSI_VALUE;
501
      }
502
      /* Check if I2C1 clock selection is SYSCLK */
503
      else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
504
      {
505
        frequency = HAL_RCC_GetSysClockFreq();
506
      }
507
      break;
508
    }
509
#if defined(USB)
510
  case RCC_PERIPHCLK_USB:
511
    {
512
      /* Get the current USB source */
513
      srcclk = __HAL_RCC_GET_USB_SOURCE();
514
 
515
      /* Check if PLL is ready and if USB clock selection is PLL */
516
      if ((srcclk == RCC_USBCLKSOURCE_PLL) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)))
517
      {
518
        /* Get PLL clock source and multiplication factor ----------------------*/
519
        pllmull      = RCC->CFGR & RCC_CFGR_PLLMUL;
520
        pllsource    = RCC->CFGR & RCC_CFGR_PLLSRC;
521
        pllmull      = (pllmull >> RCC_CFGR_PLLMUL_BITNUMBER) + 2U;
522
        predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1U;
523
 
524
        if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
525
        {
526
          /* HSE used as PLL clock source : frequency = HSE/PREDIV * PLLMUL */
527
          frequency = (HSE_VALUE/predivfactor) * pllmull;
528
        }
529
#if defined(RCC_CR2_HSI48ON)
530
        else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV)
531
        {
532
          /* HSI48 used as PLL clock source : frequency = HSI48/PREDIV * PLLMUL */
533
          frequency = (HSI48_VALUE / predivfactor) * pllmull;
534
        }
535
#endif /* RCC_CR2_HSI48ON */
536
        else
537
        {
538
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F078xx) || defined(STM32F072xB) || defined(STM32F070xB)
539
          /* HSI used as PLL clock source : frequency = HSI/PREDIV * PLLMUL */
540
          frequency = (HSI_VALUE / predivfactor) * pllmull;
541
#else
542
          /* HSI used as PLL clock source : frequency = HSI/2U * PLLMUL */
543
          frequency = (HSI_VALUE >> 1U) * pllmull;
544
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB */
545
        }
546
      }
547
#if defined(RCC_CR2_HSI48ON)
548
      /* Check if HSI48 is ready and if USB clock selection is HSI48 */
549
      else if ((srcclk == RCC_USBCLKSOURCE_HSI48) && (HAL_IS_BIT_SET(RCC->CR2, RCC_CR2_HSI48RDY)))
550
      {
551
        frequency = HSI48_VALUE;
552
      }
553
#endif /* RCC_CR2_HSI48ON */
554
      break;
555
    }
556
#endif /* USB */
557
#if defined(CEC)
558
  case RCC_PERIPHCLK_CEC:
559
    {
560
      /* Get the current CEC source */
561
      srcclk = __HAL_RCC_GET_CEC_SOURCE();
562
 
563
      /* Check if HSI is ready and if CEC clock selection is HSI */
564
      if ((srcclk == RCC_CECCLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
565
      {
566
        frequency = HSI_VALUE;
567
      }
568
      /* Check if LSE is ready  and if CEC clock selection is LSE */
569
      else if ((srcclk == RCC_CECCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
570
      {
571
        frequency = LSE_VALUE;
572
      }
573
      break;
574
    }
575
#endif /* CEC */
576
  default:
577
    {
578
      break;
579
    }
580
  }
581
  return(frequency);
582
}
583
 
584
/**
585
  * @}
586
  */
587
 
588
#if defined(CRS)
589
 
590
/** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
591
 *  @brief  Extended Clock Recovery System Control functions
592
 *
593
@verbatim
594
 ===============================================================================
595
                ##### Extended Clock Recovery System Control functions  #####
596
 ===============================================================================
597
    [..]
6 mjames 598
      For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
2 mjames 599
 
600
      (#) In System clock config, HSI48 needs to be enabled
601
 
602
      (#) Enable CRS clock in IP MSP init which will use CRS functions
603
 
604
      (#) Call CRS functions as follows:
605
          (##) Prepare synchronization configuration necessary for HSI48 calibration
606
              (+++) Default values can be set for frequency Error Measurement (reload and error limit)
607
                        and also HSI48 oscillator smooth trimming.
6 mjames 608
              (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
2 mjames 609
                        directly reload value with target and synchronization frequencies values
6 mjames 610
          (##) Call function HAL_RCCEx_CRSConfig which
2 mjames 611
              (+++) Reset CRS registers to their default values.
612
              (+++) Configure CRS registers with synchronization configuration
613
              (+++) Enable automatic calibration and frequency error counter feature
614
           Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
615
           periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
616
           provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
617
           precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
618
           should be used as SYNC signal.
619
 
620
          (##) A polling function is provided to wait for complete synchronization
6 mjames 621
              (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
2 mjames 622
              (+++) According to CRS status, user can decide to adjust again the calibration or continue
623
                        application if synchronization is OK
624
 
625
      (#) User can retrieve information related to synchronization in calling function
6 mjames 626
            HAL_RCCEx_CRSGetSynchronizationInfo()
2 mjames 627
 
628
      (#) Regarding synchronization status and synchronization information, user can try a new calibration
629
           in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
630
           Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
631
           it means that the actual frequency is lower than the target (and so, that the TRIM value should be
632
           incremented), while when it is detected during the upcounting phase it means that the actual frequency
633
           is higher (and that the TRIM value should be decremented).
634
 
635
      (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
636
          through CRS Handler (RCC_IRQn/RCC_IRQHandler)
6 mjames 637
              (++) Call function HAL_RCCEx_CRSConfig()
2 mjames 638
              (++) Enable RCC_IRQn (thanks to NVIC functions)
6 mjames 639
              (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
2 mjames 640
              (++) Implement CRS status management in the following user callbacks called from
641
                   HAL_RCCEx_CRS_IRQHandler():
6 mjames 642
                   (+++) HAL_RCCEx_CRS_SyncOkCallback()
643
                   (+++) HAL_RCCEx_CRS_SyncWarnCallback()
644
                   (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
645
                   (+++) HAL_RCCEx_CRS_ErrorCallback()
2 mjames 646
 
6 mjames 647
      (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
648
          This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
2 mjames 649
 
650
@endverbatim
651
 * @{
652
 */
653
 
654
/**
655
  * @brief  Start automatic synchronization for polling mode
656
  * @param  pInit Pointer on RCC_CRSInitTypeDef structure
657
  * @retval None
658
  */
659
void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
660
{
661
  uint32_t value = 0U;
662
 
663
  /* Check the parameters */
664
  assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
665
  assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
666
  assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
667
  assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
668
  assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
669
  assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
670
 
671
  /* CONFIGURATION */
672
 
673
  /* Before configuration, reset CRS registers to their default values*/
674
  __HAL_RCC_CRS_FORCE_RESET();
675
  __HAL_RCC_CRS_RELEASE_RESET();
676
 
677
  /* Set the SYNCDIV[2:0] bits according to Prescaler value */
678
  /* Set the SYNCSRC[1:0] bits according to Source value */
679
  /* Set the SYNCSPOL bit according to Polarity value */
680
  value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
681
  /* Set the RELOAD[15:0] bits according to ReloadValue value */
682
  value |= pInit->ReloadValue;
683
  /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
684
  value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER);
685
  WRITE_REG(CRS->CFGR, value);
686
 
687
  /* Adjust HSI48 oscillator smooth trimming */
688
  /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
689
  MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER));
690
 
691
  /* START AUTOMATIC SYNCHRONIZATION*/
692
 
693
  /* Enable Automatic trimming & Frequency error counter */
694
  SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
695
}
696
 
697
/**
698
  * @brief  Generate the software synchronization event
699
  * @retval None
700
  */
701
void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
702
{
703
  SET_BIT(CRS->CR, CRS_CR_SWSYNC);
704
}
705
 
706
/**
707
  * @brief  Return synchronization info
708
  * @param  pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
709
  * @retval None
710
  */
711
void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
712
{
713
  /* Check the parameter */
714
  assert_param(pSynchroInfo != NULL);
715
 
716
  /* Get the reload value */
717
  pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
718
 
719
  /* Get HSI48 oscillator smooth trimming */
720
  pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER);
721
 
722
  /* Get Frequency error capture */
723
  pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER);
724
 
725
  /* Get Frequency error direction */
726
  pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
727
}
728
 
729
/**
730
* @brief Wait for CRS Synchronization status.
731
* @param Timeout  Duration of the timeout
732
* @note  Timeout is based on the maximum time to receive a SYNC event based on synchronization
733
*        frequency.
734
* @note    If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
735
* @retval Combination of Synchronization status
736
*          This parameter can be a combination of the following values:
737
*            @arg @ref RCC_CRS_TIMEOUT
738
*            @arg @ref RCC_CRS_SYNCOK
739
*            @arg @ref RCC_CRS_SYNCWARN
740
*            @arg @ref RCC_CRS_SYNCERR
741
*            @arg @ref RCC_CRS_SYNCMISS
742
*            @arg @ref RCC_CRS_TRIMOVF
743
*/
744
uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
745
{
746
  uint32_t crsstatus = RCC_CRS_NONE;
747
  uint32_t tickstart = 0U;
748
 
749
  /* Get timeout */
750
  tickstart = HAL_GetTick();
751
 
752
  /* Wait for CRS flag or timeout detection */
753
  do
754
  {
755
    if(Timeout != HAL_MAX_DELAY)
756
    {
757
      if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
758
      {
759
        crsstatus = RCC_CRS_TIMEOUT;
760
      }
761
    }
762
    /* Check CRS SYNCOK flag  */
763
    if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
764
    {
765
      /* CRS SYNC event OK */
766
      crsstatus |= RCC_CRS_SYNCOK;
767
 
768
      /* Clear CRS SYNC event OK bit */
769
      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
770
    }
771
 
772
    /* Check CRS SYNCWARN flag  */
773
    if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
774
    {
775
      /* CRS SYNC warning */
776
      crsstatus |= RCC_CRS_SYNCWARN;
777
 
778
      /* Clear CRS SYNCWARN bit */
779
      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
780
    }
781
 
782
    /* Check CRS TRIM overflow flag  */
783
    if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
784
    {
785
      /* CRS SYNC Error */
786
      crsstatus |= RCC_CRS_TRIMOVF;
787
 
788
      /* Clear CRS Error bit */
789
      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
790
    }
791
 
792
    /* Check CRS Error flag  */
793
    if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
794
    {
795
      /* CRS SYNC Error */
796
      crsstatus |= RCC_CRS_SYNCERR;
797
 
798
      /* Clear CRS Error bit */
799
      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
800
    }
801
 
802
    /* Check CRS SYNC Missed flag  */
803
    if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
804
    {
805
      /* CRS SYNC Missed */
806
      crsstatus |= RCC_CRS_SYNCMISS;
807
 
808
      /* Clear CRS SYNC Missed bit */
809
      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
810
    }
811
 
812
    /* Check CRS Expected SYNC flag  */
813
    if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
814
    {
815
      /* frequency error counter reached a zero value */
816
      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
817
    }
818
  } while(RCC_CRS_NONE == crsstatus);
819
 
820
  return crsstatus;
821
}
822
 
823
/**
824
  * @brief Handle the Clock Recovery System interrupt request.
825
  * @retval None
826
  */
827
void HAL_RCCEx_CRS_IRQHandler(void)
828
{
829
  uint32_t crserror = RCC_CRS_NONE;
830
  /* Get current IT flags and IT sources values */
831
  uint32_t itflags = READ_REG(CRS->ISR);
832
  uint32_t itsources = READ_REG(CRS->CR);
833
 
834
  /* Check CRS SYNCOK flag  */
835
  if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET))
836
  {
837
    /* Clear CRS SYNC event OK flag */
838
    WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
839
 
840
    /* user callback */
841
    HAL_RCCEx_CRS_SyncOkCallback();
842
  }
843
  /* Check CRS SYNCWARN flag  */
844
  else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET))
845
  {
846
    /* Clear CRS SYNCWARN flag */
847
    WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
848
 
849
    /* user callback */
850
    HAL_RCCEx_CRS_SyncWarnCallback();
851
  }
852
  /* Check CRS Expected SYNC flag  */
853
  else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET))
854
  {
855
    /* frequency error counter reached a zero value */
856
    WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
857
 
858
    /* user callback */
859
    HAL_RCCEx_CRS_ExpectedSyncCallback();
860
  }
861
  /* Check CRS Error flags  */
862
  else
863
  {
864
    if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET))
865
    {
866
      if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET)
867
      {
868
        crserror |= RCC_CRS_SYNCERR;
869
      }
870
      if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET)
871
      {
872
        crserror |= RCC_CRS_SYNCMISS;
873
      }
874
      if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET)
875
      {
876
        crserror |= RCC_CRS_TRIMOVF;
877
      }
878
 
879
      /* Clear CRS Error flags */
880
      WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
881
 
882
      /* user error callback */
883
      HAL_RCCEx_CRS_ErrorCallback(crserror);
884
    }
885
  }
886
}
887
 
888
/**
889
  * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
890
  * @retval none
891
  */
892
__weak void HAL_RCCEx_CRS_SyncOkCallback(void)
893
{
894
  /* NOTE : This function should not be modified, when the callback is needed,
895
            the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
896
   */
897
}
898
 
899
/**
900
  * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
901
  * @retval none
902
  */
903
__weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
904
{
905
  /* NOTE : This function should not be modified, when the callback is needed,
906
            the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
907
   */
908
}
909
 
910
/**
911
  * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
912
  * @retval none
913
  */
914
__weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
915
{
916
  /* NOTE : This function should not be modified, when the callback is needed,
917
            the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
918
   */
919
}
920
 
921
/**
922
  * @brief  RCCEx Clock Recovery System Error interrupt callback.
923
  * @param  Error Combination of Error status.
924
  *         This parameter can be a combination of the following values:
925
  *           @arg @ref RCC_CRS_SYNCERR
926
  *           @arg @ref RCC_CRS_SYNCMISS
927
  *           @arg @ref RCC_CRS_TRIMOVF
928
  * @retval none
929
  */
930
__weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
931
{
932
  /* Prevent unused argument(s) compilation warning */
933
  UNUSED(Error);
934
 
935
  /* NOTE : This function should not be modified, when the callback is needed,
936
            the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
937
   */
938
}
939
 
940
/**
941
  * @}
942
  */
943
 
944
#endif /* CRS */
945
 
946
/**
947
  * @}
948
  */
949
 
950
/**
951
  * @}
952
  */
953
 
954
/**
955
  * @}
956
  */
957
 
958
#endif /* HAL_RCC_MODULE_ENABLED */
959
 
960
/**
961
  * @}
962
  */
963
 
964
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/