/*
* This program was created by AXELL CORPORATION.
* Copyright (C) 2017 AXELL CORPORATION, all rights reserved.
*/
#include "sample_common.h"
#include "com.h"
#include "timr/timrmgr.h"

/* プロトタイプ */
static int32_t Timr_init_module(void);
static int32_t Timr_term_module(void);
static void Timr_SampleHelp(void);
static void Timr_TickCountMode(void);
static void Timr_EventCountMode(void);
static void Timr_PulseCountMode(void);
static void Timr_LevelCountMode(void);
static void Timr_ResetStart(void);
static void Timr_MultiStart(void);
static void Timr_CtrlLed(uint8_t ctrl, uint8_t ledbit);
static void Timr_Tickhdr0(void* param);
static void Timr_Tickhdr1(void* param);
static void Timr_Tickhdr2(void* param);
static void Timr_Tickhdr3(void* param);
static void Timr_Evcnthdr(void* param);
static void Timr_Plscnthdr(void* param);
static void Timr_Lvcnthdr(void* param);

enum {
	TIMR_LED_CTRL_INIT=0,
	TIMR_LED_CTRL_OFF,
	TIMR_LED_CTRL_ON,
	TIMR_LED_CTRL_TOGGLE,
	TIMR_LED_CTRL_SLIDE,
};


/* Param */
#define TIMR_SMP_LED_BLINKTIM	(10)	/* LED点滅回数[回] */
#define TIMR_SMP_LED_NUM		(4)		/* LED数[個] */
#define TIMR_SMP_EVENT_CNTMAX	(5)		/* イベントカウント数[回] */
#define TIMR_SMP_PULSE_CNTMAX	(5)		/* パルスカウント数[回] */
#define TIMR_SMP_LEVEL_CNTMAX	(5)		/* レベルカウント数[回] */
#define TIMR_SMP_MULTI_TIMERNUM (4)		/* 複数タイマ起動個数[個] */


/* Macro */
#define	EPRINT(FMT, ...)		sys_print(0, FMT,##__VA_ARGS__)
#define	PRINT(FMT, ...)			sys_print(0, FMT"\r\n",##__VA_ARGS__)
#define TIMR_ERROR(str)			sys_print(1, " ERROR:%s[%d] *%s*\r\n",__FUNCTION__, __LINE__, str)

static void (*func[])() = {
	Timr_SampleHelp,
	Timr_TickCountMode,
	Timr_EventCountMode,
	Timr_PulseCountMode,
	Timr_LevelCountMode,
	Timr_ResetStart,
	Timr_MultiStart,
};

const void* TimrTickhdrTbl[TIMR_SMP_MULTI_TIMERNUM] =
{(void*)Timr_Tickhdr0, (void*)Timr_Tickhdr1, (void*)Timr_Tickhdr2, (void*)Timr_Tickhdr3};

static volatile uint32_t TimrTickCounter[TIMR_SMP_MULTI_TIMERNUM]={0};
static uint32_t	TimrEventCounter=0;
static uint32_t	TimrPulseCounter=0;
static uint32_t	TimrLevelCounter=0;


/**
 * @brief		メイン処理
 * @param[in]	param	制御パラメータ
 * @return		なし
 * @note		なし
 */
void TIMR_main(uint8_t param)
{
	uint8_t		mode = 0;
	char		input[2+2];

	((void)param);

	Timr_SampleHelp();	/* Help表示 */

	Timr_init_module();

	while (mode != 0xFF) {
		EPRINT(" -- Choose sample number (00h<HELP> to FFh): ");
		COM_GetNum_Wait(input, sizeof(input));
		mode = (ASCtoBIN(input[0]) << 4)
			 | (ASCtoBIN(input[1]) << 0);
		if(0xFF == mode) {
			break;
		}
		if(mode >= (sizeof(func)/sizeof(void*))) {
			func[0](); /* Help */
		}
		else {
			func[mode]();	/* Sample func実行 */
		}
	}

	Timr_term_module();

	return;
}

