123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /*
- * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /******************************************************************************
- * @file dw_wdt.c
- * @brief CSI Source File for WDT Driver
- * @version V1.0
- * @date 02. June 2017
- ******************************************************************************/
- #include <stdio.h>
- #include "csi_core.h"
- #include "drv_wdt.h"
- #include "dw_wdt.h"
- #include "soc.h"
- #define ERR_WDT(errno) (CSI_DRV_ERRNO_WDT_BASE | errno)
- static uint32_t timeout_ms[16] = {4, 7, 13, 26, 52, 105, 210, 419, 839, 1678, 3355, 6711,
- 13422, 26844, 53687, 107374
- };
- #define WDT_NULL_PARAM_CHK(para) \
- do { \
- if (para == NULL) { \
- return ERR_WDT(EDRV_PARAMETER); \
- } \
- } while (0)
- typedef struct {
- uint32_t base;
- uint32_t irq;
- wdt_event_cb_t cb_event;
- } dw_wdt_priv_t;
- static dw_wdt_priv_t wdt_instance[CONFIG_WDT_NUM];
- /* Driver Capabilities */
- static const wdt_capabilities_t wdt_capabilities = {
- .interrupt = 1, ///< supports interrupt
- };
- static inline void dw_wdt_enable(dw_wdt_reg_t *addr)
- {
- uint32_t value = addr->WDT_CR;
- value |= 1 << 0;
- addr->WDT_CR = value;
- }
- static inline void dw_wdt_disable(dw_wdt_reg_t *addr)
- {
- uint32_t value = addr->WDT_CR;
- value &= ~(1 << 0);
- addr->WDT_CR = value;
- }
- void dw_wdt_irqhandler(int32_t idx)
- {
- dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
- dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
- addr->WDT_EOI;
- if (wdt_priv->cb_event) {
- wdt_priv->cb_event(WDT_EVENT_TIMEOUT);
- }
- }
- int32_t __attribute__((weak)) target_get_wdt_count(void)
- {
- return 0;
- }
- int32_t __attribute__((weak)) target_get_wdt(uint32_t idx, uint32_t *base, uint32_t *irq)
- {
- return NULL;
- }
- /**
- \brief get wdt instance count.
- \return wdt instance count
- */
- int32_t csi_wdt_get_instance_count(void)
- {
- return target_get_wdt_count();
- }
- /**
- \brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
- \param[in] idx must not exceed return value of csi_wdt_get_instance_count()
- \param[in] cb_event Pointer to \ref wdt_event_cb_t
- \return pointer to wdt instance
- */
- wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event)
- {
- if (idx < 0 || idx >= CONFIG_WDT_NUM) {
- return NULL;
- }
- uint32_t base = 0u;
- uint32_t irq = 0u;
- int32_t real_idx = target_get_wdt(idx, &base, &irq);
- if (real_idx != idx) {
- return NULL;
- }
- dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
- wdt_priv->base = base;
- wdt_priv->irq = irq;
- wdt_priv->cb_event = cb_event;
- drv_nvic_enable_irq(wdt_priv->irq);
- return (wdt_handle_t)wdt_priv;
- }
- /**
- \brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
- \param[in] instance wdt instance to operate.
- \return \ref execution_status
- */
- int32_t csi_wdt_uninitialize(wdt_handle_t handle)
- {
- WDT_NULL_PARAM_CHK(handle);
- dw_wdt_priv_t *wdt_priv = handle;
- wdt_priv->cb_event = NULL;
- drv_nvic_disable_irq(wdt_priv->irq);
- return 0;
- }
- /**
- \brief Get driver capabilities.
- \param[in] wdt instance to operate.
- \return \ref wdt_capabilities_t
- */
- wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle)
- {
- return wdt_capabilities;
- }
- /**
- \brief Set the WDT value. value = (2^t*0xffff * 10^6 /freq)/10^3(t: 0 ~ 15).
- \param[in] handle wdt handle to operate.
- \param[in] value the timeout value(ms) \ref:timeout_ms[]
- \return \ref execution_status
- */
- int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value)
- {
- WDT_NULL_PARAM_CHK(handle);
- uint32_t i = 0u;
- for (i = 0; i <= 15 ; i++) {
- if (timeout_ms[i] == value) {
- break;
- }
- if (i == 15) {
- return ERR_WDT(EDRV_PARAMETER);
- }
- }
- dw_wdt_priv_t *wdt_priv = handle;
- dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
- uint32_t config = addr->WDT_CR;
- uint32_t en_stat = 0; /*origin wdt enable status*/
- if ((config & 0x1) != 0) {
- en_stat = 1;
- }
- config = 0;
- addr->WDT_CR = config;
- /*before configuration, must disable wdt first*/
- dw_wdt_disable(addr);
- i += i << 4;
- addr->WDT_TORR = i;
- if (en_stat == 1) {
- dw_wdt_enable(addr);
- csi_wdt_restart(handle);
- }
- return 0;
- }
- /**
- \brief Start the WDT.
- \param[in] handle wdt handle to operate.
- \return \ref execution_status
- */
- int32_t csi_wdt_start(wdt_handle_t handle)
- {
- WDT_NULL_PARAM_CHK(handle);
- dw_wdt_priv_t *wdt_priv = handle;
- dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
- dw_wdt_enable(addr);
- csi_wdt_restart(handle);
- return 0;
- }
- /**
- \brief Stop the WDT.
- \param[in] handle wdt handle to operate.
- \return \ref execution_status
- */
- int32_t csi_wdt_stop(wdt_handle_t handle)
- {
- WDT_NULL_PARAM_CHK(handle);
- return ERR_WDT(EDRV_UNSUPPORTED);
- }
- /**
- \brief Restart the WDT.
- \param[in] handle wdt handle to operate.
- \return \ref execution_status
- */
- int32_t csi_wdt_restart(wdt_handle_t handle)
- {
- WDT_NULL_PARAM_CHK(handle);
- dw_wdt_priv_t *wdt_priv = handle;
- dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
- addr->WDT_CRR = DW_WDT_CRR_RESET;
- return 0;
- }
- /**
- \brief Read the WDT Current value.
- \param[in] handle wdt handle to operate.
- \param[in] value Pointer to the Value.
- \return \ref execution_status
- */
- int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value)
- {
- WDT_NULL_PARAM_CHK(handle);
- dw_wdt_priv_t *wdt_priv = handle;
- dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
- *value = addr->WDT_CCVR;
- return 0;
- }
|