stm32f1xx_ll_utils.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  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. #if defined(FLASH_ACR_LATENCY)
  129. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
  130. #endif /* FLASH_ACR_LATENCY */
  131. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  132. static ErrorStatus UTILS_PLL_IsBusy(void);
  133. /**
  134. * @}
  135. */
  136. /* Exported functions --------------------------------------------------------*/
  137. /** @addtogroup UTILS_LL_Exported_Functions
  138. * @{
  139. */
  140. /** @addtogroup UTILS_LL_EF_DELAY
  141. * @{
  142. */
  143. /**
  144. * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
  145. * @note When a RTOS is used, it is recommended to avoid changing the Systick
  146. * configuration by calling this function, for a delay use rather osDelay RTOS service.
  147. * @param HCLKFrequency HCLK frequency in Hz
  148. * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
  149. * @retval None
  150. */
  151. void LL_Init1msTick(uint32_t HCLKFrequency)
  152. {
  153. /* Use frequency provided in argument */
  154. LL_InitTick(HCLKFrequency, 1000U);
  155. }
  156. /**
  157. * @brief This function provides accurate delay (in milliseconds) based
  158. * on SysTick counter flag
  159. * @note When a RTOS is used, it is recommended to avoid using blocking delay
  160. * and use rather osDelay service.
  161. * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  162. * will configure Systick to 1ms
  163. * @param Delay specifies the delay time length, in milliseconds.
  164. * @retval None
  165. */
  166. void LL_mDelay(uint32_t Delay)
  167. {
  168. __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
  169. /* Add this code to indicate that local variable is not used */
  170. ((void)tmp);
  171. /* Add a period to guaranty minimum wait */
  172. if (Delay < LL_MAX_DELAY)
  173. {
  174. Delay++;
  175. }
  176. while (Delay)
  177. {
  178. if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  179. {
  180. Delay--;
  181. }
  182. }
  183. }
  184. /**
  185. * @}
  186. */
  187. /** @addtogroup UTILS_EF_SYSTEM
  188. * @brief System Configuration functions
  189. *
  190. @verbatim
  191. ===============================================================================
  192. ##### System Configuration functions #####
  193. ===============================================================================
  194. [..]
  195. System, AHB and APB buses clocks configuration
  196. (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
  197. @endverbatim
  198. @internal
  199. Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
  200. (++) +-----------------------------------------------+
  201. (++) | Latency | SYSCLK clock frequency (MHz) |
  202. (++) |---------------|-------------------------------|
  203. (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
  204. (++) |---------------|-------------------------------|
  205. (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
  206. (++) |---------------|-------------------------------|
  207. (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
  208. (++) +-----------------------------------------------+
  209. @endinternal
  210. * @{
  211. */
  212. /**
  213. * @brief This function sets directly SystemCoreClock CMSIS variable.
  214. * @note Variable can be calculated also through SystemCoreClockUpdate function.
  215. * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
  216. * @retval None
  217. */
  218. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  219. {
  220. /* HCLK clock frequency */
  221. SystemCoreClock = HCLKFrequency;
  222. }
  223. /**
  224. * @brief This function configures system clock with HSI as clock source of the PLL
  225. * @note The application need to ensure that PLL is disabled.
  226. * @note Function is based on the following formula:
  227. * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  228. * - PREDIV: Set to 2 for few devices
  229. * - PLLMUL: The application software must set correctly the PLL multiplication factor to
  230. * not exceed 72MHz
  231. * @note FLASH latency can be modified through this function.
  232. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  233. * the configuration information for the PLL.
  234. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  235. * the configuration information for the BUS prescalers.
  236. * @retval An ErrorStatus enumeration value:
  237. * - SUCCESS: Max frequency configuration done
  238. * - ERROR: Max frequency configuration not done
  239. */
  240. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  241. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  242. {
  243. ErrorStatus status = SUCCESS;
  244. uint32_t pllfreq = 0U;
  245. /* Check if one of the PLL is enabled */
  246. if (UTILS_PLL_IsBusy() == SUCCESS)
  247. {
  248. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  249. /* Check PREDIV value */
  250. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  251. #else
  252. /* Force PREDIV value to 2 */
  253. UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
  254. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  255. /* Calculate the new PLL output frequency */
  256. pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  257. /* Enable HSI if not enabled */
  258. if (LL_RCC_HSI_IsReady() != 1U)
  259. {
  260. LL_RCC_HSI_Enable();
  261. while (LL_RCC_HSI_IsReady() != 1U)
  262. {
  263. /* Wait for HSI ready */
  264. }
  265. }
  266. /* Configure PLL */
  267. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
  268. /* Enable PLL and switch system clock to PLL */
  269. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  270. }
  271. else
  272. {
  273. /* Current PLL configuration cannot be modified */
  274. status = ERROR;
  275. }
  276. return status;
  277. }
  278. /**
  279. * @brief This function configures system clock with HSE as clock source of the PLL
  280. * @note The application need to ensure that PLL is disabled.
  281. * @note Function is based on the following formula:
  282. * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  283. * - PREDIV: Set to 2 for few devices
  284. * - PLLMUL: The application software must set correctly the PLL multiplication factor to
  285. * not exceed @ref UTILS_PLL_OUTPUT_MAX
  286. * @note FLASH latency can be modified through this function.
  287. * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
  288. * @param HSEBypass This parameter can be one of the following values:
  289. * @arg @ref LL_UTILS_HSEBYPASS_ON
  290. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  291. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  292. * the configuration information for the PLL.
  293. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  294. * the configuration information for the BUS prescalers.
  295. * @retval An ErrorStatus enumeration value:
  296. * - SUCCESS: Max frequency configuration done
  297. * - ERROR: Max frequency configuration not done
  298. */
  299. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
  300. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  301. {
  302. ErrorStatus status = SUCCESS;
  303. uint32_t pllfreq = 0U;
  304. /* Check the parameters */
  305. assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  306. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  307. /* Check if one of the PLL is enabled */
  308. if (UTILS_PLL_IsBusy() == SUCCESS)
  309. {
  310. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
  311. /* Calculate the new PLL output frequency */
  312. pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  313. /* Enable HSE if not enabled */
  314. if (LL_RCC_HSE_IsReady() != 1U)
  315. {
  316. /* Check if need to enable HSE bypass feature or not */
  317. if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  318. {
  319. LL_RCC_HSE_EnableBypass();
  320. }
  321. else
  322. {
  323. LL_RCC_HSE_DisableBypass();
  324. }
  325. /* Enable HSE */
  326. LL_RCC_HSE_Enable();
  327. while (LL_RCC_HSE_IsReady() != 1U)
  328. {
  329. /* Wait for HSE ready */
  330. }
  331. }
  332. /* Configure PLL */
  333. LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
  334. /* Enable PLL and switch system clock to PLL */
  335. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  336. }
  337. else
  338. {
  339. /* Current PLL configuration cannot be modified */
  340. status = ERROR;
  341. }
  342. return status;
  343. }
  344. /**
  345. * @}
  346. */
  347. /**
  348. * @}
  349. */
  350. /** @addtogroup UTILS_LL_Private_Functions
  351. * @{
  352. */
  353. /**
  354. * @brief Update number of Flash wait states in line with new frequency and current
  355. voltage range.
  356. * @param Frequency SYSCLK frequency
  357. * @retval An ErrorStatus enumeration value:
  358. * - SUCCESS: Latency has been modified
  359. * - ERROR: Latency cannot be modified
  360. */
  361. #if defined(FLASH_ACR_LATENCY)
  362. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
  363. {
  364. ErrorStatus status = SUCCESS;
  365. uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
  366. /* Frequency cannot be equal to 0 */
  367. if (Frequency == 0U)
  368. {
  369. status = ERROR;
  370. }
  371. else
  372. {
  373. if (Frequency > UTILS_LATENCY2_FREQ)
  374. {
  375. /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
  376. latency = LL_FLASH_LATENCY_2;
  377. }
  378. else
  379. {
  380. if (Frequency > UTILS_LATENCY1_FREQ)
  381. {
  382. /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
  383. latency = LL_FLASH_LATENCY_1;
  384. }
  385. /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
  386. }
  387. LL_FLASH_SetLatency(latency);
  388. /* Check that the new number of wait states is taken into account to access the Flash
  389. memory by reading the FLASH_ACR register */
  390. if (LL_FLASH_GetLatency() != latency)
  391. {
  392. status = ERROR;
  393. }
  394. }
  395. return status;
  396. }
  397. #endif /* FLASH_ACR_LATENCY */
  398. /**
  399. * @brief Function to check that PLL can be modified
  400. * @param PLL_InputFrequency PLL input frequency (in Hz)
  401. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  402. * the configuration information for the PLL.
  403. * @retval PLL output frequency (in Hz)
  404. */
  405. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  406. {
  407. uint32_t pllfreq = 0U;
  408. /* Check the parameters */
  409. assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
  410. /* Check different PLL parameters according to RM */
  411. #if defined (RCC_CFGR2_PREDIV1)
  412. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
  413. #else
  414. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
  415. #endif /*RCC_CFGR2_PREDIV1SRC*/
  416. assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  417. return pllfreq;
  418. }
  419. /**
  420. * @brief Function to check that PLL can be modified
  421. * @retval An ErrorStatus enumeration value:
  422. * - SUCCESS: PLL modification can be done
  423. * - ERROR: PLL is busy
  424. */
  425. static ErrorStatus UTILS_PLL_IsBusy(void)
  426. {
  427. ErrorStatus status = SUCCESS;
  428. /* Check if PLL is busy*/
  429. if (LL_RCC_PLL_IsReady() != 0U)
  430. {
  431. /* PLL configuration cannot be modified */
  432. status = ERROR;
  433. }
  434. #if defined(RCC_PLL2_SUPPORT)
  435. /* Check if PLL2 is busy*/
  436. if (LL_RCC_PLL2_IsReady() != 0U)
  437. {
  438. /* PLL2 configuration cannot be modified */
  439. status = ERROR;
  440. }
  441. #endif /* RCC_PLL2_SUPPORT */
  442. #if defined(RCC_PLLI2S_SUPPORT)
  443. /* Check if PLLI2S is busy*/
  444. if (LL_RCC_PLLI2S_IsReady() != 0U)
  445. {
  446. /* PLLI2S configuration cannot be modified */
  447. status = ERROR;
  448. }
  449. #endif /* RCC_PLLI2S_SUPPORT */
  450. return status;
  451. }
  452. /**
  453. * @brief Function to enable PLL and switch system clock to PLL
  454. * @param SYSCLK_Frequency SYSCLK frequency
  455. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  456. * the configuration information for the BUS prescalers.
  457. * @retval An ErrorStatus enumeration value:
  458. * - SUCCESS: No problem to switch system to PLL
  459. * - ERROR: Problem to switch system to PLL
  460. */
  461. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  462. {
  463. ErrorStatus status = SUCCESS;
  464. #if defined(FLASH_ACR_LATENCY)
  465. uint32_t sysclk_frequency_current = 0U;
  466. #endif /* FLASH_ACR_LATENCY */
  467. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
  468. assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  469. assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
  470. #if defined(FLASH_ACR_LATENCY)
  471. /* Calculate current SYSCLK frequency */
  472. sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
  473. #endif /* FLASH_ACR_LATENCY */
  474. /* Increasing the number of wait states because of higher CPU frequency */
  475. #if defined (FLASH_ACR_LATENCY)
  476. if (sysclk_frequency_current < SYSCLK_Frequency)
  477. {
  478. /* Set FLASH latency to highest latency */
  479. status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  480. }
  481. #endif /* FLASH_ACR_LATENCY */
  482. /* Update system clock configuration */
  483. if (status == SUCCESS)
  484. {
  485. #if defined(RCC_PLL2_SUPPORT)
  486. if (LL_RCC_PLL_GetMainSource() != LL_RCC_PLLSOURCE_HSI_DIV_2)
  487. {
  488. /* Enable PLL2 */
  489. LL_RCC_PLL2_Enable();
  490. while (LL_RCC_PLL2_IsReady() != 1U)
  491. {
  492. /* Wait for PLL2 ready */
  493. }
  494. }
  495. #endif /* RCC_PLL2_SUPPORT */
  496. /* Enable PLL */
  497. LL_RCC_PLL_Enable();
  498. while (LL_RCC_PLL_IsReady() != 1U)
  499. {
  500. /* Wait for PLL ready */
  501. }
  502. /* Sysclk activation on the main PLL */
  503. LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
  504. LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  505. while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  506. {
  507. /* Wait for system clock switch to PLL */
  508. }
  509. /* Set APB1 & APB2 prescaler*/
  510. LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  511. LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
  512. }
  513. /* Decreasing the number of wait states because of lower CPU frequency */
  514. #if defined (FLASH_ACR_LATENCY)
  515. if (sysclk_frequency_current > SYSCLK_Frequency)
  516. {
  517. /* Set FLASH latency to lowest latency */
  518. status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  519. }
  520. #endif /* FLASH_ACR_LATENCY */
  521. /* Update SystemCoreClock variable */
  522. if (status == SUCCESS)
  523. {
  524. LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
  525. }
  526. return status;
  527. }
  528. /**
  529. * @}
  530. */
  531. /**
  532. * @}
  533. */
  534. /**
  535. * @}
  536. */
  537. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/