/**
 * @brief		サブ処理
 * @param[in]	param	制御パラメータ
 * @return		なし
 * @note		なし
 */
void TIMR_sub(uint32_t param)
{
	((void)param);
	/* 処理なし */
	return;
}

/**
 * @brief		モジュール初期化
 * @param[in]	なし
 * @retval		AG903_ENONE		正常終了
 * @note		なし
 */
static int32_t Timr_init_module(void)
{
	static _Bool	TimrInit=false;
	int32_t 		result;

	if(false == TimrInit) {
		result = AG903_TIMRMgrInit(); /* Managaer 初期化 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("Init");
		}
		else {
			TimrInit = true;
		}
	}

	return AG903_ENONE;
}

/**
 * @brief		モジュール終了
 * @param[in]	なし
 * @retval		AG903_ENONE		正常終了
 * @note		なし
 */
static int32_t Timr_term_module(void)
{
	/* 処理なし */
	return AG903_ENONE;
}

/**
 * @brief		ヘルプ表示
 * @param		なし
 * @return		なし
 * @note		なし
 */
static void Timr_SampleHelp(void)
{
	PRINT("\t# 00 ... Help");
	PRINT("\t# 01 ... Tick Count [LED Blinking]");
	PRINT("\t# 02 ... Event Count");
	PRINT("\t# 03 ... Pulse Count");
	PRINT("\t# 04 ... Level Count");
	PRINT("\t# 05 ... Reset Start [LED Blinking]");
	PRINT("\t# 06 ... Multi Start [Lap count]");
	PRINT("\t# FF ... Exit Sample");

	return;
}

/**
 * @brief		Tick Count動作 （LED点滅）
 * @param		なし
 * @return		なし
 * @note		なし
 */
static void Timr_TickCountMode(void)
{
	AG903_TIMRMgrHandle*		handle;
	AG903_TIMRMgrTickCntParam 	tick;
	int32_t 	result;
	uint32_t 	timcnt= 0;

	PRINT(" Tick Count [LED Blinking]");

	Timr_CtrlLed(TIMR_LED_CTRL_INIT, 0xFF);
	Timr_CtrlLed(TIMR_LED_CTRL_OFF,  0xFF);
	TimrTickCounter[0] = 0;

	/* タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&handle); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(handle, (void*)Timr_Tickhdr0, (void*)handle);	/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	tick.period  = 100000000;	/* 500[ms] (clk 200M[Hz]時) */
	tick.match   = 0;
	tick.resolution = AG903_TIMR_CNT_SYSCLK;
	tick.oneshot = false;
	tick.output  = NULL;
	result = AG903_TIMRMgrSetTickCountMode(handle, &tick); 								/* Tick・Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetTickCountMode");
	}
	result = AG903_TIMRMgrDisableIntMask(handle, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* タイマスタート (LED点滅) */
	PRINT(" LED Blinking...");
	TimrTickCounter[0] = 0;
	result = AG903_TIMRMgrStart(handle); 												/* タイマスタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
	while(1) {
		if(timcnt != TimrTickCounter[0]) {
			timcnt = TimrTickCounter[0];
			Timr_CtrlLed(TIMR_LED_CTRL_TOGGLE, 0xFF);	/* LED更新 */
		}
		if((TIMR_SMP_LED_BLINKTIM<<1) <= TimrTickCounter[0]) {
			break;
		}
	}

	/* タイマ解放 */
	result = AG903_TIMRMgrStop(handle); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(handle, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(handle, (void*)Timr_Tickhdr0); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(handle, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(handle); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	Timr_CtrlLed(TIMR_LED_CTRL_ON,  0xFF);

	return;
}

/**
 * @brief		Event Count動作
 * @param		なし
 * @return		なし
 * @note		タイマイベントを生成し別タイマでカウントします
 */
static void Timr_EventCountMode(void)
{
	AG903_TIMRMgrHandle*		cnt_hdl;
	AG903_TIMRMgrHandle*		ev_hdl;
	AG903_TIMRMgrTickCntParam 	tick;
	AG903_TIMRMgrEventCntParam	event;
	int32_t 	result;
	uint32_t 	timcnt= 0;
	uint32_t 	evcnt = 0;
	uint8_t		ch;

	PRINT(" Event Count");

	Timr_CtrlLed(TIMR_LED_CTRL_INIT, 0xFF);
	Timr_CtrlLed(TIMR_LED_CTRL_OFF,  0xFF);
	TimrTickCounter[0] = 0;
	TimrEventCounter   = 0;

	/* Event生成用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&ev_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(ev_hdl, (void*)Timr_Tickhdr0, (void*)ev_hdl); 	/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	tick.period  = 50000000;	/* 250[ms] (clk 200M[Hz]時) */
	tick.match   = 0;
	tick.resolution = AG903_TIMR_CNT_SYSCLK;
	tick.oneshot = false;
	tick.output  = NULL;
	result = AG903_TIMRMgrSetTickCountMode(ev_hdl, &tick); 								/* Tick・Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetTickCountMode");
	}
	result = AG903_TIMRMgrEnableEventTrigger(ev_hdl, AG903_TIMR_OVERFLOW_BIT);			/* Event生成設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableEventTrigger");
	}
	result = AG903_TIMRMgrDisableIntMask(ev_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* Eventカウント用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&cnt_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(cnt_hdl, (void*)Timr_Evcnthdr, (void*)cnt_hdl);	/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	result = AG903_TIMRMgrGetChannel(ev_hdl, &ch);
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetChannel");
	}
	event.period  = 5; /* 5回で1カウント */
	event.match	  = 0;
	event.event   = AG903_EVENT32_TIM0+ch;
	event.oneshot = false;
	event.output  = NULL;
	result = AG903_TIMRMgrSetEventCountMode(cnt_hdl, &event);							/* Event Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetEventCountMode");
	}
	result = AG903_TIMRMgrDisableIntMask(cnt_hdl, AG903_TIMR_OVERFLOW_BIT); 			/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* タイマスタート (Eventカウント) */
	result = AG903_TIMRMgrStart(cnt_hdl); 												/* Event Countスタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
	result = AG903_TIMRMgrStart(ev_hdl); 												/* Event生成スタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
    while(1) {
		if(timcnt != TimrTickCounter[0]) {
			timcnt = TimrTickCounter[0];
			Timr_CtrlLed(TIMR_LED_CTRL_SLIDE,  0xFF); 	/* LED更新 */
		}
		if(evcnt != TimrEventCounter) {
			evcnt = TimrEventCounter;
			PRINT(" Count : %02d", evcnt);				/* 表示更新 */
			if(TIMR_SMP_EVENT_CNTMAX <= evcnt) {
				break;
			}
		}
   }

	/* Eventカウント用タイマ停止 */
	result = AG903_TIMRMgrStop(cnt_hdl); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(cnt_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(cnt_hdl, (void*)Timr_Evcnthdr); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(cnt_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(cnt_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	/* Event生成用タイマ停止 */
	result = AG903_TIMRMgrStop(ev_hdl); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(ev_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDisableEventTrigger(ev_hdl, AG903_TIMR_OVERFLOW_BIT); 		/* Event生成解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableEventTrigger");
	}
	result = AG903_TIMRMgrDeleteIntHandler(ev_hdl, (void*)Timr_Tickhdr0); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(ev_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(ev_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	Timr_CtrlLed(TIMR_LED_CTRL_ON,  0xFF);

	return;
}

/**
 * @brief		Pulse Count動作
 * @param		なし
 * @return		なし
 * @note		タイマでPulseを生成し別タイマでカウントします
 */
static void Timr_PulseCountMode(void)
{
	AG903_TIMRMgrHandle*		cnt_hdl;
	AG903_TIMRMgrHandle*		pls_hdl;
	AG903_TIMRMgrTickCntOutput	out;
	AG903_TIMRMgrTickCntParam 	tick;
	AG903_TIMRMgrPulseCntParam	pulse;
	int32_t 	result;
	uint32_t 	timcnt = 0;
	uint32_t 	plscnt = 0;

	PRINT(" Pulse Count");

	Timr_CtrlLed(TIMR_LED_CTRL_INIT, 0xFF);
	Timr_CtrlLed(TIMR_LED_CTRL_OFF,  0xFF);
	TimrTickCounter[0] = 0;
	TimrPulseCounter   = 0;

	/* Pulse生成用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&pls_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(pls_hdl, (void*)Timr_Tickhdr0, (void*)pls_hdl);	/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	tick.period  = 50000000;  /* 250[ms] (clk 200M[Hz]時) */
	tick.match   = 0;
	tick.resolution = AG903_TIMR_CNT_SYSCLK;
	tick.oneshot = false;
	tick.output  = &out;
	out.plusewidth = 1000000; /* 5[ms] (clk 200M[Hz]時) */
	out.mode     = AG903_TIMR_OUT_PLUSE;
	out.portch   = 0;
	out.polarity = AG903_TIMR_POL_POSITIVE;
	out.mask     = AG903_TIMR_COMPARE_BIT;
	result = AG903_TIMRMgrSetTickCountMode(pls_hdl, &tick); 							/* Tick・Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetTickCountMode");
	}
	result = AG903_TIMRMgrDisableIntMask(pls_hdl, AG903_TIMR_OVERFLOW_BIT); 			/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* Pulseカウント用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&cnt_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(cnt_hdl, (void*)Timr_Plscnthdr, (void*)cnt_hdl);/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	pulse.period   = 5; /* 5回で1カウント */
	pulse.match    = 0;
	pulse.intype   = AG903_TIMR_INPUT_EXTOUT0;
	pulse.polarity = AG903_TIMR_POL_POSITIVE;
	pulse.sampling = AG903_TIMR_CNT_SYSCLK;
	pulse.oneshot  = false;
	pulse.output   = NULL;
	result = AG903_TIMRMgrSetPulseCountMode(cnt_hdl, &pulse);							/* Pulseカウントモード */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetPulseCountMode");
	}
	result = AG903_TIMRMgrDisableIntMask(cnt_hdl, AG903_TIMR_OVERFLOW_BIT); 			/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* タイマスタート (Pulseカウント) */
	result = AG903_TIMRMgrStart(cnt_hdl); 												/* Pulseカウントスタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
	result = AG903_TIMRMgrStart(pls_hdl); 												/* Pulse生成スタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
    while(1) {
		if(timcnt != TimrTickCounter[0]) {
			timcnt = TimrTickCounter[0];
			Timr_CtrlLed(TIMR_LED_CTRL_SLIDE,  0xFF); 	/* LED更新 */
		}
		if(plscnt != TimrPulseCounter) {
			plscnt = TimrPulseCounter;
			PRINT(" Count : %02d", plscnt);				/* 表示更新 */
			if(TIMR_SMP_PULSE_CNTMAX <= plscnt) {
				break;
			}
		}
    }

	/* Pulseカウント用タイマ解放 */
	result = AG903_TIMRMgrStop(cnt_hdl); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(cnt_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(cnt_hdl, (void*)Timr_Plscnthdr); 			/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(cnt_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(cnt_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	/* Pulse生成用タイマ停止 */
	result = AG903_TIMRMgrStop(pls_hdl); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(pls_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(pls_hdl, (void*)Timr_Tickhdr0); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(pls_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(pls_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	Timr_CtrlLed(TIMR_LED_CTRL_ON,  0xFF);

	return;
}

/**
 * @brief		Level Count動作
 * @param		なし
 * @return		なし
 * @note		タイマでPulseを生成し別タイマでレベルカウントします
 */
static void Timr_LevelCountMode(void)
{
	AG903_TIMRMgrHandle*		cnt_hdl;
	AG903_TIMRMgrHandle*		pls_hdl;
	AG903_TIMRMgrTickCntOutput	out;
	AG903_TIMRMgrTickCntParam 	tick;
	AG903_TIMRMgrLevelCntParam	level;
	int32_t 	result;

	PRINT(" Level Count");

	TimrTickCounter[0] = 0;
	TimrLevelCounter   = 0;

	/* Pulse生成用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&pls_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(pls_hdl, (void*)Timr_Tickhdr0, (void*)pls_hdl);	/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	tick.period  = 20000000;  /* 100[ms] (clk 200M[Hz]時) */
	tick.match   = 0;
	tick.resolution = AG903_TIMR_CNT_SYSCLK;
	tick.oneshot = false;
	tick.output  = &out;
	out.plusewidth = 1000000; /* 5[ms] (clk 200M[Hz]時) */
	out.mode     = AG903_TIMR_OUT_PLUSE;
	out.portch   = 0;
	out.polarity = AG903_TIMR_POL_POSITIVE;
	out.mask     = AG903_TIMR_COMPARE_BIT;
	result = AG903_TIMRMgrSetTickCountMode(pls_hdl, &tick); 							/* Tick・Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetTickCountMode");
	}
	result = AG903_TIMRMgrDisableIntMask(pls_hdl, AG903_TIMR_OVERFLOW_BIT); 			/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* Levelカウント用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&cnt_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(cnt_hdl, (void*)Timr_Lvcnthdr, (void*)cnt_hdl); /* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	level.period   = 200000; /* 1[ms] (clk 200M[Hz]時) */
	level.match    = 0;
	level.intype   = AG903_TIMR_INPUT_EXTOUT0;
	level.polarity = AG903_TIMR_POL_POSITIVE;
	level.sampling = AG903_TIMR_CNT_SYSCLK;
	level.oneshot  = false;
	level.output   = NULL;
	result = AG903_TIMRMgrSetLevelCountMode(cnt_hdl, &level);							/* Levelカウントモード */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetLevelCountMode");
	}
	result = AG903_TIMRMgrDisableIntMask(cnt_hdl, AG903_TIMR_OVERFLOW_BIT);  			/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* タイマスタート (Levelカウント) */
	result = AG903_TIMRMgrStart(cnt_hdl); 												/* Levelカウントスタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
	result = AG903_TIMRMgrStart(pls_hdl); 												/* Pulse生成スタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
    while(1) {
		if(TIMR_SMP_LEVEL_CNTMAX < TimrTickCounter[0]) {
			PRINT(" ActiveLevel : %d/%d", TimrLevelCounter, (TIMR_SMP_LEVEL_CNTMAX*100));
			break;
		}
	}

	/* Levelカウント用タイマ解放 */
	result = AG903_TIMRMgrStop(cnt_hdl); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(cnt_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(cnt_hdl, (void*)Timr_Lvcnthdr);  			/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(cnt_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(cnt_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	/* Pulse生成用タイマ解放 */
	result = AG903_TIMRMgrStop(pls_hdl); 												/* Tick・Count停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(pls_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(pls_hdl, (void*)Timr_Tickhdr0); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(pls_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(pls_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	return;
}

/**
 * @brief		Reset Start動作（LED点滅）
 * @param		なし
 * @return		なし
 * @note		タイマでイベントを生成し別タイマがイベントトリガで起動します
 */
static void Timr_ResetStart(void)
{
	AG903_TIMRMgrHandle*		wup_hdl;
	AG903_TIMRMgrHandle*		ev_hdl;
	AG903_TIMRMgrTickCntParam 	tick0;
	AG903_TIMRMgrTickCntParam	tick1;
	AG903_TIMRMgrResetParam		wuptrg;
	int32_t 	result;
	uint32_t 	timcnt= 0;
	uint8_t		ch;

	PRINT(" Reset Start [LED Blinking]");

	Timr_CtrlLed(TIMR_LED_CTRL_INIT, 0xFF);
	Timr_CtrlLed(TIMR_LED_CTRL_OFF,  0xFF);
	TimrTickCounter[0] = 0;
	TimrTickCounter[1] = 0;

	/* Event生成用タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&ev_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(ev_hdl, (void*)Timr_Tickhdr0, (void*)ev_hdl); 	/* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	tick0.period  = 200000000;	/* 1000[ms] (clk 200M[Hz]時) */
	tick0.match   = 0;
	tick0.resolution = AG903_TIMR_CNT_SYSCLK;
	tick0.oneshot = true; /* Oneshot */
	tick0.output  = NULL;
	result = AG903_TIMRMgrSetTickCountMode(ev_hdl, &tick0); 							/* Tick・Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetTickCountMode");
	}
	result = AG903_TIMRMgrEnableEventTrigger(ev_hdl, AG903_TIMR_OVERFLOW_BIT);			/* Event生成設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableEventTrigger");
	}
	result = AG903_TIMRMgrDisableIntMask(ev_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* Reset起動タイマ設定 */
	result = AG903_TIMRMgrGetHandle(&wup_hdl); 											/* ハンドル取得 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetHandle");
	}
	result = AG903_TIMRMgrSetIntHandler(wup_hdl, (void*)Timr_Tickhdr1, (void*)wup_hdl); /* 割込みハンドラ登録 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetHandler");
	}
	result = AG903_TIMRMgrGetChannel(ev_hdl, &ch);
	if(AG903_ENONE != result) {
		TIMR_ERROR("GetChannel");
	}
	tick1.period  = 100000000;	/* 500[ms] (clk 200M[Hz]時) */
	tick1.match   = 0;
	tick1.resolution = AG903_TIMR_CNT_SYSCLK;
	tick1.oneshot = false;
	tick1.output  = NULL;
	result = AG903_TIMRMgrSetTickCountMode(wup_hdl, &tick1); 							/* Tick・Countモード設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetTickCountMode");
	}
	wuptrg.trigger  = AG903_TIMR_RSTTRG_EVENT;
	wuptrg.event    = AG903_EVENT32_TIM0+ch;
	wuptrg.polarity = AG903_TIMR_POL_POSITIVE;
	wuptrg.sampling = AG903_TIMR_CNT_SYSCLK;
	result = AG903_TIMRMgrEnableResetTrigger(wup_hdl, &wuptrg);							/* リセットトリガ設定 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableResetTrigger");
	}
	result = AG903_TIMRMgrDisableIntMask(wup_hdl, AG903_TIMR_OVERFLOW_BIT); 			/* 割込みマスク解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableIntMask");
	}

	/* タイマスタート */
	PRINT(" * Wait Trigger");
	result = AG903_TIMRMgrStart(ev_hdl); 												/* Event生成スタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}
	while(1) {
		if(timcnt != TimrTickCounter[1]) {
			if(0 == timcnt) {
				PRINT(" * Detect Trigger");
				PRINT(" * LED Blinking...");
			}
			timcnt = TimrTickCounter[1];
			Timr_CtrlLed(TIMR_LED_CTRL_TOGGLE, 0xFF);	/* LED更新 */
		}
		if((TIMR_SMP_LED_BLINKTIM<<1) <= TimrTickCounter[1]) {
			break;
		}
	}

	/* Reset起動タイマ解放 */
	result = AG903_TIMRMgrStop(wup_hdl); 												/* タイマ停止 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Stop");
	}
	result = AG903_TIMRMgrEnableIntMask(wup_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDeleteIntHandler(wup_hdl, (void*)Timr_Tickhdr1); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(wup_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(wup_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	/* Event生成用タイマ解放 */
	result = AG903_TIMRMgrEnableIntMask(ev_hdl, AG903_TIMR_OVERFLOW_BIT); 				/* 割込みマスク */
	if(AG903_ENONE != result) {
		TIMR_ERROR("EnableIntMask");
	}
	result = AG903_TIMRMgrDisableEventTrigger(ev_hdl, AG903_TIMR_OVERFLOW_BIT); 		/* Event生成解除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DisableEventTrigger");
	}
	result = AG903_TIMRMgrDeleteIntHandler(ev_hdl, (void*)Timr_Tickhdr0); 				/* 割込みハンドラ削除 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("DeleteHandler");
	}
	result = AG903_TIMRMgrSetCount(ev_hdl, 0);											/* カウンタクリア */
	if(AG903_ENONE != result) {
		TIMR_ERROR("SetCount");
	}
	result = AG903_TIMRMgrReleaseHandle(ev_hdl); 										/* ハンドル解放 */
	if(AG903_ENONE != result) {
		TIMR_ERROR("ReleaseHandle");
	}

	Timr_CtrlLed(TIMR_LED_CTRL_ON,  0xFF);

	return;
}

/**
 * @brief		複数タイマ同時起動動作 (ラップ計測)
 * @param		なし
 * @return		なし
 * @note		なし
 */
static void Timr_MultiStart(void)
{
	AG903_TIMRMgrHandle*		handle[TIMR_SMP_MULTI_TIMERNUM];
	AG903_TIMRMgrTickCntParam	tick;
	uint32_t 	cnt;
	int32_t 	result;
	int32_t 	loop;
	int32_t 	wakeup=0;
	char		string[32];
	uint8_t		ch[TIMR_SMP_MULTI_TIMERNUM];

	PRINT(" Multi Start [Lap count]");

	/* Lap計測用タイマ設定 */
	tick.period  = 2000000;	/* 10[ms] (clk 200M[Hz]時) */
	tick.match   = 0;
	tick.resolution = AG903_TIMR_CNT_SYSCLK;
	tick.oneshot = false;
	tick.output  = NULL;
	for(loop=0; loop<TIMR_SMP_MULTI_TIMERNUM; loop++) {
		TimrTickCounter[loop] = 0;
		result = AG903_TIMRMgrGetHandle(&handle[loop]); 								/* ハンドル取得 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("GetHandle");
		}
		result = AG903_TIMRMgrSetIntHandler(handle[loop], (void*)TimrTickhdrTbl[loop],
															(void*)handle[loop]); 		/* 割込みハンドラ登録 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("SetHandler");
		}
		result = AG903_TIMRMgrSetTickCountMode(handle[loop], &tick); 					/* Tick・Countモード設定 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("SetTickCountMode");
		}
		result = AG903_TIMRMgrDisableIntMask(handle[loop], AG903_TIMR_OVERFLOW_BIT);	/* 割込みマスク解除 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("DisableIntMask");
		}
		result = AG903_TIMRMgrGetChannel(handle[loop], &ch[loop]);						/* CH取得 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("GetChannel");
		}
		wakeup |= (1<<ch[loop]);
	}

	/* タイマスタート〜表示 */
	result = AG903_TIMRMgrStartMulti(wakeup);											/* 複数タイマ同時スタート */
	if(AG903_ENONE != result) {
		TIMR_ERROR("Start");
	}

	for(loop=0; loop<TIMR_SMP_MULTI_TIMERNUM; loop++) {
		EPRINT(" Push Enter");
		COM_GetNum_Wait(string, 2); /* 2 = CRLF */
		result = AG903_TIMRMgrStop(handle[loop]); 										/* カウント停止 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("Stop");
		}
	}
	for(loop=0; loop<TIMR_SMP_MULTI_TIMERNUM; loop++) {		/* Lap表示 */
        cnt = TimrTickCounter[loop];
		PRINT(" Lap%1d : %02d.%02d", loop, (cnt/100), (cnt%100));
	}

	/* Lap計測用タイマ解放 */
	for(loop=0; loop<TIMR_SMP_MULTI_TIMERNUM; loop++) {
		result = AG903_TIMRMgrEnableIntMask(handle[loop], AG903_TIMR_OVERFLOW_BIT); 	/* 割込みマスク */
		if(AG903_ENONE != result) {
			TIMR_ERROR("EnableIntMask");
		}
		result = AG903_TIMRMgrDeleteIntHandler(handle[loop], (void*)TimrTickhdrTbl[loop]); 	/* 割込みハンドラ削除 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("DeleteHandler");
		}
		result = AG903_TIMRMgrSetCount(handle[loop], 0);								/* カウンタクリア */
		if(AG903_ENONE != result) {
			TIMR_ERROR("SetCount");
		}
		result = AG903_TIMRMgrReleaseHandle(handle[loop]); 								/* ハンドル解放 */
		if(AG903_ENONE != result) {
			TIMR_ERROR("ReleaseHandle");
		}
	}

	return;
}

/**
 * @brief		LED制御
 * @param[in]	ctrl	制御内容
 * @param[in]	ledbit	LED選択 (bit指定)
 * @return		なし
 * @note		使用するHW環境(基板,FPGA ver.,,,)によって異なる可能性があります
 */
static void Timr_CtrlLed(uint8_t ctrl, uint8_t ledbit)
{
	uint8_t led;

	switch(ctrl) {
		case TIMR_LED_CTRL_INIT:
			Board_SelectBlpConnection(0, AG903_BLP_CONNECT_NONE);
			Board_SelectBlpConnection(1, AG903_BLP_CONNECT_NONE);
			break;
		case TIMR_LED_CTRL_OFF:
			Board_SetLedStatus(ledbit);
			break;
		case TIMR_LED_CTRL_ON:
			Board_SetLedStatus(~ledbit);
			break;
		case TIMR_LED_CTRL_TOGGLE:
			Board_GetLedStatus(&led);
			led ^= ledbit;
			Board_SetLedStatus(led);
			break;
		case TIMR_LED_CTRL_SLIDE:
			Board_GetLedStatus(&led);
			led = (~led);
			if(0x00 == (led&0x0F)) {
				led = 0x01;
				Board_SetLedStatus(~led);
			}
			else if(0x08 < led) {
				led = 0x00;
				Board_SetLedStatus(~led);
			}
			else {
				led <<= 1;
				Board_SetLedStatus(~led);
			}
			break;
	}

	return;
}

/**
 * @brief		Tick Count割込み0
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Tickhdr0(void* param)
{
	AG903_TIMRMgrHandle* handle;

	TimrTickCounter[0] ++;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	return;
}

/**
 * @brief		Tick Count割込み1
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Tickhdr1(void* param)
{
	AG903_TIMRMgrHandle* handle;

	TimrTickCounter[1] ++;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	return;
}

/**
 * @brief		Tick Count割込み2
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Tickhdr2(void* param)
{
	AG903_TIMRMgrHandle* handle;

	TimrTickCounter[2] ++;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	return;
}

/**
 * @brief		Tick Count割込み3
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Tickhdr3(void* param)
{
	AG903_TIMRMgrHandle* handle;

	TimrTickCounter[3] ++;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	return;
}
/**
 * @brief		Event Count割込み
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Evcnthdr(void* param)
{
	AG903_TIMRMgrHandle* handle;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	TimrEventCounter ++;

	return;
}

/**
 * @brief		Pulse Count割込み
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Plscnthdr(void* param)
{
	AG903_TIMRMgrHandle* handle;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	TimrPulseCounter ++;

	return;
}

/**
 * @brief		Level Count割込み
 * @param[in]	param	タイマハンドル
 * @return		なし
 * @note		なし
 */
static void Timr_Lvcnthdr(void* param)
{
	AG903_TIMRMgrHandle* handle;

	handle = (AG903_TIMRMgrHandle*)(param);
	AG903_TIMRMgrClearStatus(handle, AG903_TIMR_OVERFLOW_BIT);

	TimrLevelCounter ++;

	return;
}

