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.
 
 
 

621 lines
24 KiB

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