/*
 *	clipevtm.h
 *
 *	イベントタイマ
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2015 Naoyuki Sawa
 *
 *	* Mon Jun 09 17:53:50 JST 2014 Naoyuki Sawa
 *	- 1st リリース。
 *	- 割り込み外で処理するタイマイベントを、一元管理するための機能です。
 *	  STLプロジェクトの「イベントタイマ更新処理」(SubEventUpdateTimerInfo)の方法を参考にしました。
 *	* Wed Feb 04 21:22:53 JST 2015 Naoyuki Sawa
 *	- Hewは要素数[0]の配列に対応していないので、要素数[1]として調整しました。
 *	  P/ECE開発環境(GCC)やWindows(VC++6.0)は、要素数[0]の配列に対応しているので、関係有りません。
 *	* Sun May 31 14:08:56 JST 2015 Naoyuki Sawa
 *	- dEvtTmrC.exeを作成したことに伴い、dEvtTmrC.exeが生成するデータ形式に対応するよう関数仕様を変更しました。
 *	* Mon Jun 01 00:00:04 JST 2015 Naoyuki Sawa
 *	- ソースコードを整理して、古いコードをコメント化して残していたのを削除しました。
 *	  古いコードを参照する場合は、前回のアーカイブを参照してください。
 *	- ST_EvtTmrCh構造体を変更し、12Byte⇒8Byteにサイズを低減しました。
 *	  dEvtTmrC.exeが出力したバイナリ形式の'EvtTmrNo'と、イベントチャネル番号を1対1に対応付けて使用する場合に、
 *	  イベントチャネル数がかなり多くなるので、ST_EvtTmrCh構造体のサイズを低減する事でRAM節約の効果が高いです。
 *	- 予約済みのイベント番号を、「end=0,loop=USHRT_MAX」⇒「end=USHRT_MAX,loop=(USHRT_MAX-1)」に変更しました。
 *	  アプリケーション定義のイベント番号として、0番を開放しておく方が良いと考えたからです。
 *	* Wed Aug 12 21:51:06 JST 2015 Naoyuki Sawa
 *	- (*pData)[1]の値の意味を変更しました。
 *	  これまでは、全体を一回実行して終了するか(end)、全体をループするか(loop)の指定しか出来ませんでしたが、
 *	  今後は、一部分のループも出来るようになりました。
 *	  詳細は、'/clip/tool/dEvtTmrC/Sample/Sample.txt'を参照してください。
 *	* Thu Aug 13 21:54:21 JST 2015 Naoyuki Sawa
 *	- (*pData)[1]の値の意味を変更しました。
 *	  これまでは、イベント番号として'0'も使用可能でしたが、今後は'0'は使用不可になりました。
 *	  イベント番号='0'は、dEvtTmrC.exeによって'no-job'の意味として生成され、当モジュールの処理で破棄されます。
 *	  イベント番号='0'は、データ内には出現し得ますが、アプリケーションへ通知される事はありません。
 *	  具体的には、'/clip/tool/dEvtTmrC/winapp.h'の同日のコメントを参照してください。
 */
#ifndef __CLIP_EVTM_H__
#define __CLIP_EVTM_H__
/****************************************************************************
 *	定数、構造体
 ****************************************************************************/
//□(*pData)[1/*Event*/]の値
//│	SHRT_MIN	┐
//│	   〜		├次の命令を基準として、ループ戻り位置の命令へのマイナス距離
//│	   -2		┘
//│	   -1		─終了(ループ無し)
//│	    0		─ダミー(*no-job*)
//│	    1		┐
//│	   〜		├アプリケーション定義の、イベント番号
//│	SHRT_MAX	┘
/*--------------------------------------------------------------------------*/
//イベントタイマチャネル構造体
typedef struct _ST_EvtTmrCh {
	const unsigned short	(*pData)[2/*Wait,Event*/];	//+0,4 データポインタ	NULL=停止中
	unsigned short		Wait;				//+4,2 待ち時間の残数
	//							//+6,2 (パディング)
} ST_EvtTmrCh;							//=8
/*--------------------------------------------------------------------------*/
//イベントタイマ構造体
typedef struct _ST_EvtTmr {
	int			nEvtTmrCh;			//イベントタイマチャネル数
	struct _ST_EvtTmrFunc*	pNext;				//関数チェイン
#ifndef __RENESAS__
	ST_EvtTmrCh		EvtTmrCh[0/*nEvtTmrCh*/];	//イベントタイマチャネル
#else //__RENESAS__
	ST_EvtTmrCh		EvtTmrCh[1/*nEvtTmrCh*/];	//イベントタイマチャネル	//Hewは要素数[0]の配列に対応していないので、要素数[1]として調整しました。
#endif//__RENESAS__
} ST_EvtTmr;
/*--------------------------------------------------------------------------*/
//関数ノード構造体
typedef struct _ST_EvtTmrFunc {
	void	(*onEvent)(int iEvtTmrCh, int iEvent);		//関数			NULL=不可	アプリケーションがEvtTmr_AddFunc()を呼び出す前に設定せよ。
	struct _ST_EvtTmrFunc*	pNext;				//次の関数ノード	NULL=終端	アプリケーションがEvtTmr_AddFunc()を呼び出す時に不定値で構わない。
} ST_EvtTmrFunc;
/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/
ST_EvtTmr* EvtTmr_Init(int nEvtTmrCh);
void EvtTmr_InitStatic(ST_EvtTmr* pEvtTmr, int nEvtTmrCh);
void EvtTmr_AddFunc(ST_EvtTmr* pEvtTmr, ST_EvtTmrFunc* pFunc);
void EvtTmr_Start(ST_EvtTmr* pEvtTmr, int iEvtTmrCh, const unsigned short (*pData)[2/*Wait,Event*/]);
int EvtTmr_Stop(ST_EvtTmr* pEvtTmr, int iEvtTmrCh);
void EvtTmr_StopAll(ST_EvtTmr* pEvtTmr);
int EvtTmr_Stat(ST_EvtTmr* pEvtTmr, int iEvtTmrCh);
void EvtTmr_Exec(ST_EvtTmr* pEvtTmr);
/****************************************************************************
 *	dEvtTmrC.exeが出力したバイナリ形式を扱うためのユーティリティ関数
 ****************************************************************************/
#define USE_EVTTMR_BIN	//ユーティリティ関数が不要ならばこのシンボル定義をコメントアウトしてください。
#ifdef  USE_EVTTMR_BIN
void EvtTmr_StartNo(ST_EvtTmr* pEvtTmr, int iEvtTmrCh, const void* pEvtTmrBin, int iEvtTmrNo);
#endif//USE_EVTTMR_BIN
#endif//__CLIP_EVTM_H__
