1 /*
2  * Copyright (c) 2016-2017 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * \file arm_watchdog_drv.h
19  * \brief Generic driver for ARM watchdogs.
20  */
21 
22 #ifndef __ARM_WATCHDOG_DRV_H__
23 #define __ARM_WATCHDOG_DRV_H__
24 
25 #include <stdint.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 enum arm_watchdog_error_t {
32     ARM_WATCHDOG_ERR_NONE = 0,  /*!< No error */
33     ARM_WATCHDOG_ERR_NOT_INIT,  /*!< Watchdog is not initialized */
34     ARM_WATCHDOG_ERR_NOT_ENAB,  /*!< Watchdog is not enabled */
35     ARM_WATCHDOG_ERR_LOCKED     /*!< Watchdog is locked */
36 };
37 
38 /* ARM watchdog device configuration structure */
39 struct arm_watchdog_dev_cfg_t {
40     const uint32_t base;  /*!< Watchdog base address */
41 };
42 
43 /* ARM watchdog device data structure */
44 struct arm_watchdog_dev_data_t {
45     uint32_t state;    /*!< Indicates if the watchdog
46                             is initialized and enabled */
47     uint32_t timeout;  /*!< Timeout to reset in cycles */
48 };
49 
50 /* ARM watchdog device structure */
51 struct arm_watchdog_dev_t {
52     const struct arm_watchdog_dev_cfg_t* const cfg;  /*!< Watchdog
53                                                           configuration */
54     struct arm_watchdog_dev_data_t* const data;      /*!< Watchdog data */
55 };
56 
57 /**
58  * \brief Initializes a watchdog hardware.
59  *
60  * \param[in] dev      Watchdog to be initialized \ref arm_watchdog_dev_t
61  * \param[in] timeout  Timeout in cycles - 0 assings timeout to max value.
62  *
63  * \note This function doesn't check if dev is NULL.
64  *       This function leaves the watchdog locked. Before any further
65  *       operations, it needs to be unlocked and locked again.
66  */
67 void arm_watchdog_init(struct arm_watchdog_dev_t* dev, uint32_t timeout);
68 
69 /**
70  * \brief Feeds the watchdog to not cause a reset.
71  *
72  * \param[in] dev  Watchdog to be fed \ref arm_watchdog_dev_t
73  *
74  * \return Returns error code as specified in \ref arm_watchdog_error_t
75  *
76  * \note This function doesn't check if dev is NULL.
77  */
78 enum arm_watchdog_error_t arm_watchdog_feed(struct arm_watchdog_dev_t* dev);
79 
80 /**
81  * \brief Clear the interrupt and load timeout value to the load register.
82  *
83  * \param[in] dev  Watchdog to be fed \ref arm_watchdog_dev_t
84  *
85  * \return Returns error code as specified in \ref arm_watchdog_error_t
86  *
87  * \note This function doesn't check if dev is NULL.
88  */
89 enum arm_watchdog_error_t
90 arm_watchdog_clear_interrupt_and_refresh_counter(
91      struct arm_watchdog_dev_t* dev);
92 
93 /**
94  * \brief Enables the watchdog.
95  *
96  * \param[in] dev  Watchdog to be enabled \ref arm_watchdog_dev_t
97  *
98  * \return Returns error code as specified in \ref arm_watchdog_error_t
99  *
100  * \note This function doesn't check if dev is NULL.
101  */
102 enum arm_watchdog_error_t arm_watchdog_enable(struct arm_watchdog_dev_t* dev);
103 
104 /**
105  * \brief Checks if the watchdog is enabled
106  *
107  * \param[in] dev Watchdog to be checked \ref arm_watchdog_dev_t
108  *
109  * \return 1 if watchdog is enabled, 0 otherwise.
110  *
111  * \note This function doesn't check if dev is NULL.
112  */
113 uint32_t arm_watchdog_is_enabled(struct arm_watchdog_dev_t* dev);
114 
115 /**
116  * \brief Disables the watchdog.
117  *
118  * \param[in] dev  Watchdog to be disabled \ref arm_watchdog_dev_t
119  *
120  * \return 1 if watchdog is enabled, 0 otherwise.
121  *
122  * \note This function doesn't check if dev is NULL.
123  */
124 enum arm_watchdog_error_t arm_watchdog_disable(struct arm_watchdog_dev_t* dev);
125 
126 /**
127  * \brief Locks the registers to not be written again.
128  *
129  * \param[in] dev  Watchdog to be locked \ref arm_watchdog_dev_t
130  *
131  * \note This function doesn't check if dev is NULL.
132  */
133 void arm_watchdog_lock(struct arm_watchdog_dev_t* dev);
134 
135 /**
136  * \brief Checks if the watchdog registers are locked
137  *
138  * \param[in] dev Watchdog to be checked \ref arm_watchdog_dev_t
139  *
140  * \return 1 if the registers are locked, 0 otherwise
141  *
142  * \note This function doesn't check if dev is NULL.
143  */
144 uint32_t arm_watchdog_is_locked(struct arm_watchdog_dev_t* dev);
145 
146 /**
147  * \brief Unlocks the registers to configure the watchdog again.
148  *
149  * \param[in] dev  Watchdog to be unlocked \ref arm_watchdog_dev_t
150  *
151  * \note This function doesn't check if dev is NULL.
152  */
153 void arm_watchdog_unlock(struct arm_watchdog_dev_t* dev);
154 
155 /**
156  * \brief Provides watchdog remaining time before reset.
157  *
158  * \param[in] dev  Watchdog to get the remaining time \ref arm_watchdog_dev_t
159  *
160  * \return 0 if watchdog is disabled.
161  *
162  * \note This function doesn't check if dev is NULL.
163  */
164 uint32_t arm_watchdog_get_remaining_time(struct arm_watchdog_dev_t* dev);
165 
166 #ifdef __cplusplus
167 }
168 #endif
169 #endif /* __ARM_WATCHDOG_DRV_H__ */
170