stm32g0xx_ll_utils.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /**
  2. ******************************************************************************
  3. * @file stm32g0xx_ll_utils.c
  4. * @author MCD Application Team
  5. * @brief UTILS LL module driver.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2018 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 "stm32g0xx_ll_utils.h"
  20. #include "stm32g0xx_ll_rcc.h"
  21. #include "stm32g0xx_ll_system.h"
  22. #include "stm32g0xx_ll_pwr.h"
  23. #ifdef USE_FULL_ASSERT
  24. #include "stm32_assert.h"
  25. #else
  26. #define assert_param(expr) ((void)0U)
  27. #endif /* USE_FULL_ASSERT */
  28. /** @addtogroup STM32G0xx_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. #define UTILS_MAX_FREQUENCY 64000000U /*!< Maximum frequency for system clock, in Hz */
  41. /* Defines used for PLL range */
  42. #define UTILS_PLLVCO_INPUT_MIN 4000000U /*!< Frequency min for PLLVCO input, in Hz */
  43. #define UTILS_PLLVCO_INPUT_MAX 8000000U /*!< Frequency max for PLLVCO input, in Hz */
  44. #define UTILS_PLLVCO_OUTPUT_MIN 64000000U /*!< Frequency min for PLLVCO output, in Hz */
  45. #define UTILS_PLLVCO_OUTPUT_MAX 344000000U /*!< Frequency max for PLLVCO output, in Hz */
  46. /* Defines used for HSE range */
  47. #define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */
  48. #define UTILS_HSE_FREQUENCY_MAX 48000000U /*!< Frequency max for HSE frequency, in Hz */
  49. /* Defines used for FLASH latency according to HCLK Frequency */
  50. #define UTILS_SCALE1_LATENCY1_FREQ 24000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
  51. #define UTILS_SCALE1_LATENCY2_FREQ 48000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
  52. #define UTILS_SCALE1_LATENCY3_FREQ 64000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
  53. /**
  54. * @}
  55. */
  56. /* Private macros ------------------------------------------------------------*/
  57. /** @addtogroup UTILS_LL_Private_Macros
  58. * @{
  59. */
  60. #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
  61. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
  62. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
  63. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
  64. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
  65. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
  66. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
  67. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
  68. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
  69. #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
  70. || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
  71. || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
  72. || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
  73. || ((__VALUE__) == LL_RCC_APB1_DIV_16))
  74. #define IS_LL_UTILS_HSI_DIV(__VALUE__) (((__VALUE__) == LL_RCC_HSI_DIV_1) \
  75. || ((__VALUE__) == LL_RCC_HSI_DIV_2) \
  76. || ((__VALUE__) == LL_RCC_HSI_DIV_4) \
  77. || ((__VALUE__) == LL_RCC_HSI_DIV_8) \
  78. || ((__VALUE__) == LL_RCC_HSI_DIV_16) \
  79. || ((__VALUE__) == LL_RCC_HSI_DIV_32) \
  80. || ((__VALUE__) == LL_RCC_HSI_DIV_64) \
  81. || ((__VALUE__) == LL_RCC_HSI_DIV_128))
  82. #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
  83. || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
  84. || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
  85. || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
  86. || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
  87. || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
  88. || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
  89. || ((__VALUE__) == LL_RCC_PLLM_DIV_8))
  90. #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 86U))
  91. #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
  92. || ((__VALUE__) == LL_RCC_PLLR_DIV_3) \
  93. || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
  94. || ((__VALUE__) == LL_RCC_PLLR_DIV_5) \
  95. || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
  96. || ((__VALUE__) == LL_RCC_PLLR_DIV_7) \
  97. || ((__VALUE__) == LL_RCC_PLLR_DIV_8))
  98. #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
  99. #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
  100. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_MAX_FREQUENCY)
  101. #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
  102. || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
  103. #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
  104. /**
  105. * @}
  106. */
  107. /* Private function prototypes -----------------------------------------------*/
  108. /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
  109. * @{
  110. */
  111. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
  112. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
  113. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  114. static ErrorStatus UTILS_PLL_IsBusy(void);
  115. /**
  116. * @}
  117. */
  118. /* Exported functions --------------------------------------------------------*/
  119. /** @addtogroup UTILS_LL_Exported_Functions
  120. * @{
  121. */
  122. /** @addtogroup UTILS_LL_EF_DELAY
  123. * @{
  124. */
  125. /**
  126. * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
  127. * @note When a RTOS is used, it is recommended to avoid changing the Systick
  128. * configuration by calling this function, for a delay use rather osDelay RTOS service.
  129. * @param HCLKFrequency HCLK frequency in Hz
  130. * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
  131. * @retval None
  132. */
  133. void LL_Init1msTick(uint32_t HCLKFrequency)
  134. {
  135. /* Use frequency provided in argument */
  136. LL_InitTick(HCLKFrequency, 1000U);
  137. }
  138. /**
  139. * @brief This function provides accurate delay (in milliseconds) based
  140. * on SysTick counter flag
  141. * @note When a RTOS is used, it is recommended to avoid using blocking delay
  142. * and use rather osDelay service.
  143. * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  144. * will configure Systick to 1ms
  145. * @param Delay specifies the delay time length, in milliseconds.
  146. * @retval None
  147. */
  148. void LL_mDelay(uint32_t Delay)
  149. {
  150. __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
  151. uint32_t tmpDelay; /* MISRAC2012-Rule-17.8 */
  152. /* Add this code to indicate that local variable is not used */
  153. ((void)tmp);
  154. tmpDelay = Delay;
  155. /* Add a period to guaranty minimum wait */
  156. if (tmpDelay < LL_MAX_DELAY)
  157. {
  158. tmpDelay ++;
  159. }
  160. while (tmpDelay != 0U)
  161. {
  162. if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  163. {
  164. tmpDelay --;
  165. }
  166. }
  167. }
  168. /**
  169. * @}
  170. */
  171. /** @addtogroup UTILS_EF_SYSTEM
  172. * @brief System Configuration functions
  173. *
  174. @verbatim
  175. ===============================================================================
  176. ##### System Configuration functions #####
  177. ===============================================================================
  178. [..]
  179. System, AHB and APB buses clocks configuration
  180. (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 is 64000000 Hz.
  181. @endverbatim
  182. @internal
  183. Depending on the device voltage range, the maximum frequency should be
  184. adapted accordingly:
  185. (++) Table 1. HCLK clock frequency.
  186. (++) +-------------------------------------------------------+
  187. (++) | Latency | HCLK clock frequency (MHz) |
  188. (++) | |-------------------------------------|
  189. (++) | | voltage range 1 | voltage range 2 |
  190. (++) | | 1.08V - 1.32V | 0.9 V - 1.10V |
  191. (++) |-----------------|------------------|------------------|
  192. (++) |0WS(1 CPU cycles)| HCLK <= 24 | HCLK <= 8 |
  193. (++) |-----------------|------------------|------------------|
  194. (++) |1WS(2 CPU cycles)| HCLK <= 48 | HCLK <= 16 |
  195. (++) |-----------------|------------------|------------------|
  196. (++) |2WS(3 CPU cycles)| HCLK <= 64 | - |
  197. (++) |-----------------|------------------|------------------|
  198. @endinternal
  199. * @{
  200. */
  201. /**
  202. * @brief This function sets directly SystemCoreClock CMSIS variable.
  203. * @note Variable can be calculated also through SystemCoreClockUpdate function.
  204. * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
  205. * @retval None
  206. */
  207. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  208. {
  209. /* HCLK clock frequency */
  210. SystemCoreClock = HCLKFrequency;
  211. }
  212. /**
  213. * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
  214. * @note The application need to ensure that PLL is disabled.
  215. * @note Function is based on the following formula:
  216. * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
  217. * - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
  218. * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
  219. * - PLLR: ensure that max frequency at 64000000 Hz is reach (PLLVCO_output / PLLR)
  220. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  221. * the configuration information for the PLL.
  222. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  223. * the configuration information for the BUS prescalers.
  224. * @retval An ErrorStatus enumeration value:
  225. * - SUCCESS: Max frequency configuration done
  226. * - ERROR: Max frequency configuration not done
  227. */
  228. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  229. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  230. {
  231. ErrorStatus status;
  232. uint32_t pllfreq;
  233. /* Check if one of the PLL is enabled */
  234. if (UTILS_PLL_IsBusy() == SUCCESS)
  235. {
  236. /* Calculate the new PLL output frequency */
  237. pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  238. /* Enable HSI if not enabled */
  239. if (LL_RCC_HSI_IsReady() != 1U)
  240. {
  241. LL_RCC_HSI_Enable();
  242. while (LL_RCC_HSI_IsReady() != 1U)
  243. {
  244. /* Wait for HSI ready */
  245. }
  246. }
  247. /* Configure PLL */
  248. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
  249. UTILS_PLLInitStruct->PLLR);
  250. /* Enable PLL and switch system clock to PLL */
  251. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  252. }
  253. else
  254. {
  255. /* Current PLL configuration cannot be modified */
  256. status = ERROR;
  257. }
  258. return status;
  259. }
  260. /**
  261. * @brief This function configures system clock with HSE 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 = (((HSE frequency / PLLM) * PLLN) / PLLR)
  265. * - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSE frequency / PLLM)
  266. * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
  267. * - PLLR: ensure that max frequency at 64000000 Hz is reached (PLLVCO_output / PLLR)
  268. * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
  269. * @param HSEBypass This parameter can be one of the following values:
  270. * @arg @ref LL_UTILS_HSEBYPASS_ON
  271. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  272. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  273. * the configuration information for the PLL.
  274. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  275. * the configuration information for the BUS prescalers.
  276. * @retval An ErrorStatus enumeration value:
  277. * - SUCCESS: Max frequency configuration done
  278. * - ERROR: Max frequency configuration not done
  279. */
  280. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
  281. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  282. {
  283. ErrorStatus status;
  284. uint32_t pllfreq;
  285. /* Check the parameters */
  286. assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  287. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  288. /* Check if one of the PLL is enabled */
  289. if (UTILS_PLL_IsBusy() == SUCCESS)
  290. {
  291. /* Calculate the new PLL output frequency */
  292. pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  293. /* Enable HSE if not enabled */
  294. if (LL_RCC_HSE_IsReady() != 1U)
  295. {
  296. /* Check if need to enable HSE bypass feature or not */
  297. if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  298. {
  299. LL_RCC_HSE_EnableBypass();
  300. }
  301. else
  302. {
  303. LL_RCC_HSE_DisableBypass();
  304. }
  305. /* Enable HSE */
  306. LL_RCC_HSE_Enable();
  307. while (LL_RCC_HSE_IsReady() != 1U)
  308. {
  309. /* Wait for HSE ready */
  310. }
  311. }
  312. /* Configure PLL */
  313. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
  314. UTILS_PLLInitStruct->PLLR);
  315. /* Enable PLL and switch system clock to PLL */
  316. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  317. }
  318. else
  319. {
  320. /* Current PLL configuration cannot be modified */
  321. status = ERROR;
  322. }
  323. return status;
  324. }
  325. /**
  326. * @brief Update number of Flash wait states in line with new frequency and current
  327. * voltage range.
  328. * @param HCLKFrequency HCLK frequency
  329. * @retval An ErrorStatus enumeration value:
  330. * - SUCCESS: Latency has been modified
  331. * - ERROR: Latency cannot be modified
  332. */
  333. ErrorStatus LL_SetFlashLatency(uint32_t HCLKFrequency)
  334. {
  335. uint32_t timeout;
  336. uint32_t getlatency;
  337. uint32_t latency;
  338. ErrorStatus status;
  339. /* Frequency cannot be equal to 0 or greater than max clock */
  340. if ((HCLKFrequency == 0U) || (HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ))
  341. {
  342. status = ERROR;
  343. }
  344. else
  345. {
  346. if (HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
  347. {
  348. /* 48 < HCLK <= 64 => 2WS (3 CPU cycles) */
  349. latency = LL_FLASH_LATENCY_2;
  350. }
  351. else
  352. {
  353. if (HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
  354. {
  355. /* 24 < HCLK <= 48 => 1WS (2 CPU cycles) */
  356. latency = LL_FLASH_LATENCY_1;
  357. }
  358. else
  359. {
  360. /* else HCLKFrequency < 24MHz default LL_FLASH_LATENCY_0 0WS */
  361. latency = LL_FLASH_LATENCY_0;
  362. }
  363. }
  364. LL_FLASH_SetLatency(latency);
  365. /* Check that the new number of wait states is taken into account to access the Flash
  366. memory by reading the FLASH_ACR register */
  367. timeout = 2u;
  368. do
  369. {
  370. /* Wait for Flash latency to be updated */
  371. getlatency = LL_FLASH_GetLatency();
  372. timeout--;
  373. } while ((getlatency != latency) && (timeout > 0u));
  374. if(getlatency != latency)
  375. {
  376. status = ERROR;
  377. }
  378. else
  379. {
  380. status = SUCCESS;
  381. }
  382. }
  383. return status;
  384. }
  385. /**
  386. * @}
  387. */
  388. /**
  389. * @}
  390. */
  391. /** @addtogroup UTILS_LL_Private_Functions
  392. * @{
  393. */
  394. /**
  395. * @brief Function to check that PLL can be modified
  396. * @param PLL_InputFrequency PLL input frequency (in Hz)
  397. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  398. * the configuration information for the PLL.
  399. * @retval PLL output frequency (in Hz)
  400. */
  401. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  402. {
  403. uint32_t pllfreq;
  404. /* Check the parameters */
  405. assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
  406. assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
  407. assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
  408. /* Check different PLL parameters according to RM */
  409. /* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz. */
  410. pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
  411. assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
  412. /* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
  413. pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
  414. assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
  415. /* - PLLR: ensure that max frequency at 64000000 Hz is reached */
  416. pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U));
  417. assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  418. return pllfreq;
  419. }
  420. /**
  421. * @brief Function to check that PLL can be modified
  422. * @retval An ErrorStatus enumeration value:
  423. * - SUCCESS: PLL modification can be done
  424. * - ERROR: PLL is busy
  425. */
  426. static ErrorStatus UTILS_PLL_IsBusy(void)
  427. {
  428. ErrorStatus status = SUCCESS;
  429. /* Check if PLL is busy*/
  430. if (LL_RCC_PLL_IsReady() != 0U)
  431. {
  432. /* PLL configuration cannot be modified */
  433. status = ERROR;
  434. }
  435. return status;
  436. }
  437. /**
  438. * @brief Function to enable PLL and switch system clock to PLL
  439. * @param SYSCLK_Frequency SYSCLK frequency
  440. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  441. * the configuration information for the BUS prescalers.
  442. * @retval An ErrorStatus enumeration value:
  443. * - SUCCESS: No problem to switch system to PLL
  444. * - ERROR: Problem to switch system to PLL
  445. */
  446. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  447. {
  448. ErrorStatus status = SUCCESS;
  449. uint32_t hclk_frequency;
  450. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
  451. assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  452. /* Calculate HCLK frequency */
  453. hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
  454. /* Increasing the number of wait states because of higher CPU frequency */
  455. if (SystemCoreClock < hclk_frequency)
  456. {
  457. /* Set FLASH latency to highest latency */
  458. status = LL_SetFlashLatency(hclk_frequency);
  459. }
  460. /* Update system clock configuration */
  461. if (status == SUCCESS)
  462. {
  463. /* Enable PLL */
  464. LL_RCC_PLL_Enable();
  465. LL_RCC_PLL_EnableDomain_SYS();
  466. while (LL_RCC_PLL_IsReady() != 1U)
  467. {
  468. /* Wait for PLL ready */
  469. }
  470. /* Sysclk activation on the main PLL */
  471. LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
  472. LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  473. while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  474. {
  475. /* Wait for system clock switch to PLL */
  476. }
  477. /* Set APB1 & APB2 prescaler*/
  478. LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  479. }
  480. /* Decreasing the number of wait states because of lower CPU frequency */
  481. if (SystemCoreClock > hclk_frequency)
  482. {
  483. /* Set FLASH latency to lowest latency */
  484. status = LL_SetFlashLatency(hclk_frequency);
  485. }
  486. /* Update SystemCoreClock variable */
  487. if (status == SUCCESS)
  488. {
  489. LL_SetSystemCoreClock(hclk_frequency);
  490. }
  491. return status;
  492. }
  493. /**
  494. * @}
  495. */
  496. /**
  497. * @}
  498. */
  499. /**
  500. * @}
  501. */