1 /*
2  * Copyright 2018-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef FSL_OSTIMER_H_
8 #define FSL_OSTIMER_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup ostimer
14  * @{
15  */
16 
17 /*! @file*/
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 /*! @name Driver version */
24 /*! @{ */
25 /*! @brief OSTIMER driver version. */
26 #define FSL_OSTIMER_DRIVER_VERSION (MAKE_VERSION(2, 2, 2))
27 /*! @} */
28 
29 /*!
30  * @brief OSTIMER status flags.
31  */
32 enum _ostimer_flags
33 {
34     kOSTIMER_MatchInterruptFlag = (OSTIMER_OSEVENT_CTRL_OSTIMER_INTRFLAG_MASK), /*!< Match interrupt flag bit, sets if
35                                                                                    the match value was reached. */
36 };
37 
38 /*! @brief ostimer callback function. */
39 typedef void (*ostimer_callback_t)(void);
40 
41 /*******************************************************************************
42  * API
43  ******************************************************************************/
44 
45 #if defined(__cplusplus)
46 extern "C" {
47 #endif /* _cplusplus */
48 
49 /*!
50  * @name Initialization and deinitialization
51  * @{
52  */
53 
54 /*!
55  * @brief Initializes an OSTIMER by turning its bus clock on
56  *
57  */
58 void OSTIMER_Init(OSTIMER_Type *base);
59 
60 /*!
61  * @brief Deinitializes a OSTIMER instance.
62  *
63  * This function shuts down OSTIMER bus clock
64  *
65  * @param base OSTIMER peripheral base address.
66  */
67 void OSTIMER_Deinit(OSTIMER_Type *base);
68 
69 /*!
70  * @brief Translate the value from gray-code to decimal.
71  *
72  * @param gray The gray value input.
73  * @return The decimal value.
74  */
75 uint64_t OSTIMER_GrayToDecimal(uint64_t gray);
76 
77 /*!
78  * @brief Translate the value from decimal to gray-code.
79  *
80  * @param dec The decimal value.
81  * @return The gray code of the input value.
82  */
OSTIMER_DecimalToGray(uint64_t dec)83 static inline uint64_t OSTIMER_DecimalToGray(uint64_t dec)
84 {
85     return (dec ^ (dec >> 1U));
86 }
87 
88 /*!
89  * @brief Get OSTIMER status Flags.
90  *
91  * This returns the status flag.
92  * Currently, only match interrupt flag can be got.
93  *
94  * @param base OSTIMER peripheral base address.
95  * @return status register value
96  */
97 uint32_t OSTIMER_GetStatusFlags(OSTIMER_Type *base);
98 
99 /*!
100  * @brief Clear Status Interrupt Flags.
101  *
102  * This clears intrrupt status flag.
103  * Currently, only match interrupt flag can be cleared.
104  *
105  * @param base OSTIMER peripheral base address.
106  * @param mask Clear bit mask.
107  * @return none
108  */
109 void OSTIMER_ClearStatusFlags(OSTIMER_Type *base, uint32_t mask);
110 
111 /*!
112  * @brief Set the match raw value for OSTIMER.
113  *
114  * This function will set a match value for OSTIMER with an optional callback. And this callback
115  * will be called while the data in dedicated pair match register is equals to the value of central EVTIMER.
116  * Please note that, the data format is gray-code, if decimal data was desired, please using OSTIMER_SetMatchValue().
117  *
118  * @param base   OSTIMER peripheral base address.
119  * @param count  OSTIMER timer match value.(Value is gray-code format)
120  *
121  * @param cb     OSTIMER callback (can be left as NULL if none, otherwise should be a void func(void)).
122  * @retval kStatus_Success - Set match raw value and enable interrupt Successfully.
123  * @retval kStatus_Fail    - Set match raw value fail.
124  */
125 status_t OSTIMER_SetMatchRawValue(OSTIMER_Type *base, uint64_t count, ostimer_callback_t cb);
126 
127 /*!
128  * @brief Set the match value for OSTIMER.
129  *
130  * This function will set a match value for OSTIMER with an optional callback. And this callback
131  * will be called while the data in dedicated pair match register is equals to the value of central OS TIMER.
132  *
133  * @param base   OSTIMER peripheral base address.
134  * @param count  OSTIMER timer match value.(Value is decimal format, and this value will be translate to Gray code
135  * internally.)
136  *
137  * @param cb     OSTIMER callback (can be left as NULL if none, otherwise should be a void func(void)).
138  * @retval kStatus_Success - Set match value and enable interrupt Successfully.
139  * @retval kStatus_Fail    - Set match value fail.
140  */
141 status_t OSTIMER_SetMatchValue(OSTIMER_Type *base, uint64_t count, ostimer_callback_t cb);
142 
143 /*!
144  * @brief Set value to OSTIMER MATCH register directly.
145  *
146  * This function writes the input value to OSTIMER MATCH register directly,
147  * it does not touch any other registers. Note that, the data format is
148  * gray-code. The function @ref OSTIMER_DecimalToGray could convert decimal
149  * value to gray code.
150  *
151  * @param base   OSTIMER peripheral base address.
152  * @param value  OSTIMER timer match value (Value is gray-code format).
153  */
OSTIMER_SetMatchRegister(OSTIMER_Type * base,uint64_t value)154 static inline void OSTIMER_SetMatchRegister(OSTIMER_Type *base, uint64_t value)
155 {
156 #ifdef OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK
157     /* Wait for MATCH register ready for write. */
158     while (0U != (base->OSEVENT_CTRL & OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK))
159     {
160     }
161 #endif
162 
163     base->MATCH_L = (uint32_t)value;
164     base->MATCH_H = (uint32_t)(value >> 32U);
165 }
166 
167 /*!
168  * @brief Enable the OSTIMER counter match interrupt.
169  *
170  * Enable the timer counter match interrupt. The interrupt happens when OSTIMER
171  * counter matches the value in MATCH registers.
172  *
173  * @param base OSTIMER peripheral base address.
174  */
OSTIMER_EnableMatchInterrupt(OSTIMER_Type * base)175 static inline void OSTIMER_EnableMatchInterrupt(OSTIMER_Type *base)
176 {
177     base->OSEVENT_CTRL |= OSTIMER_OSEVENT_CTRL_OSTIMER_INTENA_MASK;
178 }
179 
180 /*!
181  * @brief Disable the OSTIMER counter match interrupt.
182  *
183  * Disable the timer counter match interrupt. The interrupt happens when OSTIMER
184  * counter matches the value in MATCH registers.
185  *
186  * @param base OSTIMER peripheral base address.
187  */
OSTIMER_DisableMatchInterrupt(OSTIMER_Type * base)188 static inline void OSTIMER_DisableMatchInterrupt(OSTIMER_Type *base)
189 {
190     base->OSEVENT_CTRL &= ~OSTIMER_OSEVENT_CTRL_OSTIMER_INTENA_MASK;
191 }
192 
193 /*!
194  * @brief Get current timer raw count value from OSTIMER.
195  *
196  * This function will get a gray code type timer count value from OS timer register.
197  * The raw value of timer count is gray code format.
198  *
199  * @param base   OSTIMER peripheral base address.
200  * @return       Raw value of OSTIMER, gray code format.
201  */
OSTIMER_GetCurrentTimerRawValue(OSTIMER_Type * base)202 static inline uint64_t OSTIMER_GetCurrentTimerRawValue(OSTIMER_Type *base)
203 {
204     uint64_t tmp = 0U;
205 
206     tmp = base->EVTIMERL;
207     tmp |= (uint64_t)(base->EVTIMERH) << 32U;
208 
209     return tmp;
210 }
211 
212 /*!
213  * @brief Get current timer count value from OSTIMER.
214  *
215  * This function will get a decimal timer count value.
216  * The RAW value of timer count is gray code format, will be translated to decimal data internally.
217  *
218  * @param base   OSTIMER peripheral base address.
219  * @return       Value of OSTIMER which will be formated to decimal value.
220  */
221 uint64_t OSTIMER_GetCurrentTimerValue(OSTIMER_Type *base);
222 
223 /*!
224  * @brief Get the capture value from OSTIMER.
225  *
226  * This function will get a captured gray-code value from OSTIMER.
227  * The Raw value of timer capture is gray code format.
228  *
229  * @param base   OSTIMER peripheral base address.
230  * @return       Raw value of capture register, data format is gray code.
231  */
OSTIMER_GetCaptureRawValue(OSTIMER_Type * base)232 static inline uint64_t OSTIMER_GetCaptureRawValue(OSTIMER_Type *base)
233 {
234     uint64_t tmp = 0U;
235 
236     tmp = base->CAPTURE_L;
237     tmp |= (uint64_t)(base->CAPTURE_H) << 32U;
238 
239     return tmp;
240 }
241 
242 /*!
243  * @brief Get the capture value from OSTIMER.
244  *
245  * This function will get a capture decimal-value from OSTIMER.
246  * The RAW value of timer capture is gray code format, will be translated to decimal data internally.
247  *
248  * @param base   OSTIMER peripheral base address.
249  * @return Value of capture register, data format is decimal.
250  */
251 uint64_t OSTIMER_GetCaptureValue(OSTIMER_Type *base);
252 
253 /*!
254  * @brief OS timer interrupt Service Handler.
255  *
256  * This function handles the interrupt and refers to the callback array in the driver to callback user (as per request
257  * in OSTIMER_SetMatchValue()).
258  * if no user callback is scheduled, the interrupt will simply be cleared.
259  *
260  * @param base   OS timer peripheral base address.
261  * @param cb     callback scheduled for this instance of OS timer
262  * @return       none
263  */
264 void OSTIMER_HandleIRQ(OSTIMER_Type *base, ostimer_callback_t cb);
265 /*! @} */
266 
267 #if defined(__cplusplus)
268 }
269 #endif
270 
271 /*! @}*/
272 
273 #endif /* FSL_OSTIMER_H_ */
274