1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_hal.c
4   * @author  MCD Application Team
5   * @brief   HAL module driver.
6   *          This is the common part of the HAL initialization
7   ******************************************************************************
8   * @attention
9   *
10   * Copyright (c) 2024 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   @verbatim
19   ==============================================================================
20                      ##### How to use this driver #####
21   ==============================================================================
22     [..]
23     The common HAL driver contains a set of generic and common APIs that can be
24     used by the PPP peripheral drivers and the user to start using the HAL.
25     [..]
26     The HAL contains two APIs' categories:
27          (+) Common HAL APIs
28          (+) Services HAL APIs
29 
30   @endverbatim
31   ******************************************************************************
32   */
33 
34 /* Includes ------------------------------------------------------------------*/
35 #include "stm32wb0x_hal.h"
36 
37 /** @addtogroup STM32WB0x_HAL_Driver
38   * @{
39   */
40 
41 /** @addtogroup HAL
42   * @brief HAL module driver
43   * @{
44   */
45 
46 #ifdef HAL_MODULE_ENABLED
47 
48 /* Private typedef -----------------------------------------------------------*/
49 /* Private define ------------------------------------------------------------*/
50 
51 /* Private macro -------------------------------------------------------------*/
52 /* Exported variables ---------------------------------------------------------*/
53 /** @defgroup HAL_Exported_Variables HAL Exported Variables
54   * @{
55   */
56 __IO uint32_t uwTick;
57 uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
58 HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */
59 /**
60   * @}
61   */
62 
63 /* Private function prototypes -----------------------------------------------*/
64 /* Exported functions --------------------------------------------------------*/
65 
66 /** @addtogroup HAL_Exported_Functions
67   * @{
68   */
69 
70 /** @addtogroup HAL_Exported_Functions_Group1
71   *  @brief    HAL Initialization and Configuration functions
72   *
73 @verbatim
74  ===============================================================================
75            ##### HAL Initialization and Configuration functions #####
76  ===============================================================================
77     [..]  This section provides functions allowing to:
78       (+) Initialize the Flash interface the NVIC allocation and initial time base
79           clock configuration.
80       (+) De-initialize common part of the HAL.
81       (+) Configure the time base source to have 1ms time base with a dedicated
82           Tick interrupt priority.
83         (++) SysTick timer is used by default as source of time base, but user
84              can eventually implement his proper time base source (a general purpose
85              timer for example or other time source), keeping in mind that Time base
86              duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
87              handled in milliseconds basis.
88         (++) Time base configuration function (HAL_InitTick ()) is called automatically
89              at the beginning of the program after reset by HAL_Init() or at any time
90              when clock is configured, by HAL_RCC_ClockConfig().
91         (++) Source of time base is configured  to generate interrupts at regular
92              time intervals. Care must be taken if HAL_Delay() is called from a
93              peripheral ISR process, the Tick interrupt line must have higher priority
94             (numerically lower) than the peripheral interrupt. Otherwise the caller
95             ISR process will be blocked.
96        (++) functions affecting time base configurations are declared as __weak
97              to make  override possible  in case of other  implementations in user file.
98 @endverbatim
99   * @{
100   */
101 
102 /**
103   * @brief  This function is used to initialize the HAL Library; it must be the first
104   *         instruction to be executed in the main program (before to call any other
105   *         HAL function), it performs the following:
106   *           Configures the SysTick to generate an interrupt each 1 millisecond,
107   *           which is clocked by the System Clock.
108   *           Calls the HAL_MspInit() callback function defined in user file
109   *           "stm32wb0x_hal_msp.c" to do the global low level hardware initialization
110   *
111   * @note   SysTick is used as time base for the HAL_Delay() function, the application
112   *         need to ensure that the SysTick time base is always set to 1 millisecond
113   *         to have correct HAL operation.
114   * @retval HAL status
115   */
HAL_Init(void)116 HAL_StatusTypeDef HAL_Init(void)
117 {
118   HAL_StatusTypeDef  status = HAL_OK;
119 
120   /* Use SysTick as time base source and configure 1ms tick (default clock after Reset is MSI) */
121   if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
122   {
123     status = HAL_ERROR;
124   }
125   else
126   {
127     /* Init the low level hardware */
128     HAL_MspInit();
129   }
130 
131   /* Return function status */
132   return status;
133 }
134 
135 /**
136   * @brief  This function de-Initializes common part of the HAL and stops the source of time base.
137   * @note   This function is optional.
138   * @retval HAL status
139   */
HAL_DeInit(void)140 HAL_StatusTypeDef HAL_DeInit(void)
141 {
142   /* Reset of all peripherals */
143   __HAL_RCC_AHB1_FORCE_RESET();
144   __HAL_RCC_AHB1_RELEASE_RESET();
145 
146   __HAL_RCC_APB0_FORCE_RESET();
147   __HAL_RCC_APB0_RELEASE_RESET();
148 
149   __HAL_RCC_APB1_FORCE_RESET();
150   __HAL_RCC_APB1_RELEASE_RESET();
151 
152   __HAL_RCC_APB2_FORCE_RESET();
153   __HAL_RCC_APB2_RELEASE_RESET();
154 
155   /* De-Init the low level hardware */
156   HAL_MspDeInit();
157 
158   /* Return function status */
159   return HAL_OK;
160 }
161 
162 /**
163   * @brief  Initialize the MSP.
164   * @retval None
165   */
HAL_MspInit(void)166 __weak void HAL_MspInit(void)
167 {
168   /* NOTE : This function should not be modified, when the callback is needed,
169             the HAL_MspInit could be implemented in the user file
170    */
171 }
172 
173 /**
174   * @brief  DeInitializes the MSP.
175   * @retval None
176   */
HAL_MspDeInit(void)177 __weak void HAL_MspDeInit(void)
178 {
179   /* NOTE : This function should not be modified, when the callback is needed,
180             the HAL_MspDeInit could be implemented in the user file
181    */
182 }
183 
184 /**
185   * @brief This function configures the source of the time base:
186   *        The time source is configured  to have 1ms time base with a dedicated
187   *        Tick interrupt priority.
188   * @note This function is called  automatically at the beginning of program after
189   *       reset by HAL_Init() or at any time when clock is reconfigured  by HAL_RCC_ClockConfig().
190   * @note In the default implementation, SysTick timer is the source of time base.
191   *       It is used to generate interrupts at regular time intervals.
192   *       Care must be taken if HAL_Delay() is called from a peripheral ISR process,
193   *       The SysTick interrupt must have higher priority (numerically lower)
194   *       than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
195   *       The function is declared as __weak  to be overwritten  in case of other
196   *       implementation  in user file.
197   * @param TickPriority Tick interrupt priority.
198   * @retval HAL status
199   */
HAL_InitTick(uint32_t TickPriority)200 __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
201 {
202   HAL_StatusTypeDef  status = HAL_OK;
203 
204   if (uwTickFreq != 0U)
205   {
206     /*Configure the SysTick to have interrupt in 1ms time basis*/
207     if (HAL_SYSTICK_Config(HAL_RCC_GetSysClockFreq() / (1000U / uwTickFreq)) == 0U)
208     {
209       /* Configure the SysTick IRQ priority */
210       if (TickPriority < (1UL << __NVIC_PRIO_BITS))
211       {
212         HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0);
213         uwTickPrio = TickPriority;
214       }
215       else
216       {
217         status = HAL_ERROR;
218       }
219     }
220     else
221     {
222       status = HAL_ERROR;
223     }
224   }
225   else
226   {
227     status = HAL_ERROR;
228   }
229 
230   /* Return function status */
231   return status;
232 }
233 
234 /**
235   * @}
236   */
237 
238 /** @addtogroup HAL_Exported_Functions_Group2
239   *  @brief    HAL Control functions
240   *
241 @verbatim
242  ===============================================================================
243                       ##### HAL Control functions #####
244  ===============================================================================
245     [..]  This section provides functions allowing to:
246       (+) Provide a tick value in millisecond
247       (+) Provide a blocking delay in millisecond
248       (+) Suspend the time base source interrupt
249       (+) Resume the time base source interrupt
250       (+) Get the HAL API driver version
251       (+) Get the device revision identifier
252       (+) Get the device identifier
253       (+) Get the unique device identifier
254 
255 @endverbatim
256   * @{
257   */
258 
259 /**
260   * @brief This function is called to increment  a global variable "uwTick"
261   *        used as application time base.
262   * @note In the default implementation, this variable is incremented each 1ms
263   *       in SysTick ISR.
264   * @note This function is declared as __weak to be overwritten in case of other
265   *      implementations in user file.
266   * @retval None
267   */
HAL_IncTick(void)268 __weak void HAL_IncTick(void)
269 {
270   uwTick += (uint32_t)uwTickFreq;
271 }
272 
273 /**
274   * @brief Provides a tick value in millisecond.
275   * @note This function is declared as __weak to be overwritten in case of other
276   *       implementations in user file.
277   * @retval tick value
278   */
HAL_GetTick(void)279 __weak uint32_t HAL_GetTick(void)
280 {
281   return uwTick;
282 }
283 
284 /**
285   * @brief This function returns a tick priority.
286   * @retval tick priority
287   */
HAL_GetTickPrio(void)288 uint32_t HAL_GetTickPrio(void)
289 {
290   return uwTickPrio;
291 }
292 
293 /**
294   * @brief Set new tick Freq.
295   * @retval Status
296   */
HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)297 HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
298 {
299   HAL_StatusTypeDef status  = HAL_OK;
300   assert_param(IS_TICKFREQ(Freq));
301 
302   if (uwTickFreq != Freq)
303   {
304     uwTickFreq = Freq;
305 
306     /* Apply the new tick Freq  */
307     status = HAL_InitTick(uwTickPrio);
308   }
309 
310   return status;
311 }
312 
313 /**
314   * @brief Return tick frequency.
315   * @retval tick period in Hz
316   */
HAL_GetTickFreq(void)317 HAL_TickFreqTypeDef HAL_GetTickFreq(void)
318 {
319   return uwTickFreq;
320 }
321 
322 /**
323   * @brief This function provides minimum delay (in milliseconds) based
324   *        on variable incremented.
325   * @note In the default implementation , SysTick timer is the source of time base.
326   *       It is used to generate interrupts at regular time intervals where uwTick
327   *       is incremented.
328   * @note This function is declared as __weak to be overwritten in case of other
329   *       implementations in user file.
330   * @param Delay  specifies the delay time length, in milliseconds.
331   * @retval None
332   */
HAL_Delay(uint32_t Delay)333 __weak void HAL_Delay(uint32_t Delay)
334 {
335   uint32_t tickstart = HAL_GetTick();
336   uint32_t wait = Delay;
337 
338   /* Add a freq to guarantee minimum wait */
339   if (wait < HAL_MAX_DELAY)
340   {
341     wait += (uint32_t)(uwTickFreq);
342   }
343 
344   while ((HAL_GetTick() - tickstart) < wait)
345   {
346   }
347 }
348 
349 
350 /**
351   * @brief Suspend Tick increment.
352   * @note In the default implementation , SysTick timer is the source of time base. It is
353   *       used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
354   *       is called, the SysTick interrupt will be disabled and so Tick increment
355   *       is suspended.
356   * @note This function is declared as __weak to be overwritten in case of other
357   *       implementations in user file.
358   * @retval None
359   */
HAL_SuspendTick(void)360 __weak void HAL_SuspendTick(void)
361 {
362   /* Disable SysTick Interrupt */
363   CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
364 }
365 
366 /**
367   * @brief Resume Tick increment.
368   * @note In the default implementation , SysTick timer is the source of time base. It is
369   *       used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
370   *       is called, the SysTick interrupt will be enabled and so Tick increment
371   *       is resumed.
372   * @note This function is declared as __weak to be overwritten in case of other
373   *       implementations in user file.
374   * @retval None
375   */
HAL_ResumeTick(void)376 __weak void HAL_ResumeTick(void)
377 {
378   /* Enable SysTick Interrupt */
379   SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
380 }
381 
382 /**
383   * @brief  Returns the HAL revision
384   * @retval version : 0xXYZR (8bits for each decimal, R for RC)
385   */
HAL_GetHalVersion(void)386 uint32_t HAL_GetHalVersion(void)
387 {
388   return __STM32WB0x_HAL_VERSION;
389 }
390 
391 /**
392   * @brief  Returns the device revision identifier.
393   * @retval Device revision identifier
394   */
HAL_GetREVID(void)395 uint32_t HAL_GetREVID(void)
396 {
397   return (LL_SYSCFG_GetDeviceRevision());
398 }
399 
400 /**
401   * @brief  Returns the device revision identifier.
402   * @retval Device revision identifier
403   */
HAL_GetVERID(void)404 uint32_t HAL_GetVERID(void)
405 {
406   return (LL_SYSCFG_GetDeviceVersion());
407 }
408 
409 /**
410   * @brief  Returns the device device identifier.
411   * @retval Device identifier
412   */
HAL_GetDEVID(void)413 uint32_t HAL_GetDEVID(void)
414 {
415   return (LL_SYSCFG_GetDeviceID());
416 }
417 
418 /**
419   * @brief  Returns the Jtag device identifier.
420   * @retval Device identifier
421   */
HAL_GetJTAGID(void)422 uint32_t HAL_GetJTAGID(void)
423 {
424   return (LL_SYSCFG_GetDeviceJTAG_ID());
425 }
426 
427 /**
428   * @brief  Return the first word of the unique device identifier (UID based on 64 bits)
429   * @retval Device identifier
430   */
HAL_GetUIDw0(void)431 uint32_t HAL_GetUIDw0(void)
432 {
433   return (READ_REG(*((uint32_t *)UID64_BASE)));
434 }
435 
436 /**
437   * @brief  Return the second word of the unique device identifier (UID based on 64 bits)
438   * @retval Device identifier
439   */
HAL_GetUIDw1(void)440 uint32_t HAL_GetUIDw1(void)
441 {
442   return (READ_REG(*((uint32_t *)(UID64_BASE + 4U))));
443 }
444 
445 
446 /**
447   * @}
448   */
449 
450 /**
451   * @}
452   */
453 
454 #endif /* HAL_MODULE_ENABLED */
455 /**
456   * @}
457   */
458 
459 /**
460   * @}
461   */
462