You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

565 lines
22 KiB

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