stm32f0xx_ll_utils.c 23 KB

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