1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2022 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 "stm32c0xx_ll_utils.h"
20 #include "stm32c0xx_ll_rcc.h"
21 #include "stm32c0xx_ll_system.h"
22 #include "stm32c0xx_ll_pwr.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32C0xx_LL_Driver
30   * @{
31   */
32 
33 /** @addtogroup UTILS_LL
34   * @{
35   */
36 
37 /* Private types -------------------------------------------------------------*/
38 /* Private variables ---------------------------------------------------------*/
39 /* Private constants ---------------------------------------------------------*/
40 /** @addtogroup UTILS_LL_Private_Constants
41   * @{
42   */
43 #define UTILS_MAX_FREQUENCY          48000000U     /*!< Maximum frequency for system clock, in Hz */
44 
45 /* Defines used for HSE range */
46 #define UTILS_HSE_FREQUENCY_MIN      4000000U      /*!< Frequency min for HSE frequency, in Hz   */
47 #define UTILS_HSE_FREQUENCY_MAX      48000000U     /*!< Frequency max for HSE frequency, in Hz   */
48 
49 /* Defines used for FLASH latency according to HCLK Frequency */
50 #define UTILS_SCALE1_LATENCY1_FREQ  24000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1  */
51 #define UTILS_SCALE1_LATENCY2_FREQ  48000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1  */
52 /**
53   * @}
54   */
55 
56 /* Private macros ------------------------------------------------------------*/
57 /** @addtogroup UTILS_LL_Private_Macros
58   * @{
59   */
60 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_HCLK_DIV_1)    \
61                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_2)   \
62                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_4)   \
63                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_8)   \
64                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_16)  \
65                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_64)  \
66                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_128) \
67                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_256) \
68                                            || ((__VALUE__) == LL_RCC_HCLK_DIV_512))
69 
70 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
71                                          || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
72                                          || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
73                                          || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
74                                          || ((__VALUE__) == LL_RCC_APB1_DIV_16))
75 
76 #define IS_LL_UTILS_HSI_DIV(__VALUE__)  (((__VALUE__) == LL_RCC_HSI_DIV_1)  \
77                                          || ((__VALUE__) == LL_RCC_HSI_DIV_2)  \
78                                          || ((__VALUE__) == LL_RCC_HSI_DIV_4)  \
79                                          || ((__VALUE__) == LL_RCC_HSI_DIV_8)  \
80                                          || ((__VALUE__) == LL_RCC_HSI_DIV_16) \
81                                          || ((__VALUE__) == LL_RCC_HSI_DIV_32) \
82                                          || ((__VALUE__) == LL_RCC_HSI_DIV_64) \
83                                          || ((__VALUE__) == LL_RCC_HSI_DIV_128))
84 
85 #define IS_LL_UTILS_HSIKER_DIV(__VALUE__)  (((__VALUE__) == LL_RCC_HSIKER_DIV_1)  \
86                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_2)  \
87                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_3)  \
88                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_4)  \
89                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_5) \
90                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_6) \
91                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_7) \
92                                             || ((__VALUE__) == LL_RCC_HSIKER_DIV_8))
93 
94 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
95                                            || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
96 
97 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN)\
98                                                   && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
99 /**
100   * @}
101   */
102 /* Private function prototypes -----------------------------------------------*/
103 /* Exported functions --------------------------------------------------------*/
104 /** @addtogroup UTILS_LL_Exported_Functions
105   * @{
106   */
107 
108 /** @addtogroup UTILS_LL_EF_DELAY
109   * @{
110   */
111 
112 /**
113   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
114   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
115   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
116   * @param  HCLKFrequency HCLK frequency in Hz
117   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
118   * @retval None
119   */
LL_Init1msTick(uint32_t HCLKFrequency)120 void LL_Init1msTick(uint32_t HCLKFrequency)
121 {
122   /* Use frequency provided in argument */
123   LL_InitTick(HCLKFrequency, 1000U);
124 }
125 
126 /**
127   * @brief  This function provides accurate delay (in milliseconds) based
128   *         on SysTick counter flag
129   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
130   *         and use rather osDelay service.
131   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
132   *         will configure Systick to 1ms
133   * @param  Delay specifies the delay time length, in milliseconds.
134   * @retval None
135   */
LL_mDelay(uint32_t Delay)136 void LL_mDelay(uint32_t Delay)
137 {
138   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
139   uint32_t tmpDelay; /* MISRAC2012-Rule-17.8 */
140   /* Add this code to indicate that local variable is not used */
141   ((void)tmp);
142   tmpDelay  = Delay;
143   /* Add a period to guaranty minimum wait */
144   if (tmpDelay  < LL_MAX_DELAY)
145   {
146     tmpDelay ++;
147   }
148 
149   while (tmpDelay  != 0U)
150   {
151     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
152     {
153       tmpDelay --;
154     }
155   }
156 }
157 
158 /**
159   * @}
160   */
161 
162 /** @addtogroup UTILS_EF_SYSTEM
163   *  @brief    System Configuration functions
164   *
165   @verbatim
166  ===============================================================================
167            ##### System Configuration functions #####
168  ===============================================================================
169     [..]
170          System, AHB and APB buses clocks configuration
171 
172          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 is 48000000 Hz.
173   @endverbatim
174   @internal
175              Depending on the device voltage range, the maximum frequency should be
176              adapted accordingly:
177 
178              (++)  Table 1. HCLK clock frequency.
179              (++)  +------------------------------------+
180              (++)  | Latency         |  HCLK clock      |
181              (++)  |                 |  frequency (MHz) |
182              (++)  |                 |                  |
183              (++)  |                 |-------------------
184              (++)  |                 | voltage range 1  |
185              (++)  |                 |   1.08V - 1.32V  |
186              (++)  |-----------------|------------------|
187              (++)  |0WS(1 CPU cycles)|      HCLK <= 24  |
188              (++)  |-----------------|------------------|
189              (++)  |1WS(2 CPU cycles)|      HCLK <= 48  |
190              (++)  +------------------------------------+
191 
192   @endinternal
193   * @{
194   */
195 
196 /**
197   * @brief  This function sets directly SystemCoreClock CMSIS variable.
198   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
199   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
200   * @retval None
201   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)202 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
203 {
204   /* HCLK clock frequency */
205   SystemCoreClock = HCLKFrequency;
206 }
207 
208 
209 
210 /**
211   * @}
212   */
213 
214 /**
215   * @}
216   */
217 
218 /** @addtogroup UTILS_LL_Private_Functions
219   * @{
220   */
221 /**
222   * @brief  Update number of Flash wait states in line with new frequency and current
223             voltage range.
224   * @param  HCLK_Frequency  HCLK frequency
225   * @retval An ErrorStatus enumeration value:
226   *          - SUCCESS: Latency has been modified
227   *          - ERROR: Latency cannot be modified
228   */
LL_SetFlashLatency(uint32_t HCLK_Frequency)229 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
230 {
231   uint32_t timeout;
232   uint32_t getlatency;
233   uint32_t latency;
234   ErrorStatus status;
235 
236   /* Frequency cannot be equal to 0 */
237   if ((HCLK_Frequency == 0U) || (HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ))
238   {
239     status = ERROR;
240   }
241   else
242   {
243     if (HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ)
244     {
245       /* 24 < HCLK <= 48 => 1WS (2 CPU cycles) */
246       latency = LL_FLASH_LATENCY_1;
247     }
248     else
249     {
250       /* else HCLK_Frequency < 24MHz default LL_FLASH_LATENCY_0 0WS */
251       latency = LL_FLASH_LATENCY_0;
252     }
253 
254     LL_FLASH_SetLatency(latency);
255 
256     /* Check that the new number of wait states is taken into account to access the Flash
257        memory by reading the FLASH_ACR register */
258     timeout = 2;
259     do
260     {
261       /* Wait for Flash latency to be updated */
262       getlatency = LL_FLASH_GetLatency();
263       timeout--;
264     } while ((getlatency != latency) && (timeout > 0U));
265 
266     if(getlatency != latency)
267     {
268       status = ERROR;
269     }
270     else
271     {
272       status = SUCCESS;
273     }
274   }
275   return status;
276 }
277 
278 
279 /**
280   * @}
281   */
282 
283 /**
284   * @}
285   */
286 
287 /**
288   * @}
289   */
290