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.
 
 
 

762 lines
29 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32wbxx_ll_utils.c
  4. * @author MCD Application Team
  5. * @brief UTILS LL module driver.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2019 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 "stm32wbxx_ll_utils.h"
  21. #include "stm32wbxx_ll_rcc.h"
  22. #include "stm32wbxx_ll_system.h"
  23. #include "stm32wbxx_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 STM32WBxx_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 64000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
  42. #if defined(PWR_CR1_VOS)
  43. #define UTILS_MAX_FREQUENCY_SCALE2 16000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
  44. #endif
  45. /* Defines used for PLL range */
  46. #define UTILS_PLLVCO_INPUT_MIN 2660000U /*!< Frequency min for PLLVCO input, in Hz */
  47. #define UTILS_PLLVCO_INPUT_MAX 16000000U /*!< Frequency max for PLLVCO input, in Hz */
  48. #define UTILS_PLLVCO_OUTPUT_MIN 96000000U /*!< Frequency min for PLLVCO output, in Hz */
  49. #define UTILS_PLLVCO_OUTPUT_MAX 344000000U /*!< Frequency max for PLLVCO output, in Hz */
  50. /* Defines used for HCLK2 frequency check */
  51. #define UTILS_HCLK2_MAX 32000000U /*!< HCLK2 frequency maximum at 32MHz */
  52. /**
  53. * @}
  54. */
  55. /* Private macros ------------------------------------------------------------*/
  56. /** @addtogroup UTILS_LL_Private_Macros
  57. * @{
  58. */
  59. #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
  60. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
  61. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_3) \
  62. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
  63. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_5) \
  64. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_6) \
  65. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
  66. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_10) \
  67. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
  68. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_32) \
  69. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
  70. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
  71. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
  72. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
  73. #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
  74. || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
  75. || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
  76. || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
  77. || ((__VALUE__) == LL_RCC_APB1_DIV_16))
  78. #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
  79. || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
  80. || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
  81. || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
  82. || ((__VALUE__) == LL_RCC_APB2_DIV_16))
  83. #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
  84. || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
  85. || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
  86. || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
  87. || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
  88. || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
  89. || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
  90. || ((__VALUE__) == LL_RCC_PLLM_DIV_8))
  91. #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((6U <= (__VALUE__)) && ((__VALUE__) <= 127U))
  92. #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
  93. || ((__VALUE__) == LL_RCC_PLLR_DIV_3) \
  94. || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
  95. || ((__VALUE__) == LL_RCC_PLLR_DIV_5) \
  96. || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
  97. || ((__VALUE__) == LL_RCC_PLLR_DIV_7) \
  98. || ((__VALUE__) == LL_RCC_PLLR_DIV_8))
  99. #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
  100. #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
  101. #if defined(PWR_CR1_VOS)
  102. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
  103. ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
  104. #else
  105. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1)
  106. #endif
  107. #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
  108. || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
  109. #define countof(a) (sizeof(a) / sizeof(*(a)))
  110. /**
  111. * @}
  112. */
  113. /* Private function prototypes -----------------------------------------------*/
  114. /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
  115. * @{
  116. */
  117. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
  118. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  119. static ErrorStatus UTILS_PLL_IsBusy(void);
  120. /**
  121. * @}
  122. */
  123. /* Exported functions --------------------------------------------------------*/
  124. /** @addtogroup UTILS_LL_Exported_Functions
  125. * @{
  126. */
  127. /** @addtogroup UTILS_LL_EF_DELAY
  128. * @{
  129. */
  130. /**
  131. * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
  132. * @note When a RTOS is used, it is recommended to avoid changing the Systick
  133. * configuration by calling this function, for a delay use rather osDelay RTOS service.
  134. * @param HCLKFrequency HCLK frequency in Hz
  135. * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq (HCLK1_Frequency field)
  136. * @retval None
  137. */
  138. void LL_Init1msTick(uint32_t HCLKFrequency)
  139. {
  140. /* Use frequency provided in argument */
  141. LL_InitTick(HCLKFrequency, 1000);
  142. }
  143. /**
  144. * @brief This function provides accurate delay (in milliseconds) based
  145. * on SysTick counter flag
  146. * @note When a RTOS is used, it is recommended to avoid using blocking delay
  147. * and use rather osDelay service.
  148. * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  149. * will configure Systick to 1ms
  150. * @param Delay specifies the delay time length, in milliseconds.
  151. * @retval None
  152. */
  153. void LL_mDelay(uint32_t Delay)
  154. {
  155. uint32_t mDelay = Delay;
  156. __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
  157. /* Add this code to indicate that local variable is not used */
  158. ((void)tmp);
  159. /* Add a period to guaranty minimum wait */
  160. if (mDelay < LL_MAX_DELAY)
  161. {
  162. mDelay++;
  163. }
  164. while (mDelay != 0U)
  165. {
  166. if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  167. {
  168. mDelay--;
  169. }
  170. }
  171. }
  172. /**
  173. * @}
  174. */
  175. /** @addtogroup UTILS_EF_SYSTEM
  176. * @brief System Configuration functions
  177. *
  178. @verbatim
  179. ===============================================================================
  180. ##### System Configuration functions #####
  181. ===============================================================================
  182. [..]
  183. System, HCLK1, HCLK2, AHBS, AHBRF and APB buses clocks configuration
  184. (+) The maximum frequency of the SYSCLK, HCLK1, HCLK4, PCLK1 and PCLK2
  185. is 640000000 Hz.
  186. ....... (+) The maximum frequency of the HCLK2 is 320000000 Hz.
  187. @endverbatim
  188. @internal
  189. Depending on the device voltage range, the maximum frequency should be
  190. adapted accordingly:
  191. (++) HCLK4 clock frequency for STM32WB55xx device
  192. (++) +--------------------------------------------------------+
  193. (++) | Latency | HCLK4 clock frequency (MHz) |
  194. (++) | |--------------------------------------|
  195. (++) | | voltage range 1 | voltage range 2 |
  196. (++) | | 1.2 V | 1.0 V |
  197. (++) |-----------------|-------------------|------------------|
  198. (++) |0WS(1 CPU cycles)| 0 < HCLK4 <= 18 | 0 < HCLK4 <= 6 |
  199. (++) |-----------------|-------------------|------------------|
  200. (++) |1WS(2 CPU cycles)| 18 < HCLK4 <= 36 | 6 < HCLK4 <= 12 |
  201. (++) |-----------------|-------------------|------------------|
  202. (++) |2WS(3 CPU cycles)| 36 < HCLK4 <= 54 | 12 < HCLK4 <= 16|
  203. (++) |-----------------|-------------------|------------------|
  204. (++) |3WS(4 CPU cycles)| 54 < HCLK4 <= 64 | N.A. |
  205. (++) +--------------------------------------------------------+
  206. @endinternal
  207. * @{
  208. */
  209. /**
  210. * @brief This function sets directly SystemCoreClock CMSIS variable.
  211. * @note Variable can be calculated also through SystemCoreClockUpdate function.
  212. * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq (HCLK1_Frequency field))
  213. * @retval None
  214. */
  215. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  216. {
  217. /* HCLK clock frequency */
  218. SystemCoreClock = HCLKFrequency;
  219. }
  220. /**
  221. * @brief Update number of Flash wait states in line with new frequency and current
  222. voltage range.
  223. * @param HCLK4Frequency HCLK4 frequency
  224. * @retval An ErrorStatus enumeration value:
  225. * - SUCCESS: Latency has been modified
  226. * - ERROR: Latency cannot be modified
  227. */
  228. ErrorStatus LL_SetFlashLatency(uint32_t HCLK4Frequency)
  229. {
  230. ErrorStatus status = ERROR;
  231. uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
  232. uint16_t index;
  233. uint32_t timeout;
  234. uint32_t getlatency;
  235. #if defined(PWR_CR1_VOS)
  236. uint32_t voltagescaling = LL_PWR_GetRegulVoltageScaling();
  237. uint32_t maxfreq = (voltagescaling == LL_PWR_REGU_VOLTAGE_SCALE1) ? UTILS_MAX_FREQUENCY_SCALE1 : UTILS_MAX_FREQUENCY_SCALE2;
  238. #else
  239. uint32_t maxfreq = UTILS_MAX_FREQUENCY_SCALE1;
  240. #endif
  241. /* Array used for FLASH latency according to HCLK4 Frequency */
  242. /* Flash Clock source (HCLK4) range in MHz with a VCORE is range1 */
  243. const uint32_t UTILS_CLK_SRC_RANGE_VOS1[] = {18000000U, 36000000U, 54000000U, UTILS_MAX_FREQUENCY_SCALE1};
  244. #if defined(PWR_CR1_VOS)
  245. /* Flash Clock source (HCLK4) range in MHz with a VCORE is range2 */
  246. const uint32_t UTILS_CLK_SRC_RANGE_VOS2[] = {6000000U, 12000000U, UTILS_MAX_FREQUENCY_SCALE2};
  247. #endif
  248. /* Flash Latency range */
  249. const uint32_t UTILS_LATENCY_RANGE[] = {LL_FLASH_LATENCY_0, LL_FLASH_LATENCY_1, LL_FLASH_LATENCY_2, LL_FLASH_LATENCY_3};
  250. /* Frequency cannot be equal to 0 or greater than max clock */
  251. if ((HCLK4Frequency > 0U) && (HCLK4Frequency <= maxfreq))
  252. {
  253. #if defined(PWR_CR1_VOS)
  254. if (voltagescaling == LL_PWR_REGU_VOLTAGE_SCALE1)
  255. {
  256. for (index = 0; index < countof(UTILS_CLK_SRC_RANGE_VOS1); index++)
  257. {
  258. if (HCLK4Frequency <= UTILS_CLK_SRC_RANGE_VOS1[index])
  259. {
  260. latency = UTILS_LATENCY_RANGE[index];
  261. status = SUCCESS;
  262. break;
  263. }
  264. }
  265. }
  266. else /* SCALE2 */
  267. {
  268. for (index = 0; index < countof(UTILS_CLK_SRC_RANGE_VOS2); index++)
  269. {
  270. if (HCLK4Frequency <= UTILS_CLK_SRC_RANGE_VOS2[index])
  271. {
  272. latency = UTILS_LATENCY_RANGE[index];
  273. status = SUCCESS;
  274. break;
  275. }
  276. }
  277. }
  278. #else
  279. for (index = 0; index < countof(UTILS_CLK_SRC_RANGE_VOS1); index++)
  280. {
  281. if (HCLK4Frequency <= UTILS_CLK_SRC_RANGE_VOS1[index])
  282. {
  283. latency = UTILS_LATENCY_RANGE[index];
  284. status = SUCCESS;
  285. break;
  286. }
  287. }
  288. #endif
  289. }
  290. if (status != ERROR)
  291. {
  292. LL_FLASH_SetLatency(latency);
  293. /* Check that the new number of wait states is taken into account to access the Flash
  294. memory by reading the FLASH_ACR register */
  295. timeout = 2U;
  296. do
  297. {
  298. /* Wait for Flash latency to be updated */
  299. getlatency = LL_FLASH_GetLatency();
  300. timeout--;
  301. }
  302. while ((getlatency != latency) && (timeout > 0U));
  303. if (getlatency != latency)
  304. {
  305. status = ERROR;
  306. }
  307. }
  308. return status;
  309. }
  310. /**
  311. * @brief This function configures system clock with MSI as clock source of the PLL
  312. * @note The application needs to ensure that PLL and PLLSAI1 are disabled.
  313. * @note The application needs to ensure that PLL configuration is valid
  314. * @note The application needs to ensure that MSI range is valid.
  315. * @note The application needs to ensure that BUS prescalers are valid
  316. * @note Function is based on the following formula:
  317. * - PLL output frequency = (((MSI frequency / PLLM) * PLLN) / PLLR)
  318. * - PLLM: ensure that the VCO input frequency ranges from 2.66 to 16 MHz (PLLVCO_input = MSI frequency / PLLM)
  319. * - PLLN: ensure that the VCO output frequency is between 96 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
  320. * - PLLR: ensure that max frequency at 64000000 Hz is reached (PLLVCO_output / PLLR)
  321. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  322. * the configuration information for the PLL.
  323. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  324. * the configuration information for the BUS prescalers.
  325. * @retval An ErrorStatus enumeration value:
  326. * - SUCCESS: Max frequency configuration done
  327. * - ERROR: Max frequency configuration not done
  328. */
  329. ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  330. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  331. {
  332. ErrorStatus status;
  333. uint32_t pllrfreq, hclk2freq, msi_range;
  334. /* Check if one of the PLL is enabled */
  335. if (UTILS_PLL_IsBusy() == SUCCESS)
  336. {
  337. /* Get the current MSI range & check coherency */
  338. msi_range = LL_RCC_MSI_GetRange();
  339. switch (msi_range)
  340. {
  341. case LL_RCC_MSIRANGE_0: /* MSI = 100 KHz */
  342. case LL_RCC_MSIRANGE_1: /* MSI = 200 KHz */
  343. case LL_RCC_MSIRANGE_2: /* MSI = 400 KHz */
  344. case LL_RCC_MSIRANGE_3: /* MSI = 800 KHz */
  345. case LL_RCC_MSIRANGE_4: /* MSI = 1 MHz */
  346. case LL_RCC_MSIRANGE_5: /* MSI = 2 MHz */
  347. /* PLLVCO input frequency can not in the range from 2.66 to 16 MHz*/
  348. status = ERROR;
  349. break;
  350. case LL_RCC_MSIRANGE_6: /* MSI = 4 MHz */
  351. case LL_RCC_MSIRANGE_7: /* MSI = 8 MHz */
  352. case LL_RCC_MSIRANGE_8: /* MSI = 16 MHz */
  353. case LL_RCC_MSIRANGE_9: /* MSI = 24 MHz */
  354. case LL_RCC_MSIRANGE_10: /* MSI = 32 MHz */
  355. case LL_RCC_MSIRANGE_11: /* MSI = 48 MHz */
  356. default:
  357. status = SUCCESS;
  358. break;
  359. }
  360. /* PLL is ready, MSI range is valid and HCLK2 frequency is coherent
  361. Main PLL configuration and activation */
  362. if (status != ERROR)
  363. {
  364. /* Calculate the new PLL output frequency & verify all PLL stages are correct (VCO input ranges,
  365. VCO output ranges & SYSCLK max) when assert activated */
  366. pllrfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSI_FREQ(msi_range), UTILS_PLLInitStruct);
  367. hclk2freq = __LL_RCC_CALC_HCLK2_FREQ(pllrfreq, UTILS_ClkInitStruct->CPU2CLKDivider);
  368. /* Check HCLK2 frequency coherency */
  369. if (hclk2freq > UTILS_HCLK2_MAX)
  370. {
  371. /* HCLK2 frequency can not be higher than 32Mhz */
  372. status = ERROR;
  373. }
  374. else
  375. {
  376. /* Enable MSI if not enabled */
  377. if (LL_RCC_MSI_IsReady() != 1U)
  378. {
  379. LL_RCC_MSI_Enable();
  380. while ((LL_RCC_MSI_IsReady() != 1U))
  381. {
  382. /* Wait for MSI ready */
  383. }
  384. }
  385. /* Configure PLL domain SYS */
  386. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
  387. UTILS_PLLInitStruct->PLLR);
  388. /* Enable PLL and switch system clock to PLL - latency check done internally */
  389. status = UTILS_EnablePLLAndSwitchSystem(pllrfreq, UTILS_ClkInitStruct);
  390. }
  391. }
  392. }
  393. else
  394. {
  395. /* Current PLL configuration cannot be modified */
  396. status = ERROR;
  397. }
  398. return status;
  399. }
  400. /**
  401. * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
  402. * @note The application need to ensure that PLL and/or PLLSAI1 are disabled.
  403. * @note The application needs to ensure that PLL configuration is valid
  404. * @note The application needs to ensure that BUS prescalers are valid
  405. * @note Function is based on the following formula:
  406. * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
  407. * - PLLM: ensure that the VCO input frequency ranges from 2.66 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
  408. * - PLLN: ensure that the VCO output frequency is between 96 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
  409. * - PLLR: ensure that max frequency at 64000000 Hz is reach (PLLVCO_output / PLLR)
  410. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  411. * the configuration information for the PLL.
  412. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  413. * the configuration information for the BUS prescalers.
  414. * @retval An ErrorStatus enumeration value:
  415. * - SUCCESS: Max frequency configuration done
  416. * - ERROR: Max frequency configuration not done
  417. */
  418. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  419. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  420. {
  421. ErrorStatus status;
  422. uint32_t pllrfreq, hclk2freq;
  423. /* Check if one of the PLL is enabled */
  424. if (UTILS_PLL_IsBusy() == SUCCESS)
  425. {
  426. /* Calculate the new PLL output frequency */
  427. pllrfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  428. hclk2freq = __LL_RCC_CALC_HCLK2_FREQ(pllrfreq, UTILS_ClkInitStruct->CPU2CLKDivider);
  429. /* Check HCLK2 frequency coherency */
  430. if (hclk2freq > UTILS_HCLK2_MAX)
  431. {
  432. /* HCLK2 frequency can not be higher than 32Mhz */
  433. status = ERROR;
  434. }
  435. else
  436. {
  437. /* Enable HSI if not enabled */
  438. if (LL_RCC_HSI_IsReady() != 1U)
  439. {
  440. LL_RCC_HSI_Enable();
  441. while (LL_RCC_HSI_IsReady() != 1U)
  442. {
  443. /* Wait for HSI ready */
  444. }
  445. }
  446. /* Configure PLL */
  447. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
  448. UTILS_PLLInitStruct->PLLR);
  449. /* Enable PLL and switch system clock to PLL */
  450. status = UTILS_EnablePLLAndSwitchSystem(pllrfreq, UTILS_ClkInitStruct);
  451. }
  452. }
  453. else
  454. {
  455. /* Current PLL configuration cannot be modified */
  456. status = ERROR;
  457. }
  458. return status;
  459. }
  460. /**
  461. * @brief This function configures system clock with HSE as clock source of the PLL
  462. * @note The application need to ensure that PLL and/or PLLSAI1 are disabled.
  463. * @note The application needs to ensure that PLL configuration is valid
  464. * @note The application needs to ensure that BUS prescalers are valid
  465. * @note Function is based on the following formula:
  466. * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
  467. * - PLLM: ensure that the VCO input frequency ranges from 2.66 to 16 MHz (PLLVCO_input = HSE frequency / PLLM)
  468. * - PLLN: ensure that the VCO output frequency is between 96 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
  469. * - PLLR: ensure that max frequency at 64000000 Hz is reached (PLLVCO_output / PLLR)
  470. * @param HSEBypass This parameter can be one of the following values:
  471. * @arg @ref LL_UTILS_HSEBYPASS_ON
  472. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  473. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  474. * the configuration information for the PLL.
  475. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  476. * the configuration information for the BUS prescalers.
  477. * @retval An ErrorStatus enumeration value:
  478. * - SUCCESS: Max frequency configuration done
  479. * - ERROR: Max frequency configuration not done
  480. */
  481. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEBypass, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  482. {
  483. ErrorStatus status;
  484. uint32_t pllrfreq, hclk2freq;
  485. /* Check the parameters */
  486. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  487. /* Check if one of the PLL is enabled */
  488. if (UTILS_PLL_IsBusy() == SUCCESS)
  489. {
  490. /* Calculate the new PLL output frequency */
  491. pllrfreq = UTILS_GetPLLOutputFrequency(HSE_VALUE, UTILS_PLLInitStruct);
  492. hclk2freq = __LL_RCC_CALC_HCLK2_FREQ(pllrfreq, UTILS_ClkInitStruct->CPU2CLKDivider);
  493. /* Check HCLK2 frequency coherency */
  494. if (hclk2freq > UTILS_HCLK2_MAX)
  495. {
  496. /* HCLK2 frequency can not be higher than 32Mhz */
  497. status = ERROR;
  498. }
  499. else
  500. {
  501. /* Enable HSE if not enabled */
  502. if (LL_RCC_HSE_IsReady() != 1U)
  503. {
  504. #if defined(RCC_CR_HSEBYP)
  505. /* Check if need to enable HSE bypass feature or not */
  506. if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  507. {
  508. LL_RCC_HSE_EnableBypass();
  509. }
  510. else
  511. {
  512. LL_RCC_HSE_DisableBypass();
  513. }
  514. #endif
  515. /* Enable HSE */
  516. LL_RCC_HSE_Enable();
  517. while (LL_RCC_HSE_IsReady() != 1U)
  518. {
  519. /* Wait for HSE ready */
  520. }
  521. }
  522. /* Configure PLL */
  523. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
  524. UTILS_PLLInitStruct->PLLR);
  525. /* Enable PLL and switch system clock to PLL */
  526. status = UTILS_EnablePLLAndSwitchSystem(pllrfreq, UTILS_ClkInitStruct);
  527. }
  528. }
  529. else
  530. {
  531. /* Current PLL configuration cannot be modified */
  532. status = ERROR;
  533. }
  534. return status;
  535. }
  536. /**
  537. * @}
  538. */
  539. /**
  540. * @}
  541. */
  542. /** @addtogroup UTILS_LL_Private_Functions
  543. * @{
  544. */
  545. /**
  546. * @brief Function to check that PLL can be modified
  547. * @param PLL_InputFrequency PLL input frequency (in Hz)
  548. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  549. * the configuration information for the PLL.
  550. * @retval PLL output frequency (in Hz)
  551. */
  552. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  553. {
  554. uint32_t pllfreq;
  555. /* Check the parameters */
  556. assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
  557. assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
  558. assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
  559. /* Check different PLL parameters according to RM */
  560. /* - PLLM: ensure that the VCO input frequency ranges from 2.66 to 16 MHz. */
  561. pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
  562. assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
  563. /* - PLLN: ensure that the VCO output frequency is between 96 and 344 MHz.*/
  564. pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
  565. assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
  566. /* - PLLR: ensure that max frequency at 64000000 Hz is reached */
  567. pllfreq = pllfreq / ((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U);
  568. assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  569. return pllfreq;
  570. }
  571. /**
  572. * @brief Function to check that PLL can be modified
  573. * @retval An ErrorStatus enumeration value:
  574. * - SUCCESS: PLL modification can be done
  575. * - ERROR: PLL is busy
  576. */
  577. static ErrorStatus UTILS_PLL_IsBusy(void)
  578. {
  579. ErrorStatus status = SUCCESS;
  580. /* Check if PLL is busy*/
  581. if (LL_RCC_PLL_IsReady() != 0U)
  582. {
  583. /* PLL configuration cannot be modified */
  584. status = ERROR;
  585. }
  586. #if defined(SAI1)
  587. /* Check if PLLSAI1 is busy*/
  588. if (LL_RCC_PLLSAI1_IsReady() != 0U)
  589. {
  590. /* PLLSAI1 configuration cannot be modified */
  591. status = ERROR;
  592. }
  593. #endif
  594. return status;
  595. }
  596. /**
  597. * @brief Function to enable PLL and switch system clock to PLL
  598. * @param SYSCLK_Frequency SYSCLK frequency
  599. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  600. * the configuration information for the BUS prescalers.
  601. * @retval An ErrorStatus enumeration value:
  602. * - SUCCESS: No problem to switch system to PLL
  603. * - ERROR: Problem to switch system to PLL
  604. */
  605. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  606. {
  607. ErrorStatus status = SUCCESS;
  608. uint32_t hclks_frequency_target, hclks_frequency_current, sysclk_current;
  609. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->CPU1CLKDivider));
  610. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->CPU2CLKDivider));
  611. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHB4CLKDivider));
  612. assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  613. assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
  614. /* Calculate HCLK4 frequency based on SYSCLK_Frequency target */
  615. hclks_frequency_target = __LL_RCC_CALC_HCLK4_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHB4CLKDivider);
  616. /* Calculate HCLK4 frequency current */
  617. sysclk_current = (SystemCoreClock * AHBPrescTable[(LL_RCC_GetAHBPrescaler() & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]);
  618. hclks_frequency_current = __LL_RCC_CALC_HCLK4_FREQ(sysclk_current, LL_RCC_GetAHB4Prescaler());
  619. /* Increasing the number of wait states because of higher CPU frequency */
  620. if (hclks_frequency_current < hclks_frequency_target)
  621. {
  622. /* Set FLASH latency to highest latency */
  623. status = LL_SetFlashLatency(hclks_frequency_target);
  624. }
  625. /* Update system clock configuration */
  626. if (status == SUCCESS)
  627. {
  628. /* Enable PLL */
  629. LL_RCC_PLL_Enable();
  630. LL_RCC_PLL_EnableDomain_SYS();
  631. while (LL_RCC_PLL_IsReady() != 1U)
  632. {
  633. /* Wait for PLL ready */
  634. }
  635. /* Sysclk activation on the main PLL */
  636. LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->CPU1CLKDivider);
  637. LL_C2_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->CPU2CLKDivider);
  638. LL_RCC_SetAHB4Prescaler(UTILS_ClkInitStruct->AHB4CLKDivider);
  639. LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  640. while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  641. {
  642. /* Wait for system clock switch to PLL */
  643. }
  644. /* Set APB1 & APB2 prescaler*/
  645. LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  646. LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
  647. }
  648. /* Decreasing the number of wait states because of lower CPU frequency */
  649. if (hclks_frequency_current > hclks_frequency_target)
  650. {
  651. /* Set FLASH latency to lowest latency */
  652. status = LL_SetFlashLatency(hclks_frequency_target);
  653. }
  654. /* Update SystemCoreClock variable */
  655. if (status == SUCCESS)
  656. {
  657. LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK1_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->CPU1CLKDivider));
  658. }
  659. return status;
  660. }
  661. /**
  662. * @}
  663. */
  664. /**
  665. * @}
  666. */
  667. /**
  668. * @}
  669. */
  670. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/