1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_hal_radio_timer.h
4   * @author  GPM WBL Application Team
5   * @brief   Radio Timer HAL module
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2024 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 
19 /* Define to prevent recursive inclusion -------------------------------------*/
20 #ifndef STM32WB0x_HAL_RADIO_TIMER_H
21 #define STM32WB0x_HAL_RADIO_TIMER_H
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /* Includes ------------------------------------------------------------------*/
28 #include <stdint.h>
29 #include <stdbool.h>
30 #include "stm32wb0x_hal_def.h"
31 #include "stm32wb0x_ll_radio_timer.h"
32 #include "stm32wb0x_hal_pwr.h"
33 
34 /** @addtogroup STM32WB0x_HAL_Driver
35   * @{
36   */
37 
38 /** @addtogroup RADIO_TIMER
39   * @{
40   */
41 
42 /* Exported types ------------------------------------------------------------*/
43 
44 /** @defgroup RADIO_TIMER_Exported_Types Radio Timer Exported Types
45   * @{
46   */
47 
48 /**
49   * @brief RADIO TIMER Init Structure definition
50   */
51 typedef struct
52 {
53   uint16_t XTAL_StartupTime;             /*!< XTAL startup in 2.44 us unit */
54   bool enableInitialCalibration;         /*!< Enable initial estimation of the frequency of the
55             * Low Speed Oscillator, otherwise it will be assumed
56             * fixed at 32.768 kHz.
57             * Ignored if periodic calibration is active
58             * (PeriodicCalibrationInterval != 0). */
59   uint32_t periodicCalibrationInterval;  /*!< Periodic calibration interval in ms, to disable set to 0 */
60 } RADIO_TIMER_InitTypeDef;
61 
62 /**
63   * @brief  VIRTUAL TIMER Callback pointer definition
64   */
65 typedef void (*VTIMER_CallbackType)(void *);
66 
67 /**
68   * @brief VIRTUAL TIMER handle Structure definition
69   */
70 typedef struct VTIMER_HandleTypeS
71 {
72   uint64_t expiryTime; /*!< Managed internally when the timer is started */
73   VTIMER_CallbackType callback; /*!< Pointer to the user callback */
74   bool active; /*!< Managed internally when the timer is started */
75   struct VTIMER_HandleTypeS *next; /*!< Managed internally when the timer is started */
76   void *userData; /*!< Pointer to user data */
77 } VTIMER_HandleType;
78 
79 /**
80   * @brief RADIO TIMER status enumeration definition
81   */
82 typedef enum
83 {
84   RADIO_TIMER_OFF = 0,
85   RADIO_TIMER_PENDING = 1,
86 } RADIO_TIMER_Status;
87 
88 
89 /**
90   * @}
91   */
92 
93 /* Exported constants --------------------------------------------------------*/
94 
95 /** @defgroup RADIO_TIMER_Exported_Constants Radio Timer Exported Constants
96   * @{
97   */
98 
99 /**
100   * @brief RADIO TIMER clearing process return values
101   */
102 #define HAL_RADIO_TIMER_SUCCESS  (0x00U)
103 #define HAL_RADIO_TIMER_LATE     (0x01U)
104 #define HAL_RADIO_TIMER_CRITICAL (0x02U)
105 /**
106   * @}
107   */
108 
109 /**
110   * @brief RADIO TIMER Status
111   */
112 #define RADIO_TIMER1_BUSY         (0x01U)
113 #define RADIO_TIMER2_BUSY         (0x02U)
114 #define WAKEUP_RADIO_TIMER_BUSY   (0x03U)
115 /**
116   * @}
117   */
118 
119 /* Exported macros -----------------------------------------------------------*/
120 /* Private constants ---------------------------------------------------------*/
121 /* Private macros ------------------------------------------------------------*/
122 /* Private functions----------------------------------------------------------*/
123 /* Exported functions --------------------------------------------------------*/
124 
125 /** @defgroup RADIO_TIMER_Exported_Functions Radio Timer Exported Functions
126   * @{
127   */
128 
129 /** @defgroup RADIO_TIMER_EF_Config Radio Timer Init and Configuration functions
130   * @{
131   */
132 
133 /**
134   * @brief Initialize the radio timer module. It must be placed in the initialization
135   *        section of the application.
136   * @param RADIO_TIMER_InitStruct Radio Timer Initialization parameters
137   * @retval None
138   */
139 void HAL_RADIO_TIMER_Init(RADIO_TIMER_InitTypeDef *RADIO_TIMER_InitStruct);
140 
141 /**
142   * @brief Timer module state machine. Check and schedule the calibration.
143   * Check expired timers and execute user callback.
144   * It must be placed inside the infinite loop.
145   * @retval None
146   */
147 void HAL_RADIO_TIMER_Tick(void);
148 
149 /**
150   * @brief  Return the status of the radio timer.
151   *         The timeout of the last radio timer activity taken into account by the Timer Module
152   *         is saved in the variable passed as parameter.
153   * @param  time: Pointer of the variable where the time of the last radio activity scheduled is stored
154   *               The time is expressed in STU.
155   * @retval 0 if no radio timer is pending.
156   * @retval 1 if a radio timer is pending.
157   */
158 RADIO_TIMER_Status HAL_RADIO_TIMER_GetRadioTimerStatus(uint64_t *time);
159 
160 /**
161   * @}
162   */
163 
164 /** @defgroup RADIO_TIMER_EF_Management Radio Timer Management functions
165   * @{
166   */
167 
168 /**
169   * @brief  Schedules a radio activity for the given absolute timeout value expressed in STU.
170   *         If the calibration of the low speed oscillator is needed, if it is possible,
171   *         the radio timer will be programmed with the latest calibration data.
172   * @param  time: Absolute time expressed in STU.
173   * @param  event_type: Specify if it is a TX (1) or RX (0) event.
174   * @param  cal_req: Specify if PLL calibration is requested (1) or not (0).
175   * @retval 0 if radio activity has been scheduled successfully.
176   * @retval 1 if radio activity has been rejected (it is too close or in the past).
177   */
178 uint32_t HAL_RADIO_TIMER_SetRadioTimerValue(uint32_t time, uint8_t event_type, uint8_t cal_req);
179 
180 /**
181   * @brief  Clear the last radio activity scheduled disabling the radio timers too.
182   *         Furthermore, it returns if the timeout is too close with respect the current time and
183   *         the radio activity might not be cleared in time.
184   * @retval 0 if the radio activity has been cleared successfully.
185   * @retval 1 if it is too late to clear the last radio activity.
186   * @retval 2 if it might not be possible to clear the last radio activity.
187   */
188 uint32_t HAL_RADIO_TIMER_ClearRadioTimerValue(void);
189 
190 /**
191   * @brief   Programs Timer1 with a relative timeout - expressed in us - wrt the previous radio event.
192   * @param   rel_timeout_us: relative delay, in us, wrt the previous radio event.
193   * @param   event_type: 1 Tx event.
194                          0 Rx event
195   * @param   cal_req: 1 PLL calibartion is requested.
196                       0 PLL calibartion is not requested.
197   * @warning This function should be called with interrupts disabled
198   *           to avoid programming the timer with a value in the past
199   * @retval  0 if a correct timeout has been programmed in the timeout register
200   * @retval  1 if a correct timeout cannot be programmed
201   */
202 uint32_t HAL_RADIO_TIMER_SetRadioTimerRelativeUsValue(uint32_t rel_timeout_us, bool event_type, bool cal_req);
203 
204 /**
205   * @brief  Return the status of the Radio timers and the last value programmed in the register.
206   * @note   When Timer2 is on schedule, the time is expressed in microseconds, otherwise in absolute machine time units.
207   * @param  time: pointer to value which is going to have time value.
208   * @retval 0 if no timer has been programmed.
209   * @retval 1 if Timer1 has been programmed.
210   * @retval 2 if Timer2 has been programmed.
211   * @retval 3 if Wakeup Timer has been programmed.
212   */
213 uint8_t HAL_RADIO_TIMER_GetRadioTimerValue(uint32_t *time);
214 
215 /**
216   * @brief Program the radio timer (a.k.a Timer1) as close as possible.
217   *        The current time is sampled and increased by two.
218   *        It means that the timer is going to trigger in a timer interval that goes
219   *        from one to two machine time units.
220   */
221 void HAL_RADIO_TIMER_SetRadioCloseTimeout(void);
222 
223 /**
224   * @brief  Radio activity finished.
225   * @retval None
226   */
227 void HAL_RADIO_TIMER_RadioTimerIsr(void);
228 
229 /**
230   * @brief  Timer State machine semaphore to signal the radio activity finished.
231   * @retval None
232   */
233 void HAL_RADIO_TIMER_EndOfRadioActivityIsr(void);
234 
235 /**
236   * @brief  Get the last anchorPoint in system time unit.
237   * @return TimerCapture register in system time unit.
238   */
239 uint64_t HAL_RADIO_TIMER_GetAnchorPoint(uint64_t *current_system_time);
240 
241 /**
242   * @brief  Returns the admitted low power mode according to the next timer activity.
243   * @return Low Power mode
244   */
245 PowerSaveLevels HAL_RADIO_TIMER_PowerSaveLevelCheck(void);
246 
247 /**
248   * @}
249   */
250 
251 /** @defgroup RADIO_TIMER_EF_Management_TimeUnit Radio Timer Management Time Unit
252   * @{
253   */
254 
255 /**
256   * @brief  Translate time in microseconds into sys time units.
257   * @param  time: Microseconds to be converted in STU
258   * @return STU value
259   */
260 uint32_t HAL_RADIO_TIMER_UsToSystime(uint32_t time);
261 
262 /**
263   * @brief   Return the STU corresponding to the MTU passed as parameter.
264   * @param   time: MTU amount to be converted in STU
265   * @warning This function is not re-entrant since it updates the context variable
266   *          storing the system time. It should be called only in
267   *          user context and not in interrupt context.
268   * @return  STU value
269   */
270 uint32_t HAL_RADIO_TIMER_MachineTimeToSysTime(uint32_t time);
271 
272 /**
273   * @brief  This function returns the current reference time expressed in system time units.
274   *         The returned value can be used as absolute time parameter where needed in the other
275   *         HAL_RADIO_TIMER* APIs
276   * @return absolute current time expressed in system time units.
277   */
278 uint64_t HAL_RADIO_TIMER_GetCurrentSysTime(void);
279 
280 /**
281   * @brief This function returns the sum of an absolute time and a signed relative time.
282   * @param  sysTime: Absolute time expressed in internal time units.
283   * @param  msTime: Signed relative time expressed in ms.
284   * @return 64bit resulting absolute time expressed in internal time units.
285   */
286 uint64_t HAL_RADIO_TIMER_AddSysTimeMs(uint64_t sysTime, int32_t msTime);
287 
288 /**
289   * @brief  Returns the difference between two absolute times: sysTime1-sysTime2.
290   * The resulting value is expressed in ms.
291   * @param  sysTime2: Absolute time expressed in internal time units.
292   * @param  sysTime1: Absolute time expressed in internal time units.
293   * @return resulting signed relative time expressed in ms.
294   */
295 int64_t HAL_RADIO_TIMER_DiffSysTimeMs(uint64_t sysTime1, uint64_t sysTime2);
296 
297 /**
298   * @brief   Returns the 64-bit system time, referred to the 32-bit system time parameter.
299   *          The returned system time refers to a time between last calibration and last
300   *          calibration + 10485 seconds.
301   * @param   sys_time: system time
302   * @warning The system time cannot be more then 10485 seconds (174 min) after the last calibration time.
303   * @return  STU value
304   */
305 uint64_t HAL_RADIO_TIMER_GetSysTime64(uint32_t sys_time);
306 
307 /**
308   * @brief   Returns the next 64-bit system time in the future, referred to the 32-bit system time parameter.
309   *          Compared to HAL_RADIO_TIMER_GetSysTime64() this function makes sure that the returned
310   *          time is always in the future, but execution time of the function is longer.
311   * @param   sys_time: system time in the future (no more than 10485 s = 174 min in the future)
312   * @return  STU value
313   */
314 uint64_t HAL_RADIO_TIMER_GetFutureSysTime64(uint32_t sys_time);
315 
316 /**
317   * @}
318   */
319 
320 /** @defgroup RADIO_TIMER_EF_Virtual_Timer Radio Timer Virtual Timer functions
321   * @{
322   */
323 
324 /**
325   * @brief Starts a one-shot virtual timer for the given relative timeout value expressed in ms
326   * @param timerHandle: The virtual timer
327   * @param msRelTimeout: The relative time, from current time, expressed in ms
328   * @retval 0 if the timerHandle is valid.
329   * @retval 1 if the timerHandle is not valid. It is already started.
330   */
331 uint32_t HAL_RADIO_TIMER_StartVirtualTimer(VTIMER_HandleType *timerHandle, uint32_t msRelTimeout);
332 
333 /**
334   * @brief Starts a one-shot virtual timer for the given absolute timeout value
335   *        expressed in internal system time units.
336   * @param timerHandle: The virtual timer
337   * @param time: Absolute time expressed in STU.
338   * @retval 0 if the timerHandle is valid.
339   * @retval 1 if the timerHandle is not valid. It is already started.
340   */
341 uint32_t HAL_RADIO_TIMER_StartVirtualTimerSysTime(VTIMER_HandleType *timerHandle, uint64_t time);
342 
343 /**
344   * @brief  Stops the one-shot virtual timer specified if found
345   * @param  timerHandle: The virtual timer
346   * @retval None
347   */
348 void HAL_RADIO_TIMER_StopVirtualTimer(VTIMER_HandleType *timerHandle);
349 
350 /**
351   * @brief Returns the absolute expiry time of a running virtual timer expressed in internal system time units.
352   * @param timerHandle: The virtual timer
353   * @retval sysTime: Absolute time expressed in internal system time units.
354   */
355 uint64_t HAL_RADIO_TIMER_ExpiryTime(VTIMER_HandleType *timerHandle);
356 
357 /**
358   * @brief  Virtual timer Timeout Callback. It signals that a host timeout occurred.
359   * @retval None
360   */
361 void HAL_RADIO_TIMER_TimeoutCallback(void);
362 
363 #if defined (STM32WB06) || defined (STM32WB07)
364 /**
365   * @brief   If the wakeup timer triggers for a host wakeup, a pending radio activity is programmed.
366   *          If the wakeup timer triggers for a radio activity, a pending virtual timer callback is executed.
367   * @retval  None
368   */
369 void HAL_RADIO_TIMER_WakeUpCallback(void);
370 #endif /* (STM32WB06) || defined (STM32WB07) */
371 
372 /**
373   * @brief  Returns the number of timers in the queue.
374   * @return number of timers in the queue.
375   */
376 uint32_t HAL_RADIO_TIMER_GetPendingTimers(void);
377 
378 
379 void HAL_RADIO_TIMER_CPU_WKUP_IRQHandler(void);
380 void HAL_RADIO_TIMER_TXRX_WKUP_IRQHandler(void);
381 void HAL_RADIO_TIMER_ERROR_IRQHandler(void);
382 
383 void HAL_RADIO_TIMER_CpuWakeUpCallback(void);
384 void HAL_RADIO_TIMER_TxRxWakeUpCallback(void);
385 
386 /**
387   * @}
388   */
389 
390 /**
391   * @}
392   */
393 
394 /**
395   * @}
396   */
397 
398 /**
399   * @}
400   */
401 
402 #ifdef __cplusplus
403 }
404 #endif
405 
406 #endif /*STM32WB0x_HAL_RADIO_TIMER_H */
407