aboutsummaryrefslogtreecommitdiff
path: root/KSDK_1.2.0/platform/system/inc/fsl_hwtimer.h
blob: 3bd2afad1fe88c208024fe9a0b622b7f671dc43d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
/*
 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __FSL_HWTIMER_H__
#define __FSL_HWTIMER_H__

#include <stdint.h>
#include "fsl_clock_manager.h"

/*!
 * @addtogroup hwtimer_driver
 * @{
 */

/*! @file*/

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*!
 * @brief Hwtimer error codes definition.
 */
typedef enum _hwtimer_error_code
{
    kHwtimerSuccess,                /*!< success */
    kHwtimerInvalidInput,           /*!< invalid input parameter */
    kHwtimerInvalidPointer,         /*!< invalid pointer */
    kHwtimerClockManagerError,      /*!< clock manager return error */
    kHwtimerRegisterHandlerError,   /*!< Interrupt handler registration returns error */
    kHwtimerUnknown,                /*!< unknown error*/
} _hwtimer_error_code_t;

/*!
 * @brief Hwtimer low level context data length definition.
 */
#define HWTIMER_LL_CONTEXT_LEN 5U

/*!
 * @brief Define for low level context data length
 */
typedef void (* hwtimer_callback_t)(void *p);

/*!
 * @brief Hwtimer structure.
 *
 * This structure defines a hwtimer.
 * The context structure is passed to all API functions (besides other parameters).
 *
 * @warning Application should not access members of this structure directly.
 *
 * @see HWTIMER_SYS_init
 * @see HWTIMER_SYS_deinit
 * @see HWTIMER_SYS_start
 * @see HWTIMER_SYS_stop
 * @see HWTIMER_SYS_set_period
 * @see HWTIMER_SYS_get_period
 * @see HWTIMER_SYS_get_modulo
 * @see HWTIMER_SYS_get_time
 * @see HWTIMER_SYS_get_ticks
 * @see HWTIMER_SYS_callback_reg
 * @see HWTIMER_SYS_callback_block
 * @see HWTIMER_SYS_callback_unblock
 * @see HWTIMER_SYS_callback_cancel
 */
typedef struct Hwtimer
{
    /*! @brief Pointer to device interface structure */
    const struct Hwtimer_devif *    devif;
    /*! @brief Timer's source clock frequency */
    uint32_t                        clockFreq;
    /*! @brief Actual total divider */
    uint32_t                        divider;
    /*! @brief Determine how many sub ticks are in one tick */
    uint32_t                        modulo;
    /*! @brief Number of elapsed ticks */
    volatile uint64_t               ticks;
    /*! @brief Function pointer to be called when the timer expires. */
    hwtimer_callback_t              callbackFunc;
    /*! @brief Arbitrary pointer passed as parameter to the callback function. */
    void                            *callbackData;
    /*! @brief Indicate pending callback.
     *  If the timer overflows when callbacks are blocked the callback becomes pending. */
    volatile int                    callbackPending;
    /*! @brief Indicate blocked callback. */
    int                             callbackBlocked;
    /*! @brief Private storage locations for arbitrary data keeping the context of the lower layer driver. */
    uint32_t                        llContext[HWTIMER_LL_CONTEXT_LEN];
} hwtimer_t, * hwtimer_ptr_t;

/*!
 * @brief Hwtimer_time structure.
 *
 * Hwtimer time structure represents a time stamp consisting of timer elapsed periods (TICKS) and current value of the timer counter (subTicks).
 *
 * @see HWTIMER_SYS_GetTime
 */
typedef struct Hwtimer_time
{
    /*! @brief Ticks of timer */
    uint64_t ticks;
    /*! @brief Sub ticks of timer */
    uint32_t subTicks;
} hwtimer_time_t, * hwtimer_time_ptr_t;

/*!
 * @brief Type defines init function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_init_t)(hwtimer_t *hwtimer, uint32_t id, void *data);

/*!
 * @brief Type defines deinit function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_deinit_t)(hwtimer_t *hwtimer);

/*!
 * @brief Type defines set_div function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_set_div_t)(hwtimer_t *hwtimer, uint32_t period);

/*!
 * @brief Type defines start function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_start_t)(hwtimer_t *hwtimer);

/*!
 * @brief Type defines stop function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_stop_t)(hwtimer_t *hwtimer);

/*!
 * @brief Type defines reset function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_reset_t)(hwtimer_t *hwtimer);

/*!
 * @brief Type defines get_time function for devif structure.
 */
