/**
 *******************************************************************************
 * @file    tmpm311_wdt.c
 * @brief   This file provides API functions for WDT driver.
 * @version V2.0.2.2
 * @date    2014/10/14
 * 
 * DO NOT USE THIS SOFTWARE WITHOUT THE SOFTWARE LICENSE AGREEMENT.
 * 
 * (C)Copyright TOSHIBA ELECTRONIC DEVICES & STORAGE CORPORATION 2017 All rights reserved
 *******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "tmpm311_wdt.h"

#if defined(__TMPM311_WDT_H)
/** @addtogroup TX03_Periph_Driver
  * @{
  */

/** @defgroup WDT 
  * @brief WDT driver modules
  * @{
  */
/** @defgroup WDT_Private_Defines
  * @{
  */

#define WDT_CR_CLR_CODE        ((uint32_t)0x0000004E)
#define WDT_CR_DISABLE_CODE    ((uint32_t)0x000000B1)

#define MOD_WDTP_MASK          ((uint32_t)0x00000086)
#define MOD_I2WDT_CLEAR        ((uint32_t)0xFFFFFFFB)
#define MOD_RESCR_SET          ((uint32_t)0x00000002)
#define MOD_RESCR_CLEAR        ((uint32_t)0xFFFFFFFD)
#define MOD_WDTE_SET           ((uint32_t)0x00000080)
#define MOD_WDTE_CLEAR         ((uint32_t)0xFFFFFF7F)

#define WDT_FLG_FLG_CLEAR      ((uint32_t)0x00000000)

/** @} */
/* End of group WDT_Private_Defines */

/** @defgroup WDT_Private_FunctionPrototypes
  * @{
  */

/** @} */
/* End of group WDT_Private_FunctionPrototypes */

/** @defgroup WDT_Private_Functions
  * @{
  */

/** @} */
/* End of group group WDT_Private_Functions */

/** @defgroup WDT_Exported_Functions
  * @{
  */

/**
  * @brief  Set detection time of watchdog.
  * @param  DetectTime: Set the Detection time.
  *   This parameter can be one of the following values:
  *   WDT_DETECT_TIME_EXP_15, WDT_DETECT_TIME_EXP_17, WDT_DETECT_TIME_EXP_19,
  *   WDT_DETECT_TIME_EXP_21, WDT_DETECT_TIME_EXP_23 or WDT_DETECT_TIME_EXP_25.
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @register The used register:
  *   WD0MOD<WDTP[2:0]>
  */
