1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_hal_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Reset and Clock Control (RCC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                       ##### RCC specific features #####
25   ==============================================================================
26     [..]
27       After reset the device is running from High Speed Internal oscillator
28       divided by 4 that is the default system clock with Flash 0 wait state.
29 
30       (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses:
31           all peripherals mapped on these busses are running at HSI speed.
32       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
33       (+) All GPIOs are in analog mode
34 
35     [..]
36       Once the device started from reset, the user application has to:
37       (+) Configure the clock source to be used to drive the System clock
38           (if the application needs higher frequency/performance)
39       (+) Configure the System clock frequency and Flash settings
40       (+) Configure the AHB and APB busses prescalers
41       (+) Enable the clock for the peripheral(s) to be used
42       (+) Configure the clock source(s) for peripherals which clocks are not
43           derived from the System clock (RTC, ADC, USART, I2C, I2S)
44 
45   @endverbatim
46   ******************************************************************************
47   */
48 
49 /* Includes ------------------------------------------------------------------*/
50 #include "stm32c0xx_hal.h"
51 
52 /** @addtogroup STM32C0xx_HAL_Driver
53   * @{
54   */
55 
56 /** @defgroup RCC RCC
57   * @brief RCC HAL module driver
58   * @{
59   */
60 
61 #ifdef HAL_RCC_MODULE_ENABLED
62 
63 /* Private typedef -----------------------------------------------------------*/
64 /* Private define ------------------------------------------------------------*/
65 /** @defgroup RCC_Private_Constants RCC Private Constants
66   * @{
67   */
68 #define RCC_HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
69 #define RCC_HSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
70 #define RCC_LSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
71 #define RCC_CLOCKSWITCH_TIMEOUT_VALUE  (5000U) /* 5 s    */
72 
73 /**
74   * @}
75   */
76 
77 /* Private macro -------------------------------------------------------------*/
78 /** @defgroup RCC_Private_Macros RCC Private Macros
79   * @{
80   */
81 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__)   ((__RCC_MCOx__) & GPIO_PIN_MASK)
82 
83 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__)    (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
84 
85 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
86 
87 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__)  (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
88 
89 /**
90   * @}
91   */
92 
93 /* Private variables ---------------------------------------------------------*/
94 /** @defgroup RCC_Private_Variables RCC Private Variables
95   * @{
96   */
97 
98 /**
99   * @}
100   */
101 
102 /* Private function prototypes -----------------------------------------------*/
103 /* Exported functions --------------------------------------------------------*/
104 
105 /** @defgroup RCC_Exported_Functions RCC Exported Functions
106   * @{
107   */
108 
109 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
110   *  @brief    Initialization and Configuration functions
111   *
112   @verbatim
113  ===============================================================================
114            ##### Initialization and de-initialization functions #####
115  ===============================================================================
116     [..]
117       This section provides functions allowing to configure the internal and external oscillators
118       (HSE, HSI, LSE, LSI, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB)
119 
120     [..] Internal/external clock
121          (+) HSI (high-speed internal): 48 MHz factory-trimmed RC used directly as System clock source.
122 
123          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
124              clock source.
125 
126          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
127              through the PLL as System clock source. Can be used also optionally as RTC clock source.
128 
129          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
130 
131          (+) CSS (Clock security system): once enabled, if a HSE or LSE clock failure occurs,
132              the System clock is automatically switched respectively to HSI or LSI and an interrupt
133              is generated if enabled. The interrupt is linked to the Cortex-M0+ NMI (Non-Maskable Interrupt)
134              exception vector.
135 
136          (+) MCOx (microcontroller clock output): used to output LSI, HSI, LSE, HSE and SYSCLK on different pins.
137 
138     [..] System, AHB and APB busses clocks configuration
139          (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
140              HSE, LSI and LSE.
141              The AHB clock (HCLK) is derived from System clock through configurable
142              prescaler and used to clock the CPU, memory and peripherals mapped
143              on AHB bus (DMA, GPIO...).and APB (PCLK1) clock is derived
144              from AHB clock through configurable prescalers and used to clock
145              the peripherals mapped on these busses. You can use
146              "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
147 
148          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
149 
150             (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
151                 divided by 2 to 31.
152                 You have to use @ref __HAL_RCC_RTC_ENABLE() and @ref HAL_RCCEx_PeriphCLKConfig() function
153                  to configure this clock.
154 
155             (+@) ADC: the ADC clock can be derived either from system clock or HSI
156 
157             (+@) USART: the USART clock can be derived either from APB clock or HSI or LSE
158             (+@) I2C: the I2C clock can be derived either from system clock or HSI
159 
160             (+@) I2S: the I2S clock can be derived either from system clock or HSI or external clock source
161 
162          (+) The maximum frequency of the SYSCLK, HCLK, PCLK is 48 MHz.
163 
164   @endverbatim
165 
166      (++)  Table 1. HCLK clock frequency.
167      (++)  +------------------------------------+
168      (++)  | Latency         |    HCLK clock    |
169      (++)  |                 |  frequency (MHz) |
170      (++)  |                 |------------------|
171      (++)  |                 | voltage range    |
172      (++)  |                 |  VDD33 2V - 3.6V |
173      (++)  |                 |  VDD12 1V - 1.32V|
174      (++)  |-----------------|------------------|
175      (++)  |0WS(1 CPU cycles)|  HCLK <= 24      |
176      (++)  |-----------------|------------------|
177      (++)  |1WS(2 CPU cycles)|  HCLK <= 48      |
178      (++)  +------------------------------------+
179      (++)
180    * @{
181   */
182 
183 /**
184   * @brief  Reset the RCC clock configuration to the default reset state.
185   * @note   The default reset state of the clock configuration is given below:
186   *            - HSI ON and used as system clock source
187   *            - HSE OFF
188   *            - AHB and APB prescaler set to 1.
189   *            - CSS, MCO1, MCO2 OFF
190   *            - All interrupts disabled
191   * @note   This function does not modify the configuration of the
192   *            - Peripheral clocks
193   *            - LSI, LSE and RTC clocks
194   * @retval HAL status
195   */
HAL_RCC_DeInit(void)196 HAL_StatusTypeDef HAL_RCC_DeInit(void)
197 {
198   uint32_t tickstart;
199 
200   /* Get Start Tick*/
201   tickstart = HAL_GetTick();
202 
203   /* Set HSION bit to the reset value */
204   SET_BIT(RCC->CR, RCC_CR_HSION);
205 
206   /* Wait till HSI is ready */
207   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
208   {
209     if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
210     {
211       return HAL_TIMEOUT;
212     }
213   }
214 
215   /* Set HSITRIM[6:0] bits to the reset value */
216   RCC->ICSCR = RCC_ICSCR_HSITRIM_6;
217 
218   /* Get Start Tick*/
219   tickstart = HAL_GetTick();
220 
221   /* Reset CFGR register (HSI is selected as system clock source) */
222   RCC->CFGR = 0x00000000u;
223 
224   /* Wait till HSI is ready */
225   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
226   {
227     if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
228     {
229       return HAL_TIMEOUT;
230     }
231   }
232 
233   /* Get Start Tick*/
234   tickstart = HAL_GetTick();
235 
236   /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
237   RCC->CR &= ~RCC_CR_HSEON;
238 
239   /* Wait till HSEON is disabled */
240   while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
241   {
242     if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
243     {
244       return HAL_TIMEOUT;
245     }
246   }
247 
248   /* Then again to HSEBYP in case bypass was enabled */
249   RCC->CR &= ~RCC_CR_HSEBYP;
250 
251   /* Disable all interrupts */
252   RCC->CIER = 0x00000000u;
253 
254   /* Clear all flags */
255   RCC->CICR = 0xFFFFFFFFu;
256 
257   /* Update the SystemCoreClock global variable */
258   SystemCoreClock = HSI_VALUE;
259 
260   /* Adapt Systick interrupt period */
261   if (HAL_InitTick(uwTickPrio) != HAL_OK)
262   {
263     return HAL_ERROR;
264   }
265   else
266   {
267     return HAL_OK;
268   }
269 }
270 
271 /**
272   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
273   *         @ref RCC_OscInitTypeDef.
274   * @param  RCC_OscInitStruct pointer to a @ref RCC_OscInitTypeDef structure that
275   *         contains the configuration information for the RCC Oscillators.
276   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
277   *         supported by this function. User should request a transition to HSE Off
278   *         first and then to HSE On or HSE Bypass.
279   * @note   Transition LSE Bypass to LSE On and LSE On to LSE Bypass are not
280   *         supported by this function. User should request a transition to LSE Off
281   *         first and then to LSE On or LSE Bypass.
282   * @retval HAL status
283   */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * RCC_OscInitStruct)284 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef  *RCC_OscInitStruct)
285 {
286   uint32_t tickstart;
287   uint32_t temp_sysclksrc;
288 
289   /* Check Null pointer */
290   if (RCC_OscInitStruct == NULL)
291   {
292     return HAL_ERROR;
293   }
294 
295   /* Check the parameters */
296   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
297 
298   /*------------------------------- HSE Configuration ------------------------*/
299   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
300   {
301     /* Check the parameters */
302     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
303 
304     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
305 
306     /* When the HSE is used as system clock in these cases it is not allowed to be disabled */
307     if (temp_sysclksrc == RCC_CFGR_SWS_HSE)
308     {
309       if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
310       {
311         return HAL_ERROR;
312       }
313     }
314     else
315     {
316       /* Set the new HSE configuration ---------------------------------------*/
317       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
318 
319       /* Check the HSE State */
320       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
321       {
322         /* Get Start Tick*/
323         tickstart = HAL_GetTick();
324 
325         /* Wait till HSE is ready */
326         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
327         {
328           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
329           {
330             return HAL_TIMEOUT;
331           }
332         }
333       }
334       else
335       {
336         /* Get Start Tick*/
337         tickstart = HAL_GetTick();
338 
339         /* Wait till HSE is disabled */
340         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
341         {
342           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
343           {
344             return HAL_TIMEOUT;
345           }
346         }
347       }
348     }
349   }
350   /*----------------------------- HSI Configuration --------------------------*/
351   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
352   {
353     /* Check the parameters */
354     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
355     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
356     assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv));
357 
358     /* Check if HSI48 is used as system clock  */
359     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
360 
361     if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
362     {
363       /* When HSI is used as system clock it can not be disabled */
364       if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
365       {
366         return HAL_ERROR;
367       }
368       /* Otherwise, just the calibration is allowed */
369       else
370       {
371         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
372         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
373 
374         if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
375         {
376           /* Adjust the HSI48 division factor */
377           __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
378 
379           /* Update the SystemCoreClock global variable with HSISYS value  */
380           SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos)));
381         }
382 
383         /* Adapt Systick interrupt period */
384         if (HAL_InitTick(uwTickPrio) != HAL_OK)
385         {
386           return HAL_ERROR;
387         }
388       }
389     }
390     else
391     {
392       /* Check the HSI State */
393       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
394       {
395         /* Configure the HSI48 division factor */
396         __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
397 
398         /* Enable the Internal High Speed oscillator (HSI48). */
399         __HAL_RCC_HSI_ENABLE();
400 
401         /* Get Start Tick*/
402         tickstart = HAL_GetTick();
403 
404         /* Wait till HSI is ready */
405         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
406         {
407           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
408           {
409             return HAL_TIMEOUT;
410           }
411         }
412 
413         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
414         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
415       }
416       else
417       {
418         /* Disable the Internal High Speed oscillator (HSI48). */
419         __HAL_RCC_HSI_DISABLE();
420 
421         /* Get Start Tick*/
422         tickstart = HAL_GetTick();
423 
424         /* Wait till HSI is disabled */
425         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
426         {
427           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
428           {
429             return HAL_TIMEOUT;
430           }
431         }
432       }
433     }
434   }
435   /*------------------------------ LSI Configuration -------------------------*/
436   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
437   {
438     /* Check the parameters */
439     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
440 
441     /* Check if LSI is used as system clock */
442     if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
443     {
444       /* When LSI is used as system clock it will not be disabled */
445       if (RCC_OscInitStruct->LSIState == RCC_LSI_OFF)
446       {
447         return HAL_ERROR;
448       }
449     }
450     else
451     {
452       /* Check the LSI State */
453       if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
454       {
455         /* Enable the Internal Low Speed oscillator (LSI). */
456         __HAL_RCC_LSI_ENABLE();
457 
458         /* Get Start Tick*/
459         tickstart = HAL_GetTick();
460 
461         /* Wait till LSI is ready */
462         while (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) == 0U)
463         {
464           if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
465           {
466             return HAL_TIMEOUT;
467           }
468         }
469       }
470       else
471       {
472         /* Disable the Internal Low Speed oscillator (LSI). */
473         __HAL_RCC_LSI_DISABLE();
474 
475         /* Get Start Tick*/
476         tickstart = HAL_GetTick();
477 
478         /* Wait till LSI is disabled */
479         while (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) != 0U)
480         {
481           if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
482           {
483             return HAL_TIMEOUT;
484           }
485         }
486       }
487     }
488   }
489   /*------------------------------ LSE Configuration -------------------------*/
490   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
491   {
492     FlagStatus       pwrclkchanged = RESET;
493 
494     /* Check the parameters */
495     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
496 
497     /* When the LSE is used as system clock, it is not allowed disable it */
498     if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
499     {
500       if (RCC_OscInitStruct->LSEState == RCC_LSE_OFF)
501       {
502         return HAL_ERROR;
503       }
504     }
505     else
506     {
507       /* Update LSE configuration in RTC Domain control register    */
508       /* Set the new LSE configuration -----------------------------------------*/
509       __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
510 
511       /* Check the LSE State */
512       if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
513       {
514         /* Get Start Tick*/
515         tickstart = HAL_GetTick();
516 
517         /* Wait till LSE is ready */
518         while (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) == 0U)
519         {
520           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
521           {
522             return HAL_TIMEOUT;
523           }
524         }
525       }
526       else
527       {
528         /* Get Start Tick*/
529         tickstart = HAL_GetTick();
530 
531         /* Wait till LSE is disabled */
532         while (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) != 0U)
533         {
534           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
535           {
536             return HAL_TIMEOUT;
537           }
538         }
539       }
540 
541       /* Restore clock configuration if changed */
542       if (pwrclkchanged == SET)
543       {
544         __HAL_RCC_PWR_CLK_DISABLE();
545       }
546     }
547   }
548   return HAL_OK;
549 }
550 
551 /**
552   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
553   *         parameters in the RCC_ClkInitStruct.
554   * @param  RCC_ClkInitStruct  pointer to a @ref RCC_ClkInitTypeDef structure that
555   *         contains the configuration information for the RCC peripheral.
556   * @param  FLatency  FLASH Latency
557   *          This parameter can be one of the following values:
558   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
559   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
560   *
561   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
562   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
563   *
564   * @note   The HSI is used by default as system clock source after
565   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
566   *         the HSI frequency is set to 12 Mhz, as HSI divider is set to 4.
567   *
568   * @note   The HSI can be selected as system clock source after
569   *         from STOP modes or in case of failure of the HSE used directly or indirectly
570   *         as system clock (if the Clock Security System CSS is enabled).
571   *
572   * @note   The LSI can be selected as system clock source after
573   *         in case of failure of the LSE used directly or indirectly
574   *         as system clock (if the Clock Security System LSECSS is enabled).
575   *
576   * @note   A switch from one clock source to another occurs only if the target
577   *         clock source is ready (clock stable after startup delay).
578   *         If a clock source which is not yet ready is selected, the switch will
579   *         occur when the clock source is ready.
580   *
581   * @note   You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
582   *         currently used as system clock source.
583   *
584   * @note   Depending on the device voltage range, the software has to set correctly
585   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
586   *         (for more details refer to section above "Initialization/de-initialization functions")
587   * @retval None
588   */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)589 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
590 {
591   uint32_t tickstart;
592 
593   /* Check Null pointer */
594   if (RCC_ClkInitStruct == NULL)
595   {
596     return HAL_ERROR;
597   }
598 
599   /* Check the parameters */
600   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
601   assert_param(IS_FLASH_LATENCY(FLatency));
602 
603   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
604     must be correctly programmed according to the frequency of the FLASH clock
605     (HCLK) and the supply voltage of the device. */
606 
607   /* Increasing the number of wait states because of higher CPU frequency */
608   if (FLatency > __HAL_FLASH_GET_LATENCY())
609   {
610     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
611     __HAL_FLASH_SET_LATENCY(FLatency);
612 
613     /* Check that the new number of wait states is taken into account to access the Flash
614     memory by polling the FLASH_ACR register */
615     tickstart = HAL_GetTick();
616 
617     while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
618     {
619       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
620       {
621         return HAL_TIMEOUT;
622       }
623     }
624   }
625 
626   /*-------------------------- HCLK Configuration --------------------------*/
627   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
628   {
629     /* Set the highest APB divider in order to ensure that we do not go through
630        a non-spec phase whatever we decrease or increase HCLK. */
631     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
632     {
633       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16);
634     }
635 
636     /* Set the new HCLK clock divider */
637     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
638     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
639   }
640 
641   /*------------------------- SYSCLK Configuration ---------------------------*/
642   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
643   {
644     assert_param(IS_RCC_SYSCLK(RCC_ClkInitStruct->SYSCLKDivider));
645     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
646     MODIFY_REG(RCC->CR, RCC_CR_SYSDIV, RCC_ClkInitStruct->SYSCLKDivider);
647 
648     /* HSE is selected as System Clock Source */
649     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
650     {
651       /* Check the HSE ready flag */
652       if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
653       {
654         return HAL_ERROR;
655       }
656     }
657     /* HSI is selected as System Clock Source */
658     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
659     {
660       /* Check the HSI ready flag */
661       if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
662       {
663         return HAL_ERROR;
664       }
665     }
666     /* LSI is selected as System Clock Source */
667     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_LSI)
668     {
669       /* Check the LSI ready flag */
670       if (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) == 0U)
671       {
672         return HAL_ERROR;
673       }
674     }
675     /* LSE is selected as System Clock Source */
676     else
677     {
678       /* Check the LSE ready flag */
679       if (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) == 0U)
680       {
681         return HAL_ERROR;
682       }
683     }
684     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
685 
686     /* Get Start Tick*/
687     tickstart = HAL_GetTick();
688 
689     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
690     {
691       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
692       {
693         return HAL_TIMEOUT;
694       }
695     }
696   }
697 
698   /* Decreasing the number of wait states because of lower CPU frequency */
699   if (FLatency < __HAL_FLASH_GET_LATENCY())
700   {
701     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
702     __HAL_FLASH_SET_LATENCY(FLatency);
703 
704     /* Check that the new number of wait states is taken into account to access the Flash
705     memory by polling the FLASH_ACR register */
706     tickstart = HAL_GetTick();
707 
708     while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
709     {
710       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
711       {
712         return HAL_TIMEOUT;
713       }
714     }
715   }
716 
717   /*-------------------------- PCLK1 Configuration ---------------------------*/
718   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
719   {
720     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
721     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
722   }
723 
724   /* Update the SystemCoreClock global variable */
725   SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
726 
727   /* Configure the source of time base considering new system clocks settings*/
728   return HAL_InitTick(uwTickPrio);
729 }
730 
731 /**
732   * @}
733   */
734 
735 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
736   *  @brief   RCC clocks control functions
737   *
738 @verbatim
739  ===============================================================================
740                       ##### Peripheral Control functions #####
741  ===============================================================================
742     [..]
743     This subsection provides a set of functions allowing to:
744 
745     (+) output clock to MCO pin.
746     (+) Retrieve current clock frequencies.
747     (+) Enable the Clock Security System.
748 
749 @endverbatim
750   * @{
751   */
752 
753 /**
754   * @brief  Select the clock source to output on MCOx pin.
755   * @note   PA8 for MCO1 and PB2 for MCO2 should be configured in alternate function mode.
756   * @param  RCC_MCOx  specifies the output direction for the clock source.
757   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pins.
758   *            @arg @ref RCC_MCO2  Clock source to output on MCO2 pins.
759   * @param  RCC_MCOSource  specifies the clock source to output.
760   *          This parameter can be one of the following values:
761   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO1 output disabled, no clock on MCO1
762   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO1 source
763   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO1 source
764   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO1 source
765   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO1 source
766   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO1 source
767   *            @arg @ref RCC_MCO2SOURCE_NOCLOCK  MCO2 output disabled, no clock on MCO2
768   *            @arg @ref RCC_MCO2SOURCE_SYSCLK  system  clock selected as MCO2 source
769   *            @arg @ref RCC_MCO2SOURCE_HSI  HSI clock selected as MCO2 source
770   *            @arg @ref RCC_MCO2SOURCE_HSE  HSE clock selected as MCO2 source
771   *            @arg @ref RCC_MCO2SOURCE_LSI  LSI clock selected as MCO2 source
772   *            @arg @ref RCC_MCO2SOURCE_LSE  LSE clock selected as MCO2 source
773   * @param  RCC_MCODiv  specifies the MCO prescaler.
774   *          This parameter can be one of the following values:
775   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
776   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
777   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
778   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
779   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
780   *            @arg @ref RCC_MCODIV_32  division by 32 applied to MCO clock
781   *            @arg @ref RCC_MCODIV_64  division by 64 applied to MCO clock
782   *            @arg @ref RCC_MCODIV_128  division by 128 applied to MCO clock
783   * @retval None
784   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)785 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
786 {
787   GPIO_InitTypeDef gpio_initstruct;
788   uint32_t mcoindex;
789   uint32_t mco_gpio_index;
790   GPIO_TypeDef *mco_gpio_port;
791 
792   /* Check the parameters */
793   assert_param(IS_RCC_MCO(RCC_MCOx));
794 
795   /* Common GPIO init parameters */
796   gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
797   gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
798   gpio_initstruct.Pull      = GPIO_NOPULL;
799 
800   /* Get MCOx selection */
801   mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
802 
803   /* Get MCOx GPIO Port */
804   mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
805 
806   /* MCOx Clock Enable */
807   mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
808   SET_BIT(RCC->IOPENR, (1UL << mco_gpio_index));
809 
810   /* Configure the MCOx pin in alternate function mode */
811   gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
812   gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
813   HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
814 
815   if (mcoindex == RCC_MCO1_INDEX)
816   {
817     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
818     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
819     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
820     LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
821   }
822   else if (mcoindex == RCC_MCO2_INDEX)
823   {
824     assert_param(IS_RCC_MCO2DIV(RCC_MCODiv));
825     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
826     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
827     LL_RCC_ConfigMCO2(RCC_MCOSource, RCC_MCODiv);
828   }
829   else
830   {}
831 }
832 
833 /**
834   * @brief  Return the SYSCLK frequency.
835   *
836   * @note   The system frequency computed by this function is not the real
837   *         frequency in the chip. It is calculated based on the predefined
838   *         constant and the selected clock source:
839   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE/HSIDIV(*)
840   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
841   * @note     If SYSCLK source is LSI, function returns values based on LSI_VALUE(***)
842   * @note     If SYSCLK source is LSE, function returns values based on LSE_VALUE(****)
843   * @note     (*) HSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
844   *               48 MHz) but the real value may vary depending on the variations
845   *               in voltage and temperature.
846   * @note     (**) HSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
847   *                48 MHz), user has to ensure that HSE_VALUE is same as the real
848   *                frequency of the crystal used. Otherwise, this function may
849   *                have wrong result.
850   * @note     (***) LSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
851   *               32768 Hz).
852   * @note     (****) LSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
853   *               32000 Hz).
854   *
855   * @note   The result of this function could be not correct when using fractional
856   *         value for HSE crystal.
857   *
858   * @note   This function can be used by the user application to compute the
859   *         baudrate for the communication peripherals or configure other parameters.
860   *
861   * @note   Each time SYSCLK changes, this function must be called to update the
862   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
863   *
864   *
865   * @retval SYSCLK frequency
866   */
HAL_RCC_GetSysClockFreq(void)867 uint32_t HAL_RCC_GetSysClockFreq(void)
868 {
869   uint32_t hsidiv;
870   uint32_t sysclockfreq;
871 
872   if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
873   {
874     /* HSISYS can be derived for HSI48 */
875     hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
876 
877     /* HSI used as system clock source */
878     sysclockfreq = (HSI_VALUE / hsidiv);
879   }
880   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
881   {
882     /* HSE used as system clock source */
883     sysclockfreq = HSE_VALUE;
884   }
885   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
886   {
887     /* LSE used as system clock source */
888     sysclockfreq = LSE_VALUE;
889   }
890   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
891   {
892     /* LSI used as system clock source */
893     sysclockfreq = LSI_VALUE;
894   }
895   else
896   {
897     sysclockfreq = 0U;
898   }
899 
900   return sysclockfreq;
901 }
902 
903 /**
904   * @brief  Return the HCLK frequency.
905   * @note   Each time HCLK changes, this function must be called to update the
906   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
907   *
908   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
909   * @retval HCLK frequency in Hz
910   */
HAL_RCC_GetHCLKFreq(void)911 uint32_t HAL_RCC_GetHCLKFreq(void)
912 {
913   return SystemCoreClock;
914 }
915 
916 /**
917   * @brief  Return the PCLK1 frequency.
918   * @note   Each time PCLK1 changes, this function must be called to update the
919   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
920   * @retval PCLK1 frequency in Hz
921   */
HAL_RCC_GetPCLK1Freq(void)922 uint32_t HAL_RCC_GetPCLK1Freq(void)
923 {
924   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
925   return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_Pos]) & 0x1FU));
926 }
927 
928 /**
929   * @brief  Configure the RCC_OscInitStruct according to the internal
930   *         RCC configuration registers.
931   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
932   *         will be configured.
933   * @retval None
934   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)935 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
936 {
937   uint32_t regval;
938 
939   /* Check the parameters */
940   assert_param(RCC_OscInitStruct != (void *)NULL);
941 
942   /* Set all possible values for the Oscillator type parameter ---------------*/
943   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
944                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
945 
946   /* Get Control register */
947   regval = RCC->CR;
948 
949   /* Get the HSE configuration -----------------------------------------------*/
950   RCC_OscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP));
951 
952   /* Get the HSI configuration -----------------------------------------------*/
953   RCC_OscInitStruct->HSIState = regval & RCC_CR_HSION;
954   RCC_OscInitStruct->HSICalibrationValue = ((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
955   RCC_OscInitStruct->HSIDiv = ((regval & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
956 
957   /* Get CSR1 register */
958   regval = RCC->CSR1;
959 
960   /* Get the LSE configuration -----------------------------------------------*/
961   RCC_OscInitStruct->LSEState = (regval & (RCC_CSR1_LSEON | RCC_CSR1_LSEBYP));
962 
963   /* Get CSR2 register */
964   regval = RCC->CSR2;
965 
966   /* Get the LSI configuration -----------------------------------------------*/
967   RCC_OscInitStruct->LSIState = regval & RCC_CSR2_LSION;
968 
969 }
970 
971 /**
972   * @brief  Configure the RCC_ClkInitStruct according to the internal
973   *         RCC configuration registers.
974   * @param  RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
975   *                           will be configured.
976   * @param  pFLatency         Pointer on the Flash Latency.
977   * @retval None
978   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)979 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
980 {
981   /* Check the parameters */
982   assert_param(RCC_ClkInitStruct != (void *)NULL);
983   assert_param(pFLatency != (void *)NULL);
984 
985   /* Set all possible values for the Clock type parameter --------------------*/
986   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1;
987 
988   /* Get the SYSCLK configuration --------------------------------------------*/
989   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
990 
991   /* Get the HCLK configuration ----------------------------------------------*/
992   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
993 
994   /* Get the APB1 configuration ----------------------------------------------*/
995   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE);
996 
997 
998   /* Get the Flash Wait State (Latency) configuration ------------------------*/
999   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1000 }
1001 
1002 /**
1003   * @brief  Enable the Clock Security System.
1004   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1005   *         is automatically disabled and an interrupt is generated to inform the
1006   *         software about the failure (Clock Security System Interrupt, CSSI),
1007   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1008   *         the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1009   * @note   The Clock Security System can only be cleared by reset.
1010   * @retval None
1011   */
HAL_RCC_EnableCSS(void)1012 void HAL_RCC_EnableCSS(void)
1013 {
1014   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1015 }
1016 
1017 /**
1018   * @brief  Enable the LSE Clock Security System.
1019   * @note   If a failure is detected on the LSE oscillator clock, this oscillator
1020   *         is automatically disabled and an interrupt is generated to inform the
1021   *         software about the failure (Clock Security System Interrupt, CSSI),
1022   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1023   *         the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1024   * @note   The LSE Clock Security System Detection bit (LSECSSD in CSR1) can only be
1025   *         cleared by a backup domain reset.
1026   * @retval None
1027   */
HAL_RCC_EnableLSECSS(void)1028 void HAL_RCC_EnableLSECSS(void)
1029 {
1030   SET_BIT(RCC->CSR1, RCC_CSR1_LSECSSON) ;
1031 }
1032 
1033 /**
1034   * @brief  Disable the LSE Clock Security System.
1035   * @note   After LSE failure detection, the software must disable LSECSSON
1036   * @note   The Clock Security System can only be cleared by reset otherwise.
1037   * @retval None
1038   */
HAL_RCC_DisableLSECSS(void)1039 void HAL_RCC_DisableLSECSS(void)
1040 {
1041   CLEAR_BIT(RCC->CSR1, RCC_CSR1_LSECSSON) ;
1042 }
1043 
1044 /**
1045   * @brief Handle the RCC Clock Security System interrupt request.
1046   * @note  This API should be called under the NMI_Handler().
1047   * @retval None
1048   */
HAL_RCC_NMI_IRQHandler(void)1049 void HAL_RCC_NMI_IRQHandler(void)
1050 {
1051   uint32_t itflag = RCC->CIFR;
1052 
1053   /* Clear interrupt flags related to CSS */
1054   RCC->CICR = (itflag & (RCC_CIFR_CSSF | RCC_CIFR_LSECSSF));
1055 
1056   /* Check RCC CSSF interrupt flag  */
1057   if ((itflag & RCC_CIFR_CSSF) != 0x00u)
1058   {
1059     /* RCC Clock Security System interrupt user callback */
1060     HAL_RCC_CSSCallback();
1061   }
1062 
1063   /* Check RCC LSECSSF interrupt flag  */
1064   if ((itflag & RCC_CIFR_LSECSSF) != 0x00u)
1065   {
1066     /* RCC Clock Security System interrupt user callback */
1067     HAL_RCC_LSECSSCallback();
1068   }
1069 }
1070 
1071 /**
1072   * @brief Handle the RCC HSE Clock Security System interrupt callback.
1073   * @retval none
1074   */
HAL_RCC_CSSCallback(void)1075 __weak void HAL_RCC_CSSCallback(void)
1076 {
1077   /* NOTE : This function should not be modified, when the callback is needed,
1078             the @ref HAL_RCC_CSSCallback should be implemented in the user file
1079    */
1080 }
1081 
1082 /**
1083   * @brief  RCC LSE Clock Security System interrupt callback.
1084   * @retval none
1085   */
HAL_RCC_LSECSSCallback(void)1086 __weak void HAL_RCC_LSECSSCallback(void)
1087 {
1088   /* NOTE : This function should not be modified, when the callback is needed,
1089             the HAL_RCC_LSECSSCallback should be implemented in the user file
1090    */
1091 }
1092 
1093 /**
1094   * @}
1095   */
1096 
1097 /**
1098   * @}
1099   */
1100 
1101 #endif /* HAL_RCC_MODULE_ENABLED */
1102 /**
1103   * @}
1104   */
1105 
1106 /**
1107   * @}
1108   */
1109