diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.c b/APP_Framework/Framework/transform_layer/xizi/transform.c index 6d2e69dd6..c3bd52813 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.c +++ b/APP_Framework/Framework/transform_layer/xizi/transform.c @@ -171,6 +171,7 @@ int PrivIoctl(int fd, int cmd, void *args) break; case ADC_TYPE: case DAC_TYPE: + case WDT_TYPE: ret = ioctl(fd, cmd, ioctl_cfg->args); break; default: diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.h b/APP_Framework/Framework/transform_layer/xizi/transform.h index 341709a65..2b071dca2 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.h +++ b/APP_Framework/Framework/transform_layer/xizi/transform.h @@ -35,6 +35,9 @@ extern "C" { #define OPE_INT 0x0000 #define OPE_CFG 0x0001 +#define OPER_WDT_SET_TIMEOUT 0x0002 +#define OPER_WDT_KEEPALIVE 0x0003 + #define NAME_NUM_MAX 32 /*********************GPIO define*********************/ @@ -142,6 +145,7 @@ enum IoctlDriverType LCD_TYPE, ADC_TYPE, DAC_TYPE, + WDT_TYPE, DEFAULT_TYPE, }; diff --git a/Ubiquitous/XiZi/board/aiit-arm32-board/third_party_driver/watchdog/connect_wdg.c b/Ubiquitous/XiZi/board/aiit-arm32-board/third_party_driver/watchdog/connect_wdg.c index 07fac1408..ac28504ea 100644 --- a/Ubiquitous/XiZi/board/aiit-arm32-board/third_party_driver/watchdog/connect_wdg.c +++ b/Ubiquitous/XiZi/board/aiit-arm32-board/third_party_driver/watchdog/connect_wdg.c @@ -11,7 +11,7 @@ */ /** -* @file connect_wdt.c +* @file connect_wdg.c * @brief support aiit-arm32-board watchdog function and register to bus framework * @version 1.0 * @author AIIT XUOS Lab diff --git a/Ubiquitous/XiZi/board/xidatong/board.c b/Ubiquitous/XiZi/board/xidatong/board.c index add8b5c4c..9ea490b0c 100644 --- a/Ubiquitous/XiZi/board/xidatong/board.c +++ b/Ubiquitous/XiZi/board/xidatong/board.c @@ -52,6 +52,10 @@ Modification: #include #endif +#ifdef BSP_USING_WDT +#include +#endif + #ifdef BSP_USING_SEMC extern status_t BOARD_InitSEMC(void); #ifdef BSP_USING_EXTSRAM @@ -331,5 +335,8 @@ void InitBoardHardware() Imxrt1052HwSdioInit(); #endif +#ifdef BSP_USING_WDT + Imxrt1052HwWdgInit(); +#endif } diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig index 1c4cbea81..a21740ed2 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig @@ -48,3 +48,11 @@ menuconfig BSP_USING_USB if BSP_USING_USB source "$BSP_DIR/third_party_driver/usb/Kconfig" endif + +menuconfig BSP_USING_WDT + bool "Using WATCHDOG TIMER device" + default n + select RESOURCES_WDT + if BSP_USING_WDT + source "$BSP_DIR/third_party_driver/wdt/Kconfig" + endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile index b439cc98f..66f6f6bbf 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile @@ -24,4 +24,8 @@ ifeq ($(CONFIG_BSP_USING_USB),y) SRC_DIR += usb endif +ifeq ($(CONFIG_BSP_USING_WDT),y) + SRC_DIR += wdt +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_wdt.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_wdt.h new file mode 100644 index 000000000..a6cf61e29 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_wdt.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_wdt.h +* @brief define imxrt1052-board watchdog function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-05-06 +*/ + +#ifndef CONNECT_WDT_H +#define CONNECT_WDT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int Imxrt1052HwWdgInit(void); + +int StartWatchdog(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/fsl_wdog.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/fsl_wdog.h new file mode 100644 index 000000000..924acce11 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/fsl_wdog.h @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_WDOG_H_ +#define _FSL_WDOG_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup wdog + * @{ + */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ +/*! @name Driver version */ +/*@{*/ +/*! @brief Defines WDOG driver version */ +#define FSL_WDOG_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ +/*! @name Refresh sequence */ +/*@{*/ +#define WDOG_REFRESH_KEY (0xAAAA5555U) +/*@}*/ + +/*! @brief Defines WDOG work mode. */ +typedef struct _wdog_work_mode +{ + bool enableWait; /*!< continue or suspend WDOG in wait mode */ + bool enableStop; /*!< continue or suspend WDOG in stop mode */ + bool enableDebug; /*!< continue or suspend WDOG in debug mode */ +} wdog_work_mode_t; + +/*! @brief Describes WDOG configuration structure. */ +typedef struct _wdog_config +{ + bool enableWdog; /*!< Enables or disables WDOG */ + wdog_work_mode_t workMode; /*!< Configures WDOG work mode in debug stop and wait mode */ + bool enableInterrupt; /*!< Enables or disables WDOG interrupt */ + uint16_t timeoutValue; /*!< Timeout value */ + uint16_t interruptTimeValue; /*!< Interrupt count timeout value */ + bool softwareResetExtension; /*!< software reset extension */ + bool enablePowerDown; /*!< power down enable bit */ + bool enableTimeOutAssert; /*!< Enable WDOG_B timeout assertion. */ +} wdog_config_t; + +/*! + * @brief WDOG interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all of the WDOG interrupt configurations. + */ +enum _wdog_interrupt_enable +{ + kWDOG_InterruptEnable = WDOG_WICR_WIE_MASK /*!< WDOG timeout generates an interrupt before reset*/ +}; + +/*! + * @brief WDOG status flags. + * + * This structure contains the WDOG status flags for use in the WDOG functions. + */ +enum _wdog_status_flags +{ + kWDOG_RunningFlag = WDOG_WCR_WDE_MASK, /*!< Running flag, set when WDOG is enabled*/ + kWDOG_PowerOnResetFlag = WDOG_WRSR_POR_MASK, /*!< Power On flag, set when reset is the result of a powerOnReset*/ + kWDOG_TimeoutResetFlag = WDOG_WRSR_TOUT_MASK, /*!< Timeout flag, set when reset is the result of a timeout*/ + kWDOG_SoftwareResetFlag = WDOG_WRSR_SFTW_MASK, /*!< Software flag, set when reset is the result of a software*/ + kWDOG_InterruptFlag = WDOG_WICR_WTIS_MASK /*!< interrupt flag,whether interrupt has occurred or not*/ +}; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name WDOG Initialization and De-initialization. + * @{ + */ + +/*! + * @brief Initializes the WDOG configuration structure. + * + * This function initializes the WDOG configuration structure to default values. The default + * values are as follows. + * @code + * wdogConfig->enableWdog = true; + * wdogConfig->workMode.enableWait = true; + * wdogConfig->workMode.enableStop = false; + * wdogConfig->workMode.enableDebug = false; + * wdogConfig->enableInterrupt = false; + * wdogConfig->enablePowerdown = false; + * wdogConfig->resetExtension = flase; + * wdogConfig->timeoutValue = 0xFFU; + * wdogConfig->interruptTimeValue = 0x04u; + * @endcode + * + * @param config Pointer to the WDOG configuration structure. + * @see wdog_config_t + */ +void WDOG_GetDefaultConfig(wdog_config_t *config); + +/*! + * @brief Initializes the WDOG. + * + * This function initializes the WDOG. When called, the WDOG runs according to the configuration. + * + * This is an example. + * @code + * wdog_config_t config; + * WDOG_GetDefaultConfig(&config); + * config.timeoutValue = 0xffU; + * config->interruptTimeValue = 0x04u; + * WDOG_Init(wdog_base,&config); + * @endcode + * + * @param base WDOG peripheral base address + * @param config The configuration of WDOG + */ +void WDOG_Init(WDOG_Type *base, const wdog_config_t *config); + +/*! + * @brief Shuts down the WDOG. + * + * This function shuts down the WDOG. + * Watchdog Enable bit is a write one once only bit. It is not + * possible to clear this bit by a software write, once the bit is set. + * This bit(WDE) can be set/reset only in debug mode(exception). + */ +void WDOG_Deinit(WDOG_Type *base); + +/*! + * @brief Enables the WDOG module. + * + * This function writes a value into the WDOG_WCR register to enable the WDOG. + * This is a write one once only bit. It is not possible to clear this bit by a software write, + * once the bit is set. only debug mode exception. + * @param base WDOG peripheral base address + */ +static inline void WDOG_Enable(WDOG_Type *base) +{ + base->WCR |= WDOG_WCR_WDE_MASK; +} + + +static inline void SET_WDOG_WDT(WDOG_Type *base) +{ + base->WCR |= WDOG_WCR_WDT_MASK; +} + + +/*! + * @brief Disables the WDOG module. + * + * This function writes a value into the WDOG_WCR register to disable the WDOG. + * This is a write one once only bit. It is not possible to clear this bit by a software write,once the bit is set. + * only debug mode exception + * @param base WDOG peripheral base address + */ +static inline void WDOG_Disable(WDOG_Type *base) +{ + base->WCR &= ~WDOG_WCR_WDE_MASK; +} + +/*! + * @brief Trigger the system software reset. + * + * This function will write to the WCR[SRS] bit to trigger a software system reset. + * This bit will automatically resets to "1" after it has been asserted to "0". + * Note: Calling this API will reset the system right now, please using it with more attention. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_TriggerSystemSoftwareReset(WDOG_Type *base) +{ + base->WCR &= ~WDOG_WCR_SRS_MASK; +} + +/*! + * @brief Trigger an output assertion. + * + * This function will write to the WCR[WDA] bit to trigger WDOG_B signal assertion. + * The WDOG_B signal can be routed to external pin of the chip, the output pin will turn to + * assertion along with WDOG_B signal. + * Note: The WDOG_B signal will remain assert until a power on reset occurred, so, please + * take more attention while calling it. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_TriggerSoftwareSignal(WDOG_Type *base) +{ + base->WCR &= ~WDOG_WCR_WDA_MASK; +} + +/*! + * @brief Enables the WDOG interrupt. + * + *This bit is a write once only bit. Once the software does a write access to this bit, it will get + *locked and cannot be reprogrammed until the next system reset assertion + * + * @param base WDOG peripheral base address + * @param mask The interrupts to enable + * The parameter can be combination of the following source if defined. + * @arg kWDOG_InterruptEnable + */ +static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint16_t mask) +{ + base->WICR |= mask; +} + +/*! + * @brief Gets the WDOG all reset status flags. + * + * This function gets all reset status flags. + * + * @code + * uint16_t status; + * status = WDOG_GetStatusFlags (wdog_base); + * @endcode + * @param base WDOG peripheral base address + * @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags + * - true: a related status flag has been set. + * - false: a related status flag is not set. + */ +uint16_t WDOG_GetStatusFlags(WDOG_Type *base); + +/*! + * @brief Clears the WDOG flag. + * + * This function clears the WDOG status flag. + * + * This is an example for clearing the interrupt flag. + * @code + * WDOG_ClearStatusFlags(wdog_base,KWDOG_InterruptFlag); + * @endcode + * @param base WDOG peripheral base address + * @param mask The status flags to clear. + * The parameter could be any combination of the following values. + * kWDOG_TimeoutFlag + */ +void WDOG_ClearInterruptStatus(WDOG_Type *base, uint16_t mask); + +/*! + * @brief Sets the WDOG timeout value. + * + * This function sets the timeout value. + * This function writes a value into WCR registers. + * The time-out value can be written at any point of time but it is loaded to the counter at the time + * when WDOG is enabled or after the service routine has been performed. + * + * @param base WDOG peripheral base address + * @param timeoutCount WDOG timeout value; count of WDOG clock tick. + */ +static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint16_t timeoutCount) +{ + base->WCR = (base->WCR & ~WDOG_WCR_WT_MASK) | WDOG_WCR_WT(timeoutCount); +} + +/*! + * @brief Sets the WDOG interrupt count timeout value. + * + * This function sets the interrupt count timeout value. + * This function writes a value into WIC registers which are wirte-once. + * This field is write once only. Once the software does a write access to this field, it will get locked + * and cannot be reprogrammed until the next system reset assertion. + * @param base WDOG peripheral base address + * @param timeoutCount WDOG timeout value; count of WDOG clock tick. + */ +static inline void WDOG_SetInterrputTimeoutValue(WDOG_Type *base, uint16_t timeoutCount) +{ + base->WICR = (base->WICR & ~WDOG_WICR_WICT_MASK) | WDOG_WICR_WICT(timeoutCount); +} + +/*! + * @brief Disable the WDOG power down enable bit. + * + * This function disable the WDOG power down enable(PDE). + * This function writes a value into WMCR registers which are wirte-once. + * This field is write once only. Once software sets this bit it cannot be reset until the next system reset. + * @param base WDOG peripheral base address + */ +static inline void WDOG_DisablePowerDownEnable(WDOG_Type *base) +{ + base->WMCR &= ~WDOG_WMCR_PDE_MASK; +} + +/*! + * @brief Refreshes the WDOG timer. + * + * This function feeds the WDOG. + * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. + * + * @param base WDOG peripheral base address + */ +void WDOG_Refresh(WDOG_Type *base); +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_WDOG_H_ */ diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/Kconfig new file mode 100644 index 000000000..f981c05cd --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/Kconfig @@ -0,0 +1,13 @@ +if BSP_USING_WDT + config WDT_BUS_NAME + string "watchdog bus name" + default "wdt" + + config WDT_DRIVER_NAME + string "watchdog driver name" + default "wdt_drv" + + config WDT_DEVICE_NAME + string "watchdog device name" + default "wdt_dev" +endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/Makefile b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/Makefile new file mode 100644 index 000000000..24c1c1efb --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_wdt.c fsl_wdog.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/connect_wdt.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/connect_wdt.c new file mode 100644 index 000000000..e8638a972 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/connect_wdt.c @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_wdt.c +* @brief support imxrt1052-board watchdog(WDG1) function and register to bus framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-05-06 +*/ + +#include +#include + +static BusType wdt; +static wdog_config_t wdog_config_t_param; + +void WDOG1_IRQHandler(void) +{ + WDOG_ClearInterruptStatus(WDOG1, kWDOG_InterruptFlag); + /* User code. User can do urgent case before timeout reset. + * IE. user can backup the ram data or ram log to flash. + * the period is set by config.interruptTimeValue, user need to + * check the period between interrupt and timeout. + */ +} + +static uint32 Imxrt1052WdgOpen(void *dev) +{ + return EOK; +} + +static uint32 Imxrt1052WdgClose(void *dev) +{ + WDOG_Deinit(WDOG1); + + return EOK; +} + +static int Imxrt1052WdgInit(struct WdtHardwareDevice *dev, uint16_t timeout) +{ + /* + * wdogConfig->enableWdog = true; + * wdogConfig->workMode.enableWait = true; + * wdogConfig->workMode.enableStop = false; + * wdogConfig->workMode.enableDebug = false; + * wdogConfig->enableInterrupt = false; + * wdogConfig->enablePowerdown = false; + * wdogConfig->resetExtension = flase; + * wdogConfig->timeoutValue = 0xFFU; + * wdogConfig->interruptTimeValue = 0x04u; + */ + WDOG_GetDefaultConfig(&wdog_config_t_param); + wdog_config_t_param.timeoutValue = timeout; /* Timeout value is 1 sec / 6.4 num, 5s means 32. */ + WDOG_Init(WDOG1, &wdog_config_t_param); + + return EOK; +} + +static uint32 Imxrt1052WdgConfigure(void *drv, struct BusConfigureInfo *args) +{ + struct WdtDriver *wdt_drv = (struct WdtDriver *)drv; + struct WdtHardwareDevice *wdt_dev = (struct WdtHardwareDevice *)wdt_drv->driver.owner_bus->owner_haldev; + + uint16_t timeout; + + switch(args->configure_cmd) + { + case OPER_WDT_SET_TIMEOUT: + timeout = *(uint16_t *)(args->private_data); + if (timeout) { + Imxrt1052WdgInit(wdt_dev, timeout); + } + break; + case OPER_WDT_KEEPALIVE: + WDOG_Refresh(WDOG1); + break; + default: + return ERROR; + } + return EOK; +} + +static const struct WdtDevDone dev_done = +{ + Imxrt1052WdgOpen, + Imxrt1052WdgClose, + NONE, + NONE, +}; + +/** + * @description: Feed watchdog task function + */ +static void FeedWatchdogTask(void) +{ + while (1) + { + /* keep watchdog alive in idle task */ + struct BusConfigureInfo cfg; + cfg.configure_cmd = OPER_WDT_KEEPALIVE; + cfg.private_data = NONE; + BusDrvConfigure(wdt->owner_driver, &cfg); + MdelayKTask(500); + } +} + +/** + * @description: Watchdog function + * @return success: EOK, failure: other + */ +int StartWatchdog(void) +{ + int ret = EOK; + uint16_t timeout = 32; /* timeout time 5s*/ + + wdt = BusFind(WDT_BUS_NAME); + wdt->owner_driver = BusFindDriver(wdt, WDT_DRIVER_NAME); + + /* set watchdog timeout time */ + struct BusConfigureInfo cfg; + cfg.configure_cmd = OPER_WDT_SET_TIMEOUT; + cfg.private_data = &timeout; + ret = BusDrvConfigure(wdt->owner_driver, &cfg); + + int32 WdtTask = KTaskCreate("WdtTask", (void *)FeedWatchdogTask, NONE, 1024, 20); + StartupKTask(WdtTask); + + return EOK; +} + +int Imxrt1052HwWdgInit(void) +{ + x_err_t ret = EOK; + + static struct WdtBus watch_dog_timer_bus; + static struct WdtDriver watch_dog_timer_drv; + static struct WdtHardwareDevice watch_dog_timer_dev; + + ret = WdtBusInit(&watch_dog_timer_bus, WDT_BUS_NAME); + if (ret != EOK) { + KPrintf("Watchdog bus init error %d\n", ret); + return ERROR; + } + + watch_dog_timer_drv.configure = Imxrt1052WdgConfigure; + ret = WdtDriverInit(&watch_dog_timer_drv, WDT_DRIVER_NAME); + if (ret != EOK) { + KPrintf("Watchdog driver init error %d\n", ret); + return ERROR; + } + + ret = WdtDriverAttachToBus(WDT_DRIVER_NAME, WDT_BUS_NAME); + if (ret != EOK) { + KPrintf("Watchdog driver attach error %d\n", ret); + return ERROR; + } + + watch_dog_timer_dev.dev_done = &dev_done; + + ret = WdtDeviceRegister(&watch_dog_timer_dev, WDT_DEVICE_NAME); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + ret = WdtDeviceAttachToBus(WDT_DEVICE_NAME, WDT_BUS_NAME); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/fsl_wdog.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/fsl_wdog.c new file mode 100644 index 000000000..9a3c7fc10 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/wdt/fsl_wdog.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_wdog.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.wdog01" +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ +static WDOG_Type *const s_wdogBases[] = WDOG_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/* Array of WDOG clock name. */ +static const clock_ip_name_t s_wdogClock[] = WDOG_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +static const IRQn_Type s_wdogIRQ[] = WDOG_IRQS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t WDOG_GetInstance(WDOG_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_wdogBases); instance++) + { + if (s_wdogBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_wdogBases)); + + return instance; +} + +/*! + * brief Initializes the WDOG configuration structure. + * + * This function initializes the WDOG configuration structure to default values. The default + * values are as follows. + * code + * wdogConfig->enableWdog = true; + * wdogConfig->workMode.enableWait = true; + * wdogConfig->workMode.enableStop = false; + * wdogConfig->workMode.enableDebug = false; + * wdogConfig->enableInterrupt = false; + * wdogConfig->enablePowerdown = false; + * wdogConfig->resetExtension = flase; + * wdogConfig->timeoutValue = 0xFFU; + * wdogConfig->interruptTimeValue = 0x04u; + * endcode + * + * param config Pointer to the WDOG configuration structure. + * see wdog_config_t + */ +void WDOG_GetDefaultConfig(wdog_config_t *config) +{ + assert(config); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + config->enableWdog = true; + config->workMode.enableWait = false; + config->workMode.enableStop = false; + config->workMode.enableDebug = false; + config->enableInterrupt = false; + config->softwareResetExtension = false; + config->enablePowerDown = false; + config->timeoutValue = 0xffu; + config->interruptTimeValue = 0x04u; + config->enableTimeOutAssert = false; +} + +/*! + * brief Initializes the WDOG. + * + * This function initializes the WDOG. When called, the WDOG runs according to the configuration. + * + * This is an example. + * code + * wdog_config_t config; + * WDOG_GetDefaultConfig(&config); + * config.timeoutValue = 0xffU; + * config->interruptTimeValue = 0x04u; + * WDOG_Init(wdog_base,&config); + * endcode + * + * param base WDOG peripheral base address + * param config The configuration of WDOG + */ +void WDOG_Init(WDOG_Type *base, const wdog_config_t *config) +{ + assert(config); + + uint16_t value = 0u; + + value = WDOG_WCR_WDE(config->enableWdog) | WDOG_WCR_WDW(config->workMode.enableWait) | + WDOG_WCR_WDZST(config->workMode.enableStop) | WDOG_WCR_WDBG(config->workMode.enableDebug) | + WDOG_WCR_SRE(config->softwareResetExtension) | WDOG_WCR_WT(config->timeoutValue) | + WDOG_WCR_WDT(config->enableTimeOutAssert) | WDOG_WCR_SRS_MASK | WDOG_WCR_WDA_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Set configuration */ + CLOCK_EnableClock(s_wdogClock[WDOG_GetInstance(base)]); +#endif + + base->WICR = WDOG_WICR_WICT(config->interruptTimeValue) | WDOG_WICR_WIE(config->enableInterrupt); + base->WMCR = WDOG_WMCR_PDE(config->enablePowerDown); + base->WCR = value; + if (config->enableInterrupt) + { + EnableIRQ(s_wdogIRQ[WDOG_GetInstance(base)]); + } +} + +/*! + * brief Shuts down the WDOG. + * + * This function shuts down the WDOG. + * Watchdog Enable bit is a write one once only bit. It is not + * possible to clear this bit by a software write, once the bit is set. + * This bit(WDE) can be set/reset only in debug mode(exception). + */ +void WDOG_Deinit(WDOG_Type *base) +{ + if (base->WCR & WDOG_WCR_WDBG_MASK) + { + WDOG_Disable(base); + } +} + +/*! + * brief Gets the WDOG all reset status flags. + * + * This function gets all reset status flags. + * + * code + * uint16_t status; + * status = WDOG_GetStatusFlags (wdog_base); + * endcode + * param base WDOG peripheral base address + * return State of the status flag: asserted (true) or not-asserted (false).see _wdog_status_flags + * - true: a related status flag has been set. + * - false: a related status flag is not set. + */ +uint16_t WDOG_GetStatusFlags(WDOG_Type *base) +{ + uint16_t status_flag = 0U; + + status_flag |= (base->WCR & WDOG_WCR_WDE_MASK); + status_flag |= (base->WRSR & WDOG_WRSR_POR_MASK); + status_flag |= (base->WRSR & WDOG_WRSR_TOUT_MASK); + status_flag |= (base->WRSR & WDOG_WRSR_SFTW_MASK); + status_flag |= (base->WICR & WDOG_WICR_WTIS_MASK); + + return status_flag; +} + +/*! + * brief Clears the WDOG flag. + * + * This function clears the WDOG status flag. + * + * This is an example for clearing the interrupt flag. + * code + * WDOG_ClearStatusFlags(wdog_base,KWDOG_InterruptFlag); + * endcode + * param base WDOG peripheral base address + * param mask The status flags to clear. + * The parameter could be any combination of the following values. + * kWDOG_TimeoutFlag + */ +void WDOG_ClearInterruptStatus(WDOG_Type *base, uint16_t mask) +{ + if (mask & kWDOG_InterruptFlag) + { + base->WICR |= WDOG_WICR_WTIS_MASK; + } +} + +/*! + * brief Refreshes the WDOG timer. + * + * This function feeds the WDOG. + * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. + * + * param base WDOG peripheral base address + */ +void WDOG_Refresh(WDOG_Type *base) +{ + base->WSR = WDOG_REFRESH_KEY & 0xFFFFU; + base->WSR = (WDOG_REFRESH_KEY >> 16U) & 0xFFFFU; +} diff --git a/Ubiquitous/XiZi/kernel/kernel_test/test_iwg.c b/Ubiquitous/XiZi/kernel/kernel_test/test_iwg.c index e9121bb0e..ebd52cf6e 100644 --- a/Ubiquitous/XiZi/kernel/kernel_test/test_iwg.c +++ b/Ubiquitous/XiZi/kernel/kernel_test/test_iwg.c @@ -28,14 +28,17 @@ static BusType wdt; */ static void FeedWatchdog(void) { - while (1) + int cnt = 0; + while (cnt < 20) { /* keep watchdog alive in idle task */ struct BusConfigureInfo cfg; cfg.configure_cmd = OPER_WDT_KEEPALIVE; cfg.private_data = NONE; BusDrvConfigure(wdt->owner_driver, &cfg); - KPrintf("feed the dog!\n "); + KPrintf("feed the dog! cnt %u\n", cnt); + cnt++; + MdelayKTask(1000); } } @@ -46,18 +49,17 @@ static void FeedWatchdog(void) int TestIwg(void) { x_err_t res = EOK; - uint32 timeout = 1000; /* timeout time */ + uint16 timeout = 1000; /* timeout time */ - wdt = BusFind(WDT_BUS_NAME_0); - wdt->owner_driver = BusFindDriver(wdt, WDT_DRIVER_NAME_0); - wdt->owner_haldev = BusFindDevice(wdt, WDT_0_DEVICE_NAME_0); + wdt = BusFind(WDT_BUS_NAME); + wdt->owner_driver = BusFindDriver(wdt, WDT_DRIVER_NAME); + wdt->owner_haldev = BusFindDevice(wdt, WDT_DEVICE_NAME); /* set watchdog timeout time */ struct BusConfigureInfo cfg; cfg.configure_cmd = OPER_WDT_SET_TIMEOUT; cfg.private_data = &timeout; res = BusDrvConfigure(wdt->owner_driver, &cfg); - KPrintf("feed the dog!\n"); int32 WdtTask = KTaskCreate("WdtTask", (void *)FeedWatchdog, NONE, 2048, 20); res = StartupKTask(WdtTask); diff --git a/Ubiquitous/XiZi/kernel/thread/init.c b/Ubiquitous/XiZi/kernel/thread/init.c index 00e255d26..583f9d7a5 100644 --- a/Ubiquitous/XiZi/kernel/thread/init.c +++ b/Ubiquitous/XiZi/kernel/thread/init.c @@ -31,6 +31,10 @@ #include "connect_usb.h" #endif +#ifdef BSP_USING_WDT +#include "connect_wdt.h" +#endif + #ifdef KERNEL_USER_MAIN #ifndef MAIN_KTASK_STACK_SIZE #define MAIN_KTASK_STACK_SIZE 2048 @@ -242,6 +246,10 @@ extern int InitUserspace(void); HwLockSpinlock(&AssignSpinLock); #endif +#ifdef BSP_USING_WDT + StartWatchdog(); +#endif + StartupOsAssign(); return 0; diff --git a/Ubiquitous/XiZi/resources/include/bus.h b/Ubiquitous/XiZi/resources/include/bus.h index 967d3a519..b9d0f4ad7 100644 --- a/Ubiquitous/XiZi/resources/include/bus.h +++ b/Ubiquitous/XiZi/resources/include/bus.h @@ -27,11 +27,11 @@ extern "C" { #endif -#define OPE_INT 0x0000 +#define OPE_INT 0x0000 #define OPE_CFG 0x0001 #define OPER_WDT_SET_TIMEOUT 0x0002 -#define OPER_WDT_KEEPALIVE 0x0003 +#define OPER_WDT_KEEPALIVE 0x0003 typedef struct Bus *BusType; typedef struct HardwareDev *HardwareDevType;