STM32L486xx HAL User Manual
stm32l4xx_ll_utils.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_ll_utils.c
00004   * @author  MCD Application Team
00005   * @brief   UTILS LL module driver.
00006   ******************************************************************************
00007   * @attention
00008   *
00009   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00010   *
00011   * Redistribution and use in source and binary forms, with or without modification,
00012   * are permitted provided that the following conditions are met:
00013   *   1. Redistributions of source code must retain the above copyright notice,
00014   *      this list of conditions and the following disclaimer.
00015   *   2. Redistributions in binary form must reproduce the above copyright notice,
00016   *      this list of conditions and the following disclaimer in the documentation
00017   *      and/or other materials provided with the distribution.
00018   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00019   *      may be used to endorse or promote products derived from this software
00020   *      without specific prior written permission.
00021   *
00022   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00023   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00025   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00026   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00030   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032   *
00033   ******************************************************************************
00034   */
00035 /* Includes ------------------------------------------------------------------*/
00036 #include "stm32l4xx_ll_utils.h"
00037 #include "stm32l4xx_ll_rcc.h"
00038 #include "stm32l4xx_ll_system.h"
00039 #include "stm32l4xx_ll_pwr.h"
00040 #ifdef  USE_FULL_ASSERT
00041 #include "stm32_assert.h"
00042 #else
00043 #define assert_param(expr) ((void)0U)
00044 #endif /* USE_FULL_ASSERT */
00045 
00046 /** @addtogroup STM32L4xx_LL_Driver
00047   * @{
00048   */
00049 
00050 /** @addtogroup UTILS_LL
00051   * @{
00052   */
00053 
00054 /* Private types -------------------------------------------------------------*/
00055 /* Private variables ---------------------------------------------------------*/
00056 /* Private constants ---------------------------------------------------------*/
00057 /** @addtogroup UTILS_LL_Private_Constants
00058   * @{
00059   */
00060 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00061 #define UTILS_MAX_FREQUENCY_SCALE1  120000000U       /*!< Maximum frequency for system clock at power scale1, in Hz */
00062 #define UTILS_MAX_FREQUENCY_SCALE2   26000000U       /*!< Maximum frequency for system clock at power scale2, in Hz */
00063 #else
00064 #define UTILS_MAX_FREQUENCY_SCALE1   80000000U       /*!< Maximum frequency for system clock at power scale1, in Hz */
00065 #define UTILS_MAX_FREQUENCY_SCALE2   26000000U       /*!< Maximum frequency for system clock at power scale2, in Hz */
00066 #endif
00067 
00068 /* Defines used for PLL range */
00069 #define UTILS_PLLVCO_INPUT_MIN        4000000U       /*!< Frequency min for PLLVCO input, in Hz   */
00070 #define UTILS_PLLVCO_INPUT_MAX       16000000U       /*!< Frequency max for PLLVCO input, in Hz   */
00071 #define UTILS_PLLVCO_OUTPUT_MIN      64000000U       /*!< Frequency min for PLLVCO output, in Hz  */
00072 #define UTILS_PLLVCO_OUTPUT_MAX     344000000U       /*!< Frequency max for PLLVCO output, in Hz  */
00073 
00074 /* Defines used for HSE range */
00075 #define UTILS_HSE_FREQUENCY_MIN      4000000U        /*!< Frequency min for HSE frequency, in Hz   */
00076 #define UTILS_HSE_FREQUENCY_MAX     48000000U        /*!< Frequency max for HSE frequency, in Hz   */
00077 
00078 /* Defines used for FLASH latency according to HCLK Frequency */
00079 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00080 #define UTILS_SCALE1_LATENCY1_FREQ   20000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
00081 #define UTILS_SCALE1_LATENCY2_FREQ   40000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
00082 #define UTILS_SCALE1_LATENCY3_FREQ   60000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
00083 #define UTILS_SCALE1_LATENCY4_FREQ   80000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
00084 #define UTILS_SCALE1_LATENCY5_FREQ  100000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
00085 #define UTILS_SCALE2_LATENCY1_FREQ    8000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
00086 #define UTILS_SCALE2_LATENCY2_FREQ   16000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
00087 #else
00088 #define UTILS_SCALE1_LATENCY1_FREQ   16000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
00089 #define UTILS_SCALE1_LATENCY2_FREQ   32000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
00090 #define UTILS_SCALE1_LATENCY3_FREQ   48000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
00091 #define UTILS_SCALE1_LATENCY4_FREQ   64000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
00092 #define UTILS_SCALE2_LATENCY1_FREQ    6000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
00093 #define UTILS_SCALE2_LATENCY2_FREQ   12000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
00094 #define UTILS_SCALE2_LATENCY3_FREQ   18000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
00095 #endif
00096 /**
00097   * @}
00098   */
00099 
00100 /* Private macros ------------------------------------------------------------*/
00101 /** @addtogroup UTILS_LL_Private_Macros
00102   * @{
00103   */
00104 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
00105                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
00106                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
00107                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
00108                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
00109                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
00110                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
00111                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
00112                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
00113 
00114 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
00115                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
00116                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
00117                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
00118                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
00119 
00120 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
00121                                       || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
00122                                       || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
00123                                       || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
00124                                       || ((__VALUE__) == LL_RCC_APB2_DIV_16))
00125 
00126 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
00127                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
00128                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
00129                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
00130                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
00131                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
00132                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
00133                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_8))
00134 
00135 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8 <= (__VALUE__)) && ((__VALUE__) <= 86))
00136 
00137 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
00138                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
00139                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
00140                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_8))
00141 
00142 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__)  ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
00143 
00144 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
00145 
00146 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
00147                                              ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
00148 
00149 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
00150                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
00151 
00152 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
00153 /**
00154   * @}
00155   */
00156 /* Private function prototypes -----------------------------------------------*/
00157 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
00158   * @{
00159   */
00160 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
00161                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
00162 static ErrorStatus UTILS_SetFlashLatency(uint32_t HCLK_Frequency);
00163 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
00164 static ErrorStatus UTILS_PLL_IsBusy(void);
00165 /**
00166   * @}
00167   */
00168 
00169 /* Exported functions --------------------------------------------------------*/
00170 /** @addtogroup UTILS_LL_Exported_Functions
00171   * @{
00172   */
00173 
00174 /** @addtogroup UTILS_LL_EF_DELAY
00175   * @{
00176   */
00177 
00178 /**
00179   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
00180   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
00181   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
00182   * @param  HCLKFrequency HCLK frequency in Hz
00183   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
00184   * @retval None
00185   */
00186 void LL_Init1msTick(uint32_t HCLKFrequency)
00187 {
00188   /* Use frequency provided in argument */
00189   LL_InitTick(HCLKFrequency, 1000U);
00190 }
00191 
00192 /**
00193   * @brief  This function provides accurate delay (in milliseconds) based
00194   *         on SysTick counter flag
00195   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
00196   *         and use rather osDelay service.
00197   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
00198   *         will configure Systick to 1ms
00199   * @param  Delay specifies the delay time length, in milliseconds.
00200   * @retval None
00201   */
00202 void LL_mDelay(uint32_t Delay)
00203 {
00204   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
00205   /* Add this code to indicate that local variable is not used */
00206   ((void)tmp);
00207 
00208   /* Add a period to guaranty minimum wait */
00209   if(Delay < LL_MAX_DELAY)
00210   {
00211     Delay++;
00212   }
00213 
00214   while (Delay)
00215   {
00216     if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
00217     {
00218       Delay--;
00219     }
00220   }
00221 }
00222 
00223 /**
00224   * @}
00225   */
00226 
00227 /** @addtogroup UTILS_EF_SYSTEM
00228   *  @brief    System Configuration functions
00229   *
00230   @verbatim
00231  ===============================================================================
00232            ##### System Configuration functions #####
00233  ===============================================================================
00234     [..]
00235          System, AHB and APB buses clocks configuration
00236 
00237          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 
00238              120000000 Hz for STM32L4Rx/STM32L4Sx devices and 80000000 Hz for others.
00239   @endverbatim
00240   @internal
00241              Depending on the device voltage range, the maximum frequency should be
00242              adapted accordingly:
00243 
00244              (++) Table 1. HCLK clock frequency for STM32L4Rx/STM32L4Sx devices
00245              (++) +--------------------------------------------------------+
00246              (++) | Latency         |     HCLK clock frequency (MHz)       |
00247              (++) |                 |--------------------------------------|
00248              (++) |                 |  voltage range 1  | voltage range 2  |
00249              (++) |                 |       1.2 V       |     1.0 V        |
00250              (++) |-----------------|-------------------|------------------|
00251              (++) |0WS(1 CPU cycles)|   0 < HCLK <= 20  |  0 < HCLK <= 8   |
00252              (++) |-----------------|-------------------|------------------|
00253              (++) |1WS(2 CPU cycles)|  20 < HCLK <= 40  |  8 < HCLK <= 16  |
00254              (++) |-----------------|-------------------|------------------|
00255              (++) |2WS(3 CPU cycles)|  40 < HCLK <= 60  | 16 < HCLK <= 26  |
00256              (++) |-----------------|-------------------|------------------|
00257              (++) |3WS(4 CPU cycles)|  60 < HCLK <= 80  | 16 < HCLK <= 26  |
00258              (++) |-----------------|-------------------|------------------|
00259              (++) |4WS(5 CPU cycles)|  80 < HCLK <= 100 | 16 < HCLK <= 26  |
00260              (++) |-----------------|-------------------|------------------|
00261              (++) |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26  |
00262              (++) +--------------------------------------------------------+
00263 
00264              (++) Table 2. HCLK clock frequency for other STM32L4 devices
00265              (++) +-------------------------------------------------------+
00266              (++) | Latency         |    HCLK clock frequency (MHz)       |
00267              (++) |                 |-------------------------------------|
00268              (++) |                 | voltage range 1  | voltage range 2  |
00269              (++) |                 |      1.2 V       |     1.0 V        |
00270              (++) |-----------------|------------------|------------------|
00271              (++) |0WS(1 CPU cycles)|  0 < HCLK <= 16  |  0 < HCLK <= 6   |
00272              (++) |-----------------|------------------|------------------|
00273              (++) |1WS(2 CPU cycles)| 16 < HCLK <= 32  |  6 < HCLK <= 12  |
00274              (++) |-----------------|------------------|------------------|
00275              (++) |2WS(3 CPU cycles)| 32 < HCLK <= 48  | 12 < HCLK <= 18  |
00276              (++) |-----------------|------------------|------------------|
00277              (++) |3WS(4 CPU cycles)| 48 < HCLK <= 64  | 18 < HCLK <= 26  |
00278              (++) |-----------------|------------------|------------------|
00279              (++) |4WS(5 CPU cycles)| 64 < HCLK <= 80  | 18 < HCLK <= 26  |
00280              (++) +-------------------------------------------------------+
00281 
00282   @endinternal
00283   * @{
00284   */
00285 
00286 /**
00287   * @brief  This function sets directly SystemCoreClock CMSIS variable.
00288   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
00289   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
00290   * @retval None
00291   */
00292 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
00293 {
00294   /* HCLK clock frequency */
00295   SystemCoreClock = HCLKFrequency;
00296 }
00297 
00298 /**
00299   * @brief  This function configures system clock with MSI as clock source of the PLL
00300   * @note   The application needs to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
00301   * @note   Function is based on the following formula:
00302   *         - PLL output frequency = (((MSI frequency / PLLM) * PLLN) / PLLR)
00303   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = MSI frequency / PLLM)
00304   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
00305   *         - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR)
00306   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
00307   *                             the configuration information for the PLL.
00308   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
00309   *                             the configuration information for the BUS prescalers.
00310   * @retval An ErrorStatus enumeration value:
00311   *          - SUCCESS: Max frequency configuration done
00312   *          - ERROR: Max frequency configuration not done
00313   */
00314 ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
00315                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
00316 {
00317   ErrorStatus status = SUCCESS;
00318   uint32_t pllfreq = 0U, msi_range = 0U;
00319 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00320   uint32_t hpre = 0U;
00321 #endif
00322 
00323   /* Check if one of the PLL is enabled */
00324   if(UTILS_PLL_IsBusy() == SUCCESS)
00325   {
00326     /* Get the current MSI range */
00327     if(LL_RCC_MSI_IsEnabledRangeSelect())
00328     {
00329       msi_range =  LL_RCC_MSI_GetRange();
00330       switch (msi_range)
00331       {
00332         case LL_RCC_MSIRANGE_0:     /* MSI = 100 KHz  */
00333         case LL_RCC_MSIRANGE_1:     /* MSI = 200 KHz  */
00334         case LL_RCC_MSIRANGE_2:     /* MSI = 400 KHz  */
00335         case LL_RCC_MSIRANGE_3:     /* MSI = 800 KHz  */
00336         case LL_RCC_MSIRANGE_4:     /* MSI = 1 MHz    */
00337         case LL_RCC_MSIRANGE_5:     /* MSI = 2 MHz    */
00338           /* PLLVCO input frequency is not in the range from 4 to 16 MHz*/
00339           status = ERROR;
00340           break;
00341 
00342         case LL_RCC_MSIRANGE_6:     /* MSI = 4 MHz    */
00343         case LL_RCC_MSIRANGE_7:     /* MSI = 8 MHz    */
00344         case LL_RCC_MSIRANGE_8:     /* MSI = 16 MHz   */
00345         case LL_RCC_MSIRANGE_9:     /* MSI = 24 MHz   */
00346         case LL_RCC_MSIRANGE_10:    /* MSI = 32 MHz   */
00347         case LL_RCC_MSIRANGE_11:    /* MSI = 48 MHz   */
00348         default:
00349           break;
00350       }
00351     }
00352     else
00353     {
00354       msi_range = LL_RCC_MSI_GetRangeAfterStandby();
00355       switch (msi_range)
00356       {
00357         case LL_RCC_MSISRANGE_4:    /* MSI = 1 MHz    */
00358         case LL_RCC_MSISRANGE_5:    /* MSI = 2 MHz    */
00359           /* PLLVCO input frequency is not in the range from 4 to 16 MHz*/
00360           status = ERROR;
00361           break;
00362 
00363         case LL_RCC_MSISRANGE_7:    /* MSI = 8 MHz    */
00364         case LL_RCC_MSISRANGE_6:    /* MSI = 4 MHz    */
00365         default:
00366           break;
00367       }
00368     }
00369 
00370     /* Main PLL configuration and activation */
00371     if(status != ERROR)
00372     {
00373       /* Calculate the new PLL output frequency */
00374       pllfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), msi_range),
00375                                             UTILS_PLLInitStruct);
00376 
00377       /* Enable MSI if not enabled */
00378       if(LL_RCC_MSI_IsReady() != 1U)
00379       {
00380         LL_RCC_MSI_Enable();
00381         while ((LL_RCC_MSI_IsReady() != 1U))
00382         {
00383           /* Wait for MSI ready */
00384         }
00385       }
00386 
00387       /* Configure PLL */
00388       LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
00389                                   UTILS_PLLInitStruct->PLLR);
00390 
00391 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00392       /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
00393       if(pllfreq > 80000000U)
00394       {
00395         hpre = UTILS_ClkInitStruct->AHBCLKDivider;
00396         if(hpre == LL_RCC_SYSCLK_DIV_1)
00397         {
00398           UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
00399         }
00400       }
00401 #endif
00402       /* Enable PLL and switch system clock to PLL */
00403       status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
00404 
00405 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00406       /* Apply definitive AHB prescaler value if necessary */
00407       if((status == SUCCESS) && (hpre != 0U))
00408       {
00409         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
00410         LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
00411       }
00412 #endif
00413     }
00414   }
00415   else
00416   {
00417     /* Current PLL configuration cannot be modified */
00418     status = ERROR;
00419   }
00420 
00421   return status;
00422 }
00423 
00424 /**
00425   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
00426   * @note   The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
00427   * @note   Function is based on the following formula:
00428   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
00429   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
00430   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
00431   *         - PLLR: ensure that max frequency at 120000000 Hz is reach (PLLVCO_output / PLLR)
00432   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
00433   *                             the configuration information for the PLL.
00434   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
00435   *                             the configuration information for the BUS prescalers.
00436   * @retval An ErrorStatus enumeration value:
00437   *          - SUCCESS: Max frequency configuration done
00438   *          - ERROR: Max frequency configuration not done
00439   */
00440 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
00441                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
00442 {
00443   ErrorStatus status = SUCCESS;
00444   uint32_t pllfreq = 0U;
00445 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00446   uint32_t hpre = 0U;
00447 #endif
00448 
00449   /* Check if one of the PLL is enabled */
00450   if(UTILS_PLL_IsBusy() == SUCCESS)
00451   {
00452     /* Calculate the new PLL output frequency */
00453     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
00454 
00455     /* Enable HSI if not enabled */
00456     if(LL_RCC_HSI_IsReady() != 1U)
00457     {
00458       LL_RCC_HSI_Enable();
00459       while (LL_RCC_HSI_IsReady() != 1U)
00460       {
00461         /* Wait for HSI ready */
00462       }
00463     }
00464 
00465     /* Configure PLL */
00466     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
00467                                 UTILS_PLLInitStruct->PLLR);
00468 
00469 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00470     /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
00471     if(pllfreq > 80000000U)
00472     {
00473       hpre = UTILS_ClkInitStruct->AHBCLKDivider;
00474       if(hpre == LL_RCC_SYSCLK_DIV_1)
00475       {
00476         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
00477       }
00478     }
00479 #endif
00480     /* Enable PLL and switch system clock to PLL */
00481     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
00482 
00483 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00484     /* Apply definitive AHB prescaler value if necessary */
00485     if((status == SUCCESS) && (hpre != 0U))
00486     {
00487       UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
00488       LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
00489     }
00490 #endif
00491   }
00492   else
00493   {
00494     /* Current PLL configuration cannot be modified */
00495     status = ERROR;
00496   }
00497 
00498   return status;
00499 }
00500 
00501 /**
00502   * @brief  This function configures system clock with HSE as clock source of the PLL
00503   * @note   The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
00504   * @note   Function is based on the following formula:
00505   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
00506   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSE frequency / PLLM)
00507   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
00508   *         - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR)
00509   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
00510   * @param  HSEBypass This parameter can be one of the following values:
00511   *         @arg @ref LL_UTILS_HSEBYPASS_ON
00512   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
00513   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
00514   *                             the configuration information for the PLL.
00515   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
00516   *                             the configuration information for the BUS prescalers.
00517   * @retval An ErrorStatus enumeration value:
00518   *          - SUCCESS: Max frequency configuration done
00519   *          - ERROR: Max frequency configuration not done
00520   */
00521 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
00522                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
00523 {
00524   ErrorStatus status = SUCCESS;
00525   uint32_t pllfreq = 0U;
00526 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00527   uint32_t hpre = 0U;
00528 #endif
00529 
00530   /* Check the parameters */
00531   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
00532   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
00533 
00534   /* Check if one of the PLL is enabled */
00535   if(UTILS_PLL_IsBusy() == SUCCESS)
00536   {
00537     /* Calculate the new PLL output frequency */
00538     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
00539 
00540     /* Enable HSE if not enabled */
00541     if(LL_RCC_HSE_IsReady() != 1U)
00542     {
00543       /* Check if need to enable HSE bypass feature or not */
00544       if(HSEBypass == LL_UTILS_HSEBYPASS_ON)
00545       {
00546         LL_RCC_HSE_EnableBypass();
00547       }
00548       else
00549       {
00550         LL_RCC_HSE_DisableBypass();
00551       }
00552 
00553       /* Enable HSE */
00554       LL_RCC_HSE_Enable();
00555       while (LL_RCC_HSE_IsReady() != 1U)
00556       {
00557         /* Wait for HSE ready */
00558       }
00559     }
00560 
00561     /* Configure PLL */
00562     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
00563                                 UTILS_PLLInitStruct->PLLR);
00564 
00565 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00566     /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
00567     if(pllfreq > 80000000U)
00568     {
00569       hpre = UTILS_ClkInitStruct->AHBCLKDivider;
00570       if(hpre == LL_RCC_SYSCLK_DIV_1)
00571       {
00572         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
00573       }
00574     }
00575 #endif
00576     /* Enable PLL and switch system clock to PLL */
00577     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
00578 
00579 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00580     /* Apply definitive AHB prescaler value if necessary */
00581     if((status == SUCCESS) && (hpre != 0U))
00582     {
00583       UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
00584       LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
00585     }
00586 #endif
00587   }
00588   else
00589   {
00590     /* Current PLL configuration cannot be modified */
00591     status = ERROR;
00592   }
00593 
00594   return status;
00595 }
00596 
00597 /**
00598   * @}
00599   */
00600 
00601 /**
00602   * @}
00603   */
00604 
00605 /** @addtogroup UTILS_LL_Private_Functions
00606   * @{
00607   */
00608 /**
00609   * @brief  Update number of Flash wait states in line with new frequency and current
00610             voltage range.
00611   * @param  HCLK_Frequency  HCLK frequency
00612   * @retval An ErrorStatus enumeration value:
00613   *          - SUCCESS: Latency has been modified
00614   *          - ERROR: Latency cannot be modified
00615   */
00616 static ErrorStatus UTILS_SetFlashLatency(uint32_t HCLK_Frequency)
00617 {
00618   ErrorStatus status = SUCCESS;
00619 
00620   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
00621 
00622   /* Frequency cannot be equal to 0 */
00623   if(HCLK_Frequency == 0U)
00624   {
00625     status = ERROR;
00626   }
00627   else
00628   {
00629     if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
00630     {
00631 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00632       if(HCLK_Frequency > UTILS_SCALE1_LATENCY5_FREQ)
00633       {
00634         /* 100 < HCLK <= 120 => 5WS (6 CPU cycles) */
00635         latency = LL_FLASH_LATENCY_5;
00636       }
00637       else if(HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ)
00638       {
00639         /* 80 < HCLK <= 100 => 4WS (5 CPU cycles) */
00640         latency = LL_FLASH_LATENCY_4;
00641       }
00642       else if(HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ)
00643       {
00644         /* 60 < HCLK <= 80 => 3WS (4 CPU cycles) */
00645         latency = LL_FLASH_LATENCY_3;
00646       }
00647       else if(HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ)
00648       {
00649         /* 40 < HCLK <= 20 => 2WS (3 CPU cycles) */
00650         latency = LL_FLASH_LATENCY_2;
00651       }
00652       else
00653       {
00654         if(HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ)
00655         {
00656           /* 20 < HCLK <= 40 => 1WS (2 CPU cycles) */
00657           latency = LL_FLASH_LATENCY_1;
00658         }
00659         /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
00660       }
00661 #else
00662       if(HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ)
00663       {
00664         /* 64 < HCLK <= 80 => 4WS (5 CPU cycles) */
00665         latency = LL_FLASH_LATENCY_4;
00666       }
00667       else if(HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ)
00668       {
00669         /* 48 < HCLK <= 64 => 3WS (4 CPU cycles) */
00670         latency = LL_FLASH_LATENCY_3;
00671       }
00672       else if(HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ)
00673       {
00674         /* 32 < HCLK <= 48 => 2WS (3 CPU cycles) */
00675         latency = LL_FLASH_LATENCY_2;
00676       }
00677       else
00678       {
00679         if(HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ)
00680         {
00681           /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
00682           latency = LL_FLASH_LATENCY_1;
00683         }
00684         /* else HCLK_Frequency <= 16MHz default LL_FLASH_LATENCY_0 0WS */
00685       }
00686 #endif
00687     }
00688     else /* SCALE2 */
00689     {
00690 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00691       if(HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ)
00692       {
00693         /* 16 < HCLK <= 26 => 2WS (3 CPU cycles) */
00694         latency = LL_FLASH_LATENCY_2;
00695       }
00696       else
00697       {
00698         if(HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ)
00699         {
00700           /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
00701           latency = LL_FLASH_LATENCY_1;
00702         }
00703         /* else HCLK_Frequency <= 8MHz default LL_FLASH_LATENCY_0 0WS */
00704       }
00705 #else
00706       if(HCLK_Frequency > UTILS_SCALE2_LATENCY3_FREQ)
00707       {
00708         /* 18 < HCLK <= 26 => 3WS (4 CPU cycles) */
00709         latency = LL_FLASH_LATENCY_3;
00710       }
00711       else if(HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ)
00712       {
00713         /* 12 < HCLK <= 18 => 2WS (3 CPU cycles) */
00714         latency = LL_FLASH_LATENCY_2;
00715       }
00716       else
00717       {
00718         if(HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ)
00719         {
00720           /* 6 < HCLK <= 12 => 1WS (2 CPU cycles) */
00721           latency = LL_FLASH_LATENCY_1;
00722         }
00723         /* else HCLK_Frequency <= 6MHz default LL_FLASH_LATENCY_0 0WS */
00724       }
00725 #endif
00726     }
00727 
00728     LL_FLASH_SetLatency(latency);
00729 
00730     /* Check that the new number of wait states is taken into account to access the Flash
00731        memory by reading the FLASH_ACR register */
00732     if(LL_FLASH_GetLatency() != latency)
00733     {
00734       status = ERROR;
00735     }
00736   }
00737   return status;
00738 }
00739 
00740 /**
00741   * @brief  Function to check that PLL can be modified
00742   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
00743   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
00744   *                             the configuration information for the PLL.
00745   * @retval PLL output frequency (in Hz)
00746   */
00747 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
00748 {
00749   uint32_t pllfreq = 0U;
00750 
00751   /* Check the parameters */
00752   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
00753   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
00754   assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
00755 
00756   /* Check different PLL parameters according to RM                          */
00757   /*  - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz.   */
00758   pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1));
00759   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
00760 
00761   /*  - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
00762   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
00763   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
00764 
00765   /*  - PLLR: ensure that max frequency at 120000000 Hz is reached                   */
00766   pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1) * 2);
00767   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
00768 
00769   return pllfreq;
00770 }
00771 
00772 /**
00773   * @brief  Function to check that PLL can be modified
00774   * @retval An ErrorStatus enumeration value:
00775   *          - SUCCESS: PLL modification can be done
00776   *          - ERROR: PLL is busy
00777   */
00778 static ErrorStatus UTILS_PLL_IsBusy(void)
00779 {
00780   ErrorStatus status = SUCCESS;
00781 
00782   /* Check if PLL is busy*/
00783   if(LL_RCC_PLL_IsReady() != 0U)
00784   {
00785     /* PLL configuration cannot be modified */
00786     status = ERROR;
00787   }
00788 
00789   /* Check if PLLSAI1 is busy*/
00790   if(LL_RCC_PLLSAI1_IsReady() != 0U)
00791   {
00792     /* PLLSAI1 configuration cannot be modified */
00793     status = ERROR;
00794   }
00795 #if defined(RCC_PLLSAI2_SUPPORT)
00796 
00797   /* Check if PLLSAI2 is busy*/
00798   if(LL_RCC_PLLSAI2_IsReady() != 0U)
00799   {
00800     /* PLLSAI2 configuration cannot be modified */
00801     status = ERROR;
00802   }
00803 #endif /*RCC_PLLSAI2_SUPPORT*/
00804 
00805   return status;
00806 }
00807 
00808 /**
00809   * @brief  Function to enable PLL and switch system clock to PLL
00810   * @param  SYSCLK_Frequency SYSCLK frequency
00811   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
00812   *                             the configuration information for the BUS prescalers.
00813   * @retval An ErrorStatus enumeration value:
00814   *          - SUCCESS: No problem to switch system to PLL
00815   *          - ERROR: Problem to switch system to PLL
00816   */
00817 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
00818 {
00819   ErrorStatus status = SUCCESS;
00820   uint32_t hclk_frequency = 0U;
00821 
00822   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
00823   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
00824   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
00825 
00826   /* Calculate HCLK frequency */
00827   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
00828 
00829   /* Increasing the number of wait states because of higher CPU frequency */
00830   if(SystemCoreClock < hclk_frequency)
00831   {
00832     /* Set FLASH latency to highest latency */
00833     status = UTILS_SetFlashLatency(hclk_frequency);
00834   }
00835 
00836   /* Update system clock configuration */
00837   if(status == SUCCESS)
00838   {
00839     /* Enable PLL */
00840     LL_RCC_PLL_Enable();
00841     LL_RCC_PLL_EnableDomain_SYS();
00842     while (LL_RCC_PLL_IsReady() != 1U)
00843     {
00844       /* Wait for PLL ready */
00845     }
00846 
00847     /* Sysclk activation on the main PLL */
00848     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
00849     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
00850     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
00851     {
00852       /* Wait for system clock switch to PLL */
00853     }
00854 
00855     /* Set APB1 & APB2 prescaler*/
00856     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
00857     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
00858   }
00859     
00860   /* Decreasing the number of wait states because of lower CPU frequency */
00861   if(SystemCoreClock > hclk_frequency)
00862   {
00863     /* Set FLASH latency to lowest latency */
00864     status = UTILS_SetFlashLatency(hclk_frequency);
00865   }
00866 
00867   /* Update SystemCoreClock variable */
00868   if(status == SUCCESS)
00869   {
00870     LL_SetSystemCoreClock(hclk_frequency);
00871   }
00872 
00873   return status;
00874 }
00875 
00876 /**
00877   * @}
00878   */
00879 
00880 /**
00881   * @}
00882   */
00883 
00884 /**
00885   * @}
00886   */
00887 
00888 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/