Subversion Repositories FuelGauge

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f0xx_ll_utils.c
  4.   * @author  MCD Application Team
  5.   * @brief   UTILS LL module driver.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19.  
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "stm32f0xx_ll_rcc.h"
  22. #include "stm32f0xx_ll_utils.h"
  23. #include "stm32f0xx_ll_system.h"
  24. #ifdef  USE_FULL_ASSERT
  25. #include "stm32_assert.h"
  26. #else
  27. #define assert_param(expr) ((void)0U)
  28. #endif
  29.  
  30. /** @addtogroup STM32F0xx_LL_Driver
  31.   * @{
  32.   */
  33.  
  34. /** @addtogroup UTILS_LL
  35.   * @{
  36.   */
  37.  
  38. /* Private types -------------------------------------------------------------*/
  39. /* Private variables ---------------------------------------------------------*/
  40. /* Private constants ---------------------------------------------------------*/
  41. /** @addtogroup UTILS_LL_Private_Constants
  42.   * @{
  43.   */
  44.  
  45. /* Defines used for PLL range */
  46. #define UTILS_PLL_OUTPUT_MIN        16000000U           /*!< Frequency min for PLL output, in Hz  */
  47. #define UTILS_PLL_OUTPUT_MAX        48000000U    /*!< Frequency max for PLL output, in Hz  */
  48.  
  49. /* Defines used for HSE range */
  50. #define UTILS_HSE_FREQUENCY_MIN      4000000U       /*!< Frequency min for HSE frequency, in Hz   */
  51. #define UTILS_HSE_FREQUENCY_MAX     32000000U       /*!< Frequency max for HSE frequency, in Hz   */
  52.  
  53. /* Defines used for FLASH latency according to SYSCLK Frequency */
  54. #define UTILS_LATENCY1_FREQ         24000000U        /*!< SYSCLK frequency to set FLASH latency 1 */
  55. /**
  56.   * @}
  57.   */
  58. /* Private macros ------------------------------------------------------------*/
  59. /** @addtogroup UTILS_LL_Private_Macros
  60.   * @{
  61.   */
  62. #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
  63.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
  64.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
  65.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
  66.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
  67.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
  68.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
  69.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
  70.                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
  71.  
  72. #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
  73.                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
  74.                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
  75.                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
  76.                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
  77.  
  78. #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
  79.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
  80.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
  81.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
  82.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
  83.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
  84.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
  85.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
  86.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
  87.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
  88.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
  89.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
  90.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
  91.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
  92.                                           || ((__VALUE__) == LL_RCC_PLL_MUL_16))
  93.  
  94. #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_2)   || \
  95.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_3)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_4)   || \
  96.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_5)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_6)   || \
  97.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_7)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_8)   || \
  98.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_9)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_10)  || \
  99.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12)  || \
  100.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14)  || \
  101.                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
  102.  
  103. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((UTILS_PLL_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX))
  104.  
  105.  
  106. #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
  107.                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
  108.  
  109. #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
  110. /**
  111.   * @}
  112.   */
  113. /* Private function prototypes -----------------------------------------------*/
  114. /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
  115.   * @{
  116.   */
  117. static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
  118.                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
  119. #if defined(FLASH_ACR_LATENCY)
  120. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
  121. #endif /* FLASH_ACR_LATENCY */
  122. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  123. static ErrorStatus UTILS_PLL_IsBusy(void);
  124. /**
  125.   * @}
  126.   */
  127.  
  128. /* Exported functions --------------------------------------------------------*/
  129. /** @addtogroup UTILS_LL_Exported_Functions
  130.   * @{
  131.   */
  132.  
  133. /** @addtogroup UTILS_LL_EF_DELAY
  134.   * @{
  135.   */
  136.  
  137. /**
  138.   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
  139.   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
  140.   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
  141.   * @param  HCLKFrequency HCLK frequency in Hz
  142.   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
  143.   * @retval None
  144.   */
  145. void LL_Init1msTick(uint32_t HCLKFrequency)
  146. {
  147.   /* Use frequency provided in argument */
  148.   LL_InitTick(HCLKFrequency, 1000U);
  149. }
  150.  
  151. /**
  152.   * @brief  This function provides accurate delay (in milliseconds) based
  153.   *         on SysTick counter flag
  154.   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
  155.   *         and use rather osDelay service.
  156.   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  157.   *         will configure Systick to 1ms
  158.   * @param  Delay specifies the delay time length, in milliseconds.
  159.   * @retval None
  160.   */
  161. void LL_mDelay(uint32_t Delay)
  162. {
  163.   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
  164.   /* Add this code to indicate that local variable is not used */
  165.   ((void)tmp);
  166.  
  167.   /* Add a period to guaranty minimum wait */
  168.   if (Delay < LL_MAX_DELAY)
  169.   {
  170.     Delay++;
  171.   }
  172.  
  173.   while (Delay)
  174.   {
  175.     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  176.     {
  177.       Delay--;
  178.     }
  179.   }
  180. }
  181.  
  182. /**
  183.   * @}
  184.   */
  185.  
  186. /** @addtogroup UTILS_EF_SYSTEM
  187.   *  @brief    System Configuration functions
  188.   *
  189.   @verbatim
  190.  ===============================================================================
  191.            ##### System Configuration functions #####
  192.  ===============================================================================
  193.     [..]
  194.          System, AHB and APB buses clocks configuration
  195.  
  196.          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 48000000 Hz.
  197.   @endverbatim
  198.   @internal
  199.              Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
  200.              (++) +-----------------------------------------------+
  201.              (++) | Latency       | SYSCLK clock frequency (MHz)  |
  202.              (++) |---------------|-------------------------------|
  203.              (++) |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
  204.              (++) |---------------|-------------------------------|
  205.              (++) |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
  206.              (++) +-----------------------------------------------+
  207.   @endinternal
  208.   * @{
  209.   */
  210.  
  211. /**
  212.   * @brief  This function sets directly SystemCoreClock CMSIS variable.
  213.   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
  214.   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
  215.   * @retval None
  216.   */
  217. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  218. {
  219.   /* HCLK clock frequency */
  220.   SystemCoreClock = HCLKFrequency;
  221. }
  222.  
  223. /**
  224.   * @brief  This function configures system clock with HSI as clock source of the PLL
  225.   * @note   The application need to ensure that PLL is disabled.
  226.   * @note   Function is based on the following formula:
  227.   *         - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  228.   *         - PREDIV: Set to 2 for few devices
  229.   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
  230.   *                   be in the range 16-48MHz
  231.   * @note   FLASH latency can be modified through this function.
  232.   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  233.   *                             the configuration information for the PLL.
  234.   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  235.   *                             the configuration information for the BUS prescalers.
  236.   * @retval An ErrorStatus enumeration value:
  237.   *          - SUCCESS: Max frequency configuration done
  238.   *          - ERROR: Max frequency configuration not done
  239.   */
  240. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  241.                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  242. {
  243.   ErrorStatus status = SUCCESS;
  244.   uint32_t pllfreq = 0U;
  245.  
  246.   /* Check if one of the PLL is enabled */
  247.   if (UTILS_PLL_IsBusy() == SUCCESS)
  248.   {
  249. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  250.     /* Check PREDIV value */
  251.     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  252. #else
  253.     /* Force PREDIV value to 2 */
  254.     UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
  255. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  256.     /* Calculate the new PLL output frequency */
  257.     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  258.  
  259.     /* Enable HSI if not enabled */
  260.     if (LL_RCC_HSI_IsReady() != 1U)
  261.     {
  262.       LL_RCC_HSI_Enable();
  263.       while (LL_RCC_HSI_IsReady() != 1U)
  264.       {
  265.         /* Wait for HSI ready */
  266.       }
  267.     }
  268.  
  269.     /* Configure PLL */
  270. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  271.     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  272. #else
  273.     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
  274. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  275.  
  276.     /* Enable PLL and switch system clock to PLL */
  277.     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  278.   }
  279.   else
  280.   {
  281.     /* Current PLL configuration cannot be modified */
  282.     status = ERROR;
  283.   }
  284.  
  285.   return status;
  286. }
  287.  
  288. #if defined(RCC_CFGR_SW_HSI48)
  289. /**
  290.   * @brief  This function configures system clock with HSI48 as clock source of the PLL
  291.   * @note   The application need to ensure that PLL is disabled.
  292.   * @note   Function is based on the following formula:
  293.   *         - PLL output frequency = ((HSI48 frequency / PREDIV) * PLLMUL)
  294.   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
  295.   *                   be in the range 16-48MHz
  296.   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  297.   *                             the configuration information for the PLL.
  298.   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  299.   *                             the configuration information for the BUS prescalers.
  300.   * @retval An ErrorStatus enumeration value:
  301.   *          - SUCCESS: Max frequency configuration done
  302.   *          - ERROR: Max frequency configuration not done
  303.   */
  304. ErrorStatus LL_PLL_ConfigSystemClock_HSI48(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  305.                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  306. {
  307.   ErrorStatus status = SUCCESS;
  308.   uint32_t pllfreq = 0U;
  309.  
  310.   /* Check if one of the PLL is enabled */
  311.   if (UTILS_PLL_IsBusy() == SUCCESS)
  312.   {
  313.     /* Check PREDIV value */
  314.     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  315.  
  316.     /* Calculate the new PLL output frequency */
  317.     pllfreq = UTILS_GetPLLOutputFrequency(HSI48_VALUE, UTILS_PLLInitStruct);
  318.  
  319.     /* Enable HSI48 if not enabled */
  320.     if (LL_RCC_HSI48_IsReady() != 1U)
  321.     {
  322.       LL_RCC_HSI48_Enable();
  323.       while (LL_RCC_HSI48_IsReady() != 1U)
  324.       {
  325.         /* Wait for HSI48 ready */
  326.       }
  327.     }
  328.  
  329.     /* Configure PLL */
  330.     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI48, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  331.  
  332.     /* Enable PLL and switch system clock to PLL */
  333.     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  334.   }
  335.   else
  336.   {
  337.     /* Current PLL configuration cannot be modified */
  338.     status = ERROR;
  339.   }
  340.  
  341.   return status;
  342. }
  343.  
  344. #endif /*RCC_CFGR_SW_HSI48*/
  345. /**
  346.   * @brief  This function configures system clock with HSE as clock source of the PLL
  347.   * @note   The application need to ensure that PLL is disabled.
  348.   * @note   Function is based on the following formula:
  349.   *         - PLL output frequency = ((HSE frequency / PREDIV) * PLLMUL)
  350.   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
  351.   *                   be in the range 16-48MHz
  352.   * @note   FLASH latency can be modified through this function.
  353.   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 32000000
  354.   * @param  HSEBypass This parameter can be one of the following values:
  355.   *         @arg @ref LL_UTILS_HSEBYPASS_ON
  356.   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
  357.   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  358.   *                             the configuration information for the PLL.
  359.   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  360.   *                             the configuration information for the BUS prescalers.
  361.   * @retval An ErrorStatus enumeration value:
  362.   *          - SUCCESS: Max frequency configuration done
  363.   *          - ERROR: Max frequency configuration not done
  364.   */
  365. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
  366.                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  367. {
  368.   ErrorStatus status = SUCCESS;
  369.   uint32_t pllfreq = 0U;
  370.  
  371.   /* Check the parameters */
  372.   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  373.   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  374.  
  375.   /* Check if one of the PLL is enabled */
  376.   if (UTILS_PLL_IsBusy() == SUCCESS)
  377.   {
  378.     /* Check PREDIV value */
  379. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  380.     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  381. #else
  382.     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
  383. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  384.  
  385.     /* Calculate the new PLL output frequency */
  386.     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  387.  
  388.     /* Enable HSE if not enabled */
  389.     if (LL_RCC_HSE_IsReady() != 1U)
  390.     {
  391.       /* Check if need to enable HSE bypass feature or not */
  392.       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  393.       {
  394.         LL_RCC_HSE_EnableBypass();
  395.       }
  396.       else
  397.       {
  398.         LL_RCC_HSE_DisableBypass();
  399.       }
  400.  
  401.       /* Enable HSE */
  402.       LL_RCC_HSE_Enable();
  403.       while (LL_RCC_HSE_IsReady() != 1U)
  404.       {
  405.         /* Wait for HSE ready */
  406.       }
  407.     }
  408.  
  409.       /* Configure PLL */
  410. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  411.       LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  412. #else
  413.     LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC_HSE_PREDIV | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
  414. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  415.  
  416.     /* Enable PLL and switch system clock to PLL */
  417.     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  418.   }
  419.   else
  420.   {
  421.     /* Current PLL configuration cannot be modified */
  422.     status = ERROR;
  423.   }
  424.  
  425.   return status;
  426. }
  427.  
  428. /**
  429.   * @}
  430.   */
  431.  
  432. /**
  433.   * @}
  434.   */
  435.  
  436. /** @addtogroup UTILS_LL_Private_Functions
  437.   * @{
  438.   */
  439. /**
  440.   * @brief  Update number of Flash wait states in line with new frequency and current
  441.             voltage range.
  442.   * @param  Frequency  SYSCLK frequency
  443.   * @retval An ErrorStatus enumeration value:
  444.   *          - SUCCESS: Latency has been modified
  445.   *          - ERROR: Latency cannot be modified
  446.   */
  447. #if defined(FLASH_ACR_LATENCY)
  448. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
  449. {
  450.   ErrorStatus status = SUCCESS;
  451.  
  452.   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
  453.  
  454.   /* Frequency cannot be equal to 0 */
  455.   if (Frequency == 0U)
  456.   {
  457.     status = ERROR;
  458.   }
  459.   else
  460.   {
  461.     if (Frequency > UTILS_LATENCY1_FREQ)
  462.     {
  463.       /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
  464.       latency = LL_FLASH_LATENCY_1;
  465.     }
  466.     /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
  467.  
  468.     LL_FLASH_SetLatency(latency);
  469.  
  470.     /* Check that the new number of wait states is taken into account to access the Flash
  471.        memory by reading the FLASH_ACR register */
  472.     if (LL_FLASH_GetLatency() != latency)
  473.     {
  474.       status = ERROR;
  475.     }
  476.   }
  477.   return status;
  478. }
  479. #endif /* FLASH_ACR_LATENCY */
  480.  
  481. /**
  482.   * @brief  Function to check that PLL can be modified
  483.   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
  484.   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  485.   *                             the configuration information for the PLL.
  486.   * @retval PLL output frequency (in Hz)
  487.   */
  488. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  489. {
  490.   uint32_t pllfreq = 0U;
  491.  
  492.   /* Check the parameters */
  493.   assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
  494.  
  495.   /* Check different PLL parameters according to RM                          */
  496.   /* The application software must set correctly the PLL multiplication factor to
  497.      be in the range 16-48MHz */
  498. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  499.   pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  500. #else
  501.   pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
  502. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  503.   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  504.  
  505.   return pllfreq;
  506. }
  507.  
  508. /**
  509.   * @brief  Function to check that PLL can be modified
  510.   * @retval An ErrorStatus enumeration value:
  511.   *          - SUCCESS: PLL modification can be done
  512.   *          - ERROR: PLL is busy
  513.   */
  514. static ErrorStatus UTILS_PLL_IsBusy(void)
  515. {
  516.   ErrorStatus status = SUCCESS;
  517.  
  518.   /* Check if PLL is busy*/
  519.   if (LL_RCC_PLL_IsReady() != 0U)
  520.   {
  521.     /* PLL configuration cannot be modified */
  522.     status = ERROR;
  523.   }
  524.  
  525.   return status;
  526. }
  527.  
  528. /**
  529.   * @brief  Function to enable PLL and switch system clock to PLL
  530.   * @param  SYSCLK_Frequency SYSCLK frequency
  531.   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  532.   *                             the configuration information for the BUS prescalers.
  533.   * @retval An ErrorStatus enumeration value:
  534.   *          - SUCCESS: No problem to switch system to PLL
  535.   *          - ERROR: Problem to switch system to PLL
  536.   */
  537. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  538. {
  539.   ErrorStatus status = SUCCESS;
  540.   uint32_t sysclk_frequency_current = 0U;
  541.  
  542.   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
  543.   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  544.  
  545.   /* Calculate current SYSCLK frequency */
  546.   sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_POSITION_HPRE]);
  547.  
  548.   /* Increasing the number of wait states because of higher CPU frequency */
  549.   if (sysclk_frequency_current < SYSCLK_Frequency)
  550.   {
  551.     /* Set FLASH latency to highest latency */
  552.     status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  553.   }
  554.  
  555.   /* Update system clock configuration */
  556.   if (status == SUCCESS)
  557.   {
  558.     /* Enable PLL */
  559.     LL_RCC_PLL_Enable();
  560.     while (LL_RCC_PLL_IsReady() != 1U)
  561.     {
  562.       /* Wait for PLL ready */
  563.     }
  564.  
  565.     /* Sysclk activation on the main PLL */
  566.     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
  567.     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  568.     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  569.     {
  570.       /* Wait for system clock switch to PLL */
  571.     }
  572.  
  573.     /* Set APB1 & APB2 prescaler*/
  574.     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  575.   }
  576.  
  577.   /* Decreasing the number of wait states because of lower CPU frequency */
  578.   if (sysclk_frequency_current > SYSCLK_Frequency)
  579.   {
  580.     /* Set FLASH latency to lowest latency */
  581.     status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  582.   }
  583.  
  584.   /* Update SystemCoreClock variable */
  585.   if (status == SUCCESS)
  586.   {
  587.     LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
  588.   }
  589.  
  590.   return status;
  591. }
  592.  
  593. /**
  594.   * @}
  595.   */
  596.  
  597. /**
  598.   * @}
  599.   */
  600.  
  601. /**
  602.   * @}
  603.   */
  604.  
  605. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  606.