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(&params);
116  *  params.resetMode = Watchdog_RESET_ON;
117  *  params.callbackFxn = (Watchdog_Callback) UserCallbackFxn;
118  *
119  *  watchdogHandle = Watchdog_open(CONFIG_WATCHDOG0, &params);
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