You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

stm32l1xx_ll_utils.c 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. /**
  2. ******************************************************************************
  3. * @file stm32l1xx_ll_utils.c
  4. * @author MCD Application Team
  5. * @brief UTILS LL module driver.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright(c) 2017 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. /* Includes ------------------------------------------------------------------*/
  20. #include "stm32l1xx_ll_rcc.h"
  21. #include "stm32l1xx_ll_utils.h"
  22. #include "stm32l1xx_ll_system.h"
  23. #include "stm32l1xx_ll_pwr.h"
  24. #ifdef USE_FULL_ASSERT
  25. #include "stm32_assert.h"
  26. #else
  27. #define assert_param(expr) ((void)0U)
  28. #endif
  29. /** @addtogroup STM32L1xx_LL_Driver
  30. * @{
  31. */
  32. /** @addtogroup UTILS_LL
  33. * @{
  34. */
  35. /* Private types -------------------------------------------------------------*/
  36. /* Private variables ---------------------------------------------------------*/
  37. /* Private constants ---------------------------------------------------------*/
  38. /** @addtogroup UTILS_LL_Private_Constants
  39. * @{
  40. */
  41. #define UTILS_MAX_FREQUENCY_SCALE1 32000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
  42. #define UTILS_MAX_FREQUENCY_SCALE2 16000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
  43. #define UTILS_MAX_FREQUENCY_SCALE3 4000000U /*!< Maximum frequency for system clock at power scale3, in Hz */
  44. /* Defines used for PLL range */
  45. #define UTILS_PLLVCO_OUTPUT_SCALE1 96000000U /*!< Frequency max for PLLVCO output at power scale1, in Hz */
  46. #define UTILS_PLLVCO_OUTPUT_SCALE2 48000000U /*!< Frequency max for PLLVCO output at power scale2, in Hz */
  47. #define UTILS_PLLVCO_OUTPUT_SCALE3 24000000U /*!< Frequency max for PLLVCO output at power scale3, in Hz */
  48. /* Defines used for HSE range */
  49. #define UTILS_HSE_FREQUENCY_MIN 1000000U /*!< Frequency min for HSE frequency, in Hz */
  50. #define UTILS_HSE_FREQUENCY_MAX 24000000U /*!< Frequency max for HSE frequency, in Hz */
  51. /* Defines used for FLASH latency according to HCLK Frequency */
  52. #define UTILS_SCALE1_LATENCY1_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
  53. #define UTILS_SCALE2_LATENCY1_FREQ 8000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
  54. #define UTILS_SCALE3_LATENCY1_FREQ 2000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
  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. #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
  72. || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
  73. || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
  74. || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
  75. || ((__VALUE__) == LL_RCC_APB1_DIV_16))
  76. #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
  77. || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
  78. || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
  79. || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
  80. || ((__VALUE__) == LL_RCC_APB2_DIV_16))
  81. #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_3) \
  82. || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
  83. || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
  84. || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
  85. || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
  86. || ((__VALUE__) == LL_RCC_PLL_MUL_16) \
  87. || ((__VALUE__) == LL_RCC_PLL_MUL_24) \
  88. || ((__VALUE__) == LL_RCC_PLL_MUL_32) \
  89. || ((__VALUE__) == LL_RCC_PLL_MUL_48))
  90. #define IS_LL_UTILS_PLLDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_DIV_2) || ((__VALUE__) == LL_RCC_PLL_DIV_3) || \
  91. ((__VALUE__) == LL_RCC_PLL_DIV_4))
  92. #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE1) : \
  93. ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE2) : \
  94. ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE3)))
  95. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
  96. ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
  97. ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3)))
  98. #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
  99. || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
  100. #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
  101. /**
  102. * @}
  103. */
  104. /* Private function prototypes -----------------------------------------------*/
  105. /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
  106. * @{
  107. */
  108. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
  109. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
  110. #if defined(FLASH_ACR_LATENCY)
  111. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
  112. #endif /* FLASH_ACR_LATENCY */
  113. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  114. static ErrorStatus UTILS_PLL_IsBusy(void);
  115. /**
  116. * @}
  117. */
  118. /* Exported functions --------------------------------------------------------*/
  119. /** @addtogroup UTILS_LL_Exported_Functions
  120. * @{
  121. */
  122. /** @addtogroup UTILS_LL_EF_DELAY
  123. * @{
  124. */
  125. /**
  126. * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
  127. * @note When a RTOS is used, it is recommended to avoid changing the Systick
  128. * configuration by calling this function, for a delay use rather osDelay RTOS service.
  129. * @param HCLKFrequency HCLK frequency in Hz
  130. * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
  131. * @retval None
  132. */
  133. void LL_Init1msTick(uint32_t HCLKFrequency)
  134. {
  135. /* Use frequency provided in argument */
  136. LL_InitTick(HCLKFrequency, 1000U);
  137. }
  138. /**
  139. * @brief This function provides accurate delay (in milliseconds) based
  140. * on SysTick counter flag
  141. * @note When a RTOS is used, it is recommended to avoid using blocking delay
  142. * and use rather osDelay service.
  143. * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  144. * will configure Systick to 1ms
  145. * @param Delay specifies the delay time length, in milliseconds.
  146. * @retval None
  147. */
  148. void LL_mDelay(uint32_t Delay)
  149. {
  150. __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
  151. uint32_t tmpDelay = Delay;
  152. /* Add this code to indicate that local variable is not used */
  153. ((void)tmp);
  154. /* Add a period to guaranty minimum wait */
  155. if(tmpDelay < LL_MAX_DELAY)
  156. {
  157. tmpDelay++;
  158. }
  159. while (tmpDelay != 0U)
  160. {
  161. if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  162. {
  163. tmpDelay--;
  164. }
  165. }
  166. }
  167. /**
  168. * @}
  169. */
  170. /** @addtogroup UTILS_EF_SYSTEM
  171. * @brief System Configuration functions
  172. *
  173. @verbatim
  174. ===============================================================================
  175. ##### System Configuration functions #####
  176. ===============================================================================
  177. [..]
  178. System, AHB and APB buses clocks configuration
  179. (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32000000 Hz.
  180. @endverbatim
  181. @internal
  182. Depending on the device voltage range, the maximum frequency should be
  183. adapted accordingly:
  184. (++) +----------------------------------------------------------------+
  185. (++) | Wait states | HCLK clock frequency (MHz) |
  186. (++) | |------------------------------------------------|
  187. (++) | (Latency) | voltage range | voltage range |
  188. (++) | | 1.65 V - 3.6 V | 2.0 V - 3.6 V |
  189. (++) | |----------------|---------------|---------------|
  190. (++) | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V |
  191. (++) |-------------- |----------------|---------------|---------------|
  192. (++) |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 |
  193. (++) |---------------|----------------|---------------|---------------|
  194. (++) |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32|
  195. (++) +----------------------------------------------------------------+
  196. @endinternal
  197. * @{
  198. */
  199. /**
  200. * @brief This function sets directly SystemCoreClock CMSIS variable.
  201. * @note Variable can be calculated also through SystemCoreClockUpdate function.
  202. * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
  203. * @retval None
  204. */
  205. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  206. {
  207. /* HCLK clock frequency */
  208. SystemCoreClock = HCLKFrequency;
  209. }
  210. /**
  211. * @brief This function configures system clock with HSI as clock source of the PLL
  212. * @note The application need to ensure that PLL is disabled.
  213. * @note Function is based on the following formula:
  214. * - PLL output frequency = ((HSI frequency * PLLMul) / PLLDiv)
  215. * - PLLMul: The application software must set correctly the PLL multiplication factor to avoid exceeding
  216. * - 96 MHz as PLLVCO when the product is in range 1,
  217. * - 48 MHz as PLLVCO when the product is in range 2,
  218. * - 24 MHz when the product is in range 3
  219. * @note FLASH latency can be modified through this function.
  220. * @note If this latency increases to 1WS, FLASH 64-bit access will be automatically enabled.
  221. * A decrease of FLASH latency to 0WS will not disable 64-bit access. If needed, user should call
  222. * the following function @ref LL_FLASH_Disable64bitAccess.
  223. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  224. * the configuration information for the PLL.
  225. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  226. * the configuration information for the BUS prescalers.
  227. * @retval An ErrorStatus enumeration value:
  228. * - SUCCESS: Max frequency configuration done
  229. * - ERROR: Max frequency configuration not done
  230. */
  231. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  232. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  233. {
  234. ErrorStatus status;
  235. uint32_t pllfreq;
  236. /* Check if one of the PLL is enabled */
  237. if (UTILS_PLL_IsBusy() == SUCCESS)
  238. {
  239. /* Calculate the new PLL output frequency */
  240. pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  241. /* Enable HSI if not enabled */
  242. if (LL_RCC_HSI_IsReady() != 1U)
  243. {
  244. LL_RCC_HSI_Enable();
  245. while (LL_RCC_HSI_IsReady() != 1U)
  246. {
  247. /* Wait for HSI ready */
  248. }
  249. }
  250. /* Configure PLL */
  251. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  252. /* Enable PLL and switch system clock to PLL */
  253. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  254. }
  255. else
  256. {
  257. /* Current PLL configuration cannot be modified */
  258. status = ERROR;
  259. }
  260. return status;
  261. }
  262. /**
  263. * @brief This function configures system clock with HSE as clock source of the PLL
  264. * @note The application need to ensure that PLL is disabled.
  265. * @note Function is based on the following formula:
  266. * - PLL output frequency = ((HSE frequency * PLLMul) / PLLDiv)
  267. * - PLLMul: The application software must set correctly the PLL multiplication factor to avoid exceeding
  268. * - 96 MHz as PLLVCO when the product is in range 1,
  269. * - 48 MHz as PLLVCO when the product is in range 2,
  270. * - 24 MHz when the product is in range 3
  271. * @note FLASH latency can be modified through this function.
  272. * @note If this latency increases to 1WS, FLASH 64-bit access will be automatically enabled.
  273. * A decrease of FLASH latency to 0WS will not disable 64-bit access. If needed, user should call
  274. * the following function @ref LL_FLASH_Disable64bitAccess.
  275. * @param HSEFrequency Value between Min_Data = 1000000 and Max_Data = 24000000
  276. * @param HSEBypass This parameter can be one of the following values:
  277. * @arg @ref LL_UTILS_HSEBYPASS_ON
  278. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  279. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  280. * the configuration information for the PLL.
  281. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  282. * the configuration information for the BUS prescalers.
  283. * @retval An ErrorStatus enumeration value:
  284. * - SUCCESS: Max frequency configuration done
  285. * - ERROR: Max frequency configuration not done
  286. */
  287. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
  288. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  289. {
  290. ErrorStatus status;
  291. uint32_t pllfreq;
  292. /* Check the parameters */
  293. assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  294. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  295. /* Check if one of the PLL is enabled */
  296. if (UTILS_PLL_IsBusy() == SUCCESS)
  297. {
  298. /* Calculate the new PLL output frequency */
  299. pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  300. /* Enable HSE if not enabled */
  301. if (LL_RCC_HSE_IsReady() != 1U)
  302. {
  303. /* Check if need to enable HSE bypass feature or not */
  304. if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  305. {
  306. LL_RCC_HSE_EnableBypass();
  307. }
  308. else
  309. {
  310. LL_RCC_HSE_DisableBypass();
  311. }
  312. /* Enable HSE */
  313. LL_RCC_HSE_Enable();
  314. while (LL_RCC_HSE_IsReady() != 1U)
  315. {
  316. /* Wait for HSE ready */
  317. }
  318. }
  319. /* Configure PLL */
  320. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  321. /* Enable PLL and switch system clock to PLL */
  322. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  323. }
  324. else
  325. {
  326. /* Current PLL configuration cannot be modified */
  327. status = ERROR;
  328. }
  329. return status;
  330. }
  331. /**
  332. * @}
  333. */
  334. /**
  335. * @}
  336. */
  337. /** @addtogroup UTILS_LL_Private_Functions
  338. * @{
  339. */
  340. /**
  341. * @brief Update number of Flash wait states in line with new frequency and current
  342. voltage range.
  343. * @param Frequency HCLK frequency
  344. * @retval An ErrorStatus enumeration value:
  345. * - SUCCESS: Latency has been modified
  346. * - ERROR: Latency cannot be modified
  347. */
  348. #if defined(FLASH_ACR_LATENCY)
  349. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
  350. {
  351. ErrorStatus status = SUCCESS;
  352. uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
  353. /* Frequency cannot be equal to 0 */
  354. if (Frequency == 0U)
  355. {
  356. status = ERROR;
  357. }
  358. else
  359. {
  360. if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
  361. {
  362. if (Frequency > UTILS_SCALE1_LATENCY1_FREQ)
  363. {
  364. /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
  365. latency = LL_FLASH_LATENCY_1;
  366. }
  367. /* else HCLK < 16MHz default LL_FLASH_LATENCY_0 0WS */
  368. }
  369. else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
  370. {
  371. if (Frequency > UTILS_SCALE2_LATENCY1_FREQ)
  372. {
  373. /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
  374. latency = LL_FLASH_LATENCY_1;
  375. }
  376. /* else HCLK < 8MHz default LL_FLASH_LATENCY_0 0WS */
  377. }
  378. else
  379. {
  380. if (Frequency > UTILS_SCALE3_LATENCY1_FREQ)
  381. {
  382. /* 2 < HCLK <= 4 => 1WS (2 CPU cycles) */
  383. latency = LL_FLASH_LATENCY_1;
  384. }
  385. /* else HCLK < 4MHz default LL_FLASH_LATENCY_0 0WS */
  386. }
  387. /* Latency cannot be set to 1WS only if 64-bit access bit is enabled */
  388. if (latency == LL_FLASH_LATENCY_1)
  389. {
  390. LL_FLASH_Enable64bitAccess();
  391. }
  392. LL_FLASH_SetLatency(latency);
  393. /* Check that the new number of wait states is taken into account to access the Flash
  394. memory by reading the FLASH_ACR register */
  395. if (LL_FLASH_GetLatency() != latency)
  396. {
  397. status = ERROR;
  398. }
  399. }
  400. return status;
  401. }
  402. #endif /* FLASH_ACR_LATENCY */
  403. /**
  404. * @brief Function to check that PLL can be modified
  405. * @param PLL_InputFrequency PLL input frequency (in Hz)
  406. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  407. * the configuration information for the PLL.
  408. * @retval PLL output frequency (in Hz)
  409. */
  410. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  411. {
  412. uint32_t pllfreq;
  413. /* Check the parameters */
  414. assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
  415. assert_param(IS_LL_UTILS_PLLDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  416. /* Check different PLL parameters according to RM */
  417. /* The application software must set correctly the PLL multiplication factor to avoid exceeding
  418. 96 MHz as PLLVCO when the product is in range 1,
  419. 48 MHz as PLLVCO when the product is in range 2,
  420. 24 MHz when the product is in range 3. */
  421. pllfreq = PLL_InputFrequency * (PLLMulTable[UTILS_PLLInitStruct->PLLMul >> RCC_CFGR_PLLMUL_Pos]);
  422. assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
  423. /* The application software must set correctly the PLL multiplication factor to avoid exceeding
  424. maximum frequency 32000000 in range 1 */
  425. pllfreq = pllfreq / ((UTILS_PLLInitStruct->PLLDiv >> RCC_CFGR_PLLDIV_Pos)+1U);
  426. assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  427. return pllfreq;
  428. }
  429. /**
  430. * @brief Function to check that PLL can be modified
  431. * @retval An ErrorStatus enumeration value:
  432. * - SUCCESS: PLL modification can be done
  433. * - ERROR: PLL is busy
  434. */
  435. static ErrorStatus UTILS_PLL_IsBusy(void)
  436. {
  437. ErrorStatus status = SUCCESS;
  438. /* Check if PLL is busy*/
  439. if (LL_RCC_PLL_IsReady() != 0U)
  440. {
  441. /* PLL configuration cannot be modified */
  442. status = ERROR;
  443. }
  444. return status;
  445. }
  446. /**
  447. * @brief Function to enable PLL and switch system clock to PLL
  448. * @param SYSCLK_Frequency SYSCLK frequency
  449. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  450. * the configuration information for the BUS prescalers.
  451. * @retval An ErrorStatus enumeration value:
  452. * - SUCCESS: No problem to switch system to PLL
  453. * - ERROR: Problem to switch system to PLL
  454. */
  455. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  456. {
  457. ErrorStatus status = SUCCESS;
  458. uint32_t hclk_frequency;
  459. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
  460. assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  461. assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
  462. /* Calculate HCLK frequency */
  463. hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
  464. /* Increasing the number of wait states because of higher CPU frequency */
  465. if (SystemCoreClock < hclk_frequency)
  466. {
  467. /* Set FLASH latency to highest latency */
  468. status = UTILS_SetFlashLatency(hclk_frequency);
  469. }
  470. /* Update system clock configuration */
  471. if (status == SUCCESS)
  472. {
  473. /* Enable PLL */
  474. LL_RCC_PLL_Enable();
  475. while (LL_RCC_PLL_IsReady() != 1U)
  476. {
  477. /* Wait for PLL ready */
  478. }
  479. /* Sysclk activation on the main PLL */
  480. LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
  481. LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  482. while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  483. {
  484. /* Wait for system clock switch to PLL */
  485. }
  486. /* Set APB1 & APB2 prescaler*/
  487. LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  488. LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
  489. }
  490. /* Decreasing the number of wait states because of lower CPU frequency */
  491. if (SystemCoreClock > hclk_frequency)
  492. {
  493. /* Set FLASH latency to lowest latency */
  494. status = UTILS_SetFlashLatency(hclk_frequency);
  495. }
  496. /* Update SystemCoreClock variable */
  497. if (status == SUCCESS)
  498. {
  499. LL_SetSystemCoreClock(hclk_frequency);
  500. }
  501. return status;
  502. }
  503. /**
  504. * @}
  505. */
  506. /**
  507. * @}
  508. */
  509. /**
  510. * @}
  511. */
  512. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/