Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:10

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_ll_utils.c
0004   * @author  MCD Application Team
0005   * @brief   UTILS LL module driver.
0006   ******************************************************************************
0007   * @attention
0008   *
0009   * Copyright (c) 2017 STMicroelectronics.
0010   * All rights reserved.
0011   *
0012   * This software is licensed under terms that can be found in the LICENSE file in
0013   * the root directory of this software component.
0014   * If no LICENSE file comes with this software, it is provided AS-IS.
0015   *
0016   ******************************************************************************
0017   */
0018 /* Includes ------------------------------------------------------------------*/
0019 #include "stm32h7xx_ll_utils.h"
0020 #include "stm32h7xx_ll_rcc.h"
0021 #include "stm32h7xx_ll_pwr.h"
0022 
0023 #ifdef  USE_FULL_ASSERT
0024   #include "stm32_assert.h"
0025 #else
0026   #define assert_param(expr) ((void)0U)
0027 #endif /* USE_FULL_ASSERT */
0028 
0029 /** @addtogroup STM32H7xx_LL_Driver
0030   * @{
0031   */
0032 
0033 /** @addtogroup UTILS_LL
0034   * @{
0035   */
0036 
0037 /* Private types -------------------------------------------------------------*/
0038 /* Private variables ---------------------------------------------------------*/
0039 /* Private constants ---------------------------------------------------------*/
0040 /** @addtogroup UTILS_LL_Private_Constants
0041   * @{
0042   */
0043 #if (STM32H7_DEV_ID == 0x450UL)
0044 #define UTILS_MAX_FREQUENCY_SCALE1  480000000U      /*!< Maximum frequency for system clock at power scale1, in Hz */
0045 #define UTILS_MAX_FREQUENCY_SCALE2  300000000U      /*!< Maximum frequency for system clock at power scale2, in Hz */
0046 #define UTILS_MAX_FREQUENCY_SCALE3  200000000U      /*!< Maximum frequency for system clock at power scale3, in Hz */
0047 #elif (STM32H7_DEV_ID == 0x480UL)
0048 #define UTILS_MAX_FREQUENCY_SCALE0  280000000U      /*!< Maximum frequency for system clock at power scale0, in Hz */
0049 #define UTILS_MAX_FREQUENCY_SCALE1  225000000U      /*!< Maximum frequency for system clock at power scale1, in Hz */
0050 #define UTILS_MAX_FREQUENCY_SCALE2  160000000U      /*!< Maximum frequency for system clock at power scale2, in Hz */
0051 #define UTILS_MAX_FREQUENCY_SCALE3   88000000U      /*!< Maximum frequency for system clock at power scale3, in Hz */
0052 #elif (STM32H7_DEV_ID == 0x483UL)
0053 #define UTILS_MAX_FREQUENCY_SCALE0  550000000U      /*!< Maximum frequency for system clock at power scale0, in Hz */
0054 #define UTILS_MAX_FREQUENCY_SCALE1  200000000U      /*!< Maximum frequency for system clock at power scale1, in Hz */
0055 #define UTILS_MAX_FREQUENCY_SCALE2  150000000U      /*!< Maximum frequency for system clock at power scale2, in Hz */
0056 #define UTILS_MAX_FREQUENCY_SCALE3   85000000U      /*!< Maximum frequency for system clock at power scale3, in Hz */
0057 #endif /*STM32H7_DEV_ID == 0x450UL*/
0058 
0059 /* Defines used for PLL range */
0060 #define UTILS_PLLVCO_INPUT_MIN1       1000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
0061 #define UTILS_PLLVCO_INPUT_MAX1       2000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
0062 #define UTILS_PLLVCO_INPUT_MIN2       2000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
0063 #define UTILS_PLLVCO_INPUT_MAX2       4000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
0064 #define UTILS_PLLVCO_INPUT_MIN3       4000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
0065 #define UTILS_PLLVCO_INPUT_MAX3       8000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
0066 #define UTILS_PLLVCO_INPUT_MIN4       8000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
0067 #define UTILS_PLLVCO_INPUT_MAX4      16000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
0068 
0069 #if (POWER_DOMAINS_NUMBER == 3U)
0070 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MIN    150000000U      /*!< Frequency min for the medium range PLLVCO output, in Hz   */
0071 #define UTILS_PLLVCO_WIDE_OUTPUT_MIN      192000000U      /*!< Frequency min for the wide range PLLVCO output, in Hz   */
0072 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MAX    420000000U      /*!< Frequency max for the medium range PLLVCO output, in Hz  */
0073 #define UTILS_PLLVCO_WIDE_OUTPUT_MAX      836000000U      /*!< Frequency max for the wide range PLLVCO output, in Hz  */
0074 #else
0075 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MIN    150000000U      /*!< Frequency min for the medium range PLLVCO output, in Hz   */
0076 #define UTILS_PLLVCO_WIDE_OUTPUT_MIN      128000000U      /*!< Frequency min for the wide range PLLVCO output, in Hz   */
0077 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MAX    420000000U      /*!< Frequency max for the medium range PLLVCO output, in Hz  */
0078 #define UTILS_PLLVCO_WIDE_OUTPUT_MAX      560000000U      /*!< Frequency max for the wide range PLLVCO output, in Hz  */
0079 #endif /*POWER_DOMAINS_NUMBER == 3U*/
0080 
0081 /* Defines used for HSE range */
0082 #define UTILS_HSE_FREQUENCY_MIN      4000000U        /*!< Frequency min for HSE frequency, in Hz   */
0083 #define UTILS_HSE_FREQUENCY_MAX     48000000U        /*!< Frequency max for HSE frequency, in Hz   */
0084 
0085 /* Defines used for FLASH latency according to HCLK Frequency */
0086 #if (STM32H7_DEV_ID == 0x480UL)
0087 #define UTILS_SCALE0_LATENCY0_FREQ   44000000U       /*!< HCLK frequency to set FLASH latency 0 in power scale 0  */
0088 #define UTILS_SCALE0_LATENCY1_FREQ   88000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 0  */
0089 #define UTILS_SCALE0_LATENCY2_FREQ  132000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 0  */
0090 #define UTILS_SCALE0_LATENCY3_FREQ  176000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 0  */
0091 #define UTILS_SCALE0_LATENCY4_FREQ  220000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 0  */
0092 #define UTILS_SCALE0_LATENCY5_FREQ  264000000U       /*!< HCLK frequency to set FLASH latency 5 in power scale 0  */
0093 #define UTILS_SCALE0_LATENCY6_FREQ  280000000U       /*!< HCLK frequency to set FLASH latency 6 in power scale 0  */
0094 
0095 #define UTILS_SCALE1_LATENCY0_FREQ   42000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 1  */
0096 #define UTILS_SCALE1_LATENCY1_FREQ   84000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 1  */
0097 #define UTILS_SCALE1_LATENCY2_FREQ  126000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 1  */
0098 #define UTILS_SCALE1_LATENCY3_FREQ  168000000U      /*!< HCLK frequency to set FLASH latency 3 in power scale 1  */
0099 #define UTILS_SCALE1_LATENCY4_FREQ  210000000U      /*!< HCLK frequency to set FLASH latency 4 in power scale 1  */
0100 #define UTILS_SCALE1_LATENCY5_FREQ  225000000U      /*!< HCLK frequency to set FLASH latency 5 in power scale 1  */
0101 
0102 #define UTILS_SCALE2_LATENCY0_FREQ   34000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 2  */
0103 #define UTILS_SCALE2_LATENCY1_FREQ   68000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 2  */
0104 #define UTILS_SCALE2_LATENCY2_FREQ  102000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 2  */
0105 #define UTILS_SCALE2_LATENCY3_FREQ  136000000U      /*!< HCLK frequency to set FLASH latency 3 in power scale 2  */
0106 #define UTILS_SCALE2_LATENCY4_FREQ  160000000U      /*!< HCLK frequency to set FLASH latency 4 in power scale 2  */
0107 
0108 #define UTILS_SCALE3_LATENCY0_FREQ   22000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 3  */
0109 #define UTILS_SCALE3_LATENCY1_FREQ   44000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 3  */
0110 #define UTILS_SCALE3_LATENCY2_FREQ   66000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 3  */
0111 #define UTILS_SCALE3_LATENCY3_FREQ   88000000U      /*!< HCLK frequency to set FLASH latency 3 in power scale 3  */
0112 
0113 #elif (STM32H7_DEV_ID == 0x450UL)
0114 
0115 #define UTILS_SCALE1_LATENCY0_FREQ   70000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 1  */
0116 #define UTILS_SCALE1_LATENCY1_FREQ  140000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 1  */
0117 #define UTILS_SCALE1_LATENCY2_FREQ  240000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 1  */
0118 
0119 #define UTILS_SCALE2_LATENCY0_FREQ   55000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 2  */
0120 #define UTILS_SCALE2_LATENCY1_FREQ  110000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 2  */
0121 #define UTILS_SCALE2_LATENCY2_FREQ  165000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 2  */
0122 #define UTILS_SCALE2_LATENCY3_FREQ  220000000U      /*!< HCLK frequency to set FLASH latency 3 in power scale 2  */
0123 
0124 #define UTILS_SCALE3_LATENCY0_FREQ   45000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 3  */
0125 #define UTILS_SCALE3_LATENCY1_FREQ   90000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 3  */
0126 #define UTILS_SCALE3_LATENCY2_FREQ  135000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 3  */
0127 #define UTILS_SCALE3_LATENCY3_FREQ  180000000U      /*!< HCLK frequency to set FLASH latency 3 in power scale 3  */
0128 #define UTILS_SCALE3_LATENCY4_FREQ  225000000U      /*!< HCLK frequency to set FLASH latency 4 in power scale 3  */
0129 
0130 #elif (STM32H7_DEV_ID == 0x483UL)
0131 
0132 #define UTILS_SCALE0_LATENCY0_FREQ   70000000U       /*!< HCLK frequency to set FLASH latency 0 in power scale 0  */
0133 #define UTILS_SCALE0_LATENCY1_FREQ  140000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 0  */
0134 #define UTILS_SCALE0_LATENCY2_FREQ  210000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 0  */
0135 #define UTILS_SCALE0_LATENCY3_FREQ  275000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 0  */
0136 
0137 #define UTILS_SCALE1_LATENCY0_FREQ   67000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 1  */
0138 #define UTILS_SCALE1_LATENCY1_FREQ  133000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 1  */
0139 #define UTILS_SCALE1_LATENCY2_FREQ  200000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 1  */
0140 
0141 #define UTILS_SCALE2_LATENCY0_FREQ   50000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 2  */
0142 #define UTILS_SCALE2_LATENCY1_FREQ  100000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 2  */
0143 #define UTILS_SCALE2_LATENCY2_FREQ  150000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 2  */
0144 
0145 #define UTILS_SCALE3_LATENCY0_FREQ   35000000U      /*!< HCLK frequency to set FLASH latency 0 in power scale 3  */
0146 #define UTILS_SCALE3_LATENCY1_FREQ   70000000U      /*!< HCLK frequency to set FLASH latency 1 in power scale 3  */
0147 #define UTILS_SCALE3_LATENCY2_FREQ   85000000U      /*!< HCLK frequency to set FLASH latency 2 in power scale 3  */
0148 
0149 #endif /*STM32H7_DEV_ID == 0x480UL*/
0150 /**
0151   * @}
0152   */
0153 
0154 /* Private macros ------------------------------------------------------------*/
0155 /** @addtogroup UTILS_LL_Private_Macros
0156   * @{
0157   */
0158 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
0159                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
0160                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
0161                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
0162                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
0163                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
0164                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
0165                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
0166                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
0167 
0168 #define IS_LL_UTILS_AHB_DIV(__VALUE__)    (((__VALUE__) == LL_RCC_AHB_DIV_1)   \
0169                                         || ((__VALUE__) == LL_RCC_AHB_DIV_2)   \
0170                                         || ((__VALUE__) == LL_RCC_AHB_DIV_4)   \
0171                                         || ((__VALUE__) == LL_RCC_AHB_DIV_8)   \
0172                                         || ((__VALUE__) == LL_RCC_AHB_DIV_16)  \
0173                                         || ((__VALUE__) == LL_RCC_AHB_DIV_64)  \
0174                                         || ((__VALUE__) == LL_RCC_AHB_DIV_128) \
0175                                         || ((__VALUE__) == LL_RCC_AHB_DIV_256) \
0176                                         || ((__VALUE__) == LL_RCC_AHB_DIV_512))
0177 
0178 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
0179                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
0180                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
0181                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
0182                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
0183 
0184 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
0185                                       || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
0186                                       || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
0187                                       || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
0188                                       || ((__VALUE__) == LL_RCC_APB2_DIV_16))
0189 
0190 #define IS_LL_UTILS_APB3_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB3_DIV_1) \
0191                                       || ((__VALUE__) == LL_RCC_APB3_DIV_2) \
0192                                       || ((__VALUE__) == LL_RCC_APB3_DIV_4) \
0193                                       || ((__VALUE__) == LL_RCC_APB3_DIV_8) \
0194                                       || ((__VALUE__) == LL_RCC_APB3_DIV_16))
0195 
0196 #define IS_LL_UTILS_APB4_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB4_DIV_1) \
0197                                       || ((__VALUE__) == LL_RCC_APB4_DIV_2) \
0198                                       || ((__VALUE__) == LL_RCC_APB4_DIV_4) \
0199                                       || ((__VALUE__) == LL_RCC_APB4_DIV_8) \
0200                                       || ((__VALUE__) == LL_RCC_APB4_DIV_16))
0201 
0202 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 63U))
0203 
0204 #if (POWER_DOMAINS_NUMBER == 3U)
0205 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
0206 #else
0207 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 420U))
0208 #endif /*POWER_DOMAINS_NUMBER == 3U*/
0209 
0210 #define IS_LL_UTILS_PLLP_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
0211 
0212 #define IS_LL_UTILS_FRACN_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU)
0213 
0214 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__, __RANGE__)  ( \
0215 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_1_2) && (UTILS_PLLVCO_INPUT_MIN1 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX1)) || \
0216 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_2_4) && (UTILS_PLLVCO_INPUT_MIN2 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX2)) || \
0217 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_4_8) && (UTILS_PLLVCO_INPUT_MIN3 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX3)) || \
0218 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_8_16) && (UTILS_PLLVCO_INPUT_MIN4 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX4)))
0219 
0220 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__, __RANGE__) ( \
0221 (((__RANGE__) == LL_RCC_PLLVCORANGE_MEDIUM) && (UTILS_PLLVCO_MEDIUM_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_MEDIUM_OUTPUT_MAX)) || \
0222 (((__RANGE__) == LL_RCC_PLLVCORANGE_WIDE) && (UTILS_PLLVCO_WIDE_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_WIDE_OUTPUT_MAX)))
0223 
0224 #define IS_LL_UTILS_CHECK_VCO_RANGES(__RANGEIN__, __RANGEOUT__) ( \
0225 (((__RANGEIN__) == LL_RCC_PLLINPUTRANGE_1_2) && ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_MEDIUM)) || \
0226 (((__RANGEIN__) != LL_RCC_PLLINPUTRANGE_1_2) && ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_WIDE)))
0227 
0228 #if (STM32H7_DEV_ID == 0x450UL)
0229 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
0230                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
0231                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3))
0232 #else
0233 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE0) : \
0234                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
0235                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
0236                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3))
0237 #endif /* STM32H7_DEV_ID == 0x450UL */
0238 
0239 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
0240                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
0241 
0242 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
0243 /**
0244   * @}
0245   */
0246 /* Private function prototypes -----------------------------------------------*/
0247 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
0248   * @ingroup RTEMSBSPsARMSTM32H7
0249   * @{
0250   */
0251 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
0252 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
0253 static ErrorStatus UTILS_IsPLLsReady(void);
0254 static uint32_t    UTILS_CalcPLLClockFreq(uint32_t PLLInputFreq, uint32_t M, uint32_t N, uint32_t FRACN, uint32_t PQR);
0255 /**
0256   * @}
0257   */
0258 
0259 /* Exported functions --------------------------------------------------------*/
0260 /** @addtogroup UTILS_LL_Exported_Functions
0261   * @{
0262   */
0263 
0264 /** @addtogroup UTILS_LL_EF_DELAY
0265   * @{
0266   */
0267 #if defined (DUAL_CORE)
0268 /**
0269   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
0270   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
0271   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
0272   * @param  CPU_Frequency Core frequency in Hz
0273   * @note   CPU_Frequency can be calculated thanks to RCC helper macro or function
0274   *         @ref LL_RCC_GetSystemClocksFreq
0275   *         LL_RCC_GetSystemClocksFreq() is used to calculate the CM7 clock frequency
0276   *         and __LL_RCC_CALC_HCLK_FREQ is used to calculate the CM4 clock frequency.
0277   * @retval None
0278   */
0279 #else
0280 /**
0281   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
0282   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
0283   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
0284   * @param  CPU_Frequency Core frequency in Hz
0285   * @note   CPU_Frequency can be calculated thanks to RCC helper macro or function
0286   *         @ref LL_RCC_GetSystemClocksFreq
0287   * @retval None
0288   */
0289 #endif /* DUAL_CORE */
0290 void LL_Init1msTick(uint32_t CPU_Frequency)
0291 {
0292   /* Use frequency provided in argument */
0293   LL_InitTick(CPU_Frequency, 1000U);
0294 }
0295 
0296 
0297 /**
0298   * @brief  This function provides accurate delay (in milliseconds) based
0299   *         on SysTick counter flag
0300   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
0301   *         and use rather osDelay service.
0302   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
0303   *         will configure Systick to 1ms
0304   * @param  Delay specifies the delay time length, in milliseconds.
0305   * @retval None
0306   */
0307 void LL_mDelay(uint32_t Delay)
0308 {
0309   uint32_t count = Delay;
0310   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
0311   /* Add this code to indicate that local variable is not used */
0312   ((void)tmp);
0313 
0314   /* Add a period to guaranty minimum wait */
0315   if(count < LL_MAX_DELAY)
0316   {
0317     count++;
0318   }
0319 
0320   while (count != 0U)
0321   {
0322     if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
0323     {
0324       count--;
0325     }
0326   }
0327 }
0328 
0329 /**
0330   * @}
0331   */
0332 
0333 #if (STM32H7_DEV_ID == 0x450UL)
0334 /** @addtogroup UTILS_EF_SYSTEM
0335   *  @brief    System Configuration functions
0336   *
0337   @verbatim
0338  ===============================================================================
0339            ##### System Configuration functions #####
0340  ===============================================================================
0341     [..]
0342          System, AHB and APB buses clocks configuration
0343 
0344          (+) The maximum frequency of the SYSCLK is 480 MHz(*) and HCLK is 240 MHz.
0345          (+) The maximum frequency of the PCLK1, PCLK2, PCLK3 and PCLK4 is 120 MHz.
0346   @endverbatim
0347   @internal
0348              Depending on the device voltage range, the maximum frequency should be
0349              adapted accordingly:
0350              (++) +----------------------------------------------------------------------------+
0351              (++) |  Wait states   |                           HCLK clock frequency (MHz)      |
0352              (++) |                |-----------------------------------------------------------|
0353              (++) |  (Latency)     |   voltage range 1 |   voltage range 2 |   voltage range 3 |
0354              (++) |                |    1.15V - 1.26V  |    1.05V - 1.15V  |    0.95V - 1.05V  |
0355              (++) |----------------|-------------------|-------------------|-------------------|
0356              (++) |0WS(1CPU cycle) |   0 < HCLK <= 70  |   0 < HCLK <= 55  |   0 < HCLK <= 45  |
0357              (++) |----------------|-------------------|-------------------|-------------------|
0358              (++) |1WS(2CPU cycle) |  70 < HCLK <= 140 |  55 < HCLK <= 110 |  45 < HCLK <= 90  |
0359              (++) |----------------|-------------------|-------------------|-------------------|
0360              (++) |2WS(3CPU cycle) | 140 < HCLK <= 240 | 110 < HCLK <= 165 |  90 < HCLK <= 135 |
0361              (++) |----------------|-------------------|-------------------|-------------------|
0362              (++) |3WS(4CPU cycle) |        --         | 165 < HCLK <= 220 | 135 < HCLK <= 180 |
0363              (++) |----------------|-------------------|-------------------|-------------------|
0364              (++) |4WS(5CPU cycle) |        --         |        --         | 180 < HCLK <= 225 |
0365              (++) +----------------------------------------------------------------------------+
0366 
0367   (*) : For stm32h74xxx and stm32h75xxx family lines and requires the board to be connected on LDO regulator not SMPS, 400MHZ otherwise.
0368   @endinternal
0369   * @{
0370   */
0371 
0372 #elif (STM32H7_DEV_ID == 0x480UL)
0373 /** @addtogroup UTILS_EF_SYSTEM
0374   *  @brief    System Configuration functions
0375   *
0376   @verbatim
0377  ===============================================================================
0378            ##### System Configuration functions #####
0379  ===============================================================================
0380     [..]
0381          System, AHB and APB buses clocks configuration
0382 
0383          (+) The maximum frequency of the SYSCLK is 280 MHz and HCLK is 280 MHz.
0384          (+) The maximum frequency of the PCLK1, PCLK2, PCLK3 and PCLK4 is 140 MHz.
0385   @endverbatim
0386   @internal
0387              Depending on the device voltage range, the maximum frequency should be
0388              adapted accordingly:
0389              (++) +------------------------------------------------------------------------------------------------+
0390              (++) |  Wait states   |                          HCLK clock frequency (MHz)                           |
0391              (++) |                |-------------------------------------------------------------------------------|
0392              (++) |  (Latency)     |   voltage range 0 |   voltage range 1 |   voltage range 2 |   voltage range 3 |
0393              (++) |                |    1.26V - 1.35V  |    1.15V - 1.26V  |    1.05V - 1.15V  |    0.95V - 1.05V  |
0394              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0395              (++) |0WS(1CPU cycle) |   0 < HCLK <= 44  |   0 < HCLK <= 42  |   0 < HCLK <= 34  |   0 < HCLK <= 22  |
0396              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0397              (++) |1WS(2CPU cycle) |  44 < HCLK <= 88  |  42 < HCLK <= 84  |  34 < HCLK <= 68  |  22 < HCLK <= 44  |
0398              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0399              (++) |2WS(3CPU cycle) |  88 < HCLK <= 132 |  84 < HCLK <= 126 |  68 < HCLK <= 102 |  44 < HCLK <= 66  |
0400              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0401              (++) |3WS(4CPU cycle) | 132 < HCLK <= 176 | 126 < HCLK <= 168 | 102 < HCLK <= 136 |  66 < HCLK <= 88  |
0402              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0403              (++) |4WS(5CPU cycle) | 176 < HCLK <= 220 | 168 < HCLK <= 210 | 136 < HCLK <= 160 |        --         |
0404              (++) +------------------------------------------------------------------------------------------------+
0405              (++) |5WS(6CPU cycle) | 220 < HCLK <= 264 | 210 < HCLK <= 225 |        --         |        --         |
0406              (++) +------------------------------------------------------------------------------------------------+
0407              (++) |6WS(7CPU cycle) | 264 < HCLK <= 280 |        --         |        --         |        --         |
0408              (++) +------------------------------------------------------------------------------------------------+
0409              (++) |7WS(8CPU cycle) |        --         |        --         |        --         |        --         |
0410              (++) +------------------------------------------------------------------------------------------------+
0411 
0412   @endinternal
0413   * @{
0414   */
0415 
0416 #elif (STM32H7_DEV_ID == 0x483UL)
0417 /** @addtogroup UTILS_EF_SYSTEM
0418   *  @brief    System Configuration functions
0419   *
0420   @verbatim
0421  ===============================================================================
0422            ##### System Configuration functions #####
0423  ===============================================================================
0424     [..]
0425          System, AHB and APB buses clocks configuration
0426 
0427          (+) The maximum frequency of the SYSCLK is 550 MHz(*) and HCLK is 275 MHz.
0428          (+) The maximum frequency of the PCLK1, PCLK2, PCLK3 and PCLK4 is 137.5 MHz.
0429   @endverbatim
0430   @internal
0431              Depending on the device voltage range, the maximum frequency should be
0432              adapted accordingly:
0433              (++) +------------------------------------------------------------------------------------------------+
0434              (++) |  Wait states   |                          HCLK clock frequency (MHz)                           |
0435              (++) |                |-------------------------------------------------------------------------------|
0436              (++) |  (Latency)     |   voltage range 0 |   voltage range 1 |   voltage range 2 |   voltage range 3 |
0437              (++) |                |    1.26V - 1.40V  |    1.15V - 1.26V  |    1.05V - 1.15V  |    0.95V - 1.05V  |
0438              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0439              (++) |0WS(1CPU cycle) |   0 < HCLK <= 70  |   0 < HCLK <= 67  |   0 < HCLK <= 50  |   0 < HCLK <= 35  |
0440              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0441              (++) |1WS(2CPU cycle) |  70 < HCLK <= 140 |  67 < HCLK <= 133 |  50 < HCLK <= 100 |  35 < HCLK <= 70  |
0442              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0443              (++) |2WS(3CPU cycle) | 140 < HCLK <= 210 | 133 < HCLK <= 200 | 100 < HCLK <= 150 |  70 < HCLK <= 85  |
0444              (++) |----------------|-------------------|-------------------|-------------------|-------------------|
0445              (++) |3WS(4CPU cycle) | 210 < HCLK <= 275 |        --         |        --         |        --         |
0446              (++) +----------------|-------------------|-------------------|-------------------|-------------------|
0447 
0448   (*)  : For stm32h72xxx and stm32h73xxx family lines and requires to enable the CPU_FREQ_BOOST flash option byte, 520MHZ otherwise.
0449   @endinternal
0450   * @{
0451   */
0452 #endif /* STM32H7_DEV_ID == 0x450UL */
0453 
0454 #if defined (DUAL_CORE)
0455 /**
0456   * @brief  This function sets directly SystemCoreClock CMSIS variable.
0457   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
0458   * @param  CPU_Frequency Core frequency in Hz
0459   * @note   CPU_Frequency can be calculated thanks to RCC helper macro or function
0460   *         @ref LL_RCC_GetSystemClocksFreq
0461   *         LL_RCC_GetSystemClocksFreq() is used to calculate the CM7 clock frequency
0462   *         and __LL_RCC_CALC_HCLK_FREQ is used to calculate the CM4 clock frequency.
0463   * @retval None
0464   */
0465 #else
0466 /**
0467   * @brief  This function sets directly SystemCoreClock CMSIS variable.
0468   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
0469   * @param  CPU_Frequency Core frequency in Hz
0470   * @note   CPU_Frequency can be calculated thanks to RCC helper macro or function
0471   *         @ref LL_RCC_GetSystemClocksFreq
0472   * @retval None
0473   */
0474 #endif /* DUAL_CORE */
0475 void LL_SetSystemCoreClock(uint32_t CPU_Frequency)
0476 {
0477   /* HCLK clock frequency */
0478   SystemCoreClock = CPU_Frequency;
0479 }
0480 
0481 /**
0482   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
0483   * @note   The application need to ensure that PLL is disabled.
0484   * @note   Function is based on the following formula:
0485   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLP)
0486   *         - PLLM: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
0487   *         - PLLN: ensure that the VCO output frequency is between 150 and 836 MHz or 128 to 560 MHz(***) (PLLVCO_output = PLLVCO_input * PLLN)
0488   *         - PLLP: ensure that max frequency at 550000000 Hz(*), 480000000 Hz(**) or 280000000 Hz(***) is reach (PLLVCO_output / PLLP)
0489   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
0490   *                             the configuration information for the PLL.
0491   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
0492   *                             the configuration information for the BUS prescalers.
0493   * @retval An ErrorStatus enumeration value:
0494   *          - SUCCESS: Max frequency configuration done
0495   *          - ERROR: Max frequency configuration not done
0496   *
0497   * (*)  : For stm32h72xxx and stm32h73xxx family lines and requires to enable the CPU_FREQ_BOOST flash option byte, 520MHZ otherwise.
0498   * (**) : For stm32h74xxx and stm32h75xxx family lines and requires the board to be connected on LDO regulator not SMPS, 400MHZ otherwise.
0499   * (***): For stm32h7a3xx, stm32h7b3xx and stm32h7b0xx family lines.
0500   *
0501   */
0502 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
0503                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
0504 {
0505   ErrorStatus status;
0506 #ifdef  USE_FULL_ASSERT
0507   uint32_t vcoinput_freq, vcooutput_freq;
0508 #endif
0509   uint32_t pllfreq, hsi_clk;
0510 
0511   /* Check the parameters */
0512   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
0513   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
0514   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
0515   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
0516 
0517   hsi_clk = (HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos));
0518 
0519   /* Check VCO Input frequency */
0520 #ifdef  USE_FULL_ASSERT
0521   vcoinput_freq = hsi_clk / UTILS_PLLInitStruct->PLLM;
0522 #endif
0523   assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
0524 
0525   /* Check VCO Output frequency */
0526 #ifdef  USE_FULL_ASSERT
0527   vcooutput_freq = UTILS_CalcPLLClockFreq(hsi_clk, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, UTILS_PLLInitStruct->FRACN, 1UL);
0528 #endif
0529   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
0530 
0531   /* Check VCO Input ranges */
0532   assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
0533 
0534   /* Check if one of the PLL is enabled */
0535   if(UTILS_IsPLLsReady() == SUCCESS)
0536   {
0537     /* Calculate the new PLL output frequency */
0538     pllfreq = UTILS_GetPLLOutputFrequency(hsi_clk, UTILS_PLLInitStruct);
0539 
0540     /* Enable HSI if not enabled */
0541     if(LL_RCC_HSI_IsReady() != 1U)
0542     {
0543       LL_RCC_HSI_Enable();
0544       while (LL_RCC_HSI_IsReady() != 1U)
0545       {
0546         /* Wait for HSI ready */
0547       }
0548     }
0549 
0550     /* Configure PLL */
0551     LL_RCC_PLL1P_Enable();
0552     LL_RCC_PLL1FRACN_Enable();
0553     LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
0554     LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
0555     LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
0556     LL_RCC_PLL1_SetM(UTILS_PLLInitStruct->PLLM);
0557     LL_RCC_PLL1_SetN(UTILS_PLLInitStruct->PLLN);
0558     LL_RCC_PLL1_SetP(UTILS_PLLInitStruct->PLLP);
0559     LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
0560 
0561     /* Enable PLL and switch system clock to PLL */
0562     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
0563   }
0564   else
0565   {
0566     /* Current PLL configuration cannot be modified */
0567     status = ERROR;
0568   }
0569 
0570   return status;
0571 }
0572 
0573 /**
0574   * @brief  This function configures system clock with HSE as clock source of the PLL
0575   * @note   The application need to ensure that PLL is disabled.
0576   * @note   Function is based on the following formula:
0577   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLP)
0578   *         - PLLM: ensure that the VCO input frequency ranges from 0.95 to 2.10 MHz (PLLVCO_input = HSE frequency / PLLM)
0579   *         - PLLN: ensure that the VCO output frequency is between 150 and 836 MHz or 128 to 560 MHz(***) (PLLVCO_output = PLLVCO_input * PLLN)
0580   *         - PLLP: ensure that max frequency at 550000000 Hz(*), 480000000 Hz(**) or 280000000 Hz(***) is reached (PLLVCO_output / PLLP)
0581   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
0582   * @param  HSEBypass This parameter can be one of the following values:
0583   *         @arg @ref LL_UTILS_HSEBYPASS_ON
0584   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
0585   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
0586   *                             the configuration information for the PLL.
0587   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
0588   *                             the configuration information for the BUS prescalers.
0589   * @retval An ErrorStatus enumeration value:
0590   *          - SUCCESS: Max frequency configuration done
0591   *          - ERROR: Max frequency configuration not done
0592   *
0593   * (*)  : For stm32h72xxx and stm32h73xxx family lines and requires to enable the CPU_FREQ_BOOST flash option byte, 520MHZ otherwise.
0594   * (**) : For stm32h74xxx and stm32h75xxx family lines and requires the board to be connected on LDO regulator not SMPS, 400MHZ otherwise.
0595   * (***): For stm32h7a3xx, stm32h7b3xx and stm32h7b0xx family lines.
0596   *
0597   */
0598 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
0599                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
0600 {
0601   ErrorStatus status;
0602 #ifdef  USE_FULL_ASSERT
0603   uint32_t vcoinput_freq, vcooutput_freq;
0604 #endif
0605   uint32_t pllfreq;
0606 
0607   /* Check the parameters */
0608   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
0609   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
0610   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
0611   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
0612   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
0613   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
0614 
0615   /* Check VCO Input frequency */
0616 #ifdef  USE_FULL_ASSERT
0617   vcoinput_freq = HSEFrequency / UTILS_PLLInitStruct->PLLM;
0618 #endif
0619   assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
0620 
0621   /* Check VCO output frequency */
0622 #ifdef  USE_FULL_ASSERT
0623   vcooutput_freq = UTILS_CalcPLLClockFreq(HSEFrequency, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, UTILS_PLLInitStruct->FRACN, 1U);
0624 #endif
0625   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
0626 
0627   /* Check VCO Input/output ranges compatibility */
0628   assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
0629 
0630   /* Check if one of the PLL is enabled */
0631   if(UTILS_IsPLLsReady() == SUCCESS)
0632   {
0633     /* Calculate the new PLL output frequency */
0634     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
0635 
0636     /* Enable HSE if not enabled */
0637     if(LL_RCC_HSE_IsReady() != 1U)
0638     {
0639       /* Check if need to enable HSE bypass feature or not */
0640       if(HSEBypass == LL_UTILS_HSEBYPASS_ON)
0641       {
0642         LL_RCC_HSE_EnableBypass();
0643       }
0644       else
0645       {
0646         LL_RCC_HSE_DisableBypass();
0647       }
0648 
0649       /* Enable HSE */
0650       LL_RCC_HSE_Enable();
0651       while (LL_RCC_HSE_IsReady() != 1U)
0652       {
0653         /* Wait for HSE ready */
0654       }
0655     }
0656 
0657     /* Configure PLL */
0658     LL_RCC_PLL1P_Enable();
0659     LL_RCC_PLL1FRACN_Enable();
0660     LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
0661     LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
0662     LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
0663     LL_RCC_PLL1_SetM(UTILS_PLLInitStruct->PLLM);
0664     LL_RCC_PLL1_SetN(UTILS_PLLInitStruct->PLLN);
0665     LL_RCC_PLL1_SetP(UTILS_PLLInitStruct->PLLP);
0666     LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
0667 
0668     /* Enable PLL and switch system clock to PLL */
0669     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
0670   }
0671   else
0672   {
0673     /* Current PLL configuration cannot be modified */
0674     status = ERROR;
0675   }
0676 
0677   return status;
0678 }
0679 
0680 /**
0681   * @}
0682   */
0683 
0684 /**
0685   * @brief  Update number of Flash wait states in line with new frequency and current
0686             voltage range.
0687   * @param  HCLK_Frequency  HCLK frequency
0688   * @retval An ErrorStatus enumeration value:
0689   *          - SUCCESS: Latency has been modified
0690   *          - ERROR: Latency cannot be modified
0691   */
0692 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
0693 {
0694   ErrorStatus status = SUCCESS;
0695   uint32_t timeout;
0696   uint32_t getlatency;
0697   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
0698 
0699 
0700 
0701   /* Frequency cannot be equal to 0 */
0702   if (HCLK_Frequency == 0U)
0703   {
0704     status = ERROR;
0705   }
0706   else
0707   {
0708 #if (STM32H7_DEV_ID == 0x480UL) || (STM32H7_DEV_ID == 0x483UL)
0709     if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0)
0710     {
0711 #if (STM32H7_DEV_ID == 0x480UL)
0712       if((HCLK_Frequency > UTILS_SCALE0_LATENCY5_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY6_FREQ))
0713       {
0714         /* 264 < HCLK <= 280 => 6WS (7 CPU cycles) */
0715         latency = LL_FLASH_LATENCY_6;
0716       }
0717       else if((HCLK_Frequency > UTILS_SCALE0_LATENCY4_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY5_FREQ))
0718       {
0719         /* 220 < HCLK <= 264 => 5WS (6 CPU cycles) */
0720         latency = LL_FLASH_LATENCY_5;
0721       }
0722       else if((HCLK_Frequency > UTILS_SCALE0_LATENCY3_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY4_FREQ))
0723       {
0724         /* 176 < HCLK <= 220 => 4WS (5 CPU cycles) */
0725         latency = LL_FLASH_LATENCY_4;
0726       }
0727       else if((HCLK_Frequency > UTILS_SCALE0_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY3_FREQ))
0728 #elif (STM32H7_DEV_ID == 0x483UL)
0729       if((HCLK_Frequency > UTILS_SCALE0_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY3_FREQ))
0730 #endif /* STM32H7_DEV_ID == 0x480UL */
0731       {
0732         /* 132 < HCLK <= 176 => 3WS (4 CPU cycles) */
0733         latency = LL_FLASH_LATENCY_3;
0734       }
0735       else if((HCLK_Frequency > UTILS_SCALE0_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY2_FREQ))
0736       {
0737         /* 88 < HCLK <= 132 => 2WS (3 CPU cycles) */
0738         latency = LL_FLASH_LATENCY_2;
0739       }
0740       else if((HCLK_Frequency > UTILS_SCALE0_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY1_FREQ))
0741       {
0742         /* 44 < HCLK <= 88 => 1WS (2 CPU cycles) */
0743         latency = LL_FLASH_LATENCY_1;
0744       }
0745       else if(HCLK_Frequency <= UTILS_SCALE0_LATENCY0_FREQ)
0746       {
0747         /* HCLK <= 44 => 0WS (1 CPU cycles) : Do nothing keep latency to default  LL_FLASH_LATENCY_0 */
0748       }
0749       else
0750       {
0751         status = ERROR;
0752       }
0753     }
0754 #if (STM32H7_DEV_ID == 0x480UL)
0755     else if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
0756     {
0757       if((HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY5_FREQ))
0758       {
0759         /* 210 < HCLK <= 225 => 5WS (6 CPU cycles) */
0760         latency = LL_FLASH_LATENCY_5;
0761       }
0762       else if((HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY4_FREQ))
0763       {
0764         /* 168 < HCLK <= 210 => 4WS (5 CPU cycles) */
0765         latency = LL_FLASH_LATENCY_4;
0766       }
0767       else if((HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ))
0768       {
0769         /* 126 < HCLK <= 168 => 3WS (4 CPU cycles) */
0770         latency = LL_FLASH_LATENCY_3;
0771       }
0772       else if((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
0773 #else
0774     if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
0775     {
0776       if((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
0777 #endif /* STM32H7_DEV_ID == 0x480UL */
0778 #else
0779     if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
0780     {
0781       if((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
0782 #endif /* STM32H7_DEV_ID == 0x480UL || STM32H7_DEV_ID == 0x483UL */
0783       {
0784         /* 140 < HCLK <= 210 => 2WS (3 CPU cycles) */
0785         latency = LL_FLASH_LATENCY_2;
0786       }
0787       else if((HCLK_Frequency > UTILS_SCALE1_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
0788       {
0789         /* 70 < HCLK <= 140 => 1WS (2 CPU cycles) */
0790         latency = LL_FLASH_LATENCY_1;
0791       }
0792       else if(HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
0793       {
0794         /* HCLK <= 70 => 0WS (1 CPU cycles) : Do nothing keep latency to default  LL_FLASH_LATENCY_0 */
0795       }
0796       else
0797       {
0798         status = ERROR;
0799       }
0800     }
0801     else if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
0802     {
0803 #if (STM32H7_DEV_ID == 0x480UL) || (STM32H7_DEV_ID == 0x450UL)
0804 #if (STM32H7_DEV_ID == 0x480UL)
0805       if((HCLK_Frequency > UTILS_SCALE2_LATENCY3_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY4_FREQ))
0806       {
0807         /* 136 < HCLK <= 160 => 4WS (5 CPU cycles) */
0808         latency = LL_FLASH_LATENCY_4;
0809       }
0810       else if((HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY3_FREQ))
0811 #else
0812       if((HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY3_FREQ))
0813 #endif /* STM32H7_DEV_ID == 0x480UL */
0814       {
0815         /* 165 < HCLK <= 220 => 3WS (4 CPU cycles) */
0816         latency = LL_FLASH_LATENCY_3;
0817       }
0818       else if((HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY2_FREQ))
0819 #else
0820       if((HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY2_FREQ))
0821 #endif /* STM32H7_DEV_ID == 0x480UL || STM32H7_DEV_ID == 0x450UL */
0822       {
0823         /* 110 < HCLK <= 165 => 2WS (3 CPU cycles) */
0824         latency = LL_FLASH_LATENCY_2;
0825       }
0826       else if((HCLK_Frequency > UTILS_SCALE2_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ))
0827       {
0828         /* 55 < HCLK <= 110 => 1WS (2 CPU cycles) */
0829         latency = LL_FLASH_LATENCY_1;
0830       }
0831       else if(HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
0832       {
0833         /* HCLK <= 55 => 0WS (1 CPU cycles) : Do nothing keep latency to default  LL_FLASH_LATENCY_0 */
0834       }
0835       else
0836       {
0837         status = ERROR;
0838       }
0839     }
0840     else /* Scale 3 */
0841     {
0842 #if (STM32H7_DEV_ID == 0x450UL) || (STM32H7_DEV_ID == 0x480UL)
0843 #if (STM32H7_DEV_ID == 0x450UL)
0844       if((HCLK_Frequency > UTILS_SCALE3_LATENCY3_FREQ) && (HCLK_Frequency <= UTILS_SCALE3_LATENCY4_FREQ))
0845       {
0846         /* 180 < HCLK <= 225 => 4WS (5 CPU cycles) */
0847         latency = LL_FLASH_LATENCY_4;
0848       }
0849       else if((HCLK_Frequency > UTILS_SCALE3_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE3_LATENCY3_FREQ))
0850 #else
0851       if((HCLK_Frequency > UTILS_SCALE3_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE3_LATENCY3_FREQ))
0852 #endif /*STM32H7_DEV_ID == 0x450UL*/
0853       {
0854         /* 135 < HCLK <= 180 => 3WS (4 CPU cycles) */
0855         latency = LL_FLASH_LATENCY_3;
0856       }
0857       else if((HCLK_Frequency > UTILS_SCALE3_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE3_LATENCY2_FREQ))
0858 #else
0859       if((HCLK_Frequency > UTILS_SCALE3_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE3_LATENCY2_FREQ))
0860 #endif /* STM32H7_DEV_ID == 0x450UL || STM32H7_DEV_ID == 0x480UL */
0861       {
0862         /* 90 < HCLK <= 135 => 2WS (3 CPU cycles) */
0863         latency = LL_FLASH_LATENCY_2;
0864       }
0865       else if((HCLK_Frequency > UTILS_SCALE3_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE3_LATENCY1_FREQ))
0866       {
0867         /* 45 < HCLK <= 90 => 1WS (2 CPU cycles) */
0868         latency = LL_FLASH_LATENCY_1;
0869       }
0870       else if(HCLK_Frequency <= UTILS_SCALE3_LATENCY0_FREQ)
0871       {
0872         /* HCLK <= 45 => 0WS (1 CPU cycles) : Do nothing keep latency to default  LL_FLASH_LATENCY_0 */
0873       }
0874       else
0875       {
0876         status = ERROR;
0877       }
0878     }
0879 
0880     if(status == SUCCESS)
0881     {
0882       LL_FLASH_SetLatency(latency);
0883 
0884       /* Check that the new number of wait states is taken into account to access the Flash
0885       memory by reading the FLASH_ACR register */
0886       timeout = 2;
0887       do
0888       {
0889         /* Wait for Flash latency to be updated */
0890         getlatency = LL_FLASH_GetLatency();
0891         timeout--;
0892       } while ((getlatency != latency) && (timeout > 0U));
0893 
0894       if(getlatency != latency)
0895       {
0896         status = ERROR;
0897       }
0898     }
0899   }
0900 
0901   return status;
0902 }
0903 
0904 
0905 /**
0906   * @}
0907   */
0908 
0909 /** @addtogroup UTILS_LL_Private_Functions
0910   * @{
0911   */
0912 
0913 
0914 /**
0915   * @brief  Function to check that PLL can be modified
0916   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
0917   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
0918   *                             the configuration information for the PLL.
0919   * @retval PLL output frequency (in Hz)
0920   */
0921 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
0922 {
0923   uint32_t pllfreq;
0924 
0925   /* Check the parameters */
0926   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
0927   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
0928   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
0929   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
0930 
0931   pllfreq = UTILS_CalcPLLClockFreq(PLL_InputFrequency, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, UTILS_PLLInitStruct->FRACN, UTILS_PLLInitStruct->PLLP);
0932 
0933   return pllfreq;
0934 }
0935 
0936 /**
0937   * @brief  Check that all PLLs are ready therefore configuration can be done
0938   * @retval An ErrorStatus enumeration value:
0939   *          - SUCCESS: All PLLs are ready so configuration can be done
0940   *          - ERROR: One PLL at least is busy
0941   */
0942 static ErrorStatus UTILS_IsPLLsReady(void)
0943 {
0944   ErrorStatus status = SUCCESS;
0945 
0946   /* Check if one of the PLL1 is busy */
0947   if(LL_RCC_PLL1_IsReady() != 0U)
0948   {
0949     /* PLL1 configuration cannot be done */
0950     status = ERROR;
0951   }
0952 
0953   /* Check if one of the PLL2 is busy */
0954   if(LL_RCC_PLL2_IsReady() != 0U)
0955   {
0956     /* PLL2 configuration cannot be done */
0957     status = ERROR;
0958   }
0959 
0960   /* Check if one of the PLL3 is busy */
0961   if(LL_RCC_PLL3_IsReady() != 0U)
0962   {
0963     /* PLL3 configuration cannot be done */
0964     status = ERROR;
0965   }
0966 
0967   return status;
0968 }
0969 
0970 /**
0971   * @brief  Helper function to calculate the PLL frequency output
0972   * @param  PLLInputFreq PLL Input frequency (based on HSE/(HSI/HSIDIV)/CSI)
0973   * @param  M      Between 1 and 63
0974   * @param  N      Between 4 and 512
0975   * @param  FRACN  Between 0 and 0x1FFF
0976   * @param  PQR    VCO output divider (P, Q or R)
0977   *                Between 1 and 128, except for PLL1P Odd value not allowed
0978   * @retval PLL1 clock frequency (in Hz)
0979   */
0980 static uint32_t UTILS_CalcPLLClockFreq(uint32_t PLLInputFreq, uint32_t M, uint32_t N, uint32_t FRACN, uint32_t PQR)
0981 {
0982   float_t freq;
0983 
0984   freq = ((float_t)PLLInputFreq / (float_t)M) * ((float_t)N + ((float_t)FRACN / (float_t)0x2000));
0985 
0986   freq = freq / (float_t)PQR;
0987 
0988   return (uint32_t)freq;
0989 }
0990 
0991 /**
0992   * @brief  Function to enable PLL and switch system clock to PLL
0993   * @param  SYSCLK_Frequency SYSCLK frequency
0994   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
0995   *                             the configuration information for the BUS prescalers.
0996   * @retval An ErrorStatus enumeration value:
0997   *          - SUCCESS: No problem to switch system to PLL
0998   *          - ERROR: Problem to switch system to PLL
0999   */
1000 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
1001 {
1002   ErrorStatus status = SUCCESS;
1003   uint32_t new_hclk_frequency;
1004 
1005   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->SYSCLKDivider));
1006   assert_param(IS_LL_UTILS_AHB_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
1007   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
1008   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
1009   assert_param(IS_LL_UTILS_APB3_DIV(UTILS_ClkInitStruct->APB3CLKDivider));
1010   assert_param(IS_LL_UTILS_APB4_DIV(UTILS_ClkInitStruct->APB4CLKDivider));
1011 
1012   /* Calculate the new HCLK frequency */
1013   new_hclk_frequency = LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
1014 
1015     /* Increasing the number of wait states because of higher CPU frequency */
1016   if (SystemD2Clock < new_hclk_frequency)
1017     {
1018     /* Set FLASH latency to highest latency */
1019     status = LL_SetFlashLatency(new_hclk_frequency);
1020     }
1021 
1022   /* Update system clock configuration */
1023   if(status == SUCCESS)
1024   {
1025     /* Enable PLL */
1026     LL_RCC_PLL1_Enable();
1027     while (LL_RCC_PLL1_IsReady() != 1U)
1028     {
1029       /* Wait for PLL ready */
1030     }
1031 
1032     /* Set All APBxPrescaler to the Highest Divider */
1033     LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_16);
1034     LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_16);
1035     LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_16);
1036     LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_16);
1037 
1038     /* Set SYS prescaler*/
1039     LL_RCC_SetSysPrescaler(UTILS_ClkInitStruct->SYSCLKDivider);
1040 
1041     /* Set AHB prescaler*/
1042     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
1043 
1044     /* Sysclk activation on the main PLL */
1045     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
1046     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
1047     {
1048       /* Wait for system clock switch to PLL */
1049     }
1050 
1051     /* Set APBn prescaler*/
1052     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
1053     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
1054     LL_RCC_SetAPB3Prescaler(UTILS_ClkInitStruct->APB3CLKDivider);
1055     LL_RCC_SetAPB4Prescaler(UTILS_ClkInitStruct->APB4CLKDivider);
1056 
1057     /* Decreasing the number of wait states because of lower CPU frequency */
1058   if (SystemD2Clock > new_hclk_frequency)
1059   {
1060     /* Set FLASH latency to lowest latency */
1061     status = LL_SetFlashLatency(new_hclk_frequency);
1062   }
1063 
1064       /* Update the SystemD2Clock global variable */
1065 #if defined(RCC_D1CFGR_HPRE)
1066       SystemD2Clock = (SYSCLK_Frequency >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
1067 #else
1068       SystemD2Clock = (SYSCLK_Frequency >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_HPRE)>> RCC_CDCFGR1_HPRE_Pos]) & 0x1FU));
1069 #endif
1070 
1071       /* Update SystemCoreClock variable */
1072 #if defined(DUAL_CORE) && defined(CORE_CM4)
1073       LL_SetSystemCoreClock(SystemD2Clock);
1074 #else
1075       LL_SetSystemCoreClock(SYSCLK_Frequency);
1076 #endif /* DUAL_CORE && CORE_CM4 */
1077 
1078     }
1079 
1080 
1081   return status;
1082 }
1083 
1084 /**
1085   * @}
1086   */
1087 
1088 /**
1089   * @}
1090   */
1091 
1092 /**
1093   * @}
1094   */
1095