typedef _hwtimer_error_code_t (*  hwtimer_devif_get_time_t)(hwtimer_t *hwtimer, hwtimer_time_t *time);

/*!
 * @brief hwtimer_devif structure.
 *
 * Each low layer driver exports instance of this structure initialized with pointers to API functions the driver implements.
 * The functions themselves should be declared as static (not exported directly).
 *
 * @see HWTIMER_SYS_Init
 * @see HWTIMER_SYS_Deinit
 */
typedef struct Hwtimer_devif
{
     /*! @brief Function pointer to lower layer initialization */
    hwtimer_devif_init_t             init;
     /*! @brief Function pointer to lower layer de-initialization */
    hwtimer_devif_deinit_t           deinit;
     /*! @brief Function pointer to lower layer set divider functionality */
    hwtimer_devif_set_div_t          setDiv;
     /*! @brief Function pointer to lower layer start functionality */
    hwtimer_devif_start_t            start;
     /*! @brief Function pointer to lower layer stop functionality */
    hwtimer_devif_stop_t             stop;
     /*! @brief Function pointer to lower layer get time functionality */
    hwtimer_devif_get_time_t         getTime;
} hwtimer_devif_t, * hwtimer_devif_ptr_t;

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Initializes caller allocated structure according to given parameters.
 *
 * The device interface pointer determines low layer driver to be used.
 * Device interface structure is exported by each low layer driver and is opaque to the applications.
 * Please refer to chapter concerning low layer driver below for details.
 * Meaning of the numerical identifier varies depending on low layer driver used.
 * Typically, it identifies particular timer channel to initialize.
 * The initialization function has to be called prior using any other API function.
 *
 * @param hwtimer [out]  Returns initialized hwtimer structure handle.
 * @param kDevif [in]    Structure determines low layer driver to be used.
 * @param id [in]        Numerical identifier of the timer.
 * @param data [in]      Specific data for low level of interrupt.
 *
 * @return success or an error code returned from low level init function.
 * @retval kHwtimerSuccess          Success
 * @retval kHwtimerInvalidInput     When input parameter hwtimer is a NULL pointer
 * @retval kHwtimerInvalidPointer   When device structure points to NULL.
 *
 * @warning The initialization function has to be called prior using any other API function.
 *
 * @see HWTIMER_SYS_deinit
 * @see HWTIMER_SYS_start
 * @see HWTIMER_SYS_stop
 */
_hwtimer_error_code_t HWTIMER_SYS_Init(hwtimer_t *hwtimer, const hwtimer_devif_t * kDevif, uint32_t id, void *data);

/*!
 * @brief De-initialization of the hwtimer.
 *
 * Calls lower layer stop function to stop timer, then calls low layer de-initialization function
 * and afterwards invalidates hwtimer structure by clearing it.
 *
 * @param hwtimer [in] Pointer to hwtimer structure.
 *
 * @return success or an error code returned from low level DEINIT function.
 * @retval kHwtimerSuccess          Success
 * @retval kHwtimerInvalidInput     When input parameter hwtimer is a NULL pointer
 * @retval kHwtimerInvalidPointer   When device structure points to NULL.
 *
 * @see HWTIMER_SYS_Init
 * @see HWTIMER_SYS_Start
 * @see HWTIMER_SYS_Stop
 */
_hwtimer_error_code_t HWTIMER_SYS_Deinit(hwtimer_t *hwtimer);

/*!
 * @brief Set period of hwtimer.
 *
 * The function provides a way to set up the timer to desired period specified in microseconds.
 * Calls the low layer driver to set up the timer divider according to the specified period.
 *
 * @param hwtimer [in]   Pointer to hwtimer structure.
 * @param period [in]    Required period of timer in micro seconds.
 *
 * @return success or an error code returned from low level SETDIV function.
 * @retval kHwtimerSuccess           Success
 * @retval kHwtimerInvalidInput      When input parameter hwtimer or his device structure are NULL pointers.
 * @retval kHwtimerInvalidPointer    When low level SETDIV function point to NULL.
 * @retval kHwtimerClockManagerError When Clock manager returns error.
 *
 * @see HWTIMER_SYS_GetPeriod
 * @see HWTIMER_SYS_GetModulo
 * @see HWTIMER_SYS_GetTime
 * @see HWTIMER_SYS_GetTicks
 */
