1 /* 2 * Copyright (c) 2015-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 Watchdog.h 34 * 35 * @brief Watchdog driver interface 36 * 37 * @anchor ti_drivers_Watchdog_Overview 38 * # Overview # 39 * 40 * A watchdog timer can be used to generate a reset signal if a system has 41 * become unresponsive. The Watchdog driver simplifies configuring and 42 * starting the watchdog peripherals. The watchdog peripheral can be 43 * configured with resets either on or off and a user-specified timeout 44 * period. 45 * 46 * When the watchdog peripheral is configured not to generate a reset, it 47 * can be used to cause a hardware interrupt at a programmable interval. 48 * The driver provides the ability to specify a user-provided callback 49 * function that is called when the watchdog causes an interrupt. 50 * 51 * The Watchdog driver simplifies configuring and starting the Watchdog 52 * peripherals. The Watchdog can be set up to produce a reset signal after a 53 * timeout, or simply cause a hardware interrupt at a programmable interval. 54 * The driver provides the ability to specify a callback function that is 55 * called when the Watchdog causes an interrupt. 56 * 57 * When resets are turned on, it is the user application's responsibility to 58 * call Watchdog_clear() in order to clear the Watchdog and prevent a reset. 59 * Watchdog_clear() can be called at any time. 60 * 61 * @anchor ti_drivers_Watchdog_Usage 62 * # Usage # 63 * 64 * This section will cover driver usage. 65 * @anchor ti_drivers_Watchdog_Synopsis 66 * ## Synopsis # 67 * 68 * Open the driver with default settings: 69 * @code 70 * Watchdog_Handle watchdogHandle; 71 * 72 * Watchdog_init(); 73 * watchdogHandle = Watchdog_open(WATCHDOG_INDEX, NULL); 74 * if (watchdogHandle == NULL) { 75 * // Spin forever 76 * while(1); 77 * } 78 * @endcode 79 * 80 * The Watchdog driver must be initialized by calling Watchdog_init(), 81 * before any other Watchdog APIs can be called. 82 * Once the watchdog is initialized, a Watchdog object can be created 83 * through the following steps: 84 * - Create and initialize the #Watchdog_Params structure. 85 * - Assign desired values to parameters. 86 * - Call Watchdog_open(). 87 * - Save the Watchdog_Handle returned by Watchdog_open(). This will be 88 * used to interact with the Watchdog object just created. 89 * 90 * To have a user-defined function run at the hardware interrupt caused by 91 * a watchdog timer timeout, define a function of the following type: 92 * @code 93 * typedef void (*Watchdog_Callback)(uintptr_t); 94 * @endcode 95 * Then pass the function to Watchdog_open() through the #Watchdog_Params 96 * structure. 97 * 98 * An example of the Watchdog creation process that uses a callback 99 * function: 100 * @anchor ti_drivers_Watchdog_example_callback 101 * @code 102 * void UserCallbackFxn(Watchdog_Handle handle) 103 * { 104 * printf("Watchdog timer triggered!\n"); 105 * releaseResources(); 106 * } 107 * 108 * ... 109 * 110 * Watchdog_Params params; 111 * Watchdog_Handle watchdogHandle; 112 * 113 * Watchdog_init(); 114 * 115 * Watchdog_Params_init(¶ms); 116 * params.resetMode = Watchdog_RESET_ON; 117 * params.callbackFxn = (Watchdog_Callback) UserCallbackFxn; 118 * 119 * watchdogHandle = Watchdog_open(CONFIG_WATCHDOG0, ¶ms); 120 * if (watchdogHandle == NULL) { 121 * // Error opening Watchdog 122 * while (1); 123 * } 124 * 125 * @endcode 126 * 127 * If no #Watchdog_Params structure is passed to Watchdog_open(), the 128 * default values are used. By default, the Watchdog driver has resets 129 * turned on, no callback function specified, and stalls the timer at 130 * breakpoints during debugging. 131 * 132 * Options for the resetMode parameter are #Watchdog_RESET_ON and 133 * #Watchdog_RESET_OFF. The latter allows the watchdog to be used like 134 * another timer interrupt. When resetMode is #Watchdog_RESET_ON, it is up 135 * to the application to call Watchdog_clear() to clear the Watchdog 136 * interrupt flag to prevent a reset. Watchdog_clear() can be called at 137 * any time. 138 * 139 * @anchor ti_drivers_Watchdog_Examples 140 * # Examples 141 * - @ref ti_drivers_Watchdog_Synopsis "Default Example" 142 * - @ref ti_drivers_Watchdog_example_callback "Callback Function before watchdog reset" 143 * 144 * @anchor ti_drivers_Watchdog_Configuration 145 * # Configuration 146 * 147 * Refer to the @ref driver_configuration "Driver's Configuration" section 148 * for more information. 149 * 150 ******************************************************************************* 151 */ 152 153 #ifndef ti_drivers_Watchdog__include 154 #define ti_drivers_Watchdog__include 155 156 #include <stdint.h> 157 158 #ifdef __cplusplus 159 extern "C" { 160 #endif 161 162 /** 163 * @defgroup Watchdog_CONTROL Watchdog_control command and status codes 164 * These Watchdog macros are reservations for Watchdog.h 165 * @{ 166 */ 167 168 /*! 169 * Common Watchdog_control command code reservation offset. 170 * Watchdog driver implementations should offset command codes with 171 * Watchdog_CMD_RESERVED growing positively 172 * 173 * Example implementation specific command codes: 174 * @code 175 * #define WatchdogXYZ_CMD_COMMAND0 Watchdog_CMD_RESERVED + 0 176 * #define WatchdogXYZ_CMD_COMMAND1 Watchdog_CMD_RESERVED + 1 177 * @endcode 178 */ 179 #define Watchdog_CMD_RESERVED (32) 180 181 /*! 182 * Common Watchdog_control status code reservation offset. 183 * Watchdog driver implementations should offset status codes with 184 * Watchdog_STATUS_RESERVED growing negatively. 185 * 186 * Example implementation specific status codes: 187 * @code 188 * #define WatchdogXYZ_STATUS_ERROR0 Watchdog_STATUS_RESERVED - 0 189 * #define WatchdogXYZ_STATUS_ERROR1 Watchdog_STATUS_RESERVED - 1 190 * #define WatchdogXYZ_STATUS_ERROR2 Watchdog_STATUS_RESERVED - 2 191 * @endcode 192 */ 193 #define Watchdog_STATUS_RESERVED (-32) 194 195 /** 196 * @defgroup Watchdog_STATUS Status Codes 197 * Watchdog_STATUS_* macros are general status codes returned by Watchdog_control() 198 * @{ 199 * @ingroup Watchdog_CONTROL 200 */ 201 202 /*! 203 * @brief Successful status code returned by Watchdog_control(). 204 * 205 * Watchdog_control() returns Watchdog_STATUS_SUCCESS if the control code was 206 * executed successfully. 207 */ 208 #define Watchdog_STATUS_SUCCESS (0) 209 210 /*! 211 * @brief Generic error status code returned by Watchdog_control(). 212 * 213 * Watchdog_control() returns Watchdog_STATUS_ERROR if the control code was not 214 * executed successfully. 215 */ 216 #define Watchdog_STATUS_ERROR (-1) 217 218 /*! 219 * @brief An error status code returned by Watchdog_control() for undefined 220 * command codes. 221 * 222 * Watchdog_control() returns Watchdog_STATUS_UNDEFINEDCMD if the control code 223 * is not recognized by the driver implementation. 224 */ 225 #define Watchdog_STATUS_UNDEFINEDCMD (-2) 226 227 /*! 228 * @brief An error status code returned by Watchdog_setReload() for drivers 229 * which do not support the aforementioned API. 230 * 231 * Watchdog_setReload() returns Watchdog_STATUS_UNSUPPORTED if the driver 232 * implementation does not support the aforementioned API. 233 */ 234 #define Watchdog_STATUS_UNSUPPORTED (-3) 235 /** @}*/ 236 237 /** 238 * @defgroup Watchdog_CMD Command Codes 239 * Watchdog_CMD_* macros are general command codes for Watchdog_control(). Not all Watchdog 240 * driver implementations support these command codes. 241 * @{ 242 * @ingroup Watchdog_CONTROL 243 */ 244 245 /* Add Watchdog_CMD_<commands> here */ 246 247 /** @}*/ 248 249 /** @}*/ 250 251 /*! 252 * @brief Watchdog Handle 253 */ 254 typedef struct Watchdog_Config_ *Watchdog_Handle; 255 256 /*! 257 * @brief Watchdog debug stall settings 258 * 259 * This enumeration defines the debug stall modes for the Watchdog. On some 260 * targets, the Watchdog timer will continue to count down while a debugging 261 * session is halted. To avoid unwanted resets, the Watchdog can be set to 262 * stall while the processor is stopped by the debugger. 263 */ 264 typedef enum { 265 Watchdog_DEBUG_STALL_ON, /*!< Watchdog will be stalled at breakpoints */ 266 Watchdog_DEBUG_STALL_OFF /*!< Watchdog will keep running at breakpoints */ 267 } Watchdog_DebugMode; 268 269 /*! 270 * @brief Watchdog reset mode settings 271 * 272 * This enumeration defines the reset modes for the Watchdog. The Watchdog can 273 * be configured to either generate a reset upon timeout or simply produce a 274 * periodic interrupt. 275 */ 276 typedef enum { 277 Watchdog_RESET_OFF, /*!< Timeouts generate interrupts only */ 278 Watchdog_RESET_ON /*!< Generates reset after timeout */ 279 } Watchdog_ResetMode; 280 281 /*! 282 * @brief Watchdog callback pointer 283 * 284 * This is the typedef for the function pointer that will allow a callback 285 * function to be specified in the #Watchdog_Params structure. The function 286 * will take a #Watchdog_Handle of the Watchdog causing the interrupt (cast as 287 * a uintptr_t) as an argument. 288 */ 289 typedef void (*Watchdog_Callback)(uintptr_t handle); 290 291 /*! 292 * @brief Watchdog Parameters 293 * 294 * Watchdog parameters are used to with the Watchdog_open() call. Default 295 * values for these parameters are set using Watchdog_Params_init(). 296 * 297 * @sa Watchdog_Params_init() 298 */ 299 typedef struct { 300 Watchdog_Callback callbackFxn; /*!< Pointer to callback. Not supported 301 on all targets. */ 302 Watchdog_ResetMode resetMode; /*!< Mode to enable resets. 303 Not supported on all targets. */ 304 Watchdog_DebugMode debugStallMode; /*!< Mode to stall WDT at breakpoints. 305 Not supported on all targets. */ 306 void *custom; /*!< Custom argument used by driver 307 implementation */ 308 } Watchdog_Params; 309 310 /*! 311 * @brief A function pointer to a driver specific implementation of 312 * Watchdog_clear(). 313 */ 314 typedef void (*Watchdog_ClearFxn) (Watchdog_Handle handle); 315 316 /*! 317 * @brief A function pointer to a driver specific implementation of 318 * Watchdog_close(). 319 */ 320 typedef void (*Watchdog_CloseFxn) (Watchdog_Handle handle); 321 322 /*! 323 * @brief A function pointer to a driver specific implementation of 324 * Watchdog_control(). 325 */ 326 typedef int_fast16_t (*Watchdog_ControlFxn) (Watchdog_Handle handle, 327 uint_fast16_t cmd, 328 void *arg); 329 330 /*! 331 * @brief A function pointer to a driver specific implementation of 332 * Watchdog_init(). 333 */ 334 typedef void (*Watchdog_InitFxn) (Watchdog_Handle handle); 335 336 /*! 337 * @brief A function pointer to a driver specific implementation of 338 * Watchdog_open(). 339 */ 340 typedef Watchdog_Handle (*Watchdog_OpenFxn) (Watchdog_Handle handle, 341 Watchdog_Params *params); 342 343 /*! 344 * @brief A function pointer to a driver specific implementation of 345 * Watchdog_setReload(). 346 */ 347 typedef int_fast16_t (*Watchdog_SetReloadFxn)(Watchdog_Handle handle, 348 uint32_t ticks); 349 350 /*! 351 * @brief A function pointer to a driver specific implementation of 352 * Watchdog_ConvertMsToTicksFxn(). 353 */ 354 typedef uint32_t (*Watchdog_ConvertMsToTicksFxn) (Watchdog_Handle handle, 355 uint32_t milliseconds); 356 357 /*! 358 * @brief The definition of a Watchdog function table that contains the 359 * required set of functions to control a specific Watchdog driver 360 * implementation. 361 */ 362 typedef struct { 363 Watchdog_ClearFxn watchdogClear; 364 Watchdog_CloseFxn watchdogClose; 365 Watchdog_ControlFxn watchdogControl; 366 Watchdog_InitFxn watchdogInit; 367 Watchdog_OpenFxn watchdogOpen; 368 Watchdog_SetReloadFxn watchdogSetReload; 369 Watchdog_ConvertMsToTicksFxn watchdogConvertMsToTicks; 370 } Watchdog_FxnTable; 371 372 /*! 373 * @brief Watchdog Global configuration 374 * 375 * The Watchdog_Config structure contains a set of pointers used to 376 * characterize the Watchdog driver implementation. 377 * 378 * This structure needs to be defined before calling Watchdog_init() and 379 * it must not be changed thereafter. 380 * 381 * @sa Watchdog_init() 382 */ 383 typedef struct Watchdog_Config_ { 384 /*! 385 * Pointer to a table of driver-specific implementations of Watchdog APIs 386 */ 387 Watchdog_FxnTable const *fxnTablePtr; 388 389 /*! Pointer to a driver specific data object */ 390 void *object; 391 392 /*! Pointer to a driver specific hardware attributes structure */ 393 void const *hwAttrs; 394 } Watchdog_Config; 395 396 /*! 397 * @brief Clears the Watchdog 398 * 399 * Clears the Watchdog to to prevent a reset signal from being generated if the 400 * module is in #Watchdog_RESET_ON reset mode. 401 * 402 * @param handle A #Watchdog_Handle 403 */ 404 extern void Watchdog_clear(Watchdog_Handle handle); 405 406 /*! 407 * @brief Function to close a Watchdog peripheral specified by the Watchdog 408 * handle.It stops (holds) the Watchdog counting on applicable 409 * platforms. 410 * 411 * @pre Watchdog_open() has to be called first. 412 * 413 * @param handle A #Watchdog_Handle returned from Watchdog_open() 414 * 415 * @sa Watchdog_open() 416 */ 417 extern void Watchdog_close(Watchdog_Handle handle); 418 419 /*! 420 * @brief Function performs implementation specific features on a given 421 * #Watchdog_Handle. 422 * 423 * Commands for Watchdog_control can originate from Watchdog.h or from implementation 424 * specific Watchdog*.h files. 425 * While commands from Watchdog.h are API portable across driver implementations, 426 * not all implementations may support all these commands. 427 * Conversely, commands from driver implementation specific Watchdog*.h files add 428 * unique driver capabilities but are not API portable across all Watchdog driver 429 * implementations. 430 * 431 * Commands supported by Watchdog.h follow a Watchdog_CMD_\<cmd\> naming 432 * convention.<br> 433 * Commands supported by Watchdog*.h follow a Watchdog*_CMD_\<cmd\> naming 434 * convention.<br> 435 * Each control command defines @b arg differently. The types of @b arg are 436 * documented with each command. 437 * 438 * See @ref Watchdog_CMD "Watchdog_control command codes" for command codes. 439 * 440 * See @ref Watchdog_STATUS "Watchdog_control return status codes" for status codes. 441 * 442 * @pre Watchdog_open() has to be called first. 443 * 444 * @param handle A #Watchdog_Handle returned from Watchdog_open() 445 * 446 * @param cmd Watchdog.h or Watchdog*.h commands. 447 * 448 * @param arg An optional R/W (read/write) command argument 449 * accompanied with cmd 450 * 451 * @return Implementation specific return codes. Negative values indicate 452 * unsuccessful operations. 453 * 454 * @sa Watchdog_open() 455 */ 456 extern int_fast16_t Watchdog_control(Watchdog_Handle handle, 457 uint_fast16_t cmd, 458 void *arg); 459 460 /*! 461 * @brief Initializes the Watchdog module 462 * 463 * The application-provided Watchdog_config must be present before the 464 * Watchdog_init() function is called. The Watchdog_config must be persistent 465 * and not changed after Watchdog_init is called. This function must be called 466 * before any of the other Watchdog driver APIs. 467 */ 468 extern void Watchdog_init(void); 469 470 /*! 471 * @brief Opens a Watchdog 472 * 473 * Opens a Watchdog object with the index and parameters specified, and 474 * returns a #Watchdog_Handle. 475 * 476 * @param index Logical peripheral number for the Watchdog indexed 477 * into the Watchdog_config table 478 * 479 * @param params Pointer to a #Watchdog_Params, if NULL it will use 480 * default values. All the fields in this structure are 481 * RO (read-only). 482 * 483 * @return A #Watchdog_Handle on success or a NULL on an error or if it has 484 * been opened already. 485 * 486 * @sa Watchdog_init() 487 * @sa Watchdog_close() 488 */ 489 extern Watchdog_Handle Watchdog_open(uint_least8_t index, Watchdog_Params *params); 490 491 /*! 492 * @brief Function to initialize the #Watchdog_Params structure to its defaults 493 * 494 * @param params An pointer to #Watchdog_Params structure for 495 * initialization 496 * 497 * Default parameters: 498 * callbackFxn = NULL 499 * resetMode = #Watchdog_RESET_ON 500 * debugStallMode = #Watchdog_DEBUG_STALL_ON 501 */ 502 extern void Watchdog_Params_init(Watchdog_Params *params); 503 504 /*! 505 * @brief Sets the Watchdog reload value 506 * 507 * Sets the value from which the Watchdog will countdown after it reaches 508 * zero. This is how the reload value can be changed after the Watchdog has 509 * already been opened. The new reload value will be loaded into the Watchdog 510 * timer when this function is called. Watchdog_setReload is not reentrant. 511 * For CC13XX/CC26XX, if the parameter 'ticks' is set to zero (0), a Watchdog 512 * interrupt is immediately generated. 513 * 514 * This API is not applicable for all platforms. See the page for your 515 * specific driver implementation for details. 516 * 517 * @param handle A #Watchdog_Handle 518 * 519 * @param ticks Value to be loaded into Watchdog timer 520 * Unit is in Watchdog clock ticks 521 * 522 * @return #Watchdog_STATUS_SUCCESS on success, #Watchdog_STATUS_UNSUPPORTED 523 * if driver does not support this API. 524 */ 525 extern int_fast16_t Watchdog_setReload(Watchdog_Handle handle, uint32_t ticks); 526 527 /*! 528 * @brief Converts milliseconds to Watchdog clock ticks 529 * 530 * Converts the input value into number of Watchdog clock ticks as close as 531 * possible. If the converted value exceeds 32 bits, a zero (0) will be 532 * returned to indicate overflow. The converted value can be used as the 533 * function parameter 'ticks' in Watchdog_setReload(). 534 * 535 * This API is not applicable for all platforms. See the page for your 536 * specific driver implementation for details. 537 * 538 * @param handle A #Watchdog_Handle 539 * 540 * @param milliseconds Value to be converted 541 * 542 * @return Converted value in number of Watchdog clock ticks 543 * A value of zero (0) means the converted value exceeds 32 bits 544 * or that the operation is not supported for the specific device. 545 * 546 * @sa Watchdog_setReload() 547 */ 548 extern uint32_t Watchdog_convertMsToTicks(Watchdog_Handle handle, 549 uint32_t milliseconds); 550 551 #ifdef __cplusplus 552 } 553 #endif 554 555 #endif /* ti_drivers_Watchdog__include */ 556