1 /*
2  * Copyright (c) 2016-2019, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*!*****************************************************************************
33  *  @file       Timer.h
34  *  @brief      Timer driver
35  *
36  *  @anchor ti_drivers_Timer_Overview
37  *  # Overview
38  *  The timer driver allows you to measure elapsed time with simple and
39  *  portable APIs.This driver does not have PWM or capture functionalities.
40  *  These functionalities are addressed in both the capture and PWM driver.
41  *
42  *  The timer driver also handles the general purpose timer resource allocation.
43  *  For each driver that requires use of a general purpose timer, it calls
44  *  Timer_open() to occupy the specified timer, and calls Timer_close() to
45  *  release the occupied timer resource.
46  *
47  *  @anchor ti_drivers_Timer_Usage
48  *  # Usage
49  *
50  *  This documentation provides a basic @ref ti_drivers_Timer_Synopsis
51  *  "usage summary" and a set of @ref ti_drivers_Timer_Examples "examples"
52  *  in the form of commented code fragments. Detailed descriptions of the
53  *  APIs are provided in subsequent sections.
54  *
55  *  @anchor ti_drivers_Timer_Synopsis
56  *  ## Synopsis
57  *  @anchor ti_drivers_Timer_Synopsis_Code
58  *  @code
59  *  // Import Timer Driver definitions
60  *  #include <ti/drivers/Timer.h>
61  *
62  *  Timer_Handle    handle;
63  *  Timer_Params    params;
64  *
65  *  Timer_Params_init(&params);
66  *  params.periodUnits = Timer_PERIOD_HZ;
67  *  params.period = 1000;
68  *  params.timerMode  = Timer_CONTINUOUS_CALLBACK;
69  *  params.timerCallback = UserCallbackFunction;
70  *
71  *  handle = Timer_open(CONFIG_TIMER0, &params);
72  *
73  *  @code
74  *  // Import Timer Driver definitions
75  *  #include <ti/drivers/Timer.h>
76  *
77  *  Timer_Handle    handle;
78  *  Timer_Params    params;
79  *
80  *  // Initialize Timer parameters
81  *  Timer_Params_init(&params);
82  *  params.periodUnits = Timer_PERIOD_HZ;
83  *  params.period = 1000;
84  *  params.timerMode  = Timer_CONTINUOUS_CALLBACK;
85  *  params.timerCallback = UserCallbackFunction;
86  *
87  *  // Open Timer instance
88  *  handle = Timer_open(CONFIG_TIMER0, &params);
89  *
90  *  sleep(10000);
91  *
92  *  Timer_stop(handle);
93  *  @endcode
94  *
95  *  <hr>
96  *  @anchor ti_drivers_Timer_Examples
97  *  # Examples
98  *
99  *  @li @ref ti_drivers_Timer_Examples_open "Opening a Timer Instance"
100  *  @li @ref ti_drivers_Timer_Examples_mode "Configuring Timer mode and period"
101  *
102  *  @anchor ti_drivers_Timer_Examples_open
103  *  ## Opening a Timer instance
104  *
105  *  @code
106  *  Timer_Handle    handle;
107  *  Timer_Params    params;
108  *
109  *  Timer_Params_init(&params);
110  *  handle = Timer_open(CONFIG_TIMER0, &params);
111  *
112  *  if (handle == NULL) {
113  *      // Timer_open() failed
114  *      while (1);
115  *  }
116  @endcode
117  *
118  *  @anchor ti_drivers_Timer_Examples_mode
119  *  ##Configuring Timer mode and period
120  *
121  *  The following example code opens a timer in continuous callback mode. The
122  *  period is set to 1000 Hz.
123  *
124  *  @code
125  *  Timer_Handle    handle;
126  *  Timer_Params    params;
127  *
128  *  Timer_Params_init(&params);
129  *  params.periodUnits = Timer_PERIOD_HZ;
130  *  params.period = 1000;
131  *  params.timerMode  = Timer_CONTINUOUS_CALLBACK;
132  *  params.timerCallback = UserCallbackFunction;
133  *
134  *  handle = Timer_open(CONFIG_TIMER0, &params);
135  *
136  *  if (handle == NULL) {
137  *      // Timer_open() failed
138  *      while (1);
139  *  }
140  *
141  *  status = Timer_start(handle);
142  *
143  *  if (status == Timer_STATUS_ERROR) {
144  *      //Timer_start() failed
145  *      while (1);
146  *  }
147  *
148  *  sleep(10000);
149  *
150  *  Timer_stop(handle);
151  *  @endcode
152  *
153  *  ### Initializing the Timer Driver #
154  *
155  *  Timer_init() must be called before any other timer APIs. This function
156  *  calls the device implementation's timer initialization function, for each
157  *  element of Timer_config[].
158  *
159  *  <hr>
160  *  @anchor ti_drivers_Timer_Configuration
161  *  # Configuration
162  *
163  *  Refer to the @ref driver_configuration "Driver's Configuration" section
164  *  for driver configuration information.
165  *  <hr>
166 *******************************************************************************
167  */
168 
169 #ifndef ti_drivers_Timer__include
170 #define ti_drivers_Timer__include
171 
172 #include <stdint.h>
173 
174 #ifdef __cplusplus
175 extern "C"
176 {
177 #endif
178 
179 /*!
180  * Common Timer_control command code reservation offset.
181  * Timer driver implementations should offset command codes with Timer_CMD_RESERVED
182  * growing positively
183  *
184  * Example implementation specific command codes:
185  * @code
186  * #define TimerXYZ_CMD_COMMAND0      Timer_CMD_RESERVED + 0
187  * #define TimerXYZ_CMD_COMMAND1      Timer_CMD_RESERVED + 1
188  * @endcode
189  */
190 #define Timer_CMD_RESERVED                (32)
191 
192 /*!
193  * Common Timer_control status code reservation offset.
194  * Timer driver implementations should offset status codes with
195  * Timer_STATUS_RESERVED growing negatively.
196  *
197  * Example implementation specific status codes:
198  * @code
199  * #define TimerXYZ_STATUS_ERROR0     Timer_STATUS_RESERVED - 0
200  * #define TimerXYZ_STATUS_ERROR1     Timer_STATUS_RESERVED - 1
201  * @endcode
202  */
203 #define Timer_STATUS_RESERVED            (-32)
204 
205 /*!
206  * @brief   Successful status code.
207  */
208 #define Timer_STATUS_SUCCESS               (0)
209 
210 /*!
211  * @brief   Generic error status code.
212  */
213 #define Timer_STATUS_ERROR                (-1)
214 
215 /*!
216  * @brief   An error status code returned by Timer_control() for undefined
217  *          command codes.
218  *
219  * Timer_control() returns Timer_STATUS_UNDEFINEDCMD if the control code is not
220  * recognized by the driver implementation.
221  */
222 #define Timer_STATUS_UNDEFINEDCMD         (-2)
223 
224 /*!
225  *  @brief      A handle that is returned from a Timer_open() call.
226  */
227 typedef struct Timer_Config_ *Timer_Handle;
228 
229 /*!
230  *  @brief Timer mode settings
231  *
232  *  This enum defines the timer modes that may be specified in #Timer_Params.
233  *
234  *  The timer driver supports four modes of operation which may be specified in
235  *  the Timer_Params. The device specific implementation may configure the timer
236  *  peripheral as an up or down counter. In any case, Timer_getCount() will
237  *  return a value characteristic of an up counter.
238  */
239 typedef enum {
240     Timer_ONESHOT_CALLBACK,       /*!< Is a non-blocking call. After Timer_start()
241                                        is called, the calling thread will continue
242                                        execution. When the timer interrupt is
243                                        triggered, the specified callback function
244                                        will be called. The timer will not generate
245                                        another interrupt unless Timer_start() is
246                                        called again. Calling Timer_stop() or
247                                        Timer_close() after Timer_start() but,
248                                        before the timer interrupt, will prevent
249                                        the specified callback from ever being invoked.
250                                         */
251     Timer_ONESHOT_BLOCKING,       /*!< Is a blocking call. A semaphore is used to
252                                        block the calling thread's execution until
253                                        the timer generates an interrupt. If
254                                        Timer_stop() is called, the calling thread
255                                        will become unblocked immediately. The
256                                        behavior of the timer in this mode is similar
257                                        to a sleep function.
258                                         */
259     Timer_CONTINUOUS_CALLBACK,    /*!< Is a non-blocking call. After Timer_start()
260                                        is called, the calling thread will continue
261                                        execution. When the timer interrupt is
262                                        triggered, the specified callback function
263                                        will be called. The timer is automatically
264                                        restarted and will continue to periodically
265                                        generate interrupts until Timer_stop() is
266                                        called.
267                                         */
268     Timer_FREE_RUNNING            /*!< Is a non-blocking call. After Timer_start()
269                                        is called, the calling thread will continue
270                                        execution. The timer will not generate an
271                                        interrupt in this mode. The timer hardware
272                                        will run until Timer_stop() is called.
273                                         */
274 } Timer_Mode;
275 
276 /*!
277  *  @brief Timer period unit enum
278  *
279  *  This enum defines the units that may be specified for the period
280  *  in #Timer_Params. This unit has no effect with Timer_getCounts.
281  */
282 typedef enum {
283     Timer_PERIOD_US,      /*!< Period specified in micro seconds. */
284     Timer_PERIOD_HZ,      /*!< Period specified in hertz; interrupts per
285                                   second. */
286     Timer_PERIOD_COUNTS   /*!< Period specified in ticks or counts. Varies
287                                   from board to board. */
288 } Timer_PeriodUnits;
289 
290 /*!
291  *  @brief  Timer callback function
292  *
293  *  User definable callback function prototype. The timer driver will call the
294  *  defined function and pass in the timer driver's handle and the status code.
295  *
296  *  @param[in]  handle         Timer_Handle
297  *  @param[in]  status         Status of timer interrupt
298  */
299 typedef void (*Timer_CallBackFxn)(Timer_Handle handle, int_fast16_t status);
300 
301 /*!
302  *  @brief Timer Parameters
303  *
304  *  Timer parameters are used with the Timer_open() call. Default values for
305  *  these parameters are set using Timer_Params_init().
306  *
307  */
308 typedef struct {
309     /*! Mode to be used by the timer driver. */
310     Timer_Mode           timerMode;
311 
312     /*! Units used to specify the period. */
313     Timer_PeriodUnits    periodUnits;
314 
315     /*! Callback function called when timerMode is Timer_ONESHOT_CALLBACK or
316          Timer_CONTINUOUS_CALLBACK. */
317     Timer_CallBackFxn    timerCallback;
318 
319     /*! Period in units of periodUnits. */
320     uint32_t             period;
321 } Timer_Params;
322 
323 /*!
324  *  @brief      A function pointer to a driver specific implementation of
325  *              Timer_control().
326  */
327 typedef int_fast16_t (*Timer_ControlFxn)(Timer_Handle handle,
328     uint_fast16_t cmd, void *arg);
329 
330 /*!
331  *  @brief      A function pointer to a driver specific implementation of
332  *              Timer_close().
333  */
334 typedef void (*Timer_CloseFxn)(Timer_Handle handle);
335 
336 /*!
337  *  @brief      A function pointer to a driver specific implementation of
338  *              Timer_getCount().
339  */
340 typedef uint32_t (*Timer_GetCountFxn)(Timer_Handle handle);
341 
342 /*!
343  *  @brief      A function pointer to a driver specific implementation of
344  *              Timer_init().
345  */
346 typedef void (*Timer_InitFxn)(Timer_Handle handle);
347 
348 /*!
349  *  @brief      A function pointer to a driver specific implementation of
350  *              Timer_open().
351  */
352 typedef Timer_Handle (*Timer_OpenFxn)(Timer_Handle handle,
353     Timer_Params *params);
354 
355 /*!
356  *  @brief      A function pointer to a driver specific implementation of
357  *              Timer_setPeriod().
358  */
359 typedef int32_t (*Timer_SetPeriodFxn)(Timer_Handle handle,
360     Timer_PeriodUnits periodUnits, uint32_t period);
361 
362 /*!
363  *  @brief      A function pointer to a driver specific implementation of
364  *              Timer_start().
365  */
366 typedef int32_t (*Timer_StartFxn)(Timer_Handle handle);
367 
368 /*!
369  *  @brief      A function pointer to a driver specific implementation of
370  *              Timer_stop().
371  */
372 typedef void (*Timer_StopFxn)(Timer_Handle handle);
373 
374 /*!
375  *  @brief      The definition of a timer function table that contains the
376  *              required set of functions to control a specific timer driver
377  *              implementation.
378  */
379 typedef struct {
380     /*! Function to close the specified timer. */
381     Timer_CloseFxn closeFxn;
382 
383     /*! Implementation-specific control function. */
384     Timer_ControlFxn controlFxn;
385 
386     /*! Function to get the count of the specified timer. */
387     Timer_GetCountFxn getCountFxn;
388 
389     /*! Function to initialize the driver instance. */
390     Timer_InitFxn initFxn;
391 
392     /*! Function to open the specified timer. */
393     Timer_OpenFxn openFxn;
394 
395     /*! Function to set the period of the specified timer. */
396     Timer_SetPeriodFxn setPeriodFxn;
397 
398     /*! Function to start the specified timer. */
399     Timer_StartFxn startFxn;
400 
401     /*! Function to stop the specified timer. */
402     Timer_StopFxn stopFxn;
403 } Timer_FxnTable;
404 
405 /*!
406  *  @brief  Timer Global configuration
407  *
408  *  The Timer_Config structure contains a set of pointers used to characterize
409  *  the timer driver implementation.
410  *
411  *  This structure needs to be defined before calling Timer_init() and it must
412  *  not be changed thereafter.
413  *
414  *  @sa     Timer_init()
415  */
416 typedef struct Timer_Config_ {
417     /*! Pointer to a table of driver-specific implementations of timer APIs. */
418     Timer_FxnTable const *fxnTablePtr;
419 
420     /*! Pointer to a driver-specific data object. */
421     void                 *object;
422 
423     /*! Pointer to a driver-specific hardware attributes structure. */
424     void           const *hwAttrs;
425 } Timer_Config;
426 
427 /*!
428  *  @brief  Function to close a timer. The corresponding timer
429  *          becomes an available timer resource.
430  *
431  *  @pre    Timer_open() has been called.
432  *
433  *  @param[in]  handle  A Timer_Handle returned from Timer_open().
434  *
435  *  @sa     Timer_open()
436  */
437 extern void Timer_close(Timer_Handle handle);
438 
439 /*!
440  *  @brief  Function performs device-specific features on a given
441  *          timer.
442  *
443  *  @pre    Timer_open() has been called.
444  *
445  *  @param[in]  handle      A Timer_Handle returned from Timer_open().
446  *
447  *  @param[in]  cmd         A command value defined by the driver-specific
448  *                      implementation.
449  *
450  *  @param[in]  arg         A pointer to an optional R/W (read/write) argument that
451  *                      is accompanied with cmd.
452  *
453  *  @retval #Timer_STATUS_SUCCESS  The control call was successful.
454  *  @retval #Timer_STATUS_ERROR    The control call failed
455  *
456  *  @sa     Timer_open()
457  */
458 extern int_fast16_t Timer_control(Timer_Handle handle, uint_fast16_t cmd,
459     void *arg);
460 
461 /*!
462  *  @brief  Function to get the current count of a timer. The value returned
463  *          represents timer counts. The value returned is always
464  *          characteristic of an up counter. This is true even if the timer
465  *          peripheral is counting down. Some device-specific implementations
466  *          may employ a prescaler in addition to this timer count.
467  *
468  *  @pre    Timer_open() has been called.
469  *
470  *  @param[in]  handle  A Timer_Handle returned from Timer_open().
471  *
472  *  @sa     Timer_open()
473  *
474  *  @return The current count of the timer in timer ticks.
475  *
476  */
477 extern uint32_t Timer_getCount(Timer_Handle handle);
478 
479 
480 /*!
481  *  @brief  Function to initialize a timer. This function will go through
482  *          all available hardware resources and mark them as "available".
483  *
484  *  @pre    The Timer_config structure must exist before this function is
485  *          called, and must be persistent. This function must be called
486  *          before any other timer driver APIs.
487  *
488  *  @sa     Timer_open()
489  */
490 extern void Timer_init(void);
491 
492 /*!
493  *  @brief  Function to initialize a given timer peripheral specified by the
494  *          index argument. The Timer_Params specifies the mode the timer will
495  *          operate in. The accuracy of the desired period is limited by the
496  *          the clock. For example, a 100 MHz clock will have a tick resolution
497  *          of 10 nanoseconds. This function takes care of timer resource
498  *          allocation. If the particular timer is available to use, the timer
499  *          driver acquires it and returns a Timer_Handle.
500  *
501  *  @pre    Timer_init() has been called.
502  *
503  *  @param[in]  index         Logical peripheral number for the timer indexed into
504  *                        the Timer_config table.
505  *
506  *  @param[in]  params        Pointer to an parameter block, if NULL it will use
507  *                        default values.
508  *
509  *  @return A #Timer_Handle upon success, or NULL. NULL is returned if the
510  *          desired period results in overflow or saturation of the timer, or
511  *          if the timer resource is already in use.
512  *
513  *  @sa     Timer_init()
514  *  @sa     Timer_close()
515  */
516 extern Timer_Handle Timer_open(uint_least8_t index, Timer_Params *params);
517 
518 /*!
519  *  @brief  Function to set the period of a timer after it has been opened.
520  *
521  *  @pre    Timer_open() has been called. It is also recommended Timer_stop() has
522  *          been called on an already running timer before calling this API as the
523             period is updated asynchronously.
524  *
525  *  @param[in]  handle       A Timer_Handle returned from Timer_open().
526  *
527  *  @param[in]  periodUnits  #Timer_PeriodUnits of the desired period value.
528  *
529  *  @param[in]  period       Period value to set.
530  *
531  *  @retval #Timer_STATUS_SUCCESS  The setPeriod call was successful.
532  *  @retval #Timer_STATUS_ERROR    The setPeriod call failed.
533  *
534  *  @sa     Timer_open()
535  *  @sa     Timer_stop()
536  */
537 extern int32_t Timer_setPeriod(Timer_Handle handle, Timer_PeriodUnits periodUnits, uint32_t period);
538 
539 /*!
540  *  @brief  Function to initialize the Timer_Params struct to its defaults.
541  *
542  *  @param[in]  params      A pointer to Timer_Params structure for
543  *                      initialization.
544  *
545  *  Defaults values are:
546  *      timerMode = Timer_ONESHOT_BLOCKING
547  *      periodUnit = Timer_PERIOD_COUNTS
548  *      timerCallback = NULL
549  *      period = (uint16_t) ~0
550  */
551 extern void Timer_Params_init(Timer_Params *params);
552 
553 /*!
554  *  @brief  Function to start a timer.
555  *
556  *  @pre    Timer_open() has been called.
557  *
558  *  @param[in]  handle  A Timer_Handle returned from Timer_open().
559  *
560  *  @retval #Timer_STATUS_SUCCESS  The start call was successful.
561  *  @retval #Timer_STATUS_ERROR    The start call failed
562  *
563  *  @sa     Timer_stop()
564  */
565 extern int32_t Timer_start(Timer_Handle handle);
566 
567 /*!
568  *  @brief  Function to stop a timer. If the timer is already stopped this
569  *          function has no effect.
570  *
571  *  @pre    Timer_open() has been called.
572  *
573  *  @param[in]  handle  A Timer_Handle returned from Timer_open().
574  *
575  *  @sa     Timer_start()
576  */
577 extern void Timer_stop(Timer_Handle handle);
578 
579 #ifdef __cplusplus
580 }
581 #endif
582 
583 #endif /* ti_drivers_Timer__include */
584