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 FLASH latency according to HCLK Frequency */
46 #define UTILS_SCALE1_LATENCY1_FREQ  24000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1  */
47 #define UTILS_SCALE1_LATENCY2_FREQ  48000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1  */
48 /**
49   * @}
50   */
51 
52 /* Private macros ------------------------------------------------------------*/
53 /* Private function prototypes -----------------------------------------------*/
54 /* Exported functions --------------------------------------------------------*/
55 /** @addtogroup UTILS_LL_Exported_Functions
56   * @{
57   */
58 
59 /** @addtogroup UTILS_LL_EF_DELAY
60   * @{
61   */
62 
63 /**
64   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
65   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
66   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
67   * @param  HCLKFrequency HCLK frequency in Hz
68   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
69   * @retval None
70   */
LL_Init1msTick(uint32_t HCLKFrequency)71 void LL_Init1msTick(uint32_t HCLKFrequency)
72 {
73   /* Use frequency provided in argument */
74   LL_InitTick(HCLKFrequency, 1000U);
75 }
76 
77 /**
78   * @brief  This function provides accurate delay (in milliseconds) based
79   *         on SysTick counter flag
80   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
81   *         and use rather osDelay service.
82   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
83   *         will configure Systick to 1ms
84   * @param  Delay specifies the delay time length, in milliseconds.
85   * @retval None
86   */
LL_mDelay(uint32_t Delay)87 void LL_mDelay(uint32_t Delay)
88 {
89   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
90   uint32_t tmpDelay; /* MISRAC2012-Rule-17.8 */
91   /* Add this code to indicate that local variable is not used */
92   ((void)tmp);
93   tmpDelay  = Delay;
94   /* Add a period to guaranty minimum wait */
95   if (tmpDelay  < LL_MAX_DELAY)
96   {
97     tmpDelay ++;
98   }
99 
100   while (tmpDelay  != 0U)
101   {
102     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
103     {
104       tmpDelay --;
105     }
106   }
107 }
108 
109 /**
110   * @}
111   */
112 
113 /** @addtogroup UTILS_EF_SYSTEM
114   *  @brief    System Configuration functions
115   *
116   @verbatim
117  ===============================================================================
118            ##### System Configuration functions #####
119  ===============================================================================
120     [..]
121          System, AHB and APB buses clocks configuration
122 
123          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 is 48000000 Hz.
124   @endverbatim
125   @internal
126              Depending on the device voltage range, the maximum frequency should be
127              adapted accordingly:
128 
129              (++)  Table 1. HCLK clock frequency.
130              (++)  +------------------------------------+
131              (++)  | Latency         |  HCLK clock      |
132              (++)  |                 |  frequency (MHz) |
133              (++)  |                 |                  |
134              (++)  |                 |-------------------
135              (++)  |                 | voltage range 1  |
136              (++)  |                 |   1.08V - 1.32V  |
137              (++)  |-----------------|------------------|
138              (++)  |0WS(1 CPU cycles)|      HCLK <= 24  |
139              (++)  |-----------------|------------------|
140              (++)  |1WS(2 CPU cycles)|      HCLK <= 48  |
141              (++)  +------------------------------------+
142 
143   @endinternal
144   * @{
145   */
146 
147 /**
148   * @brief  This function sets directly SystemCoreClock CMSIS variable.
149   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
150   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
151   * @retval None
152   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)153 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
154 {
155   /* HCLK clock frequency */
156   SystemCoreClock = HCLKFrequency;
157 }
158 
159 /**
160   * @}
161   */
162 
163 /**
164   * @}
165   */
166 
167 /** @addtogroup UTILS_LL_Private_Functions
168   * @{
169   */
170 /**
171   * @brief  Update number of Flash wait states in line with new frequency and current
172             voltage range.
173   * @param  HCLK_Frequency  HCLK frequency
174   * @retval An ErrorStatus enumeration value:
175   *          - SUCCESS: Latency has been modified
176   *          - ERROR: Latency cannot be modified
177   */
LL_SetFlashLatency(uint32_t HCLK_Frequency)178 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
179 {
180   uint32_t timeout;
181   uint32_t getlatency;
182   uint32_t latency;
183   ErrorStatus status;
184 
185   /* Frequency cannot be equal to 0 */
186   if ((HCLK_Frequency == 0U) || (HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ))
187   {
188     status = ERROR;
189   }
190   else
191   {
192     if (HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ)
193     {
194       /* 24 < HCLK <= 48 => 1WS (2 CPU cycles) */
195       latency = LL_FLASH_LATENCY_1;
196     }
197     else
198     {
199       /* else HCLK_Frequency < 24MHz default LL_FLASH_LATENCY_0 0WS */
200       latency = LL_FLASH_LATENCY_0;
201     }
202 
203     LL_FLASH_SetLatency(latency);
204 
205     /* Check that the new number of wait states is taken into account to access the Flash
206        memory by reading the FLASH_ACR register */
207     timeout = 2;
208     do
209     {
210       /* Wait for Flash latency to be updated */
211       getlatency = LL_FLASH_GetLatency();
212       timeout--;
213     } while ((getlatency != latency) && (timeout > 0U));
214 
215     if (getlatency != latency)
216     {
217       status = ERROR;
218     }
219     else
220     {
221       status = SUCCESS;
222     }
223   }
224   return status;
225 }
226 
227 /**
228   * @}
229   */
230 
231 /**
232   * @}
233   */
234 
235 /**
236   * @}
237   */
238