1 /**
2   ******************************************************************************
3   * @file    stm32wlxx_ll_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2020 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 #if defined(USE_FULL_LL_DRIVER)
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32wlxx_ll_rcc.h"
22 #ifdef  USE_FULL_ASSERT
23 #include "stm32_assert.h"
24 #else
25 #define assert_param(expr) ((void)0U)
26 #endif /* USE_FULL_ASSERT */
27 /** @addtogroup STM32WLxx_LL_Driver
28   * @{
29   */
30 
31 #if defined(RCC)
32 
33 /** @addtogroup RCC_LL
34   * @{
35   */
36 
37 /* Private types -------------------------------------------------------------*/
38 /* Private variables ---------------------------------------------------------*/
39 /* Private constants ---------------------------------------------------------*/
40 /* Private macros ------------------------------------------------------------*/
41 /** @addtogroup RCC_LL_Private_Macros
42   * @{
43   */
44 #define IS_LL_RCC_USART_CLKSOURCE(__VALUE__)  (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) || \
45                                                ((__VALUE__) == LL_RCC_USART2_CLKSOURCE))
46 
47 #define IS_LL_RCC_LPUART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPUART1_CLKSOURCE))
48 
49 #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__)    (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) || \
50                                                ((__VALUE__) == LL_RCC_I2C2_CLKSOURCE) || \
51                                                ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE))
52 
53 #define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__)  (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) || \
54                                                ((__VALUE__) == LL_RCC_LPTIM2_CLKSOURCE) || \
55                                                ((__VALUE__) == LL_RCC_LPTIM3_CLKSOURCE))
56 
57 #define IS_LL_RCC_RNG_CLKSOURCE(__VALUE__)    (((__VALUE__) == LL_RCC_RNG_CLKSOURCE))
58 
59 #define IS_LL_RCC_I2S_CLKSOURCE(__VALUE__)    (((__VALUE__) == LL_RCC_I2S2_CLKSOURCE))
60 
61 #define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__)    (((__VALUE__) == LL_RCC_ADC_CLKSOURCE))
62 
63 /**
64   * @}
65   */
66 
67 /* Private function prototypes -----------------------------------------------*/
68 /** @defgroup RCC_LL_Private_Functions RCC Private functions
69   * @{
70   */
71 static uint32_t RCC_PLL_GetFreqDomain_SYS(void);
72 static uint32_t RCC_PLL_GetFreqDomain_ADC(void);
73 static uint32_t RCC_PLL_GetFreqDomain_RNG(void);
74 static uint32_t RCC_PLL_GetFreqDomain_I2S(void);
75 
76 static uint32_t RCC_GetSystemClockFreq(void);
77 
78 static uint32_t RCC_GetHCLK1ClockFreq(uint32_t SYSCLK_Frequency);
79 #if defined(DUAL_CORE)
80 static uint32_t RCC_GetHCLK2ClockFreq(uint32_t SYSCLK_Frequency);
81 #endif /* DUAL_CORE */
82 static uint32_t RCC_GetHCLK3ClockFreq(uint32_t SYSCLK_Frequency);
83 
84 
85 static uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
86 static uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
87 /**
88   * @}
89   */
90 
91 
92 /* Exported functions --------------------------------------------------------*/
93 /** @addtogroup RCC_LL_Exported_Functions
94   * @{
95   */
96 
97 /** @addtogroup RCC_LL_EF_Init
98   * @{
99   */
100 
101 /**
102   * @brief  Reset the RCC clock  to the default reset state.
103   * @note   The default reset state of the clock configuration is given below:
104   *         - MSI ON and used as system clock source
105   *         - HSE, HSI, PLL Source OFF
106   *         - CPU1, CPU2, AHB3, APB1 and APB2 prescaler set to 1.
107   *         - CSS, MCO OFF
108   *         - All interrupts disabled
109   * @note   This function doesn't modify the configuration of the
110   *         - Peripheral clocks
111   *         - LSI, LSE and RTC clocks
112   * @retval An ErrorStatus enumeration value:
113   *          - SUCCESS: RCC registers are de-initialized
114   *          - ERROR: not applicable
115   */
LL_RCC_DeInit(void)116 ErrorStatus LL_RCC_DeInit(void)
117 {
118   __IO uint32_t vl_mask;
119 
120   /* Set MSION bit */
121   LL_RCC_MSI_Enable();
122 
123   /* Insure MSIRDY bit is set before writing default MSIRANGE value */
124   while (LL_RCC_MSI_IsReady() == 0U)
125   {}
126 
127   /* Set MSIRANGE default value */
128   LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6);
129 
130   /* Set MSITRIM bits to the reset value*/
131   LL_RCC_MSI_SetCalibTrimming(0);
132 
133   /* Set HSITRIM bits to the reset value*/
134   LL_RCC_HSI_SetCalibTrimming(0x40U);
135 
136   /* Reset CFGR register */
137   LL_RCC_WriteReg(CFGR, 0x00070000U); /* MSI selected as System Clock and all prescaler to not divided */
138 
139   /* Read CR register */
140   vl_mask = LL_RCC_ReadReg(CR);
141 
142   /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSEBYP, HSEPRE, HSEBYPPWR and PLLSYSON bits */
143   CLEAR_BIT(vl_mask, (RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | \
144                       RCC_CR_HSEPRE | RCC_CR_HSEBYPPWR | RCC_CR_PLLON));
145 
146   /* Write new value in CR register */
147   LL_RCC_WriteReg(CR, vl_mask);
148 
149   /* Wait for PLL READY bit to be reset */
150   while (LL_RCC_PLL_IsReady() != 0U)
151   {}
152 
153   /* Reset PLLCFGR register */
154   LL_RCC_WriteReg(PLLCFGR, 0x22041000U);
155 
156   /* Disable all interrupts */
157   LL_RCC_WriteReg(CIER, 0x00000000U);
158 
159   /* Clear all interrupt flags */
160   vl_mask = RCC_CICR_LSIRDYC | RCC_CICR_LSERDYC | RCC_CICR_MSIRDYC | RCC_CICR_HSIRDYC | \
161             RCC_CICR_HSERDYC | RCC_CICR_PLLRDYC | RCC_CICR_CSSC | RCC_CICR_LSECSSC;
162 
163   LL_RCC_WriteReg(CICR, vl_mask);
164 
165   /* Clear reset flags */
166   LL_RCC_ClearResetFlags();
167 
168   /* EXTCFGR reset*/
169   LL_RCC_WriteReg(EXTCFGR, 0x00030000U);
170 
171   return SUCCESS;
172 }
173 
174 /**
175   * @}
176   */
177 
178 /** @addtogroup RCC_LL_EF_Get_Freq
179   * @brief  Return the frequencies of different on chip clocks;  System, AHB, APB1 and APB2 buses clocks
180   *         and different peripheral clocks available on the device.
181   * @note   If SYSCLK source is MSI, function returns values based on MSI values(*)
182   * @note   If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
183   * @note   If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
184   * @note   If SYSCLK source is PLL, function returns values based on HSE_VALUE(***)
185   *         or HSI_VALUE(**) or MSI values(*) multiplied/divided by the PLL factors.
186   * @note   (*)  MSI values are retrieved thanks to __LL_RCC_CALC_MSI_FREQ macro
187   * @note   (**) HSI_VALUE is a constant defined in this file (default value
188   *              16 MHz) but the real value may vary depending on the variations
189   *              in voltage and temperature.
190   * @note   (***) HSE_VALUE is a constant defined in this file (default value
191   *               32 MHz), user has to ensure that HSE_VALUE is same as the real
192   *               frequency of the crystal used. Otherwise, this function may
193   *               have wrong result.
194   * @note   The result of this function could be incorrect when using fractional
195   *         value for HSE crystal.
196   * @note   This function can be used by the user application to compute the
197   *         baud-rate for the communication peripherals or configure other parameters.
198   * @{
199   */
200 
201 /**
202   * @brief  Return the frequencies of different on chip clocks;  System, AHB, APB1 and APB2 buses clocks
203   * @note   Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
204   *         must be called to update structure fields. Otherwise, any
205   *         configuration based on this function will be incorrect.
206   * @param  RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
207   * @retval None
208   */
LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef * RCC_Clocks)209 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
210 {
211   /* Get SYSCLK frequency */
212   RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
213 
214   /* HCLK1 clock frequency */
215   RCC_Clocks->HCLK1_Frequency   = RCC_GetHCLK1ClockFreq(RCC_Clocks->SYSCLK_Frequency);
216 
217 #if defined(DUAL_CORE)
218   /* HCLK2 clock frequency */
219   RCC_Clocks->HCLK2_Frequency   = RCC_GetHCLK2ClockFreq(RCC_Clocks->SYSCLK_Frequency);
220 #endif /* DUAL_CORE */
221 
222   /* HCLK3 clock frequency */
223   RCC_Clocks->HCLK3_Frequency   = RCC_GetHCLK3ClockFreq(RCC_Clocks->SYSCLK_Frequency);
224 
225   /* PCLK1 clock frequency */
226   RCC_Clocks->PCLK1_Frequency  = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK1_Frequency);
227 
228   /* PCLK2 clock frequency */
229   RCC_Clocks->PCLK2_Frequency  = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK1_Frequency);
230 }
231 
232 /**
233   * @brief  Return USARTx clock frequency
234   * @param  USARTxSource This parameter can be one of the following values:
235   *         @arg @ref LL_RCC_USART1_CLKSOURCE
236   *         @arg @ref LL_RCC_USART1_CLKSOURCE
237   * @retval USART clock frequency (in Hz)
238   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
239   */
LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)240 uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)
241 {
242   uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
243 
244   /* Check parameter */
245   assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource));
246 
247   if (USARTxSource == LL_RCC_USART1_CLKSOURCE)
248   {
249     /* USART1CLK clock frequency */
250     switch (LL_RCC_GetUSARTClockSource(USARTxSource))
251     {
252       case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
253         usart_frequency = RCC_GetSystemClockFreq();
254         break;
255 
256       case LL_RCC_USART1_CLKSOURCE_HSI:    /* USART1 Clock is HSI Osc. */
257         if (LL_RCC_HSI_IsReady() == 1U)
258         {
259           usart_frequency = HSI_VALUE;
260         }
261         break;
262 
263       case LL_RCC_USART1_CLKSOURCE_LSE:    /* USART1 Clock is LSE Osc. */
264         if (LL_RCC_LSE_IsReady() == 1U)
265         {
266           usart_frequency = LSE_VALUE;
267         }
268         break;
269 
270       case LL_RCC_USART1_CLKSOURCE_PCLK2:  /* USART1 Clock is PCLK2 */
271       default:
272         usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
273         break;
274     }
275   }
276   else
277   {
278     /* USART2CLK clock frequency */
279     switch (LL_RCC_GetUSARTClockSource(USARTxSource))
280     {
281       case LL_RCC_USART2_CLKSOURCE_SYSCLK: /* USART2 Clock is System Clock */
282         usart_frequency = RCC_GetSystemClockFreq();
283         break;
284 
285       case LL_RCC_USART2_CLKSOURCE_HSI:    /* USART2 Clock is HSI Osc. */
286         if (LL_RCC_HSI_IsReady() == 1U)
287         {
288           usart_frequency = HSI_VALUE;
289         }
290         break;
291 
292       case LL_RCC_USART2_CLKSOURCE_LSE:    /* USART2 Clock is LSE Osc. */
293         if (LL_RCC_LSE_IsReady() == 1U)
294         {
295           usart_frequency = LSE_VALUE;
296         }
297         break;
298 
299       case LL_RCC_USART2_CLKSOURCE_PCLK1:  /* USART2 Clock is PCLK2 */
300       default:
301         usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
302         break;
303     }
304   }
305   return usart_frequency;
306 }
307 
308 /**
309   * @brief  Return I2Cx clock frequency
310   * @param  I2CxSource This parameter can be one of the following values:
311   *         @arg @ref LL_RCC_I2C1_CLKSOURCE
312   *         @arg @ref LL_RCC_I2C2_CLKSOURCE
313   *         @arg @ref LL_RCC_I2C3_CLKSOURCE
314   * @retval I2C clock frequency (in Hz)
315   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that HSI oscillator is not ready
316   */
LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)317 uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)
318 {
319   uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
320 
321   /* Check parameter */
322   assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource));
323 
324   if (I2CxSource == LL_RCC_I2C1_CLKSOURCE)
325   {
326     /* I2C1 CLK clock frequency */
327     switch (LL_RCC_GetI2CClockSource(I2CxSource))
328     {
329       case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
330         i2c_frequency = RCC_GetSystemClockFreq();
331         break;
332 
333       case LL_RCC_I2C1_CLKSOURCE_HSI:    /* I2C1 Clock is HSI Osc. */
334         if (LL_RCC_HSI_IsReady() == 1U)
335         {
336           i2c_frequency = HSI_VALUE;
337         }
338         break;
339 
340       case LL_RCC_I2C1_CLKSOURCE_PCLK1:  /* I2C1 Clock is PCLK1 */
341       default:
342         i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
343         break;
344     }
345   }
346   else if (I2CxSource == LL_RCC_I2C2_CLKSOURCE)
347   {
348     /* I2C2 CLK clock frequency */
349     switch (LL_RCC_GetI2CClockSource(I2CxSource))
350     {
351       case LL_RCC_I2C2_CLKSOURCE_SYSCLK: /* I2C2 Clock is System Clock */
352         i2c_frequency = RCC_GetSystemClockFreq();
353         break;
354 
355       case LL_RCC_I2C2_CLKSOURCE_HSI:    /* I2C2 Clock is HSI Osc. */
356         if (LL_RCC_HSI_IsReady() == 1U)
357         {
358           i2c_frequency = HSI_VALUE;
359         }
360         break;
361 
362       case LL_RCC_I2C2_CLKSOURCE_PCLK1:  /* I2C2 Clock is PCLK1 */
363       default:
364         i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
365         break;
366     }
367   }
368   else
369   {
370     /* I2C3 CLK clock frequency */
371     switch (LL_RCC_GetI2CClockSource(I2CxSource))
372     {
373       case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */
374         i2c_frequency = RCC_GetSystemClockFreq();
375         break;
376 
377       case LL_RCC_I2C3_CLKSOURCE_HSI:    /* I2C3 Clock is HSI Osc. */
378         if (LL_RCC_HSI_IsReady() == 1U)
379         {
380           i2c_frequency = HSI_VALUE;
381         }
382         break;
383 
384       case LL_RCC_I2C3_CLKSOURCE_PCLK1:  /* I2C3 Clock is PCLK1 */
385       default:
386         i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
387         break;
388     }
389   }
390 
391   return i2c_frequency;
392 }
393 
394 
395 /**
396   * @brief  Return LPUARTx clock frequency
397   * @param  LPUARTxSource This parameter can be one of the following values:
398   *         @arg @ref LL_RCC_LPUART1_CLKSOURCE
399   * @retval LPUART clock frequency (in Hz)
400   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
401   */
LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)402 uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)
403 {
404   uint32_t lpuart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
405 
406   /* Check parameter */
407   assert_param(IS_LL_RCC_LPUART_CLKSOURCE(LPUARTxSource));
408 
409   /* LPUART1CLK clock frequency */
410   switch (LL_RCC_GetLPUARTClockSource(LPUARTxSource))
411   {
412     case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */
413       lpuart_frequency = RCC_GetSystemClockFreq();
414       break;
415 
416     case LL_RCC_LPUART1_CLKSOURCE_HSI:    /* LPUART1 Clock is HSI Osc. */
417       if (LL_RCC_HSI_IsReady() == 1U)
418       {
419         lpuart_frequency = HSI_VALUE;
420       }
421       break;
422 
423     case LL_RCC_LPUART1_CLKSOURCE_LSE:    /* LPUART1 Clock is LSE Osc. */
424       if (LL_RCC_LSE_IsReady() == 1U)
425       {
426         lpuart_frequency = LSE_VALUE;
427       }
428       break;
429 
430     case LL_RCC_LPUART1_CLKSOURCE_PCLK1:  /* LPUART1 Clock is PCLK1 */
431     default:
432       lpuart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
433       break;
434   }
435 
436   return lpuart_frequency;
437 }
438 
439 /**
440   * @brief  Return LPTIMx clock frequency
441   * @param  LPTIMxSource This parameter can be one of the following values:
442   *         @arg @ref LL_RCC_LPTIM1_CLKSOURCE
443   *         @arg @ref LL_RCC_LPTIM2_CLKSOURCE
444   *         @arg @ref LL_RCC_LPTIM2_CLKSOURCE
445   * @retval LPTIM clock frequency (in Hz)
446   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI, LSI or LSE) is not ready
447   */
LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource)448 uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource)
449 {
450   uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
451 
452   /* Check parameter */
453   assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMxSource));
454 
455   if (LPTIMxSource == LL_RCC_LPTIM1_CLKSOURCE)
456   {
457     /* LPTIM1CLK clock frequency */
458     switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
459     {
460       case LL_RCC_LPTIM1_CLKSOURCE_LSI:    /* LPTIM1 Clock is LSI Osc. */
461         if (LL_RCC_LSI_IsReady() == 1U)
462         {
463           if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
464           {
465             lptim_frequency = LSI_VALUE / 128U;
466           }
467           else
468           {
469             lptim_frequency = LSI_VALUE;
470           }
471         }
472         break;
473 
474       case LL_RCC_LPTIM1_CLKSOURCE_HSI:    /* LPTIM1 Clock is HSI Osc. */
475         if (LL_RCC_HSI_IsReady() == 1U)
476         {
477           lptim_frequency = HSI_VALUE;
478         }
479         break;
480 
481       case LL_RCC_LPTIM1_CLKSOURCE_LSE:    /* LPTIM1 Clock is LSE Osc. */
482         if (LL_RCC_LSE_IsReady() == 1U)
483         {
484           lptim_frequency = LSE_VALUE;
485         }
486         break;
487 
488       case LL_RCC_LPTIM1_CLKSOURCE_PCLK1:  /* LPTIM1 Clock is PCLK1 */
489       default:
490         lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
491         break;
492     }
493   }
494   else if (LPTIMxSource == LL_RCC_LPTIM2_CLKSOURCE)
495   {
496     /* LPTIM2CLK clock frequency */
497     switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
498     {
499       case LL_RCC_LPTIM2_CLKSOURCE_LSI:    /* LPTIM2 Clock is LSI Osc. */
500         if (LL_RCC_LSI_IsReady() == 1U)
501         {
502           if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
503           {
504             lptim_frequency = LSI_VALUE / 128U;
505           }
506           else
507           {
508             lptim_frequency = LSI_VALUE;
509           }
510         }
511         break;
512 
513       case LL_RCC_LPTIM2_CLKSOURCE_HSI:    /* LPTIM2 Clock is HSI Osc. */
514         if (LL_RCC_HSI_IsReady() == 1U)
515         {
516           lptim_frequency = HSI_VALUE;
517         }
518         break;
519 
520       case LL_RCC_LPTIM2_CLKSOURCE_LSE:    /* LPTIM2 Clock is LSE Osc. */
521         if (LL_RCC_LSE_IsReady() == 1U)
522         {
523           lptim_frequency = LSE_VALUE;
524         }
525         break;
526 
527       case LL_RCC_LPTIM2_CLKSOURCE_PCLK1:  /* LPTIM2 Clock is PCLK1 */
528       default:
529         lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
530         break;
531     }
532   }
533   else
534   {
535     /* LPTIM3CLK clock frequency */
536     switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
537     {
538       case LL_RCC_LPTIM3_CLKSOURCE_LSI:    /* LPTIM3 Clock is LSI Osc. */
539         if (LL_RCC_LSI_IsReady() == 1U)
540         {
541           lptim_frequency = LSI_VALUE;
542         }
543         break;
544 
545       case LL_RCC_LPTIM3_CLKSOURCE_HSI:    /* LPTIM3 Clock is HSI Osc. */
546         if (LL_RCC_HSI_IsReady() == 1U)
547         {
548           lptim_frequency = HSI_VALUE;
549         }
550         break;
551 
552       case LL_RCC_LPTIM3_CLKSOURCE_LSE:    /* LPTIM3 Clock is LSE Osc. */
553         if (LL_RCC_LSI_IsReady() == 1U)
554         {
555           if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
556           {
557             lptim_frequency = LSI_VALUE / 128U;
558           }
559           else
560           {
561             lptim_frequency = LSI_VALUE;
562           }
563         }
564         break;
565 
566 
567       case LL_RCC_LPTIM3_CLKSOURCE_PCLK1:  /* LPTIM3 Clock is PCLK1 */
568       default:
569         lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLK1ClockFreq(RCC_GetSystemClockFreq()));
570         break;
571     }
572   }
573 
574   return lptim_frequency;
575 }
576 
577 /**
578   * @brief  Return RNGx clock frequency
579   * @param  RNGxSource This parameter can be one of the following values:
580   *         @arg @ref LL_RCC_RNG_CLKSOURCE
581   * @retval RNG clock frequency (in Hz)
582   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLLs (PLL) is not ready
583   */
LL_RCC_GetRNGClockFreq(uint32_t RNGxSource)584 uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource)
585 {
586   uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
587 
588   /* Check parameter */
589   assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource));
590 
591   /* RNGCLK clock frequency */
592   switch (LL_RCC_GetRNGClockSource(RNGxSource))
593   {
594     case LL_RCC_RNG_CLKSOURCE_MSI:           /* MSI used as RNG clock source */
595       if (LL_RCC_MSI_IsReady() == 1U)
596       {
597         rng_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
598                                                ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
599                                                 LL_RCC_MSI_GetRange() :
600                                                 LL_RCC_MSI_GetRangeAfterStandby()));
601       }
602       break;
603     case LL_RCC_RNG_CLKSOURCE_LSI:           /* LSI clock used as RNG clock source */
604 
605       if (LL_RCC_LSI_IsReady() == 1U)
606       {
607         if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
608         {
609           rng_frequency = LSI_VALUE / 128U;
610         }
611         else
612         {
613           rng_frequency = LSI_VALUE;
614         }
615         break;
616       }
617       break;
618     case LL_RCC_RNG_CLKSOURCE_LSE:           /* LSE clock used as RNG clock source */
619 
620       if (LL_RCC_LSE_IsReady() == 1U)
621       {
622         rng_frequency = LSE_VALUE;
623       }
624       break;
625     case LL_RCC_RNG_CLKSOURCE_PLL:           /* PLL clock used as RNG clock source */
626     default:
627       if (LL_RCC_PLL_IsReady() == 1U)
628       {
629         if (LL_RCC_PLL_IsEnabledDomain_RNG() == 1U)
630         {
631           rng_frequency = RCC_PLL_GetFreqDomain_RNG();
632         }
633       }
634       break;
635   }
636   return rng_frequency;
637 }
638 
639 /**
640   * @brief  Return I2Sx clock frequency
641   * @param  I2SxSource This parameter can be one of the following values:
642   *         @arg @ref LL_RCC_I2S2_CLKSOURCE
643   * @retval I2S clock frequency (in Hz)
644   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI) or PLLs (PLL) is not ready
645   */
LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)646 uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)
647 {
648   uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
649 
650   /* Check parameter */
651   assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource));
652 
653   /* I2SCLK clock frequency */
654   switch (LL_RCC_GetI2SClockSource(I2SxSource))
655   {
656     case LL_RCC_I2S2_CLKSOURCE_PLL:    /* I2S2 Clock is PLL"P" */
657       if (LL_RCC_PLL_IsReady() == 1U)
658       {
659         if (LL_RCC_PLL_IsEnabledDomain_I2S() == 1U)
660         {
661           i2s_frequency = RCC_PLL_GetFreqDomain_I2S();
662         }
663       }
664       break;
665 
666     case LL_RCC_I2S2_CLKSOURCE_PIN:          /* I2S2 Clock is External clock */
667       i2s_frequency = EXTERNAL_CLOCK_VALUE;
668       break;
669 
670     case LL_RCC_I2S2_CLKSOURCE_HSI:           /* HSI clock used as I2S clock source */
671     default:
672       if (LL_RCC_HSI_IsReady() == 1U)
673       {
674         i2s_frequency = HSI_VALUE;
675       }
676       break;
677   }
678   return i2s_frequency;
679 }
680 
681 /**
682   * @brief  Return ADCx clock frequency
683   * @param  ADCxSource This parameter can be one of the following values:
684   *         @arg @ref LL_RCC_ADC_CLKSOURCE
685   * @retval ADC clock frequency (in Hz)
686   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready
687   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
688   */
LL_RCC_GetADCClockFreq(uint32_t ADCxSource)689 uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
690 {
691   uint32_t adc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
692 
693   /* Check parameter */
694   assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
695 
696   /* ADCCLK clock frequency */
697   switch (LL_RCC_GetADCClockSource(ADCxSource))
698   {
699     case LL_RCC_ADC_CLKSOURCE_HSI:    /* ADC Clock is HSI Osc. */
700       if (LL_RCC_HSI_IsReady() == 1U)
701       {
702         adc_frequency = HSI_VALUE;
703       }
704       break;
705     case LL_RCC_ADC_CLKSOURCE_SYSCLK:        /* SYSCLK clock used as ADC clock source */
706       adc_frequency = RCC_GetSystemClockFreq();
707       break;
708     case LL_RCC_ADC_CLKSOURCE_PLL:           /* PLL clock used as ADC clock source */
709       if (LL_RCC_PLL_IsReady() == 1U)
710       {
711         if (LL_RCC_PLL_IsEnabledDomain_ADC() == 1U)
712         {
713           adc_frequency = RCC_PLL_GetFreqDomain_ADC();
714         }
715       }
716       break;
717     case LL_RCC_ADC_CLKSOURCE_NONE:          /* No clock used as ADC clock source */
718     default:
719       adc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
720       break;
721   }
722 
723   return adc_frequency;
724 }
725 
726 /**
727   * @brief  Return RTC clock frequency
728   * @retval RTC clock frequency (in Hz)
729   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillators (LSI, LSE or HSE) are not ready
730   *         - @ref  LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
731   */
LL_RCC_GetRTCClockFreq(void)732 uint32_t LL_RCC_GetRTCClockFreq(void)
733 {
734   uint32_t rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
735 
736   /* RTCCLK clock frequency */
737   switch (LL_RCC_GetRTCClockSource())
738   {
739     case LL_RCC_RTC_CLKSOURCE_LSE:       /* LSE clock used as RTC clock source */
740       if (LL_RCC_LSE_IsReady() == 1U)
741       {
742         rtc_frequency = LSE_VALUE;
743       }
744       break;
745 
746     case LL_RCC_RTC_CLKSOURCE_LSI:       /* LSI clock used as RTC clock source */
747       if (LL_RCC_LSI_IsReady() == 1U)
748       {
749         if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
750         {
751           rtc_frequency = LSI_VALUE / 128U;
752         }
753         else
754         {
755           rtc_frequency = LSI_VALUE;
756         }
757       }
758       break;
759 
760     case LL_RCC_RTC_CLKSOURCE_HSE_DIV32:        /* HSE clock used as ADC clock source */
761       rtc_frequency = HSE_VALUE / 32U;
762       break;
763 
764     case LL_RCC_RTC_CLKSOURCE_NONE:          /* No clock used as RTC clock source */
765     default:
766       rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
767       break;
768   }
769 
770   return rtc_frequency;
771 }
772 
773 /**
774   * @}
775   */
776 
777 /**
778   * @}
779   */
780 
781 /** @addtogroup RCC_LL_Private_Functions
782   * @{
783   */
784 
785 /**
786   * @brief  Return SYSTEM clock (SYSCLK) frequency
787   * @retval SYSTEM clock frequency (in Hz)
788   */
RCC_GetSystemClockFreq(void)789 static uint32_t RCC_GetSystemClockFreq(void)
790 {
791   uint32_t frequency;
792 
793   /* Get SYSCLK source -------------------------------------------------------*/
794   switch (LL_RCC_GetSysClkSource())
795   {
796     case LL_RCC_SYS_CLKSOURCE_STATUS_MSI:  /* MSI used as system clock source */
797       frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
798                                          ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
799                                           LL_RCC_MSI_GetRange() :
800                                           LL_RCC_MSI_GetRangeAfterStandby()));
801       break;
802 
803     case LL_RCC_SYS_CLKSOURCE_STATUS_HSI:  /* HSI used as system clock  source */
804       frequency = HSI_VALUE;
805       break;
806 
807     case LL_RCC_SYS_CLKSOURCE_STATUS_HSE:  /* HSE used as system clock  source */
808       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
809       {
810         frequency = HSE_VALUE / 2U;
811       }
812       else
813       {
814         frequency = HSE_VALUE;
815       }
816       break;
817 
818 
819     case LL_RCC_SYS_CLKSOURCE_STATUS_PLL:  /* PLL used as system clock  source */
820       frequency = RCC_PLL_GetFreqDomain_SYS();
821       break;
822 
823     default:
824       frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
825                                          ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
826                                           LL_RCC_MSI_GetRange() :
827                                           LL_RCC_MSI_GetRangeAfterStandby()));
828       break;
829   }
830 
831   return frequency;
832 }
833 
834 /**
835   * @brief  Return HCLK1 clock frequency
836   * @param  SYSCLK_Frequency SYSCLK clock frequency
837   * @retval HCLK1 clock frequency (in Hz)
838   */
RCC_GetHCLK1ClockFreq(uint32_t SYSCLK_Frequency)839 static uint32_t RCC_GetHCLK1ClockFreq(uint32_t SYSCLK_Frequency)
840 {
841   /* HCLK clock frequency */
842   return __LL_RCC_CALC_HCLK1_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
843 }
844 
845 #if defined(DUAL_CORE)
846 /**
847   * @brief  Return HCLK2 clock frequency
848   * @param  SYSCLK_Frequency SYSCLK clock frequency
849   * @retval HCLK2 clock frequency (in Hz)
850   */
RCC_GetHCLK2ClockFreq(uint32_t SYSCLK_Frequency)851 static uint32_t RCC_GetHCLK2ClockFreq(uint32_t SYSCLK_Frequency)
852 {
853   /* HCLK clock frequency */
854   return __LL_RCC_CALC_HCLK2_FREQ(SYSCLK_Frequency, LL_C2_RCC_GetAHBPrescaler());
855 }
856 #endif /* DUAL_CORE */
857 
858 /**
859   * @brief  Return HCLK clock frequency
860   * @param  SYSCLK_Frequency SYSCLK clock frequency
861   * @retval HCLK3 clock frequency (in Hz)
862   */
RCC_GetHCLK3ClockFreq(uint32_t SYSCLK_Frequency)863 static uint32_t RCC_GetHCLK3ClockFreq(uint32_t SYSCLK_Frequency)
864 {
865   /* HCLK clock frequency */
866   return __LL_RCC_CALC_HCLK3_FREQ(SYSCLK_Frequency, LL_RCC_GetAHB3Prescaler());
867 }
868 
869 /**
870   * @brief  Return PCLK1 clock frequency
871   * @param  HCLK_Frequency HCLK clock frequency
872   * @retval PCLK1 clock frequency (in Hz)
873   */
RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)874 static uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
875 {
876   /* PCLK1 clock frequency */
877   return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
878 }
879 
880 /**
881   * @brief  Return PCLK2 clock frequency
882   * @param  HCLK_Frequency HCLK clock frequency
883   * @retval PCLK2 clock frequency (in Hz)
884   */
RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)885 static uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
886 {
887   /* PCLK2 clock frequency */
888   return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
889 }
890 
891 /**
892   * @brief  Return PLL clock (PLLRCLK) frequency used for system domain
893   * @retval PLLRCLK clock frequency (in Hz)
894   */
RCC_PLL_GetFreqDomain_SYS(void)895 static uint32_t RCC_PLL_GetFreqDomain_SYS(void)
896 {
897   uint32_t pllinputfreq;
898   uint32_t pllsource;
899 
900   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLN
901      SYSCLK = PLL_VCO / PLLR
902   */
903   pllsource = LL_RCC_PLL_GetMainSource();
904 
905   switch (pllsource)
906   {
907     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
908       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
909                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
910                                              LL_RCC_MSI_GetRange() :
911                                              LL_RCC_MSI_GetRangeAfterStandby()));
912       break;
913 
914     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
915       pllinputfreq = HSI_VALUE;
916       break;
917 
918     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
919       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
920       {
921         pllinputfreq = HSE_VALUE / 2U;
922       }
923       else
924       {
925         pllinputfreq = HSE_VALUE;
926       }
927       break;
928 
929 
930     default:
931       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
932                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
933                                              LL_RCC_MSI_GetRange() :
934                                              LL_RCC_MSI_GetRangeAfterStandby()));
935       break;
936   }
937   return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
938                                    LL_RCC_PLL_GetN(), LL_RCC_PLL_GetR());
939 }
940 
941 /**
942   * @brief  Return PLL clock (PLLPCLK) frequency used for ADC domain
943   * @retval PLLPCLK clock frequency (in Hz)
944   */
RCC_PLL_GetFreqDomain_ADC(void)945 static uint32_t RCC_PLL_GetFreqDomain_ADC(void)
946 {
947   uint32_t pllinputfreq;
948   uint32_t pllsource;
949 
950   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value / PLLM) * PLLN
951   */
952   pllsource = LL_RCC_PLL_GetMainSource();
953 
954   switch (pllsource)
955   {
956     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
957       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
958                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
959                                              LL_RCC_MSI_GetRange() :
960                                              LL_RCC_MSI_GetRangeAfterStandby()));
961       break;
962 
963     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
964       pllinputfreq = HSI_VALUE;
965       break;
966 
967     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
968       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
969       {
970         pllinputfreq = HSE_VALUE / 2U;
971       }
972       else
973       {
974         pllinputfreq = HSE_VALUE;
975       }
976       break;
977 
978     default:
979       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
980                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
981                                              LL_RCC_MSI_GetRange() :
982                                              LL_RCC_MSI_GetRangeAfterStandby()));
983       break;
984   }
985   return __LL_RCC_CALC_PLLCLK_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
986                                        LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP());
987 }
988 
989 /**
990   * @brief  Return PLL clock (PLLQCLK) frequency used for RNG domain
991   * @retval PLLQCLK clock frequency (in Hz)
992   */
RCC_PLL_GetFreqDomain_RNG(void)993 static uint32_t RCC_PLL_GetFreqDomain_RNG(void)
994 {
995   uint32_t pllinputfreq;
996   uint32_t pllsource;
997 
998   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value / PLLM) * PLLN
999   */
1000   pllsource = LL_RCC_PLL_GetMainSource();
1001 
1002   switch (pllsource)
1003   {
1004     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1005       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
1006                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
1007                                              LL_RCC_MSI_GetRange() :
1008                                              LL_RCC_MSI_GetRangeAfterStandby()));
1009       break;
1010 
1011     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1012       pllinputfreq = HSI_VALUE;
1013       break;
1014 
1015     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1016       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
1017       {
1018         pllinputfreq = HSE_VALUE / 2U;
1019       }
1020       else
1021       {
1022         pllinputfreq = HSE_VALUE;
1023       }
1024       break;
1025 
1026     default:
1027       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
1028                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
1029                                              LL_RCC_MSI_GetRange() :
1030                                              LL_RCC_MSI_GetRangeAfterStandby()));
1031       break;
1032   }
1033   return __LL_RCC_CALC_PLLCLK_RNG_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
1034                                        LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
1035 }
1036 
1037 /**
1038   * @brief  Return PLL clock (PLLQCLK) frequency used for I2S domain
1039   * @retval PLLQCLK clock frequency (in Hz)
1040   */
RCC_PLL_GetFreqDomain_I2S(void)1041 static uint32_t RCC_PLL_GetFreqDomain_I2S(void)
1042 {
1043   uint32_t pllinputfreq;
1044   uint32_t pllsource;
1045 
1046   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value / PLLM) * PLLN
1047   */
1048   pllsource = LL_RCC_PLL_GetMainSource();
1049 
1050   switch (pllsource)
1051   {
1052     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1053       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
1054                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
1055                                              LL_RCC_MSI_GetRange() :
1056                                              LL_RCC_MSI_GetRangeAfterStandby()));
1057       break;
1058 
1059     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1060       pllinputfreq = HSI_VALUE;
1061       break;
1062 
1063     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1064       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
1065       {
1066         pllinputfreq = HSE_VALUE / 2U;
1067       }
1068       else
1069       {
1070         pllinputfreq = HSE_VALUE;
1071       }
1072       break;
1073 
1074     default:
1075       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
1076                                             ((LL_RCC_MSI_IsEnabledRangeSelect()  == 1U) ?
1077                                              LL_RCC_MSI_GetRange() :
1078                                              LL_RCC_MSI_GetRangeAfterStandby()));
1079       break;
1080   }
1081   return __LL_RCC_CALC_PLLCLK_I2S2_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
1082                                         LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
1083 }
1084 
1085 
1086 /**
1087   * @}
1088   */
1089 
1090 /**
1091   * @}
1092   */
1093 
1094 #endif /* defined(RCC) */
1095 
1096 /**
1097   * @}
1098   */
1099 
1100 #endif /* USE_FULL_LL_DRIVER */
1101