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(¶ms); 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, ¶ms); 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(¶ms); 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, ¶ms); 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(¶ms); 110 * handle = Timer_open(CONFIG_TIMER0, ¶ms); 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(¶ms); 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, ¶ms); 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