_hwtimer_error_code_t HWTIMER_SYS_SetPeriod(hwtimer_t *hwtimer, uint32_t period);

/*!
 * @brief Get period of hwtimer.
 *
 * The function returns current period of the timer in microseconds calculated from the base frequency and actual divider settings of the timer.
 *
 * @param hwtimer [in]   Pointer to hwtimer structure.
 *
 * @return already set period of hwtimer.
 * @retval 0  Input parameter hwtimer is NULL pointer or clock manager returns error.
 *
 * @see HWTIMER_SYS_SetPeriod
 * @see HWTIMER_SYS_GetModulo
 * @see HWTIMER_SYS_GetTime
 * @see HWTIMER_SYS_GetTicks
 */
uint32_t HWTIMER_SYS_GetPeriod(hwtimer_t *hwtimer);

/*!
 * @brief Enables the timer and leaves it running.
 *
 * The timer starts counting a new period generating interrupts every time the timer rolls over.
 *
 * @param hwtimer [in] Pointer to hwtimer structure.
 *
 * @return success or an error code returned from low level START function.
 * @retval kHwtimerSuccess           Success
 * @retval kHwtimerInvalidInput      When input parameter hwtimer is a NULL pointer
 * @retval kHwtimerInvalidPointer    When device structure points to NULL.
 *
 * @see HWTIMER_SYS_Init
 * @see HWTIMER_SYS_Deinit
 * @see HWTIMER_SYS_Stop
 */
_hwtimer_error_code_t HWTIMER_SYS_Start(hwtimer_t *hwtimer);

/*!
 * @brief The timer stops counting after this function is called.
 *
 * Pending interrupts and callbacks are cancelled.
 *
 * @param hwtimer [in] Pointer to hwtimer structure.
 *
 * @return success or an error code returned from low level STOP function.
 * @retval kHwtimerSuccess           Success
 * @retval kHwtimerInvalidInput      When input parameter hwtimer is a NULL pointer
 * @retval kHwtimerInvalidPointer    When device structure points to NULL.
 *
 * @see HWTIMER_SYS_Init
 * @see HWTIMER_SYS_Deinit
 * @see HWTIMER_SYS_Start
 */
_hwtimer_error_code_t HWTIMER_SYS_Stop(hwtimer_t *hwtimer);

/*!
 * @brief The function returns period of the timer in sub-ticks.
 *
 * It is typically called after HWTIMER_SYS_SetPeriod() to obtain actual resolution of the timer in the current configuration.
 *
 * @param hwtimer [in]   Pointer to hwtimer structure.
 *
 * @return resolution of hwtimer.
 * @retval 0 Input parameter hwtimer is NULL pointer.
 *
 * @see HWTIMER_SYS_SetPeriod
 * @see HWTIMER_SYS_GetPeriod
 * @see HWTIMER_SYS_GetTime
 * @see HWTIMER_SYS_GetTicks
 */
uint32_t HWTIMER_SYS_GetModulo(hwtimer_t *hwtimer);

/*!
 * @brief The function reads the current value of the hwtimer.
 *
 * Elapsed periods(ticks) and current value of the timer counter (sub-ticks) are filled into the Hwtimer_time structure.
 * The sub-ticks number always counts up and is reset to zero when the timer overflows regardless of the counting direction of the underlying device.
 *
 * @param hwtimer [in]   Pointer to hwtimer structure.
 * @param time [out]     Pointer to time structure. This value is filled with current value of the timer.
 *
 * @return success or an error code returned from low level GET_TIME function.
 * @retval kHwtimerSuccess        Success
 * @retval kHwtimerInvalidInput   When input parameter hwtimer or input parameter time are NULL pointers.
 * @retval kHwtimerInvalidPointer When device structure points to NULL.
 *
 * @see HWTIMER_SYS_SetPeriod
 * @see HWTIMER_SYS_GetPeriod
 * @see HWTIMER_SYS_GetModulo
 * @see HWTIMER_SYS_GetTicks
 */
_hwtimer_error_code_t HWTIMER_SYS_GetTime(hwtimer_t *hwtimer, hwtimer_time_t *time);

