/**
 * @brief       WDT Primitive
 * @author      AXELL CORPORATION
 * @description WDT Primitive Layer
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
 * @history     2019_03_08  [SDK2.2] WDTのレジスタ値を取得する関数を追加 (#2474)
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2019 AXELL CORPORATION, all rights reserved.
 */
/* DOM-IGNORE-END */

#include "AG903_errno.h"
#include "AG903_common.h"
#include "wdt/wdtprm.h"
#include "register/AG903_wdtreg.h"

#define	AG903_WDT_READ_REG(REG)			((AG903_WDT)->REG)
#define	AG903_WDT_WRITE_REG(REG,VAL)	((AG903_WDT)->REG  = (uint32_t)(VAL))
#define	AG903_WDT_SET_REG(REG,VAL)		((AG903_WDT)->REG |= (uint32_t)(VAL))
#define	AG903_WDT_CLR_REG(REG,VAL)		((AG903_WDT)->REG &= (uint32_t)(~VAL))

#define AG903_WDT_PASSWORD		(0x5AB9)

/**
 * @brief           WDTWdCounterのレジスタRead
 * @param           cnt [out] カウンタ値
 * @return          void
 * @description     WDTWdCounterのレジスタRead
*/
void AG903_WDTPrmGetCount(uint32_t* cnt)
{
	ASSERT(NULL != cnt);
	
	(*cnt) = AG903_WDT_READ_REG(WdCounter);
}

/**
 * @brief           WDTWdLoadのレジスタWrite
 * @param           cnt [in] カウンタ値
 * @return          void
 * @description     WDTWdLoadのレジスタWrite
*/
void AG903_WDTPrmSetCount(uint32_t cnt)
{
	AG903_WDT_WRITE_REG(WdLoad, cnt);
}

/**
 * @brief           WDTWdLoadのレジスタRead
 * @param           cnt [out] カウンタ値
 * @return          void
 * @description     WDTWdLoadのレジスタRead
*/
void AG903_WDTPrmGetLoad(uint32_t *load)
{
	ASSERT(NULL != load);

	(*load) = AG903_WDT_READ_REG(WdLoad);
}

/**
 * @brief           WDTWdRestartのレジスタWrite
 * @param           none
 * @return          void
 * @description     WDTWdRestartのレジスタWrite
*/
void AG903_WDTPrmRestartCount(void)
{
	AG903_WDT_WRITE_REG(WdRestart, AG903_WDT_PASSWORD);
}

/**
 * @brief           WDTWdCRのレジスタWrite
 * @param           rst [in] system reset制御
 * @param           intr [in] system interrupt制御
 * @param           ext [in] external signal制御
 * @return          void
 * @description     WDTWdCRのレジスタWrite<p>
 *                  rst , intr , ext は true=Enable , false=Disable です。
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_WDTPrmSetControl(_Bool rst, _Bool intr, _Bool ext)
{
	uint32_t set=0;
	uint32_t clr=0;
	
	if(true == rst) {
		set |= (1<<AG903_WDT_WdCR_WdRst_POS);
	}
	if(true == intr) {
		set |= (1<<AG903_WDT_WdCR_WdIntr_POS);
	}
	if(true == ext) {
		set |= (1<<AG903_WDT_WdCR_WdExt_POS);
	}
	clr  = ~set & (AG903_WDT_WdCR_WdRst_MSK|AG903_WDT_WdCR_WdIntr_MSK|AG903_WDT_WdCR_WdExt_POS);
	clr |= (1<<AG903_WDT_WdCR_WdClock_POS);	/* PCLK指定 */

	AG903_WDT_CLR_REG(WdCR, clr);
	AG903_WDT_SET_REG(WdCR, set);
}

/**
 * @brief           WDTWdCRのレジスタRead
 * @param           rst [out] system reset制御
 * @param           intr [out] system interrupt制御
 * @param           ext [out] external signal制御
 * @return          void
 * @description     WDTWdCRのレジスタRead<p>
 *                  rst , intr , ext は true=Enable , false=Disable です。
*/
void AG903_WDTPrmGetControl(_Bool *rst, _Bool *intr, _Bool *ext)
{
	uint32_t cr=0;
	ASSERT(NULL != rst);
	ASSERT(NULL != intr);
	ASSERT(NULL != ext);

	cr = AG903_WDT_READ_REG(WdCR);
	if (cr & (1<<AG903_WDT_WdCR_WdRst_POS)) {
		(*rst) = true;
	} else {
		(*rst) = false;
	}
	if (cr & (1<<AG903_WDT_WdCR_WdIntr_POS)) {
		(*intr) = true;
	} else {
		(*intr) = false;
	}
	if (cr & (1<<AG903_WDT_WdCR_WdExt_POS)) {
		(*ext) = true;
	} else {
		(*ext) = false;
	}
}

/**
 * @brief           WDTWdCRレジスタのWdEnableビットSet
 * @param           none
 * @return          void
 * @description     WDTWdCRレジスタのWdEnableビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_WDTPrmEnableCount(void)
{
	AG903_WDT_SET_REG(WdCR, (1<<AG903_WDT_WdCR_WdEnable_POS));
}

/**
 * @brief           WDTWdCRレジスタのWdEnableビットClear
 * @param           none
 * @return          void
 * @description     WDTWdCRレジスタのWdEnableビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_WDTPrmDisableCount(void)
{
	AG903_WDT_CLR_REG(WdCR, (1<<AG903_WDT_WdCR_WdEnable_POS));
}

/**
 * @brief           WDTWdStatusのレジスタRead
 * @param           status [out] ステータス
 * @return          void
 * @description     WDTWdStatusのレジスタRead
*/
void AG903_WDTPrmGetStatus(uint32_t* status)
{
	ASSERT(NULL != status);
	
	(*status) = AG903_WDT_READ_REG(WdStatus);
}

/**
 * @brief           WDTWdClearのレジスタWrite
 * @param           none
 * @return          void
 * @description     WDTWdClearのレジスタWrite
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_WDTPrmClearStatus(void)
{
	AG903_WDT_SET_REG(WdClear, (1<<AG903_WDT_WdClear_WdClear_POS));
}

/**
 * @brief           WDTWdIntrlenのレジスタWrite
 * @param           intrlen [in] wd_rstアサート時間 [clk]
 * @return          void
 * @description     WDTWdIntrlenのレジスタWrite
*/
void AG903_WDTPrmSetIntrlen(uint8_t intrlen)
{
	AG903_WDT_WRITE_REG(WdIntrlen, intrlen);
}

/**
 * @brief           WDTWdIntrlenのレジスタRead
 * @param           intrlen [out] wd_rstアサート時間 [clk]
 * @return          void
 * @description     WDTWdIntrlenのレジスタRead
*/
void AG903_WDTPrmGetIntrlen(uint8_t *intrlen)
{
	ASSERT(NULL != intrlen);
	(*intrlen) = AG903_WDT_READ_REG(WdIntrlen);
}

/**
 * @brief           WDTWdRevisionのレジスタRead
 * @param           revision [out] revision番号
 * @return          void
 * @description     WDTWdRevisionのレジスタRead
*/
void AG903_WDTPrmGetRevision(uint8_t *revision)
{
	ASSERT(NULL != revision);
	(*revision) = AG903_WDT_READ_REG(WdRevision);
}
