/**
 ******************************************************************************
 * @file    kpm32xx_ddl_wwdg.h
 * @author  Kiwi Software Team
 * @brief   Header file of WWDG DDL module.
 * @note
 *          V1.0.0, 2024/12/20.
 *
 * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *	1. Redistributions of source code must retain the above copyright notice,
 *	   this list of conditions and the following disclaimer.
 *
 *	2. Redistributions in binary form must reproduce the above copyright notice,
 *	   this list of conditions and the following disclaimer in the documentation
 *	   and/or other materials provided with the distribution.
 *
 *	3. Neither the name of the copyright holder nor the names of its contributors
 *	   may be used to endorse or promote products derived from this software without
 *	   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************
 */

#ifndef __KPM32xx_DDL_WWDG_H
#define __KPM32xx_DDL_WWDG_H

#ifdef __cplusplus
extern "C" {
#endif


#include "kpm32xx_ddl_def.h"


/* WWDG clock source */
typedef enum
{
    WWDG_CLKSRC_LIRC = SYSCONF_CSEL2_WDT_LIRC,    /* LIRC as WWDG clock source (32KHz)     */
    WWDG_CLKSRC_MCLK = SYSCONF_CSEL2_WDT_MCLK,    /* LOSC as WWDG clock source (32.768KHz) */
} WWDG_ClkSrc_T;

/* WWDG work mode */
typedef enum
{
	WWDG_MODE_NORMAL = WWDG_CTRL_NORMALMODE,
	WWDG_MODE_WINDOW = WWDG_CTRL_WINMODE,
} WWDG_WorkMode_T;

/* WWDG window length, the preset threshold value for EWI */
typedef enum
{
	WWDG_WINLEN_80H = WWDG_CTRL_WINLEN_80H,
	WWDG_WINLEN_100H = WWDG_CTRL_WINLEN_100H,
	WWDG_WINLEN_200H = WWDG_CTRL_WINLEN_200H,
	WWDG_WINLEN_400H = WWDG_CTRL_WINLEN_400H,
	WWDG_WINLEN_800H = WWDG_CTRL_WINLEN_800H,
	WWDG_WINLEN_1000H = WWDG_CTRL_WINLEN_1000H,
	WWDG_WINLEN_2000H = WWDG_CTRL_WINLEN_2000H,
	WWDG_WINLEN_4000H = WWDG_CTRL_WINLEN_4000H,
} WWDG_WinLen_T;

/* WWDG initialization structure definition */
typedef struct
{
	uint32_t           counter;          /* Specifies the WWDG free-running downcounter value.         */
	uint32_t           windowVal;        /* Specifies the WWDG window value, should less than counter. */
	uint32_t           ewiEnable;        /* Enable Early warning interrupt or not.                     */
	uint32_t           ewiThreshold;     /* When WWDG counter decreased down to this value will generate an interrupt. */
	uint32_t           mode;             /* Watch Dog Normal or Window mode.                           */
	WWDG_ClkSrc_T      clkSrc;           /* Specifies WWDG source clock.                               */
} WWDG_Init_T;


/* WWDG unlock key to enable writing to all other registers */
#define WWDG_REGS_UNLOCK_KEY               0x2EE1D879

/* WWDG feed key to refresh WWDG counter */
#define WWDG_FEED_KEY                      0xAAAA


/* check WWDG work mode correct or not */
#define IS_WWDG_WORK_MODE(__MODE__)                 (((__MODE__) == WWDG_MODE_NORMAL) || ((__MODE__) == WWDG_MODE_WINDOW))

/**
 * check counter is in close window or not, feed WWDT when
 * in close window will trigger watchdog reset
 */
#define IS_IN_CLOSE_WINDOW(__INSTANCE__)               ((__INSTANCE__)->CTRL & WWDG_CTRL_WMCLOSEFLAG)

/* Unlock to enable writing WWDG registers */
#define __DDL_WWDG_REGS_UNLOCK__( __INSTANCE__ )       WRITE_REG((__INSTANCE__)->KEY, WWDG_REGS_UNLOCK_KEY)

/* lock to disable writing WWDG registers */
#define __DDL_WWDG_REGS_LOCK__( __INSTANCE__ )         WRITE_REG((__INSTANCE__)->KEY, 0)

/* Enable WWDG */
#define __DDL_WWDG_ENABLE(__INSTANCE__)                         SET_BIT((__INSTANCE__)->CTRL, WWDG_CTRL_ENABLE)

/* Disable WWDG */
#define __DDL_WWDG_DISABLE(__INSTANCE__)                        CLEAR_BIT((__INSTANCE__)->CTRL, WWDG_CTRL_ENABLE)

/* Enable Window mode for WWDG */
#define __DDL_WWDG_ENABLE_WINMOD(__INSTANCE__)                  SET_BIT((__INSTANCE__)->CTRL, WWDG_CTRL_WINMODE)

/* Enable Watchdog EWI */
#define __DDL_WWDG_ENABLE_EWI(__INSTANCE__)                   SET_BIT((__INSTANCE__)->CTRL, WWDG_CTRL_EWIEN)

/* Check Watchdog EWI is enable or not */
#define __DDL_WWDG_EWI_IS_ENABLE(__INSTANCE__)                   ((__INSTANCE__)->CTRL & WWDG_CTRL_EWIEN)

/* Get interrupt status of WWDG */
#define __DDL_WWDG_GET_EWI_STATUS(__INSTANCE__)                  ((__INSTANCE__)->ST & WWDG_ST_EWI)

/* Clear interrupt status of WWDG */
#define __DDL_WWDG_CLEAR_EWI_STATUS(__INSTANCE__)                WRITE_REG((__INSTANCE__)->ST, WWDG_ST_EWI)

/* Check WWDG is busy refreshing or not */
#define __DDL_WWDG_IS_REFRESH_BUSY(__INSTANCE__)                  ((__INSTANCE__)->ST & WWDG_ST_REFRESH)

/* Check WWDG is real enable or not (for sync with different time zone) */
#define __DDL_WWDG_IS_REAL_ENABLE(__INSTANCE__)                   ((__INSTANCE__)->ST & WWDG_ST_ENABLE)

/* get current value of WWDG */
#define __DDL_WWDG_GET_CURRENT_COUNT(__INSTANCE__)               ((__INSTANCE__)->CNT & 0x00FFFFFF)


/**
  * @brief  Makes WWDG active.
  * @param  none
  *
  * @retval none
  */
void DDL_WWDG_Instance_Active(void);


/**
  * @brief  Configure the elements of structure WWDG_Init_T to default values.
  *
  * @param  pWWDGStructInit Pointer to a WWDG_Init_T structure that contains
  *                         the configuration information for the given WWDG module.
  *
  * @retval None
  */
void DDL_WWDG_StructInit(WWDG_Init_T *pWWDGStructInit);


/**
  * @brief  Initialize the WWDG according to the specified.
  *         parameters in the WWDG_Init_T of  associated handle.
  * @param  WWDGx WWDG instance.
  * @param  pWWDGStructInit Pointer to a WWDG_Init_T structure that contains
  *                         the configuration information for the given WWDG module.
  * @retval DDL status
  */
void DDL_WWDG_Init(WWDG_Type *WWDGx, WWDG_Init_T *pWWDGStructInit);

/**
  * @brief  Refresh the WWDG.
  * @param  WWDGx  WWDG instance.
  * @retval None
  */
void DDL_WWDG_Refresh(WWDG_Type *WWDGx);


#ifdef __cplusplus
}
#endif

#endif /* __KPM32xx_DDL_WWDG_H */

