stm32f1xx_ll_utils.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_ll_utils.c
  4. * @author MCD Application Team
  5. * @brief UTILS LL module driver.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2016 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* Includes ------------------------------------------------------------------*/
  19. #include "stm32f1xx_ll_rcc.h"
  20. #include "stm32f1xx_ll_utils.h"
  21. #include "stm32f1xx_ll_system.h"
  22. #ifdef USE_FULL_ASSERT
  23. #include "stm32_assert.h"
  24. #else
  25. #define assert_param(expr) ((void)0U)
  26. #endif
  27. /** @addtogroup STM32F1xx_LL_Driver
  28. * @{
  29. */
  30. /** @addtogroup UTILS_LL
  31. * @{
  32. */
  33. /* Private types -------------------------------------------------------------*/
  34. /* Private variables ---------------------------------------------------------*/
  35. /* Private constants ---------------------------------------------------------*/
  36. /** @addtogroup UTILS_LL_Private_Constants
  37. * @{
  38. */
  39. /* Defines used for PLL range */
  40. #define UTILS_PLL_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL output, in Hz */
  41. #define UTILS_PLL2_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL2 output, in Hz */
  42. /* Defines used for HSE range */
  43. #define UTILS_HSE_FREQUENCY_MIN RCC_HSE_MIN /*!< Frequency min for HSE frequency, in Hz */
  44. #define UTILS_HSE_FREQUENCY_MAX RCC_HSE_MAX /*!< Frequency max for HSE frequency, in Hz */
  45. /* Defines used for FLASH latency according to HCLK Frequency */
  46. #if defined(FLASH_ACR_LATENCY)
  47. #define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */
  48. #define UTILS_LATENCY2_FREQ 48000000U /*!< SYSCLK frequency to set FLASH latency 2 */
  49. #else
  50. /*!< No Latency Configuration in this device */
  51. #endif
  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_4) \
  62. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
  63. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
  64. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
  65. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
  66. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
  67. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
  68. #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
  69. || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
  70. || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
  71. || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
  72. || ((__VALUE__) == LL_RCC_APB1_DIV_16))
  73. #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
  74. || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
  75. || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
  76. || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
  77. || ((__VALUE__) == LL_RCC_APB2_DIV_16))
  78. #if defined(RCC_CFGR_PLLMULL6_5)
  79. #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \
  80. || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
  81. || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
  82. || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
  83. || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
  84. || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
  85. || ((__VALUE__) == LL_RCC_PLL_MUL_6_5))
  86. #else
  87. #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
  88. || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
  89. || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
  90. || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
  91. || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
  92. || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
  93. || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
  94. || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
  95. || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
  96. || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
  97. || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
  98. || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
  99. || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
  100. || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
  101. || ((__VALUE__) == LL_RCC_PLL_MUL_16))
  102. #endif /* RCC_CFGR_PLLMULL6_5 */
  103. #if defined(RCC_CFGR2_PREDIV1)
  104. #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \
  105. ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \
  106. ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \
  107. ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \
  108. ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \
  109. ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \
  110. ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \
  111. ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
  112. #else
  113. #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2))
  114. #endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/
  115. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)
  116. #if defined(RCC_PLL2_SUPPORT)
  117. #define IS_LL_UTILS_PLL2MUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL2_MUL_8) \
  118. || ((__VALUE__) == LL_RCC_PLL2_MUL_9) \
  119. || ((__VALUE__) == LL_RCC_PLL2_MUL_10) \
  120. || ((__VALUE__) == LL_RCC_PLL2_MUL_11) \
  121. || ((__VALUE__) == LL_RCC_PLL2_MUL_12) \
  122. || ((__VALUE__) == LL_RCC_PLL2_MUL_13) \
  123. || ((__VALUE__) == LL_RCC_PLL2_MUL_14) \
  124. || ((__VALUE__) == LL_RCC_PLL2_MUL_16) \
  125. || ((__VALUE__) == LL_RCC_PLL2_MUL_20))
  126. #define IS_LL_UTILS_PREDIV2_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_1) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_2) || \
  127. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_3) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_4) || \
  128. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_5) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_6) || \
  129. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_7) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_8) || \
  130. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_9) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_10) || \
  131. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_11) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_12) || \
  132. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_13) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_14) || \
  133. ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_15) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_16))
  134. #define IS_LL_UTILS_PLL2_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL2_OUTPUT_MAX)
  135. #endif /* RCC_PLL2_SUPPORT */
  136. #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
  137. || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
  138. #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
  139. /**
  140. * @}
  141. */
  142. /* Private function prototypes -----------------------------------------------*/
  143. /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
  144. * @{
  145. */
  146. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
  147. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
  148. static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass,
  149. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  150. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  151. #if defined(RCC_PLL2_SUPPORT)
  152. static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency,
  153. LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct);
  154. #endif /* RCC_PLL2_SUPPORT */
  155. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  156. static ErrorStatus UTILS_PLL_IsBusy(void);
  157. /**
  158. * @}
  159. */
  160. /* Exported functions --------------------------------------------------------*/
  161. /** @addtogroup UTILS_LL_Exported_Functions
  162. * @{
  163. */
  164. /** @addtogroup UTILS_LL_EF_DELAY
  165. * @{
  166. */
  167. /**
  168. * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
  169. * @note When a RTOS is used, it is recommended to avoid changing the Systick
  170. * configuration by calling this function, for a delay use rather osDelay RTOS service.
  171. * @param HCLKFrequency HCLK frequency in Hz
  172. * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
  173. * @retval None
  174. */
  175. void LL_Init1msTick(uint32_t HCLKFrequency)
  176. {
  177. /* Use frequency provided in argument */
  178. LL_InitTick(HCLKFrequency, 1000U);
  179. }
  180. /**
  181. * @brief This function provides accurate delay (in milliseconds) based
  182. * on SysTick counter flag
  183. * @note When a RTOS is used, it is recommended to avoid using blocking delay
  184. * and use rather osDelay service.
  185. * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  186. * will configure Systick to 1ms
  187. * @param Delay specifies the delay time length, in milliseconds.
  188. * @retval None
  189. */
  190. void LL_mDelay(uint32_t Delay)
  191. {
  192. __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
  193. /* Add this code to indicate that local variable is not used */
  194. ((void)tmp);
  195. /* Add a period to guaranty minimum wait */
  196. if (Delay < LL_MAX_DELAY)
  197. {
  198. Delay++;
  199. }
  200. while (Delay)
  201. {
  202. if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  203. {
  204. Delay--;
  205. }
  206. }
  207. }
  208. /**
  209. * @}
  210. */
  211. /** @addtogroup UTILS_EF_SYSTEM
  212. * @brief System Configuration functions
  213. *
  214. @verbatim
  215. ===============================================================================
  216. ##### System Configuration functions #####
  217. ===============================================================================
  218. [..]
  219. System, AHB and APB buses clocks configuration
  220. (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
  221. @endverbatim
  222. @internal
  223. Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
  224. (++) +-----------------------------------------------+
  225. (++) | Latency | SYSCLK clock frequency (MHz) |
  226. (++) |---------------|-------------------------------|
  227. (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
  228. (++) |---------------|-------------------------------|
  229. (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
  230. (++) |---------------|-------------------------------|
  231. (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
  232. (++) +-----------------------------------------------+
  233. @endinternal
  234. * @{
  235. */
  236. /**
  237. * @brief This function sets directly SystemCoreClock CMSIS variable.
  238. * @note Variable can be calculated also through SystemCoreClockUpdate function.
  239. * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
  240. * @retval None
  241. */
  242. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  243. {
  244. /* HCLK clock frequency */
  245. SystemCoreClock = HCLKFrequency;
  246. }
  247. /**
  248. * @brief Update number of Flash wait states in line with new frequency and current
  249. voltage range.
  250. * @param Frequency SYSCLK frequency
  251. * @retval An ErrorStatus enumeration value:
  252. * - SUCCESS: Latency has been modified
  253. * - ERROR: Latency cannot be modified
  254. */
  255. #if defined(FLASH_ACR_LATENCY)
  256. ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
  257. {
  258. uint32_t timeout;
  259. uint32_t getlatency;
  260. uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
  261. ErrorStatus status = SUCCESS;
  262. /* Frequency cannot be equal to 0 */
  263. if (Frequency == 0U)
  264. {
  265. status = ERROR;
  266. }
  267. else
  268. {
  269. if (Frequency > UTILS_LATENCY2_FREQ)
  270. {
  271. /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
  272. latency = LL_FLASH_LATENCY_2;
  273. }
  274. else
  275. {
  276. if (Frequency > UTILS_LATENCY1_FREQ)
  277. {
  278. /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
  279. latency = LL_FLASH_LATENCY_1;
  280. }
  281. else
  282. {
  283. /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
  284. latency = LL_FLASH_LATENCY_0;
  285. }
  286. }
  287. if (status != ERROR)
  288. {
  289. LL_FLASH_SetLatency(latency);
  290. /* Check that the new number of wait states is taken into account to access the Flash
  291. memory by reading the FLASH_ACR register */
  292. timeout = 2;
  293. do
  294. {
  295. /* Wait for Flash latency to be updated */
  296. getlatency = LL_FLASH_GetLatency();
  297. timeout--;
  298. }
  299. while ((getlatency != latency) && (timeout > 0));
  300. if (getlatency != latency)
  301. {
  302. status = ERROR;
  303. }
  304. else
  305. {
  306. status = SUCCESS;
  307. }
  308. }
  309. }
  310. return status;
  311. }
  312. #endif /* FLASH_ACR_LATENCY */
  313. /**
  314. * @brief This function configures system clock with HSI as clock source of the PLL
  315. * @note The application need to ensure that PLL is disabled.
  316. * @note Function is based on the following formula:
  317. * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  318. * - PREDIV: Set to 2 for few devices
  319. * - PLLMUL: The application software must set correctly the PLL multiplication factor to
  320. * not exceed 72MHz
  321. * @note FLASH latency can be modified through this function.
  322. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  323. * the configuration information for the PLL.
  324. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  325. * the configuration information for the BUS prescalers.
  326. * @retval An ErrorStatus enumeration value:
  327. * - SUCCESS: Max frequency configuration done
  328. * - ERROR: Max frequency configuration not done
  329. */
  330. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  331. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  332. {
  333. ErrorStatus status = SUCCESS;
  334. uint32_t pllfreq = 0U;
  335. /* Check if one of the PLL is enabled */
  336. if (UTILS_PLL_IsBusy() == SUCCESS)
  337. {
  338. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  339. /* Check PREDIV value */
  340. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  341. #else
  342. /* Force PREDIV value to 2 */
  343. UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
  344. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  345. /* Calculate the new PLL output frequency */
  346. pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  347. /* Enable HSI if not enabled */
  348. if (LL_RCC_HSI_IsReady() != 1U)
  349. {
  350. LL_RCC_HSI_Enable();
  351. while (LL_RCC_HSI_IsReady() != 1U)
  352. {
  353. /* Wait for HSI ready */
  354. }
  355. }
  356. /* Configure PLL */
  357. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
  358. /* Enable PLL and switch system clock to PLL */
  359. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  360. }
  361. else
  362. {
  363. /* Current PLL configuration cannot be modified */
  364. status = ERROR;
  365. }
  366. return status;
  367. }
  368. /**
  369. * @brief This function configures system clock with HSE as clock source of the PLL
  370. * @note The application need to ensure that PLL is disabled.
  371. * @note Function is based on the following formula:
  372. * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  373. * - PREDIV: Set to 2 for few devices
  374. * - PLLMUL: The application software must set correctly the PLL multiplication factor to
  375. * not exceed @ref UTILS_PLL_OUTPUT_MAX
  376. * @note FLASH latency can be modified through this function.
  377. * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
  378. * @param HSEBypass This parameter can be one of the following values:
  379. * @arg @ref LL_UTILS_HSEBYPASS_ON
  380. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  381. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  382. * the configuration information for the PLL.
  383. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  384. * the configuration information for the BUS prescalers.
  385. * @retval An ErrorStatus enumeration value:
  386. * - SUCCESS: Max frequency configuration done
  387. * - ERROR: Max frequency configuration not done
  388. */
  389. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
  390. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  391. {
  392. ErrorStatus status = SUCCESS;
  393. uint32_t pllfrequency = 0U;
  394. /* Check the parameters */
  395. assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  396. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  397. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
  398. /* Calculate the new PLL output frequency */
  399. pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  400. /* Enable HSE if not enabled */
  401. status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct);
  402. /* Check if HSE is not enabled*/
  403. if (status == SUCCESS)
  404. {
  405. /* Configure PLL */
  406. LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_HSE | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
  407. /* Enable PLL and switch system clock to PLL */
  408. status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct);
  409. }
  410. return status;
  411. }
  412. #if defined(RCC_PLL2_SUPPORT)
  413. /**
  414. * @brief This function configures system clock with HSE as clock source of the PLL, via PLL2
  415. * @note The application need to ensure that PLL and PLL2 are disabled.
  416. * @note Function is based on the following formula:
  417. * - PLL output frequency = ((((HSE frequency / PREDIV2) * PLL2MUL) / PREDIV) * PLLMUL)
  418. * - PREDIV, PLLMUL, PREDIV2, PLL2MUL: The application software must set correctly the
  419. * PLL multiplication factor to not exceed @ref UTILS_PLL_OUTPUT_MAX
  420. * @note FLASH latency can be modified through this function.
  421. * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
  422. * @param HSEBypass This parameter can be one of the following values:
  423. * @arg @ref LL_UTILS_HSEBYPASS_ON
  424. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  425. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  426. * the configuration information for the PLL.
  427. * @param UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  428. * the configuration information for the PLL2.
  429. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  430. * the configuration information for the BUS prescalers.
  431. * @retval An ErrorStatus enumeration value:
  432. * - SUCCESS: Max frequency configuration done
  433. * - ERROR: Max frequency configuration not done
  434. */
  435. ErrorStatus LL_PLL_ConfigSystemClock_PLL2(uint32_t HSEFrequency, uint32_t HSEBypass,
  436. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  437. LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct,
  438. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  439. {
  440. ErrorStatus status = SUCCESS;
  441. uint32_t pllfrequency = 0U;
  442. /* Check the parameters */
  443. assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  444. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  445. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
  446. assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv));
  447. /* Calculate the new PLL output frequency */
  448. pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  449. /* Enable HSE if not enabled */
  450. status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct);
  451. /* Check if HSE is not enabled*/
  452. if (status == SUCCESS)
  453. {
  454. /* Configure PLL */
  455. LL_RCC_PLL_ConfigDomain_PLL2(UTILS_PLL2InitStruct->Prediv, UTILS_PLL2InitStruct->PLLMul);
  456. LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_PLL2 | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
  457. /* Calculate the new PLL output frequency */
  458. pllfrequency = UTILS_GetPLL2OutputFrequency(pllfrequency, UTILS_PLL2InitStruct);
  459. /* Enable PLL and switch system clock to PLL */
  460. status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct);
  461. }
  462. return status;
  463. }
  464. #endif /* RCC_PLL2_SUPPORT */
  465. /**
  466. * @}
  467. */
  468. /**
  469. * @}
  470. */
  471. /** @addtogroup UTILS_LL_Private_Functions
  472. * @{
  473. */
  474. /**
  475. * @brief Function to check that PLL can be modified
  476. * @param PLL_InputFrequency PLL input frequency (in Hz)
  477. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  478. * the configuration information for the PLL.
  479. * @retval PLL output frequency (in Hz)
  480. */
  481. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  482. {
  483. uint32_t pllfreq = 0U;
  484. /* Check the parameters */
  485. assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
  486. /* Check different PLL parameters according to RM */
  487. #if defined (RCC_CFGR2_PREDIV1)
  488. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
  489. #else
  490. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
  491. #endif /*RCC_CFGR2_PREDIV1SRC*/
  492. assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  493. return pllfreq;
  494. }
  495. /**
  496. * @brief This function enable the HSE when it is used by PLL or PLL2
  497. * @note The application need to ensure that PLL is disabled.
  498. * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
  499. * @param HSEBypass This parameter can be one of the following values:
  500. * @arg @ref LL_UTILS_HSEBYPASS_ON
  501. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  502. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  503. * the configuration information for the PLL.
  504. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  505. * the configuration information for the BUS prescalers.
  506. * @retval An ErrorStatus enumeration value:
  507. * - SUCCESS: HSE configuration done
  508. * - ERROR: HSE configuration not done
  509. */
  510. static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass,
  511. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  512. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  513. {
  514. ErrorStatus status = SUCCESS;
  515. /* Check if one of the PLL is enabled */
  516. if (UTILS_PLL_IsBusy() == SUCCESS)
  517. {
  518. /* Enable HSE if not enabled */
  519. if (LL_RCC_HSE_IsReady() != 1U)
  520. {
  521. /* Check if need to enable HSE bypass feature or not */
  522. if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  523. {
  524. LL_RCC_HSE_EnableBypass();
  525. }
  526. else
  527. {
  528. LL_RCC_HSE_DisableBypass();
  529. }
  530. /* Enable HSE */
  531. LL_RCC_HSE_Enable();
  532. while (LL_RCC_HSE_IsReady() != 1U)
  533. {
  534. /* Wait for HSE ready */
  535. }
  536. }
  537. }
  538. else
  539. {
  540. /* Current PLL configuration cannot be modified */
  541. status = ERROR;
  542. }
  543. return status;
  544. }
  545. #if defined(RCC_PLL2_SUPPORT)
  546. /**
  547. * @brief Function to check that PLL2 can be modified
  548. * @param PLL2_InputFrequency PLL2 input frequency (in Hz)
  549. * @param UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  550. * the configuration information for the PLL.
  551. * @retval PLL2 output frequency (in Hz)
  552. */
  553. static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct)
  554. {
  555. uint32_t pll2freq = 0U;
  556. /* Check the parameters */
  557. assert_param(IS_LL_UTILS_PLL2MUL_VALUE(UTILS_PLL2InitStruct->PLLMul));
  558. assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv));
  559. /* Check different PLL2 parameters according to RM */
  560. pll2freq = __LL_RCC_CALC_PLL2CLK_FREQ(PLL2_InputFrequency, UTILS_PLL2InitStruct->PLLMul, UTILS_PLL2InitStruct->Prediv);
  561. assert_param(IS_LL_UTILS_PLL2_FREQUENCY(pll2freq));
  562. return pll2freq;
  563. }
  564. #endif /* RCC_PLL2_SUPPORT */
  565. /**
  566. * @brief Function to check that PLL can be modified
  567. * @retval An ErrorStatus enumeration value:
  568. * - SUCCESS: PLL modification can be done
  569. * - ERROR: PLL is busy
  570. */
  571. static ErrorStatus UTILS_PLL_IsBusy(void)
  572. {
  573. ErrorStatus status = SUCCESS;
  574. /* Check if PLL is busy*/
  575. if (LL_RCC_PLL_IsReady() != 0U)
  576. {
  577. /* PLL configuration cannot be modified */
  578. status = ERROR;
  579. }
  580. #if defined(RCC_PLL2_SUPPORT)
  581. /* Check if PLL2 is busy*/
  582. if (LL_RCC_PLL2_IsReady() != 0U)
  583. {
  584. /* PLL2 configuration cannot be modified */
  585. status = ERROR;
  586. }
  587. #endif /* RCC_PLL2_SUPPORT */
  588. #if defined(RCC_PLLI2S_SUPPORT)
  589. /* Check if PLLI2S is busy*/
  590. if (LL_RCC_PLLI2S_IsReady() != 0U)
  591. {
  592. /* PLLI2S configuration cannot be modified */
  593. status = ERROR;
  594. }
  595. #endif /* RCC_PLLI2S_SUPPORT */
  596. return status;
  597. }
  598. /**
  599. * @brief Function to enable PLL and switch system clock to PLL
  600. * @param SYSCLK_Frequency SYSCLK frequency
  601. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  602. * the configuration information for the BUS prescalers.
  603. * @retval An ErrorStatus enumeration value:
  604. * - SUCCESS: No problem to switch system to PLL
  605. * - ERROR: Problem to switch system to PLL
  606. */
  607. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  608. {
  609. ErrorStatus status = SUCCESS;
  610. #if defined(FLASH_ACR_LATENCY)
  611. uint32_t sysclk_frequency_current = 0U;
  612. #endif /* FLASH_ACR_LATENCY */
  613. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
  614. assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  615. assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
  616. #if defined(FLASH_ACR_LATENCY)
  617. /* Calculate current SYSCLK frequency */
  618. sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
  619. #endif /* FLASH_ACR_LATENCY */
  620. /* Increasing the number of wait states because of higher CPU frequency */
  621. #if defined (FLASH_ACR_LATENCY)
  622. if (sysclk_frequency_current < SYSCLK_Frequency)
  623. {
  624. /* Set FLASH latency to highest latency */
  625. status = LL_SetFlashLatency(SYSCLK_Frequency);
  626. }
  627. #endif /* FLASH_ACR_LATENCY */
  628. /* Update system clock configuration */
  629. if (status == SUCCESS)
  630. {
  631. #if defined(RCC_PLL2_SUPPORT)
  632. if (LL_RCC_PLL_GetMainSource() != LL_RCC_PLLSOURCE_HSI_DIV_2)
  633. {
  634. /* Enable PLL2 */
  635. LL_RCC_PLL2_Enable();
  636. while (LL_RCC_PLL2_IsReady() != 1U)
  637. {
  638. /* Wait for PLL2 ready */
  639. }
  640. }
  641. #endif /* RCC_PLL2_SUPPORT */
  642. /* Enable PLL */
  643. LL_RCC_PLL_Enable();
  644. while (LL_RCC_PLL_IsReady() != 1U)
  645. {
  646. /* Wait for PLL ready */
  647. }
  648. /* Sysclk activation on the main PLL */
  649. LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
  650. LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  651. while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  652. {
  653. /* Wait for system clock switch to PLL */
  654. }
  655. /* Set APB1 & APB2 prescaler*/
  656. LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  657. LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
  658. }
  659. /* Decreasing the number of wait states because of lower CPU frequency */
  660. #if defined (FLASH_ACR_LATENCY)
  661. if (sysclk_frequency_current > SYSCLK_Frequency)
  662. {
  663. /* Set FLASH latency to lowest latency */
  664. status = LL_SetFlashLatency(SYSCLK_Frequency);
  665. }
  666. #endif /* FLASH_ACR_LATENCY */
  667. /* Update SystemCoreClock variable */
  668. if (status == SUCCESS)
  669. {
  670. LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
  671. }
  672. return status;
  673. }
  674. /**
  675. * @}
  676. */
  677. /**
  678. * @}
  679. */
  680. /**
  681. * @}
  682. */