stm32f3xx_ll_utils.c 21 KB

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