1 /**
2 ******************************************************************************
3 * @file stm32l0xx_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>© 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 "stm32l0xx_hal.h"
43
44 /** @addtogroup STM32L0xx_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 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
58 * @{
59 */
60 #if defined (CRS)
61 /* Bit position in register */
62 #define CRS_CFGR_FELIM_BITNUMBER CRS_CFGR_FELIM_Pos
63 #define CRS_CR_TRIM_BITNUMBER CRS_CR_TRIM_Pos
64 #define CRS_ISR_FECAP_BITNUMBER CRS_ISR_FECAP_Pos
65 #endif /* CRS */
66
67 #if defined(USB)
68 extern const uint8_t PLLMulTable[];
69 #endif /* USB */
70 /**
71 * @}
72 */
73
74 /* Private macro -------------------------------------------------------------*/
75 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
76 * @{
77 */
78 /**
79 * @}
80 */
81
82 /* Private variables ---------------------------------------------------------*/
83 /* Private function prototypes -----------------------------------------------*/
84 /* Private functions ---------------------------------------------------------*/
85
86 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
87 * @{
88 */
89
90 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
91 * @brief Extended Peripheral Control functions
92 *
93 @verbatim
94 ===============================================================================
95 ##### Extended Peripheral Control functions #####
96 ===============================================================================
97 [..]
98 This subsection provides a set of functions allowing to control the RCC Clocks
99 frequencies.
100 [..]
101 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
102 select the RTC clock source; in this case the Backup domain will be reset in
103 order to modify the RTC Clock source, as consequence RTC registers (including
104 the backup registers) are set to their reset values.
105
106 @endverbatim
107 * @{
108 */
109
110 /**
111 * @brief Initializes the RCC extended peripherals clocks according to the specified
112 * parameters in the RCC_PeriphCLKInitTypeDef.
113 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
114 * contains the configuration information for the Extended Peripherals clocks(USART1,USART2, LPUART1,
115 * I2C1, I2C3, RTC, USB/RNG and LPTIM1 clocks).
116 * @retval HAL status
117 * @note If HAL_ERROR returned, first switch-OFF HSE clock oscillator with @ref HAL_RCC_OscConfig()
118 * to possibly update HSE divider.
119 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)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/LCD Configuration ------------------------*/
129 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
130 #if defined(LCD)
131 || (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)
132 #endif /* LCD */
133 )
134 {
135 /* check for RTC Parameters used to output RTCCLK */
136 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
137 {
138 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
139 }
140
141 #if defined(LCD)
142 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)
143 {
144 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->LCDClockSelection));
145 }
146 #endif /* LCD */
147
148 FlagStatus pwrclkchanged = RESET;
149
150 /* As soon as function is called to change RTC clock source, activation of the
151 power domain is done. */
152 /* Requires to enable write access to Backup Domain of necessary */
153 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
154 {
155 __HAL_RCC_PWR_CLK_ENABLE();
156 pwrclkchanged = SET;
157 }
158
159 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
160 {
161 /* Enable write access to Backup domain */
162 SET_BIT(PWR->CR, PWR_CR_DBP);
163
164 /* Wait for Backup domain Write protection disable */
165 tickstart = HAL_GetTick();
166
167 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
168 {
169 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
170 {
171 return HAL_TIMEOUT;
172 }
173 }
174 }
175
176 /* Check if user wants to change HSE RTC prescaler whereas HSE is enabled */
177 temp_reg = (RCC->CR & RCC_CR_RTCPRE);
178 if ((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CR_RTCPRE))
179 #if defined (LCD)
180 || (temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CR_RTCPRE))
181 #endif /* LCD */
182 )
183 { /* Check HSE State */
184 if (((PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL) == RCC_CSR_RTCSEL_HSE) && HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
185 {
186 /* To update HSE divider, first switch-OFF HSE clock oscillator*/
187 return HAL_ERROR;
188 }
189 }
190
191 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
192 temp_reg = (RCC->CSR & RCC_CSR_RTCSEL);
193
194 if((temp_reg != 0x00000000U) && (((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL)) \
195 && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
196 #if defined(LCD)
197 || ((temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CSR_RTCSEL)) \
198 && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD))
199 #endif /* LCD */
200 ))
201 {
202 /* Store the content of CSR register before the reset of Backup Domain */
203 temp_reg = (RCC->CSR & ~(RCC_CSR_RTCSEL));
204
205 /* RTC Clock selection can be changed only if the Backup Domain is reset */
206 __HAL_RCC_BACKUPRESET_FORCE();
207 __HAL_RCC_BACKUPRESET_RELEASE();
208
209 /* Restore the Content of CSR register */
210 RCC->CSR = temp_reg;
211
212 /* Wait for LSERDY if LSE was enabled */
213 if (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSEON))
214 {
215 /* Get Start Tick */
216 tickstart = HAL_GetTick();
217
218 /* Wait till LSE is ready */
219 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
220 {
221 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
222 {
223 return HAL_TIMEOUT;
224 }
225 }
226 }
227 }
228 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
229
230 /* Require to disable power clock if necessary */
231 if(pwrclkchanged == SET)
232 {
233 __HAL_RCC_PWR_CLK_DISABLE();
234 }
235 }
236
237 #if defined (RCC_CCIPR_USART1SEL)
238 /*------------------------------- USART1 Configuration ------------------------*/
239 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
240 {
241 /* Check the parameters */
242 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
243
244 /* Configure the USART1 clock source */
245 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
246 }
247 #endif /* RCC_CCIPR_USART1SEL */
248
249 /*----------------------------- USART2 Configuration --------------------------*/
250 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
251 {
252 /* Check the parameters */
253 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
254
255 /* Configure the USART2 clock source */
256 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
257 }
258
259 /*------------------------------ LPUART1 Configuration ------------------------*/
260 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
261 {
262 /* Check the parameters */
263 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
264
265 /* Configure the LPUAR1 clock source */
266 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
267 }
268
269 /*------------------------------ I2C1 Configuration ------------------------*/
270 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
271 {
272 /* Check the parameters */
273 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
274
275 /* Configure the I2C1 clock source */
276 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
277 }
278
279 #if defined (RCC_CCIPR_I2C3SEL)
280 /*------------------------------ I2C3 Configuration ------------------------*/
281 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
282 {
283 /* Check the parameters */
284 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
285
286 /* Configure the I2C3 clock source */
287 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
288 }
289 #endif /* RCC_CCIPR_I2C3SEL */
290
291 #if defined(USB)
292 /*---------------------------- USB and RNG configuration --------------------*/
293 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
294 {
295 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
296 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
297 }
298 #endif /* USB */
299
300 /*---------------------------- LPTIM1 configuration ------------------------*/
301 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
302 {
303 assert_param(IS_RCC_LPTIMCLK(PeriphClkInit->LptimClockSelection));
304 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->LptimClockSelection);
305 }
306
307 return HAL_OK;
308 }
309
310 /**
311 * @brief Get the PeriphClkInit according to the internal RCC configuration registers.
312 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
313 * returns the configuration information for the Extended Peripherals clocks(USART1,USART2, LPUART1,
314 * I2C1, I2C3, RTC, USB/RNG and LPTIM1 clocks).
315 * @retval None
316 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)317 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
318 {
319 uint32_t srcclk = 0;
320
321 /* Set all possible values for the extended clock type parameter -----------*/
322 /* Common part first */
323 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \
324 RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | \
325 RCC_PERIPHCLK_LPTIM1;
326 #if defined(RCC_CCIPR_USART1SEL)
327 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART1;
328 #endif /* RCC_CCIPR_USART1SEL */
329 #if defined(RCC_CCIPR_I2C3SEL)
330 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3;
331 #endif /* RCC_CCIPR_I2C3SEL */
332 #if defined(USB)
333 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
334 #endif /* USB */
335 #if defined(LCD)
336 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LCD;
337 #endif /* LCD */
338
339 /* Get the RTC/LCD configuration -----------------------------------------------*/
340 srcclk = __HAL_RCC_GET_RTC_SOURCE();
341 if (srcclk != RCC_RTCCLKSOURCE_HSE_DIV2)
342 {
343 /* Source clock is LSE or LSI*/
344 PeriphClkInit->RTCClockSelection = srcclk;
345 }
346 else
347 {
348 /* Source clock is HSE. Need to get the prescaler value*/
349 PeriphClkInit->RTCClockSelection = srcclk | (READ_BIT(RCC->CR, RCC_CR_RTCPRE));
350 }
351 #if defined(LCD)
352 PeriphClkInit->LCDClockSelection = PeriphClkInit->RTCClockSelection;
353 #endif /* LCD */
354 #if defined(RCC_CCIPR_USART1SEL)
355 /* Get the USART1 configuration --------------------------------------------*/
356 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
357 #endif /* RCC_CCIPR_USART1SEL */
358 /* Get the USART2 clock source ---------------------------------------------*/
359 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
360 /* Get the LPUART1 clock source ---------------------------------------------*/
361 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
362 /* Get the I2C1 clock source -----------------------------------------------*/
363 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
364 #if defined(RCC_CCIPR_I2C3SEL)
365 /* Get the I2C3 clock source -----------------------------------------------*/
366 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
367 #endif /* RCC_CCIPR_I2C3SEL */
368 /* Get the LPTIM1 clock source -----------------------------------------------*/
369 PeriphClkInit->LptimClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
370 /* Get the RTC clock source -----------------------------------------------*/
371 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
372 #if defined(USB)
373 /* Get the USB/RNG clock source -----------------------------------------------*/
374 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
375 #endif /* USB */
376 }
377
378 /**
379 * @brief Return the peripheral clock frequency
380 * @note Return 0 if peripheral clock is unknown
381 * @param PeriphClk Peripheral clock identifier
382 * This parameter can be one of the following values:
383 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
384 * @arg @ref RCC_PERIPHCLK_LCD LCD peripheral clock (*)
385 * @arg @ref RCC_PERIPHCLK_USB USB or RNG peripheral clock (*)
386 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock (*)
387 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
388 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
389 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
390 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock (*)
391 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock (*)
392 * @note (*) means that this peripheral is not present on all the devices
393 * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
394 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)395 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
396 {
397 uint32_t temp_reg = 0U, clkprediv = 0U, frequency = 0U;
398 uint32_t srcclk = 0U;
399 #if defined(USB)
400 uint32_t pllmul = 0U, plldiv = 0U, pllvco = 0U;
401 #endif /* USB */
402
403 /* Check the parameters */
404 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
405
406 switch (PeriphClk)
407 {
408 case RCC_PERIPHCLK_RTC:
409 #if defined(LCD)
410 case RCC_PERIPHCLK_LCD:
411 #endif /* LCD */
412 {
413 /* Get RCC CSR configuration ------------------------------------------------------*/
414 temp_reg = RCC->CSR;
415
416 /* Get the current RTC source */
417 srcclk = __HAL_RCC_GET_RTC_SOURCE();
418
419 /* Check if LSE is ready if RTC clock selection is LSE */
420 if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY)))
421 {
422 frequency = LSE_VALUE;
423 }
424 /* Check if LSI is ready if RTC clock selection is LSI */
425 else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSIRDY)))
426 {
427 frequency = LSI_VALUE;
428 }
429 /* Check if HSE is ready and if RTC clock selection is HSE */
430 else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIVX) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
431 {
432 /* Get the current HSE clock divider */
433 clkprediv = __HAL_RCC_GET_RTC_HSE_PRESCALER();
434
435 switch (clkprediv)
436 {
437 case RCC_RTC_HSE_DIV_16: /* HSE DIV16 has been selected */
438 {
439 frequency = HSE_VALUE / 16U;
440 break;
441 }
442 case RCC_RTC_HSE_DIV_8: /* HSE DIV8 has been selected */
443 {
444 frequency = HSE_VALUE / 8U;
445 break;
446 }
447 case RCC_RTC_HSE_DIV_4: /* HSE DIV4 has been selected */
448 {
449 frequency = HSE_VALUE / 4U;
450 break;
451 }
452 default: /* HSE DIV2 has been selected */
453 {
454 frequency = HSE_VALUE / 2U;
455 break;
456 }
457 }
458 }
459 /* Clock not enabled for RTC */
460 else
461 {
462 frequency = 0U;
463 }
464 break;
465 }
466 #if defined(USB)
467 case RCC_PERIPHCLK_USB:
468 {
469 /* Get the current USB source */
470 srcclk = __HAL_RCC_GET_USB_SOURCE();
471
472 if((srcclk == RCC_USBCLKSOURCE_PLL) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)))
473 {
474 /* Get PLL clock source and multiplication factor ----------------------*/
475 pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
476 plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
477 pllmul = PLLMulTable[(pllmul >> RCC_CFGR_PLLMUL_Pos)];
478 plldiv = (plldiv >> RCC_CFGR_PLLDIV_Pos) + 1U;
479
480 /* Compute PLL clock input */
481 if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)
482 {
483 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
484 {
485 pllvco = (HSI_VALUE >> 2U);
486 }
487 else
488 {
489 pllvco = HSI_VALUE;
490 }
491 }
492 else /* HSE source */
493 {
494 pllvco = HSE_VALUE;
495 }
496 /* pllvco * pllmul / plldiv */
497 pllvco = (pllvco * pllmul);
498 frequency = (pllvco/ plldiv);
499
500 }
501 else if((srcclk == RCC_USBCLKSOURCE_HSI48) && (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)))
502 {
503 frequency = HSI48_VALUE;
504 }
505 else /* RCC_USBCLKSOURCE_NONE */
506 {
507 frequency = 0U;
508 }
509 break;
510 }
511 #endif /* USB */
512 #if defined(RCC_CCIPR_USART1SEL)
513 case RCC_PERIPHCLK_USART1:
514 {
515 /* Get the current USART1 source */
516 srcclk = __HAL_RCC_GET_USART1_SOURCE();
517
518 /* Check if USART1 clock selection is PCLK2 */
519 if (srcclk == RCC_USART1CLKSOURCE_PCLK2)
520 {
521 frequency = HAL_RCC_GetPCLK2Freq();
522 }
523 /* Check if HSI is ready and if USART1 clock selection is HSI */
524 else if ((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
525 {
526 frequency = HSI_VALUE;
527 }
528 /* Check if USART1 clock selection is SYSCLK */
529 else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK)
530 {
531 frequency = HAL_RCC_GetSysClockFreq();
532 }
533 /* Check if LSE is ready and if USART1 clock selection is LSE */
534 else if ((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY)))
535 {
536 frequency = LSE_VALUE;
537 }
538 /* Clock not enabled for USART1*/
539 else
540 {
541 frequency = 0U;
542 }
543 break;
544 }
545 #endif /* RCC_CCIPR_USART1SEL */
546 case RCC_PERIPHCLK_USART2:
547 {
548 /* Get the current USART2 source */
549 srcclk = __HAL_RCC_GET_USART2_SOURCE();
550
551 /* Check if USART2 clock selection is PCLK1 */
552 if (srcclk == RCC_USART2CLKSOURCE_PCLK1)
553 {
554 frequency = HAL_RCC_GetPCLK1Freq();
555 }
556 /* Check if HSI is ready and if USART2 clock selection is HSI */
557 else if ((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
558 {
559 frequency = HSI_VALUE;
560 }
561 /* Check if USART2 clock selection is SYSCLK */
562 else if (srcclk == RCC_USART2CLKSOURCE_SYSCLK)
563 {
564 frequency = HAL_RCC_GetSysClockFreq();
565 }
566 /* Check if LSE is ready and if USART2 clock selection is LSE */
567 else if ((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY)))
568 {
569 frequency = LSE_VALUE;
570 }
571 /* Clock not enabled for USART2*/
572 else
573 {
574 frequency = 0U;
575 }
576 break;
577 }
578 case RCC_PERIPHCLK_LPUART1:
579 {
580 /* Get the current LPUART1 source */
581 srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
582
583 /* Check if LPUART1 clock selection is PCLK1 */
584 if (srcclk == RCC_LPUART1CLKSOURCE_PCLK1)
585 {
586 frequency = HAL_RCC_GetPCLK1Freq();
587 }
588 /* Check if HSI is ready and if LPUART1 clock selection is HSI */
589 else if ((srcclk == RCC_LPUART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
590 {
591 frequency = HSI_VALUE;
592 }
593 /* Check if LPUART1 clock selection is SYSCLK */
594 else if (srcclk == RCC_LPUART1CLKSOURCE_SYSCLK)
595 {
596 frequency = HAL_RCC_GetSysClockFreq();
597 }
598 /* Check if LSE is ready and if LPUART1 clock selection is LSE */
599 else if ((srcclk == RCC_LPUART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY)))
600 {
601 frequency = LSE_VALUE;
602 }
603 /* Clock not enabled for LPUART1*/
604 else
605 {
606 frequency = 0U;
607 }
608 break;
609 }
610 case RCC_PERIPHCLK_I2C1:
611 {
612 /* Get the current I2C1 source */
613 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
614
615 /* Check if I2C1 clock selection is PCLK1 */
616 if (srcclk == RCC_I2C1CLKSOURCE_PCLK1)
617 {
618 frequency = HAL_RCC_GetPCLK1Freq();
619 }
620 /* Check if HSI is ready and if I2C1 clock selection is HSI */
621 else if ((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
622 {
623 frequency = HSI_VALUE;
624 }
625 /* Check if I2C1 clock selection is SYSCLK */
626 else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
627 {
628 frequency = HAL_RCC_GetSysClockFreq();
629 }
630 /* Clock not enabled for I2C1*/
631 else
632 {
633 frequency = 0U;
634 }
635 break;
636 }
637 #if defined(I2C2)
638 case RCC_PERIPHCLK_I2C2:
639 {
640
641 /* Check if I2C2 on APB1 clock enabled*/
642 if (READ_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN))==RCC_APB1ENR_I2C2EN)
643 {
644 frequency = HAL_RCC_GetPCLK1Freq();
645 }
646 else
647 {
648 frequency = 0U;
649 }
650 break;
651 }
652 #endif /* I2C2 */
653
654 #if defined(RCC_CCIPR_I2C3SEL)
655 case RCC_PERIPHCLK_I2C3:
656 {
657 /* Get the current I2C1 source */
658 srcclk = __HAL_RCC_GET_I2C3_SOURCE();
659
660 /* Check if I2C3 clock selection is PCLK1 */
661 if (srcclk == RCC_I2C3CLKSOURCE_PCLK1)
662 {
663 frequency = HAL_RCC_GetPCLK1Freq();
664 }
665 /* Check if HSI is ready and if I2C3 clock selection is HSI */
666 else if ((srcclk == RCC_I2C3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
667 {
668 frequency = HSI_VALUE;
669 }
670 /* Check if I2C3 clock selection is SYSCLK */
671 else if (srcclk == RCC_I2C3CLKSOURCE_SYSCLK)
672 {
673 frequency = HAL_RCC_GetSysClockFreq();
674 }
675 /* Clock not enabled for I2C3*/
676 else
677 {
678 frequency = 0U;
679 }
680 break;
681 }
682 #endif /* RCC_CCIPR_I2C3SEL */
683 default:
684 {
685 break;
686 }
687 }
688 return(frequency);
689 }
690
691 /**
692 * @brief Enables the LSE Clock Security System.
693 * @retval None
694 */
HAL_RCCEx_EnableLSECSS(void)695 void HAL_RCCEx_EnableLSECSS(void)
696 {
697 SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ;
698 }
699
700 /**
701 * @brief Disables the LSE Clock Security System.
702 * @note Once enabled this bit cannot be disabled, except after an LSE failure detection
703 * (LSECSSD=1). In that case the software MUST disable the LSECSSON bit.
704 * Reset by power on reset and RTC software reset (RTCRST bit).
705 * @retval None
706 */
HAL_RCCEx_DisableLSECSS(void)707 void HAL_RCCEx_DisableLSECSS(void)
708 {
709 /* Disable LSE CSS */
710 CLEAR_BIT(RCC->CSR, RCC_CSR_LSECSSON) ;
711
712 /* Disable LSE CSS IT */
713 __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
714 }
715
716 /**
717 * @brief Enable the LSE Clock Security System IT & corresponding EXTI line.
718 * @note LSE Clock Security System IT is mapped on RTC EXTI line 19
719 * @retval None
720 */
HAL_RCCEx_EnableLSECSS_IT(void)721 void HAL_RCCEx_EnableLSECSS_IT(void)
722 {
723 /* Enable LSE CSS */
724 SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ;
725
726 /* Enable LSE CSS IT */
727 __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
728
729 /* Enable IT on EXTI Line 19 */
730 __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
731 __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
732 }
733
734 /**
735 * @brief Handle the RCC LSE Clock Security System interrupt request.
736 * @retval None
737 */
HAL_RCCEx_LSECSS_IRQHandler(void)738 void HAL_RCCEx_LSECSS_IRQHandler(void)
739 {
740 /* Check RCC LSE CSSF flag */
741 if(__HAL_RCC_GET_IT(RCC_IT_LSECSS))
742 {
743 /* RCC LSE Clock Security System interrupt user callback */
744 HAL_RCCEx_LSECSS_Callback();
745
746 /* Clear RCC LSE CSS pending bit */
747 __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
748 }
749 }
750
751 /**
752 * @brief RCCEx LSE Clock Security System interrupt callback.
753 * @retval none
754 */
HAL_RCCEx_LSECSS_Callback(void)755 __weak void HAL_RCCEx_LSECSS_Callback(void)
756 {
757 /* NOTE : This function should not be modified, when the callback is needed,
758 the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
759 */
760 }
761
762 #if defined(SYSCFG_CFGR3_ENREF_HSI48)
763 /**
764 * @brief Enables Vrefint for the HSI48.
765 * @note This is functional only if the LOCK is not set
766 * @retval None
767 */
HAL_RCCEx_EnableHSI48_VREFINT(void)768 void HAL_RCCEx_EnableHSI48_VREFINT(void)
769 {
770 /* Enable the Buffer for the ADC by setting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */
771 SET_BIT (SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48);
772 }
773
774 /**
775 * @brief Disables the Vrefint for the HSI48.
776 * @note This is functional only if the LOCK is not set
777 * @retval None
778 */
HAL_RCCEx_DisableHSI48_VREFINT(void)779 void HAL_RCCEx_DisableHSI48_VREFINT(void)
780 {
781 /* Disable the Vrefint by resetting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */
782 CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48);
783 }
784
785 #endif /* SYSCFG_CFGR3_ENREF_HSI48 */
786
787 /**
788 * @}
789 */
790
791 #if defined (CRS)
792
793 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
794 * @brief Extended Clock Recovery System Control functions
795 *
796 @verbatim
797 ===============================================================================
798 ##### Extended Clock Recovery System Control functions #####
799 ===============================================================================
800 [..]
801 For devices with Clock Recovery System feature (CRS), RCC Extention HAL driver can be used as follows:
802
803 (#) In System clock config, HSI48 needs to be enabled
804
805 (#) Enable CRS clock in IP MSP init which will use CRS functions
806
807 (#) Call CRS functions as follows:
808 (##) Prepare synchronization configuration necessary for HSI48 calibration
809 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
810 and also HSI48 oscillator smooth trimming.
811 (+++) Macro @ref __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
812 directly reload value with target and synchronization frequencies values
813 (##) Call function @ref HAL_RCCEx_CRSConfig which
814 (+++) Reset CRS registers to their default values.
815 (+++) Configure CRS registers with synchronization configuration
816 (+++) Enable automatic calibration and frequency error counter feature
817 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
818 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
819 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
820 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
821 should be used as SYNC signal.
822
823 (##) A polling function is provided to wait for complete synchronization
824 (+++) Call function @ref HAL_RCCEx_CRSWaitSynchronization()
825 (+++) According to CRS status, user can decide to adjust again the calibration or continue
826 application if synchronization is OK
827
828 (#) User can retrieve information related to synchronization in calling function
829 @ref HAL_RCCEx_CRSGetSynchronizationInfo()
830
831 (#) Regarding synchronization status and synchronization information, user can try a new calibration
832 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
833 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
834 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
835 incremented), while when it is detected during the upcounting phase it means that the actual frequency
836 is higher (and that the TRIM value should be decremented).
837
838 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
839 through CRS Handler (RCC_IRQn/RCC_IRQHandler)
840 (++) Call function @ref HAL_RCCEx_CRSConfig()
841 (++) Enable RCC_IRQn (thanks to NVIC functions)
842 (++) Enable CRS interrupt (@ref __HAL_RCC_CRS_ENABLE_IT)
843 (++) Implement CRS status management in the following user callbacks called from
844 HAL_RCCEx_CRS_IRQHandler():
845 (+++) @ref HAL_RCCEx_CRS_SyncOkCallback()
846 (+++) @ref HAL_RCCEx_CRS_SyncWarnCallback()
847 (+++) @ref HAL_RCCEx_CRS_ExpectedSyncCallback()
848 (+++) @ref HAL_RCCEx_CRS_ErrorCallback()
849
850 (#) To force a SYNC EVENT, user can use the function @ref HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
851 This function can be called before calling @ref HAL_RCCEx_CRSConfig (for instance in Systick handler)
852
853 @endverbatim
854 * @{
855 */
856
857 /**
858 * @brief Start automatic synchronization for polling mode
859 * @param pInit Pointer on RCC_CRSInitTypeDef structure
860 * @retval None
861 */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)862 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
863 {
864 uint32_t value = 0;
865
866 /* Check the parameters */
867 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
868 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
869 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
870 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
871 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
872 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
873
874 /* CONFIGURATION */
875
876 /* Before configuration, reset CRS registers to their default values*/
877 __HAL_RCC_CRS_FORCE_RESET();
878 __HAL_RCC_CRS_RELEASE_RESET();
879
880 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
881 /* Set the SYNCSRC[1:0] bits according to Source value */
882 /* Set the SYNCSPOL bit according to Polarity value */
883 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
884 /* Set the RELOAD[15:0] bits according to ReloadValue value */
885 value |= pInit->ReloadValue;
886 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
887 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER);
888 WRITE_REG(CRS->CFGR, value);
889
890 /* Adjust HSI48 oscillator smooth trimming */
891 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
892 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER));
893
894 /* START AUTOMATIC SYNCHRONIZATION*/
895
896 /* Enable Automatic trimming & Frequency error counter */
897 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
898 }
899
900 /**
901 * @brief Generate the software synchronization event
902 * @retval None
903 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)904 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
905 {
906 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
907 }
908
909 /**
910 * @brief Return synchronization info
911 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
912 * @retval None
913 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)914 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
915 {
916 /* Check the parameter */
917 assert_param(pSynchroInfo != NULL);
918
919 /* Get the reload value */
920 pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
921
922 /* Get HSI48 oscillator smooth trimming */
923 pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER);
924
925 /* Get Frequency error capture */
926 pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER);
927
928 /* Get Frequency error direction */
929 pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
930 }
931
932 /**
933 * @brief Wait for CRS Synchronization status.
934 * @param Timeout Duration of the timeout
935 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
936 * frequency.
937 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
938 * @retval Combination of Synchronization status
939 * This parameter can be a combination of the following values:
940 * @arg @ref RCC_CRS_TIMEOUT
941 * @arg @ref RCC_CRS_SYNCOK
942 * @arg @ref RCC_CRS_SYNCWARN
943 * @arg @ref RCC_CRS_SYNCERR
944 * @arg @ref RCC_CRS_SYNCMISS
945 * @arg @ref RCC_CRS_TRIMOVF
946 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)947 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
948 {
949 uint32_t crsstatus = RCC_CRS_NONE;
950 uint32_t tickstart = 0U;
951
952 /* Get timeout */
953 tickstart = HAL_GetTick();
954
955 /* Wait for CRS flag or timeout detection */
956 do
957 {
958 if(Timeout != HAL_MAX_DELAY)
959 {
960 if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
961 {
962 crsstatus = RCC_CRS_TIMEOUT;
963 }
964 }
965 /* Check CRS SYNCOK flag */
966 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
967 {
968 /* CRS SYNC event OK */
969 crsstatus |= RCC_CRS_SYNCOK;
970
971 /* Clear CRS SYNC event OK bit */
972 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
973 }
974
975 /* Check CRS SYNCWARN flag */
976 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
977 {
978 /* CRS SYNC warning */
979 crsstatus |= RCC_CRS_SYNCWARN;
980
981 /* Clear CRS SYNCWARN bit */
982 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
983 }
984
985 /* Check CRS TRIM overflow flag */
986 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
987 {
988 /* CRS SYNC Error */
989 crsstatus |= RCC_CRS_TRIMOVF;
990
991 /* Clear CRS Error bit */
992 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
993 }
994
995 /* Check CRS Error flag */
996 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
997 {
998 /* CRS SYNC Error */
999 crsstatus |= RCC_CRS_SYNCERR;
1000
1001 /* Clear CRS Error bit */
1002 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1003 }
1004
1005 /* Check CRS SYNC Missed flag */
1006 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1007 {
1008 /* CRS SYNC Missed */
1009 crsstatus |= RCC_CRS_SYNCMISS;
1010
1011 /* Clear CRS SYNC Missed bit */
1012 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1013 }
1014
1015 /* Check CRS Expected SYNC flag */
1016 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1017 {
1018 /* frequency error counter reached a zero value */
1019 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1020 }
1021 } while(RCC_CRS_NONE == crsstatus);
1022
1023 return crsstatus;
1024 }
1025
1026 /**
1027 * @brief Handle the Clock Recovery System interrupt request.
1028 * @retval None
1029 */
HAL_RCCEx_CRS_IRQHandler(void)1030 void HAL_RCCEx_CRS_IRQHandler(void)
1031 {
1032 uint32_t crserror = RCC_CRS_NONE;
1033 /* Get current IT flags and IT sources values */
1034 uint32_t itflags = READ_REG(CRS->ISR);
1035 uint32_t itsources = READ_REG(CRS->CR);
1036
1037 /* Check CRS SYNCOK flag */
1038 if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET))
1039 {
1040 /* Clear CRS SYNC event OK flag */
1041 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
1042
1043 /* user callback */
1044 HAL_RCCEx_CRS_SyncOkCallback();
1045 }
1046 /* Check CRS SYNCWARN flag */
1047 else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET))
1048 {
1049 /* Clear CRS SYNCWARN flag */
1050 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
1051
1052 /* user callback */
1053 HAL_RCCEx_CRS_SyncWarnCallback();
1054 }
1055 /* Check CRS Expected SYNC flag */
1056 else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET))
1057 {
1058 /* frequency error counter reached a zero value */
1059 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
1060
1061 /* user callback */
1062 HAL_RCCEx_CRS_ExpectedSyncCallback();
1063 }
1064 /* Check CRS Error flags */
1065 else
1066 {
1067 if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET))
1068 {
1069 if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET)
1070 {
1071 crserror |= RCC_CRS_SYNCERR;
1072 }
1073 if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET)
1074 {
1075 crserror |= RCC_CRS_SYNCMISS;
1076 }
1077 if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET)
1078 {
1079 crserror |= RCC_CRS_TRIMOVF;
1080 }
1081
1082 /* Clear CRS Error flags */
1083 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
1084
1085 /* user error callback */
1086 HAL_RCCEx_CRS_ErrorCallback(crserror);
1087 }
1088 }
1089 }
1090
1091 /**
1092 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
1093 * @retval none
1094 */
HAL_RCCEx_CRS_SyncOkCallback(void)1095 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1096 {
1097 /* NOTE : This function should not be modified, when the callback is needed,
1098 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1099 */
1100 }
1101
1102 /**
1103 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
1104 * @retval none
1105 */
HAL_RCCEx_CRS_SyncWarnCallback(void)1106 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1107 {
1108 /* NOTE : This function should not be modified, when the callback is needed,
1109 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1110 */
1111 }
1112
1113 /**
1114 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
1115 * @retval none
1116 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1117 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1118 {
1119 /* NOTE : This function should not be modified, when the callback is needed,
1120 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1121 */
1122 }
1123
1124 /**
1125 * @brief RCCEx Clock Recovery System Error interrupt callback.
1126 * @param Error Combination of Error status.
1127 * This parameter can be a combination of the following values:
1128 * @arg @ref RCC_CRS_SYNCERR
1129 * @arg @ref RCC_CRS_SYNCMISS
1130 * @arg @ref RCC_CRS_TRIMOVF
1131 * @retval none
1132 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1133 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1134 {
1135 /* Prevent unused argument(s) compilation warning */
1136 UNUSED(Error);
1137
1138 /* NOTE : This function should not be modified, when the callback is needed,
1139 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1140 */
1141 }
1142
1143 /**
1144 * @}
1145 */
1146
1147 #endif /* CRS */
1148 /**
1149 * @}
1150 */
1151
1152 /**
1153 * @}
1154 */
1155
1156 /**
1157 * @}
1158 */
1159
1160 #endif /* HAL_RCC_MODULE_ENABLED */
1161 /**
1162 * @}
1163 */
1164
1165 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1166