2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 /******************************************************************************
19 * @brief CSI Source File for WDT Driver
22 ******************************************************************************/
29 #define ERR_WDT(errno) (CSI_DRV_ERRNO_WDT_BASE | errno)
31 static uint32_t timeout_ms[16] = {4, 7, 13, 26, 52, 105, 210, 419, 839, 1678, 3355, 6711,
32 13422, 26844, 53687, 107374
35 #define WDT_NULL_PARAM_CHK(para) \
38 return ERR_WDT(EDRV_PARAMETER); \
45 wdt_event_cb_t cb_event;
48 extern int32_t target_get_wdt_count(void);
49 extern int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq);
51 static dw_wdt_priv_t wdt_instance[CONFIG_WDT_NUM];
53 /* Driver Capabilities */
54 static const wdt_capabilities_t wdt_capabilities = {
55 .interrupt = 1, ///< supports interrupt
58 static inline void dw_wdt_enable(dw_wdt_reg_t *addr)
60 uint32_t value = addr->WDT_CR;
65 static inline void dw_wdt_disable(dw_wdt_reg_t *addr)
67 uint32_t value = addr->WDT_CR;
73 void dw_wdt_irqhandler(int32_t idx)
75 dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
76 dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
80 if (wdt_priv->cb_event) {
81 wdt_priv->cb_event(WDT_EVENT_TIMEOUT);
86 \brief get wdt instance count.
87 \return wdt instance count
89 int32_t csi_wdt_get_instance_count(void)
91 return target_get_wdt_count();
95 \brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
96 \param[in] idx must not exceed return value of csi_wdt_get_instance_count()
97 \param[in] cb_event Pointer to \ref wdt_event_cb_t
98 \return pointer to wdt instance
100 wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event)
102 if (idx < 0 || idx >= CONFIG_WDT_NUM) {
109 int32_t real_idx = target_get_wdt(idx, &base, &irq);
111 if (real_idx != idx) {
115 dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
116 wdt_priv->base = base;
119 wdt_priv->cb_event = cb_event;
120 drv_nvic_enable_irq(wdt_priv->irq);
122 return (wdt_handle_t)wdt_priv;
126 \brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
127 \param[in] instance wdt instance to operate.
128 \return \ref execution_status
130 int32_t csi_wdt_uninitialize(wdt_handle_t handle)
132 WDT_NULL_PARAM_CHK(handle);
134 dw_wdt_priv_t *wdt_priv = handle;
136 wdt_priv->cb_event = NULL;
137 drv_nvic_disable_irq(wdt_priv->irq);
141 \brief Get driver capabilities.
142 \param[in] wdt instance to operate.
143 \return \ref wdt_capabilities_t
145 wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle)
147 return wdt_capabilities;
151 \brief Set the WDT value. value = (2^t*0xffff * 10^6 /freq)/10^3(t: 0 ~ 15).
152 \param[in] handle wdt handle to operate.
153 \param[in] value the timeout value(ms) \ref:timeout_ms[]
154 \return \ref execution_status
156 int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value)
158 WDT_NULL_PARAM_CHK(handle);
161 for (i = 0; i <= 15 ; i++) {
162 if (timeout_ms[i] == value) {
167 return ERR_WDT(EDRV_PARAMETER);
171 dw_wdt_priv_t *wdt_priv = handle;
172 dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
174 uint32_t config = addr->WDT_CR;
175 uint32_t en_stat = 0; /*origin wdt enable status*/
177 if ((config & 0x1) != 0) {
182 addr->WDT_CR = config;
184 /*before configuration, must disable wdt first*/
185 dw_wdt_disable(addr);
191 csi_wdt_restart(handle);
198 \brief Start the WDT.
199 \param[in] handle wdt handle to operate.
200 \return \ref execution_status
202 int32_t csi_wdt_start(wdt_handle_t handle)
204 WDT_NULL_PARAM_CHK(handle);
206 dw_wdt_priv_t *wdt_priv = handle;
207 dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
210 csi_wdt_restart(handle);
216 \param[in] handle wdt handle to operate.
217 \return \ref execution_status
219 int32_t csi_wdt_stop(wdt_handle_t handle)
221 WDT_NULL_PARAM_CHK(handle);
223 return ERR_WDT(EDRV_UNSUPPORTED);
227 \brief Restart the WDT.
228 \param[in] handle wdt handle to operate.
229 \return \ref execution_status
231 int32_t csi_wdt_restart(wdt_handle_t handle)
233 WDT_NULL_PARAM_CHK(handle);
235 dw_wdt_priv_t *wdt_priv = handle;
236 dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
238 addr->WDT_CRR = DW_WDT_CRR_RESET;
244 \brief Read the WDT Current value.
245 \param[in] handle wdt handle to operate.
246 \param[in] value Pointer to the Value.
247 \return \ref execution_status
249 int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value)
251 WDT_NULL_PARAM_CHK(handle);
253 dw_wdt_priv_t *wdt_priv = handle;
254 dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
256 *value = addr->WDT_CCVR;