1 /*
2  * Copyright 2018-2021 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _TIMER_H_
10 #define _TIMER_H_
11 
12 #include "fsl_common.h"
13 /*!
14  * @addtogroup Timer_Adapter
15  * @{
16  */
17 
18 /*!
19  * @brief The timer adapter component
20  *
21  * The timer adapter is built based on the timer SDK driver provided by the NXP
22  * MCUXpresso SDK. The timer adapter could provide high accuracy timer for user.
23  * Since callback function would be handled in ISR, and timer clock use high
24  * accuracy clock, user can get accuracy millisecond timer.
25  *
26  * The timer adapter would be used with different HW timer modules like FTM, PIT, LPTMR.
27  * But at the same time, only one HW timer module could be used. On different platforms, different
28  * HW timer module would be used. For the platforms which have multiple HW timer modules,
29  * one HW timer module would be selected as the default, but it is easy to change the default
30  * HW timer module to another. Just two steps to switch the HW timer module:
31  * 1.Remove the default HW timer module source file from the project
32  * 2.Add the expected HW timer module source file to the project.
33  * For example, in platform FRDM-K64F, there are two HW timer modules available, FTM and PIT.
34  * FTM is used as the default HW timer, so ftm_adapter.c and timer.h is included in the project by
35  * default. If PIT is expected to be used as the HW timer, ftm_adapter.c need to be removed from the
36  * project and pit_adapter.c should be included in the project
37  */
38 
39 /************************************************************************************
40 *************************************************************************************
41 * Include
42 *************************************************************************************
43 ***********************************************************************************/
44 
45 #if defined(SDK_OS_FREE_RTOS)
46 #include "FreeRTOS.h"
47 #endif
48 
49 /************************************************************************************
50 *************************************************************************************
51 * Public types
52 *************************************************************************************
53 ************************************************************************************/
54 /*! @brief HAL timer callback function. */
55 typedef void (*hal_timer_callback_t)(void* param);
56 
57 /*! @brief HAL timer status. */
58 typedef enum _hal_timer_status
59 {
60     kStatus_HAL_TimerSuccess = kStatus_Success,                           /*!< Success */
61     kStatus_HAL_TimerNotSupport = MAKE_STATUS(kStatusGroup_HAL_TIMER, 1), /*!< Not Support */
62     kStatus_HAL_TimerIsUsed = MAKE_STATUS(kStatusGroup_HAL_TIMER, 2),     /*!< timer is used  */
63     kStatus_HAL_TimerInvalid = MAKE_STATUS(kStatusGroup_HAL_TIMER, 3),    /*!< timer is invalid  */
64     kStatus_HAL_TimerOutOfRanger = MAKE_STATUS(kStatusGroup_HAL_TIMER, 4), /*!< timer is Out Of Ranger */
65 } hal_timer_status_t;
66 
67 /*! @brief HAL timer configuration structure for HAL timer setting. */
68 typedef struct _hal_timer_config
69 {
70     uint32_t timeout;                     /*!< Timeout of the timer, should use microseconds, for example: if set timeout to 1000, mean 1000 microseconds
71                                                interval would generate timer timeout interrupt*/
72     uint32_t srcClock_Hz;                 /*!< Source clock of the timer */
73     uint8_t  instance;                    /*!< Hardware timer module instance, for example: if you want use FTM0,then the instance is configured to 0, if
74                                                you want use FTM2 hardware timer, then configure the instance to 2, detail information please refer to the
75                                                SOC corresponding RM.Invalid instance value will cause initialization failure. */
76 
77     uint8_t  clockSrcSelect;              /*!< Select clock source. It is for timer clock select, if the lptmr does not
78                                                want to use the default clock source*/
79 } hal_timer_config_t;
80 
81 /*! @brief Definition of timer adapter handle size. */
82 #define HAL_TIMER_HANDLE_SIZE                (20U)
83 
84 /*!
85  * @brief Defines the timer handle
86  *
87  * This macro is used to define a 4 byte aligned timer handle.
88  * Then use "(hal_timer_handle_t)name" to get the timer handle.
89  *
90  * The macro should be global and could be optional. You could also define timer handle by yourself.
91  *
92  * This is an example,
93  * @code
94  * TIMER_HANDLE_DEFINE(timerHandle);
95  * @endcode
96  *
97  * @param name The name string of the timer handle.
98  */
99 #define TIMER_HANDLE_DEFINE(name) uint32_t name[((HAL_TIMER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
100 
101 /*! @brief HAL timer handle. */
102 typedef void* hal_timer_handle_t;
103 
104 #if defined(__GIC_PRIO_BITS)
105 #ifndef HAL_TIMER_ISR_PRIORITY
106 #define HAL_TIMER_ISR_PRIORITY (25U)
107 #endif
108 #else
109 #if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
110 #ifndef HAL_TIMER_ISR_PRIORITY
111 #define HAL_TIMER_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
112 #endif
113 #else
114 /* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
115  * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
116  * priority is 3 (2^2 - 1). So, the default value is 3.
117  */
118 #ifndef HAL_TIMER_ISR_PRIORITY
119 #define HAL_TIMER_ISR_PRIORITY (3U)
120 #endif
121 #endif
122 #endif
123 
124 /************************************************************************************
125 *************************************************************************************
126 * Public prototypes
127 *************************************************************************************
128 ************************************************************************************/
129 #if defined(__cplusplus)
130     extern "C" {
131 #endif /* _cplusplus */
132 
133 /*!
134  * @brief Initializes the timer adapter module for a timer basic operation.
135  *
136  * @note This API should be called at the beginning of the application using the timer adapter.
137  * For Initializes timer adapter,
138  *  @code
139  *   TIMER_HANDLE_DEFINE(halTimerHandle);
140  *   hal_timer_config_t halTimerConfig;
141  *   halTimerConfig.timeout = 1000;
142  *   halTimerConfig.srcClock_Hz = BOARD_GetTimeSrcClock();
143  *   halTimerConfig.instance = 0;
144  *   HAL_TimerInit((hal_timer_handle_t)halTimerHandle, &halTimerConfig);
145  *  @endcode
146  *
147  * @param halTimerHandle HAL timer adapter handle, the handle buffer with size #HAL_TIMER_HANDLE_SIZE
148  * should be allocated at upper level.
149  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
150  * You can define the handle in the following two ways:
151  * #TIMER_HANDLE_DEFINE(halTimerHandle);
152  * or
153  * uint32_t halTimerHandle[((HAL_TIMER_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
154  * @param halTimerConfig A pointer to the HAL timer configuration structure
155  * @retval kStatus_HAL_TimerSuccess The timer adapter module initialization succeed.
156  * @retval kStatus_HAL_TimerOutOfRanger The timer adapter instance out of ranger.
157  */
158 hal_timer_status_t HAL_TimerInit(hal_timer_handle_t halTimerHandle, hal_timer_config_t* halTimerConfig);
159 
160 /*!
161  * @brief DeInitilizate the timer adapter module.
162  *
163  * @note This API should be called when not using the timer adapter anymore.
164  *
165  * @param halTimerHandle     HAL timer adapter handle
166  */
167 void HAL_TimerDeinit(hal_timer_handle_t halTimerHandle);
168 
169 /*!
170  * @brief Enable the timer adapter module.
171  *
172  * @note This API should be called when enable the timer adapter.
173  *
174  * @param halTimerHandle     HAL timer adapter handle
175  */
176 void HAL_TimerEnable(hal_timer_handle_t halTimerHandle);
177 
178 /*!
179  * @brief Disable the timer adapter module.
180  *
181  * @note This API should be called when disable the timer adapter.
182  *
183  * @param halTimerHandle     HAL timer adapter handle
184  */
185 void HAL_TimerDisable(hal_timer_handle_t halTimerHandle);
186 
187 /*!
188  * @brief Install the timer adapter module callback function.
189  *
190  * @note This API should be called to when to install callback function for the timer.Since callback function
191  *       would be handled in ISR, and timer clock use high accuracy clock, user can get accuracy millisecond timer.
192  *
193  * @param halTimerHandle     HAL timer adapter handle
194  * @param callback            The installed callback function by upper layer
195  * @param callbackParam         The callback function parameter
196  */
197 void HAL_TimerInstallCallback(hal_timer_handle_t halTimerHandle, hal_timer_callback_t callback, void* callbackParam);
198 
199 /*!
200  * @brief Get the timer count of the timer adapter.
201  *
202  * @note This API should be return the real-time timer counting value in a range from 0 to a
203  *        timer period, and return microseconds.
204  *
205  * @param halTimerHandle     HAL timer adapter handle
206  * @retval the real-time timer counting value and return microseconds.
207  */
208 uint32_t HAL_TimerGetCurrentTimerCount(hal_timer_handle_t halTimerHandle);
209 
210 /*!
211  * @brief Update the timeout of the timer adapter to generate timeout interrupt.
212  *
213  * @note This API should be called when need set the timeout of the timer interrupt..
214  *
215  * @param halTimerHandle     HAL timer adapter handle
216  * @param timeout            Timeout time, should be used microseconds.
217  * @retval kStatus_HAL_TimerSuccess The timer adapter module update timeout succeed.
218  * @retval kStatus_HAL_TimerOutOfRanger The timer adapter set the timeout out of ranger.
219  */
220 hal_timer_status_t HAL_TimerUpdateTimeout(hal_timer_handle_t halTimerHandle, uint32_t timeout);
221 
222 /*!
223  * @brief Get maximum Timer timeout
224  *
225  * @note This API should to get maximum Timer timeout value to avoid overflow
226  *
227  * @param halTimerHandle     HAL timer adapter handle
228  * @retval get the real-time timer maximum timeout value and return microseconds.
229  */
230 uint32_t HAL_TimerGetMaxTimeout(hal_timer_handle_t halTimerHandle);
231 
232 /*!
233  * @brief Timer adapter power up function.
234  *
235  * @note This API should be called by low power module when system exit from sleep mode.
236  *
237  * @param halTimerHandle     HAL timer adapter handle
238  */
239 void HAL_TimerExitLowpower(hal_timer_handle_t halTimerHandle);
240 
241 /*!
242  * @brief Timer adapter power down function.
243  *
244  * @note This API should be called by low power module before system enter into sleep mode.
245  *
246  * @param halTimerHandle     HAL timer adapter handle
247  */
248 void HAL_TimerEnterLowpower(hal_timer_handle_t halTimerHandle);
249 
250 #if defined(__cplusplus)
251 }
252 #endif
253 /*! @}*/
254 #endif /* _TIMER_H_ */
255