stm32f1xx_ll_utils.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_ll_utils.c
  4. * @author MCD Application Team
  5. * @version V1.1.1
  6. * @date 12-May-2017
  7. * @brief UTILS LL module driver.
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  12. *
  13. * Redistribution and use in source and binary forms, with or without modification,
  14. * are permitted provided that the following conditions are met:
  15. * 1. Redistributions of source code must retain the above copyright notice,
  16. * this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright notice,
  18. * this list of conditions and the following disclaimer in the documentation
  19. * and/or other materials provided with the distribution.
  20. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  21. * may be used to endorse or promote products derived from this software
  22. * without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  31. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  32. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  33. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. ******************************************************************************
  36. */
  37. /* Includes ------------------------------------------------------------------*/
  38. #include "stm32f1xx_ll_rcc.h"
  39. #include "stm32f1xx_ll_utils.h"
  40. #include "stm32f1xx_ll_system.h"
  41. #ifdef USE_FULL_ASSERT
  42. #include "stm32_assert.h"
  43. #else
  44. #define assert_param(expr) ((void)0U)
  45. #endif
  46. /** @addtogroup STM32F1xx_LL_Driver
  47. * @{
  48. */
  49. /** @addtogroup UTILS_LL
  50. * @{
  51. */
  52. /* Private types -------------------------------------------------------------*/
  53. /* Private variables ---------------------------------------------------------*/
  54. /* Private constants ---------------------------------------------------------*/
  55. /** @addtogroup UTILS_LL_Private_Constants
  56. * @{
  57. */
  58. /* Defines used for PLL range */
  59. #define UTILS_PLL_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL output, in Hz */
  60. /* Defines used for HSE range */
  61. #define UTILS_HSE_FREQUENCY_MIN RCC_HSE_MIN /*!< Frequency min for HSE frequency, in Hz */
  62. #define UTILS_HSE_FREQUENCY_MAX RCC_HSE_MAX /*!< Frequency max for HSE frequency, in Hz */
  63. /* Defines used for FLASH latency according to HCLK Frequency */
  64. #if defined(FLASH_ACR_LATENCY)
  65. #define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */
  66. #define UTILS_LATENCY2_FREQ 48000000U /*!< SYSCLK frequency to set FLASH latency 2 */
  67. #else
  68. /*!< No Latency Configuration in this device */
  69. #endif
  70. /**
  71. * @}
  72. */
  73. /* Private macros ------------------------------------------------------------*/
  74. /** @addtogroup UTILS_LL_Private_Macros
  75. * @{
  76. */
  77. #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
  78. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
  79. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
  80. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
  81. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
  82. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
  83. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
  84. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
  85. || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
  86. #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
  87. || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
  88. || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
  89. || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
  90. || ((__VALUE__) == LL_RCC_APB1_DIV_16))
  91. #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
  92. || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
  93. || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
  94. || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
  95. || ((__VALUE__) == LL_RCC_APB2_DIV_16))
  96. #if defined(RCC_CFGR_PLLMULL6_5)
  97. #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \
  98. || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
  99. || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
  100. || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
  101. || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
  102. || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
  103. || ((__VALUE__) == LL_RCC_PLL_MUL_6_5))
  104. #else
  105. #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
  106. || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
  107. || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
  108. || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
  109. || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
  110. || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
  111. || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
  112. || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
  113. || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
  114. || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
  115. || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
  116. || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
  117. || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
  118. || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
  119. || ((__VALUE__) == LL_RCC_PLL_MUL_16))
  120. #endif /* RCC_CFGR_PLLMULL6_5 */
  121. #if defined(RCC_CFGR2_PREDIV1)
  122. #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \
  123. ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \
  124. ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \
  125. ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \
  126. ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \
  127. ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \
  128. ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \
  129. ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
  130. #else
  131. #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2))
  132. #endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/
  133. #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)
  134. #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
  135. || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
  136. #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
  137. /**
  138. * @}
  139. */
  140. /* Private function prototypes -----------------------------------------------*/
  141. /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
  142. * @{
  143. */
  144. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
  145. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
  146. #if defined(FLASH_ACR_LATENCY)
  147. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
  148. #endif /* FLASH_ACR_LATENCY */
  149. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
  150. static ErrorStatus UTILS_PLL_IsBusy(void);
  151. /**
  152. * @}
  153. */
  154. /* Exported functions --------------------------------------------------------*/
  155. /** @addtogroup UTILS_LL_Exported_Functions
  156. * @{
  157. */
  158. /** @addtogroup UTILS_LL_EF_DELAY
  159. * @{
  160. */
  161. /**
  162. * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
  163. * @note When a RTOS is used, it is recommended to avoid changing the Systick
  164. * configuration by calling this function, for a delay use rather osDelay RTOS service.
  165. * @param HCLKFrequency HCLK frequency in Hz
  166. * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
  167. * @retval None
  168. */
  169. void LL_Init1msTick(uint32_t HCLKFrequency)
  170. {
  171. /* Use frequency provided in argument */
  172. LL_InitTick(HCLKFrequency, 1000U);
  173. }
  174. /**
  175. * @brief This function provides accurate delay (in milliseconds) based
  176. * on SysTick counter flag
  177. * @note When a RTOS is used, it is recommended to avoid using blocking delay
  178. * and use rather osDelay service.
  179. * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
  180. * will configure Systick to 1ms
  181. * @param Delay specifies the delay time length, in milliseconds.
  182. * @retval None
  183. */
  184. void LL_mDelay(uint32_t Delay)
  185. {
  186. __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
  187. /* Add this code to indicate that local variable is not used */
  188. ((void)tmp);
  189. /* Add a period to guaranty minimum wait */
  190. if (Delay < LL_MAX_DELAY)
  191. {
  192. Delay++;
  193. }
  194. while (Delay)
  195. {
  196. if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
  197. {
  198. Delay--;
  199. }
  200. }
  201. }
  202. /**
  203. * @}
  204. */
  205. /** @addtogroup UTILS_EF_SYSTEM
  206. * @brief System Configuration functions
  207. *
  208. @verbatim
  209. ===============================================================================
  210. ##### System Configuration functions #####
  211. ===============================================================================
  212. [..]
  213. System, AHB and APB buses clocks configuration
  214. (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
  215. @endverbatim
  216. @internal
  217. Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
  218. (++) +-----------------------------------------------+
  219. (++) | Latency | SYSCLK clock frequency (MHz) |
  220. (++) |---------------|-------------------------------|
  221. (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
  222. (++) |---------------|-------------------------------|
  223. (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
  224. (++) |---------------|-------------------------------|
  225. (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
  226. (++) +-----------------------------------------------+
  227. @endinternal
  228. * @{
  229. */
  230. /**
  231. * @brief This function sets directly SystemCoreClock CMSIS variable.
  232. * @note Variable can be calculated also through SystemCoreClockUpdate function.
  233. * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
  234. * @retval None
  235. */
  236. void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
  237. {
  238. /* HCLK clock frequency */
  239. SystemCoreClock = HCLKFrequency;
  240. }
  241. /**
  242. * @brief This function configures system clock with HSI as clock source of the PLL
  243. * @note The application need to ensure that PLL is disabled.
  244. * @note Function is based on the following formula:
  245. * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  246. * - PREDIV: Set to 2 for few devices
  247. * - PLLMUL: The application software must set correctly the PLL multiplication factor to
  248. * not exceed 72MHz
  249. * @note FLASH latency can be modified through this function.
  250. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  251. * the configuration information for the PLL.
  252. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  253. * the configuration information for the BUS prescalers.
  254. * @retval An ErrorStatus enumeration value:
  255. * - SUCCESS: Max frequency configuration done
  256. * - ERROR: Max frequency configuration not done
  257. */
  258. ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
  259. LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  260. {
  261. ErrorStatus status = SUCCESS;
  262. uint32_t pllfreq = 0U;
  263. /* Check if one of the PLL is enabled */
  264. if (UTILS_PLL_IsBusy() == SUCCESS)
  265. {
  266. #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
  267. /* Check PREDIV value */
  268. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
  269. #else
  270. /* Force PREDIV value to 2 */
  271. UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
  272. #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
  273. /* Calculate the new PLL output frequency */
  274. pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
  275. /* Enable HSI if not enabled */
  276. if (LL_RCC_HSI_IsReady() != 1U)
  277. {
  278. LL_RCC_HSI_Enable();
  279. while (LL_RCC_HSI_IsReady() != 1U)
  280. {
  281. /* Wait for HSI ready */
  282. }
  283. }
  284. /* Configure PLL */
  285. LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
  286. /* Enable PLL and switch system clock to PLL */
  287. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  288. }
  289. else
  290. {
  291. /* Current PLL configuration cannot be modified */
  292. status = ERROR;
  293. }
  294. return status;
  295. }
  296. /**
  297. * @brief This function configures system clock with HSE as clock source of the PLL
  298. * @note The application need to ensure that PLL is disabled.
  299. * @note Function is based on the following formula:
  300. * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
  301. * - PREDIV: Set to 2 for few devices
  302. * - PLLMUL: The application software must set correctly the PLL multiplication factor to
  303. * not exceed @ref UTILS_PLL_OUTPUT_MAX
  304. * @note FLASH latency can be modified through this function.
  305. * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
  306. * @param HSEBypass This parameter can be one of the following values:
  307. * @arg @ref LL_UTILS_HSEBYPASS_ON
  308. * @arg @ref LL_UTILS_HSEBYPASS_OFF
  309. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  310. * the configuration information for the PLL.
  311. * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
  312. * the configuration information for the BUS prescalers.
  313. * @retval An ErrorStatus enumeration value:
  314. * - SUCCESS: Max frequency configuration done
  315. * - ERROR: Max frequency configuration not done
  316. */
  317. ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
  318. LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  319. {
  320. ErrorStatus status = SUCCESS;
  321. uint32_t pllfreq = 0U;
  322. /* Check the parameters */
  323. assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
  324. assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
  325. /* Check if one of the PLL is enabled */
  326. if (UTILS_PLL_IsBusy() == SUCCESS)
  327. {
  328. assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
  329. /* Calculate the new PLL output frequency */
  330. pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
  331. /* Enable HSE if not enabled */
  332. if (LL_RCC_HSE_IsReady() != 1U)
  333. {
  334. /* Check if need to enable HSE bypass feature or not */
  335. if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
  336. {
  337. LL_RCC_HSE_EnableBypass();
  338. }
  339. else
  340. {
  341. LL_RCC_HSE_DisableBypass();
  342. }
  343. /* Enable HSE */
  344. LL_RCC_HSE_Enable();
  345. while (LL_RCC_HSE_IsReady() != 1U)
  346. {
  347. /* Wait for HSE ready */
  348. }
  349. }
  350. /* Configure PLL */
  351. LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
  352. /* Enable PLL and switch system clock to PLL */
  353. status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
  354. }
  355. else
  356. {
  357. /* Current PLL configuration cannot be modified */
  358. status = ERROR;
  359. }
  360. return status;
  361. }
  362. /**
  363. * @}
  364. */
  365. /**
  366. * @}
  367. */
  368. /** @addtogroup UTILS_LL_Private_Functions
  369. * @{
  370. */
  371. /**
  372. * @brief Update number of Flash wait states in line with new frequency and current
  373. voltage range.
  374. * @param Frequency SYSCLK frequency
  375. * @retval An ErrorStatus enumeration value:
  376. * - SUCCESS: Latency has been modified
  377. * - ERROR: Latency cannot be modified
  378. */
  379. #if defined(FLASH_ACR_LATENCY)
  380. static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
  381. {
  382. ErrorStatus status = SUCCESS;
  383. uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
  384. /* Frequency cannot be equal to 0 */
  385. if (Frequency == 0U)
  386. {
  387. status = ERROR;
  388. }
  389. else
  390. {
  391. if (Frequency > UTILS_LATENCY2_FREQ)
  392. {
  393. /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
  394. latency = LL_FLASH_LATENCY_2;
  395. }
  396. else
  397. {
  398. if (Frequency > UTILS_LATENCY1_FREQ)
  399. {
  400. /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
  401. latency = LL_FLASH_LATENCY_1;
  402. }
  403. /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
  404. }
  405. LL_FLASH_SetLatency(latency);
  406. /* Check that the new number of wait states is taken into account to access the Flash
  407. memory by reading the FLASH_ACR register */
  408. if (LL_FLASH_GetLatency() != latency)
  409. {
  410. status = ERROR;
  411. }
  412. }
  413. return status;
  414. }
  415. #endif /* FLASH_ACR_LATENCY */
  416. /**
  417. * @brief Function to check that PLL can be modified
  418. * @param PLL_InputFrequency PLL input frequency (in Hz)
  419. * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
  420. * the configuration information for the PLL.
  421. * @retval PLL output frequency (in Hz)
  422. */
  423. static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
  424. {
  425. uint32_t pllfreq = 0U;
  426. /* Check the parameters */
  427. assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
  428. /* Check different PLL parameters according to RM */
  429. #if defined (RCC_CFGR2_PREDIV1)
  430. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
  431. #elif defined(RCC_CFGR2_PREDIV1SRC)
  432. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
  433. #else
  434. pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
  435. #endif /*RCC_CFGR2_PREDIV1SRC*/
  436. assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
  437. return pllfreq;
  438. }
  439. /**
  440. * @brief Function to check that PLL can be modified
  441. * @retval An ErrorStatus enumeration value:
  442. * - SUCCESS: PLL modification can be done
  443. * - ERROR: PLL is busy
  444. */
  445. static ErrorStatus UTILS_PLL_IsBusy(void)
  446. {
  447. ErrorStatus status = SUCCESS;
  448. /* Check if PLL is busy*/
  449. if (LL_RCC_PLL_IsReady() != 0U)
  450. {
  451. /* PLL configuration cannot be modified */
  452. status = ERROR;
  453. }
  454. #if defined(RCC_PLL2_SUPPORT)
  455. /* Check if PLL2 is busy*/
  456. if (LL_RCC_PLL2_IsReady() != 0U)
  457. {
  458. /* PLL2 configuration cannot be modified */
  459. status = ERROR;
  460. }
  461. #endif /* RCC_PLL2_SUPPORT */
  462. #if defined(RCC_PLLI2S_SUPPORT)
  463. /* Check if PLLI2S is busy*/
  464. if (LL_RCC_PLLI2S_IsReady() != 0U)
  465. {
  466. /* PLLI2S configuration cannot be modified */
  467. status = ERROR;
  468. }
  469. #endif /* RCC_PLLI2S_SUPPORT */
  470. return status;
  471. }
  472. /**
  473. * @brief Function to enable PLL and switch system clock to PLL
  474. * @param SYSCLK_Frequency SYSCLK frequency
  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: No problem to switch system to PLL
  479. * - ERROR: Problem to switch system to PLL
  480. */
  481. static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
  482. {
  483. ErrorStatus status = SUCCESS;
  484. #if defined(FLASH_ACR_LATENCY)
  485. uint32_t sysclk_frequency_current = 0U;
  486. #endif /* FLASH_ACR_LATENCY */
  487. assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
  488. assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
  489. assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
  490. #if defined(FLASH_ACR_LATENCY)
  491. /* Calculate current SYSCLK frequency */
  492. sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
  493. #endif /* FLASH_ACR_LATENCY */
  494. /* Increasing the number of wait states because of higher CPU frequency */
  495. #if defined (FLASH_ACR_LATENCY)
  496. if (sysclk_frequency_current < SYSCLK_Frequency)
  497. {
  498. /* Set FLASH latency to highest latency */
  499. status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  500. }
  501. #endif /* FLASH_ACR_LATENCY */
  502. /* Update system clock configuration */
  503. if (status == SUCCESS)
  504. {
  505. #if defined(RCC_PLL2_SUPPORT)
  506. /* Enable PLL2 */
  507. LL_RCC_PLL2_Enable();
  508. while (LL_RCC_PLL2_IsReady() != 1U)
  509. {
  510. /* Wait for PLL2 ready */
  511. }
  512. #endif /* RCC_PLL2_SUPPORT */
  513. /* Enable PLL */
  514. LL_RCC_PLL_Enable();
  515. while (LL_RCC_PLL_IsReady() != 1U)
  516. {
  517. /* Wait for PLL ready */
  518. }
  519. /* Sysclk activation on the main PLL */
  520. LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
  521. LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  522. while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  523. {
  524. /* Wait for system clock switch to PLL */
  525. }
  526. /* Set APB1 & APB2 prescaler*/
  527. LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
  528. LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
  529. }
  530. /* Decreasing the number of wait states because of lower CPU frequency */
  531. #if defined (FLASH_ACR_LATENCY)
  532. if (sysclk_frequency_current > SYSCLK_Frequency)
  533. {
  534. /* Set FLASH latency to lowest latency */
  535. status = UTILS_SetFlashLatency(SYSCLK_Frequency);
  536. }
  537. #endif /* FLASH_ACR_LATENCY */
  538. /* Update SystemCoreClock variable */
  539. if (status == SUCCESS)
  540. {
  541. LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
  542. }
  543. return status;
  544. }
  545. /**
  546. * @}
  547. */
  548. /**
  549. * @}
  550. */
  551. /**
  552. * @}
  553. */
  554. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/