/** * @file sdrv_watchdog.h * @brief SemiDrive Watchdog driver header file. * * @copyright Copyright (c) 2022 Semidrive Semiconductor. * All rights reserved. */ #ifndef SDRV_WATCHDOG_DRV_H_ #define SDRV_WATCHDOG_DRV_H_ #include #include #include "sdrv_common.h" #undef __I #undef __O #undef __IO #ifdef __cplusplus #define __I volatile /*!< Defines 'read only' permissions */ #else #define __I volatile const /*!< Defines 'read only' permissions */ #endif #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */ /** * @brief watchdog status error code. */ enum sdrv_watchdog_error { SDRV_STATUS_TIMEOUT_FAILED = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_WATCHDOG, 0), /* watchdog status for timeout failed. */ SDRV_STATUS_DELTA_FAILED = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_WATCHDOG,1), /* watchdog status for delta failed. */ SDRV_STATUS_WINDOW_LOW_FAILED= SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_WATCHDOG, 2), /* watchdog status for window_low failed. */ SDRV_STATUS_INTR_UNCLEARED = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_WATCHDOG, 3), /* watchdog status for interrupt not cleared. */ }; /** * @brief Definition for sdrv watchdog register. */ typedef struct sdrv_wdt { __IO uint32_t ctrl; /**< Global control, offset: 0x0 */ __IO uint32_t wtc; /**< Terminal count value, offset: 0x4 */ __IO uint32_t wrc_ctrl; /**< Refresh control, offset: 0x8 */ __IO uint32_t wrc_val; /**< Refresh window limit, offset: 0xC */ __IO uint32_t wrc_seq; /**< Refresh sequence delta, offset: 0x10 */ __IO uint32_t rst_ctl; /**< Reset control, offset: 0x14 */ __IO uint32_t ext_rst_ctl; /**< External reset control, offset: 0x18 */ __I uint32_t cnt; /**< Counter, offset: 0x1C */ __O uint32_t tsw; /**< Timestamp, offset: 0x20 */ __IO uint32_t intr; /**< Interrupt, offset: 0x24 */ __IO uint32_t rst_req_mon; /**< Reset request monitor, offset: 0x28 */ __IO uint32_t dummy_res; /**< Dummy reserved, offset: 0x2C */ uint32_t reserved1[4]; __IO uint32_t lock; /**< Lock, offset: 0x40 */ } sdrv_wdt_t; /** * @brief Definition for watchdog clock source. */ typedef enum sdrv_wdt_clock { WDT_MAIN_CLOCK = 0U, /**< System 24M clock */ WDT_BUS_CLOCK, /**< System bus clock */ WDT_EXT_CLOCK, /**< External clock */ WDT_TIE_OFF, /**< Tie off */ WDT_LP_CLOCK, /**< System 32K clock */ } sdrv_wdt_clock_e; /** * @brief Definition for watchdog refresh type. */ typedef enum sdrv_wdt_refresh { WDT_DIRECT_REFRESH = 0U, /**< WDT direct refresh, you must feed dog before timeout. */ WDT_WINDOW_REFRESH, /**< WDT window based refresh, you must feed dog bewteen time low limit and timeout. */ WDT_SEQUENCE_REFRESH, /**< WDT sequence based refresh, after you read current counter, you must write it to timestamp register before delta time. */ WDT_DIRECT_SEQUENCE_REFRESH, /**< WDT direct/sequence base refresh combine. */ WDT_WINDOW_SEQUENCE_REFRESH, /**< WDT window base/sequence base refresh combine. */ } sdrv_wdt_refresh_e; /** * @brief Definition for watchdog interrupt type. */ typedef enum sdrv_wdt_intr { WDT_ILL_WINDOW_REFRESH = 0X1U, /**< WDT illeage window based counter refresh interrupt. */ WDT_ILL_SEQUENCE_RESRESH = 0X2U, /**< WDT illeage sequential refresh interrupt. */ WDT_OVERFLOW = 0X4U, /**< WDT timer overflow interrupt. */ } sdrv_wdt_intr_e; /** * @brief Definition for watchdog internal reset config. */ typedef struct sdrv_wdt_internal_reset { bool reset_en; /**< WDT internal system reset request enable. */ uint8_t reset_mode; /**< WDT reset mode, 0-level, 1-pulse. */ uint8_t reset_win; /**< WDT pulse mode reset window. */ uint16_t reset_cnt; /**< WDT reset counter, time between overflow to trigger reset. */ bool wdt_reset_en; /**< WDT restart after internal system reset enable. */ } sdrv_wdt_internal_reset_t; /** * @brief Definition for watchdog external reset config. */ typedef struct sdrv_wdt_external_reset { bool reset_en; /**< WDT external system reset request enable. */ uint8_t reset_mode; /**< WDT reset mode, 0-level, 1-pulse. */ uint8_t reset_pol; /**< WDT reset request polarity, 0-low active, 1-high active. */ uint8_t reset_win; /**< WDT pulse mode reset window. */ uint16_t reset_cnt; /**< WDT reset counter, time between overflow to trigger reset. */ } sdrv_wdt_external_reset_t; /** * @brief Definition for watchdog initialize config. */ typedef struct sdrv_wdt_config { sdrv_wdt_clock_e clk_src; /**< WDT clock source. */ uint16_t pre_divide; /**< Clock pre-divider ratio, 0 ~ 0xFFFF. */ uint8_t wdt_en_src; /**< WDT enable control by: 0-Fuse, 1-Software. */ uint8_t wtc_src; /**< WDT terminal count config by: 0-Fuse, 1-Software. */ bool auto_restart; /**< WDT overflow auto restart enable. */ sdrv_wdt_refresh_e refresh; /**< WDT refresh mode. */ uint32_t timeout; /**< WDT timeout value, unit: ms. */ uint32_t window_low; /**< WDT refresh window low limit, unit: ms. */ uint32_t seq_delta; /**< WDT refresh sequence delta, unit: ms. */ uint32_t intr_bitmap; /**< WDT interrupt enable bitmap. */ sdrv_wdt_internal_reset_t int_rst; /**< WDT internal reset. */ sdrv_wdt_external_reset_t ext_rst; /**< WDT external reset. */ } sdrv_wdt_config_t; /** * @brief Get the default configuration for watchdog. * * This function get the default configuration for watchdog. When you want initialize, * you can call this function first and modify some of them, then call sdrv_wdt_init. * * @param [in] config WDT config struct. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed. */ status_t sdrv_wdt_get_default_config(sdrv_wdt_config_t *config); /** * @brief Initialize watchdog with config parameters. * * This function config watchdog with parameters in sdrv_wdt_config_t. * * @param [in] base WDT control base. * @param [in] config WDT config struct. * @return Return SDRV_STATUS_OK or error code. */ status_t sdrv_wdt_init(sdrv_wdt_t *base, sdrv_wdt_config_t *config); /** * @brief De-Initialize watchdog. * * This function disable watchdog interrupt and clear interrupt status. * Disable internal and external reset config. * * @param [in] base WDT control base. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed, * SDRV_STATUS_INTR_UNCLEARED represents interrupt not cleared. */ status_t sdrv_wdt_deinit(sdrv_wdt_t *base); /** * @brief Enable watchdog. * * This function enable watchdog timer counter. * * @param [in] base WDT control base. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed. */ status_t sdrv_wdt_enable(sdrv_wdt_t *base); /** * @brief Disable watchdog. * * This function disable watchdog timer counter. * * @param [in] base WDT control base * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed. */ status_t sdrv_wdt_disable(sdrv_wdt_t *base); /** * @brief Set watchdog timeout value. * * This function get timeout value in milliseconds and convert to timer counter according * to clock source pre-configed. * * @param [in] base WDT control base. * @param [in] timeout unit: ms. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed, * SDRV_STATUS_INVALID_PARAM represents invalid paramemt. */ status_t sdrv_wdt_set_timeout(sdrv_wdt_t *base, uint32_t timeout); /** * @brief Set watchdog time window low limit value. * * This function get time window low limit value in milliseconds and convert to timer * counter according to clock source pre-configed. * * @param [in] base WDT control base. * @param [in] low_limit unit: ms. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed, * SDRV_STATUS_INVALID_PARAM represents invalid paramemt. */ status_t sdrv_wdt_set_window_low(sdrv_wdt_t *base, uint32_t low_limit); /** * @brief Set watchdog sequence delta value. * * This function get sequence delta value in milliseconds and convert to timer * counter according to clock source pre-configed. * * @param [in] base WDT control base. * @param [in] delta unit: ms. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed, * SDRV_STATUS_INVALID_PARAM represents invalid paramemt. */ status_t sdrv_wdt_set_sequence_delta(sdrv_wdt_t *base, uint32_t delta); /** * @brief Feed watchdog. * * This function trigger watchdog do refresh. * * @param [in] base WDT control base. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed. */ status_t sdrv_wdt_refresh(sdrv_wdt_t *base); /** * @brief Read watchdog current counter. * * This function read watchdog current counter. When you enable sequence refresh, you need call * this function first and store read value. Before time delta, use sdrv_wdt_write_timestamp with * stored value. Otherwise, illeage sequential refresh interrupt status will set. * * @param [in] base WDT control base. * @return current timer counter. */ uint32_t sdrv_wdt_read_timestamp(sdrv_wdt_t *base); /** * @brief Write watchdog counter to TSW register. * * This function write counter to TSW register. When config sequence base refresh, * read timestamp first, then write read value to TSW before sequence delta. * * @param [in] base WDT control base. * @param [in] timestamp last read wdt conunter. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed. */ status_t sdrv_wdt_write_timestamp(sdrv_wdt_t *base, uint32_t timestamp); /** * @brief Get watchdog interrupt status of specific type. * * This function get specific type interrupt status. * * @param [in] base WDT control base. * @param [in] intr interrupt type defined in sdrv_wdt_intr_e. * @return true represents status is set, false represents status not set. */ status_t sdrv_wdt_get_intr_status(sdrv_wdt_t *base, sdrv_wdt_intr_e intr); /** * @brief Clear watchdog interrupt status of specific type. * * @param [in] base WDT control base. * @param [in] intr interrupt type defined in sdrv_wdt_intr_e. * @return SDRV_STATUS_OK represents success, SDRV_STATUS_FAIL represents failed. */ status_t sdrv_wdt_clear_intr_status(sdrv_wdt_t *base, sdrv_wdt_intr_e intr); #endif /* SDRV_WATCHDOG_DRV_H_ */