stm32f1xx_ll_utils.c 23 KB

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