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