/*****************************************************
sample.c : 
  μITRONトレーナcmtoy サンプルプログラム
  Copyright(C) 2002 佐々木芳

タイマタスクの実装


Windowsのシミュレーション環境上で動作するアプリケーションプログラムのコンパイル時には以下のマクロ定義が必要
	_CMTOY
*****************************************************/

#include "hal.h"
#include "hal_uart.h"
#include "itron.h"


/*システム起動時からのカウント値*/
DWORD	TimerCount;

//各セグメントの位置を計算する
//	==0==
//	5	1
//	==6==
//	4	2
//	==3== 7
//					    0     1     2     3     4     5     6     7     8     9
BYTE num_pattern[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x27, 0x7f, 0x6f};
void DisplayDecimal(int num)
{
	WORD stat = num_pattern[(num/10)%10]<<8 | num_pattern[num%10];
	halSetSegLED(stat);
}

void DisplayContext(void)
{
	BOOL ctx = sns_ctx();
	if(ctx)
		CMTRACE("app: handler context.\n");
	else
		CMTRACE("app: task context.\n");
}


/*****************************************************
//ボタン押下検出タスク（Break信号制御）
//・２０ミリ秒ごとに起床
	６０ミリ秒以上同じ状態が続いたら、ボタン状態変化を確定する
	（チャタリングを除去）
*****************************************************/
extern int ch16550;
typedef enum{
	BS_STABLE,
	BS_CHANGE,
}BUTTON_TASK_STATE;
void WatchButtonTask(VP_INT exinf)
{
	ER ercd;
	BOOL preStat, curStat, fixStat;
	BUTTON_TASK_STATE state = BS_STABLE;
	int DetectTime = 3;			//20*3=60msec
	int DetectCount = 0;
	SYSTIM systim = 0;
	/*DisplayContext();*/
	CMTRACE("app: WatchButtonTask started.\n");
	fixStat = preStat = halGetPushButton(0);

	while(1){
		ercd = tslp_tsk(20/*20ミリ秒*/);
		//DisplayContext();
		get_tim(&systim);
		curStat = halGetPushButton(0);
		//CMTRACE("app: WatchButtonTask: %d, ercd = %d\n", curStat, ercd);
		//CMTRACE("app: WatchButtonTask: %d\n", curStat);
		switch(state){
		case BS_STABLE:
			if(preStat != curStat){
				preStat = curStat;
				DetectCount = 0;
				state = BS_CHANGE;
				//CMTRACE("app: WatchButtonTask: 状態→BS_CHANGE(%d)\n", curStat);
			}
			break;
		case BS_CHANGE:
			if(preStat == curStat){
				if(++DetectCount == DetectTime){
					state = BS_STABLE;
					if(fixStat != preStat){
						//新しい状態（UP/DOWN)を確定
						fixStat = preStat;
						if(curStat){
							CMTRACE("app: WatchButtonTask: DOWN @%d\n", systim);
							//Break信号ON
							SET_BREAK16550(ch16550);
						}else{
							CMTRACE("app: WatchButtonTask: UP   @%d\n", systim);
							//Break信号OFF
							CLEAR_BREAK16550(ch16550);
						}
					}
				}
			}else{
				preStat = curStat;
				DetectCount = 0;
			}
			break;
		}
		
	}
}


/*****************************************************
//初期化ルーチン
*****************************************************/
void InitHandler(void)
{
	CMTRACE("app: InitHandler invoked.\n");
	//halInitialize();	カーネルスタート時に実行
	DisplayDecimal(0);
//	CMTRACE("app: Serial MS=%02x\n", halSerialGetSignal(0));
//	halSerialSetMask(0, ENABLE_RECV_READY | ENABLE_SEND_EMPTY | ENABLE_SEND_READY);

}




