/**
 * @brief       WDT Controler
 * @author      AXELL CORPORATION
 * @description WDT Controler
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
*/
/* 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_intno.h"
#include "wdt/wdtctl.h"
#include "wdt/wdtprm.h"
#include "int/intmgr.h"

typedef struct _AG903_WDTCtlInthdrStat {
	int32_t	hdrid;		/* ハンドラID */
	void*	func;		/* 割込みハンドラの起動番地 */
}AG903_WDTCtlInthdrStat;

static AG903_WDTCtlInthdrStat	WdtInthdrStat = {0, NULL};

/**
 * @brief           WDT初期化
 * @param           param [in] WDT設定パラメータ
 * @return          初期化結果
 * @retval          AG903_ENONE    正常終了
 * @retval          -AG903_EINVAL  引数異常
 * @description     WDTの初期化をします。WDTが動作中であった場合は停止して初期化します。<p>
 *                  割込みハンドラの登録は削除されません。
 *                  ステータスはクリアされます。
 * @note            使用を中止するときは必要に応じアプリでAG903_INTMgrDisableIntによりWDTの割り込みを無効にして下さい。
*/
int32_t AG903_WDTCtlInit(AG903_WDTCtlParam* param)
{
	_Bool rst  = false;
	_Bool intr = false;
	_Bool ext  = false;
	
	if(NULL == param) {
		return -AG903_EINVAL;
	}

	AG903_WDTPrmDisableCount();		/* WDT停止 */
	AG903_WDTPrmClearStatus();
	AG903_WDTPrmSetIntrlen(param->intrlen);
	AG903_WDTPrmSetCount(param->count);
	AG903_WDTPrmRestartCount();
	if(AG903_WDT_SYSRESET_ENABLE & param->enable) {
		rst = true;
	}
	if(AG903_WDT_SYSINTR_ENABLE & param->enable) {
		intr = true;
	}
	if(AG903_WDT_EXTSIGNAL_ENABLE & param->enable) {
		ext = true;
	}
	AG903_WDTPrmSetControl(rst, intr, ext);

	return AG903_ENONE;
}

/**
 * @brief           割込みハンドラの登録
 * @param           func [in] 割込みハンドラの起動番地
 * @param           param [in] パラメータ
 * @return          割り込みハンドラの登録結果
 * @retval          AG903_ENONE    正常終了
 * @retval          -AG903_EINVAL  引数異常
 * @retval          -AG903_EPERM   既に登録済み.
 * @retval          -AG903_EFAULT  処理失敗 (ハンドラが登録出来ない).
 * @description     割り込みハンドラを登録します。<p>
 *                  param はコールバック関数に引数として渡されます。
*/
int32_t	AG903_WDTCtlSetIntHandler(void* func, void* param)
{
	AG903_INTMgrHdrPrm inthdr;
	int32_t	 hdrid;

	if(NULL == func) {
		return -AG903_EINVAL;
	}
	if(NULL != WdtInthdrStat.func) {
		return -AG903_EPERM;	/* 既に登録済み */
	}
	inthdr.atr   = AG903_INT_HLNG;
	inthdr.intno = AG903_IRQ25_WDT;
	inthdr.func  = func;
	inthdr.exinf = param;
	hdrid = AG903_INTMgrSetHandler(&inthdr);
	if(0 >= hdrid) {
		return -AG903_EFAULT;
	}
	AG903_INTMgrEnableInt(AG903_IRQ25_WDT);
	WdtInthdrStat.hdrid = hdrid;
	WdtInthdrStat.func  = func;
	
	return AG903_ENONE;
}

/**
 * @brief           割込みハンドラの削除
 * @param           none
 * @return          割り込みハンドラの削除結果
 * @retval          AG903_ENONE    正常終了
 * @retval          -AG903_EFAULT  処理失敗 (ハンドラが削除出来ない).
 * @description     割り込みハンドラを削除します。
*/
int32_t	AG903_WDTCtlDeleteIntHandler(void)
{
	int32_t	 retval = AG903_ENONE;
	
	if(NULL != WdtInthdrStat.func) {
		retval = AG903_INTMgrDeleteHandler(WdtInthdrStat.hdrid);
		if(AG903_ENONE != retval) {
			return -AG903_EFAULT;
		}
		WdtInthdrStat.hdrid = 0;
		WdtInthdrStat.func  = NULL;
	}

	return retval;
}

/**
 * @brief           WDT Enable
 * @param           none
 * @return          void
 * @retval          none
 * @description     WDTをEnableします。
*/
void AG903_WDTCtlEnable(void)
{
	AG903_WDTPrmEnableCount();
}

/**
 * @brief           WDT Disable
 * @param           none
 * @return          void
 * @retval          none
 * @description     WDTをDisableします。
*/
void AG903_WDTCtlDisable(void)
{
	AG903_WDTPrmDisableCount();
}

/**
 * @brief           WDT Restart
 * @param           none
 * @return          void
 * @retval          none
 * @description     WDTをRestartします。
*/
void AG903_WDTCtlRestart(void)
{
	AG903_WDTPrmRestartCount();
}

/**
 * @brief           ステータス取得
 * @param           status [out] ステータス
 * @return          ステータス取得結果
 * @retval          AG903_ENONE    正常終了
 * @retval          -AG903_EINVAL  引数異常
 * @description     ステータスの取得をします。<p>
 *                  status は"0"が時間未達、"1"が時間到達です。
*/
int32_t AG903_WDTCtlGetStatus(uint32_t* status)
{
	if(NULL == status) {
		return -AG903_EINVAL;
	}
	
	AG903_WDTPrmGetStatus(status);
	
	return AG903_ENONE;
}

/**
 * @brief           ステータスクリア
 * @param           none
 * @return          ステータスクリア結果
 * @retval          AG903_ENONE    正常終了
 * @description     ステータスをクリアします。
*/
int32_t AG903_WDTCtlClearStatus(void)
{
	AG903_WDTPrmClearStatus();
	
	return AG903_ENONE;
}

/**
 * @brief           カウンタ値取得
 * @param           count [out] カウンタ値
 * @return          カウンタ値取得結果
 * @retval          AG903_ENONE    正常終了
 * @retval          -AG903_EINVAL  引数異常
 * @description     カウンタ値を取得します。
*/
int32_t AG903_WDTCtlGetCount(uint32_t* count)
{
	if(NULL == count) {
		return -AG903_EINVAL;
	}
	
	AG903_WDTPrmGetCount(count);
	
	return AG903_ENONE;
}