Result WDT_SetDetectTime(uint32_t DetectTime)
{
    uint32_t tmp = 0U;
    Result retval = ERROR;

    /* Check the parameters */
    assert_param(IS_WDT_DETECT_TIME(DetectTime));

    if (WDT_GetWritingFlg() == ENABLE) {
        /* Set WDT Detection time */
        tmp = TSB_WD0->MOD;
        tmp &= MOD_WDTP_MASK;
        tmp |= DetectTime;
        TSB_WD0->MOD = tmp;
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Run or stop the WDT counter when the system enters IDLE mode. 
  * @param  None
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @note  Low-power consumption mode operation function of the 
  *   WDT has no meaning. Write "0" to the <I2WDT>.
  * @register The used register:
  *   WD0MOD<I2WDT>
  */
Result WDT_SetIdleMode(void)
{
    uint32_t tmp = 0U;
    Result retval = ERROR;

    if (WDT_GetWritingFlg() == ENABLE) {
        tmp = TSB_WD0->MOD;
        /* Set WDMOD<I2WDT> to stop the WDT counter before enter IDLE mode */
        tmp &= MOD_I2WDT_CLEAR;
        TSB_WD0->MOD = tmp;
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Set WDT generate NMI interrupt or reset when counter overflow.
  * @param  OverflowOutput: Select function of WDT when counter overflow. 
  *   This parameter can be: WDT_WDOUT or WDT_NMIINT.
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @register The used register:
  *   WD0MOD<RESCR>
  */
Result WDT_SetOverflowOutput(uint32_t OverflowOutput)
{
    uint32_t tmp = 0U;
    Result retval = ERROR;
    /* Check the parameters */
    assert_param(IS_WDT_OUTPUT(OverflowOutput));

    if (WDT_GetWritingFlg() == ENABLE) {
        tmp = TSB_WD0->MOD;
        if (OverflowOutput == WDT_WDOUT) {
            /* Set WDMOD<RESCR> to 1 */
            tmp |= MOD_RESCR_SET;
        } else {
            /* Clear WDMOD<RESCR> to 0 */
            tmp &= MOD_RESCR_CLEAR;
        }
        TSB_WD0->MOD = tmp;
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Initialize WDT.
  * @param  InitStruct: The structure containing basic WD configuration.
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @register The used register:
  *   WD0MOD<WDTP[2:0]><RESCR>
  */
Result WDT_Init(WDT_InitTypeDef * InitStruct)
{
    Result retval = ERROR;

    /* Check the parameters */
    assert_param(IS_POINTER_NOT_NULL(InitStruct));
    assert_param(IS_WDT_DETECT_TIME(InitStruct->DetectTime));
    assert_param(IS_WDT_OUTPUT(InitStruct->OverflowOutput));

    if (WDT_GetWritingFlg() == ENABLE) {
        /* Set WDT Detection time */
        WDT_SetDetectTime(InitStruct->DetectTime);
        /* Set WDMOD<RESCR> to select function of WDT when counter overflow */
        WDT_SetOverflowOutput(InitStruct->OverflowOutput);
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Enable the WDT.
  * @param  None
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @register The used register:
  *   WD0MOD<WDTE>
  */
Result WDT_Enable(void)
{
    Result retval = ERROR;

    if (WDT_GetWritingFlg() == ENABLE) {
        /* Set WDMOD<WDTE> to enable WDT */
        TSB_WD0->MOD |= MOD_WDTE_SET;
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Disable the WDT.
  * @param  None
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @register The used registers:
  *   WD0MOD<WDTE>, WD0CR<WDCR>
  */
Result WDT_Disable(void)
{
    Result retval = ERROR;

    if (WDT_GetWritingFlg() == ENABLE) {
        /* Clear WDxMOD<WDTE> and (B1H) be written to the WDCR register to disable WDT */
        TSB_WD0->MOD &= MOD_WDTE_CLEAR;
        TSB_WD0->CR = WDT_CR_DISABLE_CODE;
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Write the clear code.
  * @param  None
  * @retval The value returned can be one of the following values:
  *   SUCCESS or ERROR
  * @register The used register:
  *   WD0CR<WDCR>
  */
Result WDT_WriteClearCode(void)
{
    Result retval = ERROR;

    if (WDT_GetWritingFlg() == ENABLE) {
        /* Set WDTCR to clear the binary counter */
        TSB_WD0->CR = WDT_CR_CLR_CODE;
        retval = SUCCESS;
    } else {
        /* Do nothing */
    }
    return retval;
}

/**
  * @brief  Get the flag for writing to registers.
  * @param  None
  * @retval The flag for writing to registers.
  *   The value returned can be one of the following values:
  *   ENABLE or DISABLE
  * @note When writing to WDMOD or WDCR, confirm writing flag enable.
  * @register The used register:
  *   WD0FLG<FLG>
  */
FunctionalState WDT_GetWritingFlg(void)
{
    FunctionalState retval = DISABLE;

    if (TSB_WD0->FLG == WDT_FLG_FLG_CLEAR) {
        retval = ENABLE;
    } else {
        /* Do nothing */
    }
    return retval;
}

/** @} */
/* End of group WDT_Exported_Functions */

/** @} */
/* End of group WDT */

/** @} */
/* End of group TX03_Periph_Driver */
#endif                          /* defined(__TMPM311_WDT_H) */