/*!
 * @brief The function reads the current value of the hwtimer
 *
 * The returned value corresponds with lower 32 bits of elapsed periods (ticks).
 * The value is guaranteed to be obtained atomically without necessity to mask timer interrupt.
 * Lower layer driver is not involved at all, thus call to this function is considerably faster than HWTIMER_SYS_GetTime.
 *
 * @param hwtimer [in]   Pointer to hwtimer structure.
 *
 * @return low 32 bits of 64 bit tick value.
 * @retval 0  When input parameter hwtimer is NULL pointer.
 *
 * @see HWTIMER_SYS_SetPeriod
 * @see HWTIMER_SYS_GetPeriod
 * @see HWTIMER_SYS_GetModulo
 * @see HWTIMER_SYS_GetTime
 */
uint32_t HWTIMER_SYS_GetTicks(hwtimer_t *hwtimer);

/*!
 * @brief Registers function to be called when the timer expires.
 *
 * The callback_data is arbitrary pointer passed as parameter to the callback function.
 *
 * @param hwtimer [in]        Pointer to hwtimer structure.
 * @param callbackFunc [in] Function pointer to be called when the timer expires.
 * @param callbackData [in] Data pointer for the function callback_func.
 *
 * @return success or an error code
 * @retval kHwtimerInvalidInput When input parameter hwtimer is NULL pointer.
 * @retval kHwtimerSuccess      When registration callback succeed.
 *
 * @warning This function must not be called from a callback routine.
 *
 * @see HWTIMER_SYS_BlockCallback
 * @see HWTIMER_SYS_UnblockCallback
 * @see HWTIMER_SYS_CancelCallback
 */
_hwtimer_error_code_t HWTIMER_SYS_RegisterCallback(hwtimer_t *hwtimer, hwtimer_callback_t callbackFunc, void *callbackData);

/*!
 * @brief The function is used to block callbacks in circumstances when execution of the callback function is undesired.
 *
 * If the timer overflows when callbacks are blocked the callback becomes pending.
 *
 * @param hwtimer [in] Pointer to hwtimer structure.
 *
 * @return success or an error code
 * @retval kHwtimerInvalidInput When input parameter hwtimer is NULL pointer.
 * @retval kHwtimerSuccess      When callback block succeed.
 *
 * @warning This function must not be called from a callback routine.
 *
 * @see HWTIMER_SYS_RegCallback
 * @see HWTIMER_SYS_UnblockCallback
 * @see HWTIMER_SYS_CancelCallback
 */
_hwtimer_error_code_t HWTIMER_SYS_BlockCallback(hwtimer_t *hwtimer);

/*!
 * @brief The function is used to unblock previously blocked callbacks.
 *
 * If there is a callback pending, it gets immediately executed.
 * This function must not be called from a callback routine (it does not make sense to do so anyway as callback function never gets executed while callbacks are blocked).
 *
 * @param hwtimer [in] Pointer to hwtimer structure.
 *
 * @return success or an error code
 * @retval kHwtimerInvalidInput When input parameter hwtimer is NULL pointer.
 * @retval kHwtimerSuccess      When callback unblock succeed.
 *
 * @warning This function must not be called from a callback routine.
 *
 * @see HWTIMER_SYS_RegCallback
 * @see HWTIMER_SYS_BlockCallback
 * @see HWTIMER_SYS_CancelCallback
 */
_hwtimer_error_code_t HWTIMER_SYS_UnblockCallback(hwtimer_t *hwtimer);

/*!
 * @brief The function cancels pending callback, if any.
 *
 * @param hwtimer [in] Pointer to hwtimer structure.
 *
 * @return success or an error code
 * @retval kHwtimerInvalidInput When input parameter hwtimer is NULL pointer.
 * @retval kHwtimerSuccess      When callback cancel succeed.
 *
 * @warning This function must not be called from a callback routine (it does not make sense to do so anyway as callback function never gets executed while callbacks are blocked).
 *
 * @see HWTIMER_SYS_RegCallback
 * @see HWTIMER_SYS_BlockCallback
 * @see HWTIMER_SYS_UnblockCallback
 */
_hwtimer_error_code_t HWTIMER_SYS_CancelCallback(hwtimer_t *hwtimer);

#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* __FSL_HWTIMER_H__ */
/*******************************************************************************
 * EOF
 ******************************************************************************/