#include"Device.h"
#include "gvalue.h"
#include "ProtoInnerCan.h"
#include "Runtime.h"

extern "C"{
	#include "uart_key_drv.h"
	#include "HW_config.h"
}

//Root Device
static const char cAvtive[8]	= {"活动"};
static const char cCarry[8] 	= {"搭载"};
static const char cVoltage[8] 	= {"电压"};
static const char cCurrent[8] 	= {"电流"};
static const char cTempe[8] 	= {"温度"};
static const char cVer[8]		= {"版本"};

static const char cFBV[16]		= {"回码电压"};
static const char cFBC[16]		= {"回码电流"};
	
static const char cFBCZero[8]	= {"静态mA"};
static const char cFBCFull[8]	= {"动态mA"};
static const char cFBVZero[8]	= {"静态V"};
static const char cFBVOL[8]		= {"动态V"};


static const char cK[4] = "K";
static const char cCAN[8] = "CAN";
static const char cRS485[8] = "RS485";
static const char cEth[8] = "Ether";

TDisplayPadSetting TPort::tmpDisplayPadSet[dDISPLAYPAD_MAX_COUNT];

void TRootDevice::PrintProperty(TMyString *Str0, TMyString *Str1, TMyString *Str2)
{
	Str0->Clear();
	Str1->Clear();
	Str2->Clear();
	
	Str0->AddOn6Dg(fData.Common.UserCode);
	Str1->AddOn3Dg(fData.Common.Id);
	Str2->FromStr(StrType[fData.Common.dType]);
}

void TRootDevice::PrintAttribute(TMyString *Str0, TMyString *Str1)
{	
	Str0->FromUInt3Dg(fData.Port.ResistedCount);
	Str1->FromUInt4Dg(fData.Port.Ver);
}

void TRootDevice::PrintDynamicsData(TMyString *Str0, TMyString *Str1, TMyString *Str2, TMyString *Str3, TMyString *Str4, TMyString *Str5, TMyString *Str6, TMyString *Str7)
{
	switch(fData.Common.dType){
		case dgTYPE_PORT:
			Str0->FromUInt4Dg(fData.Port.Voltage);
			Str1->FromUInt4Dg(fData.Port.Current);
			Str2->FromUInt3Dg(fData.Port.OnlineCount);
			Str3->FromUInt3Dg(fData.Port.Tempe);
			break;
		case dgTYPE_HAND_CTL:
			Str0->FromUInt4Dg(fData.HandCtl.Voltage);
			Str1->FromUInt4Dg(fData.HandCtl.Current);
			Str2->FromUInt3Dg(fData.HandCtl.OnlineCount);
			Str3->FromUInt3Dg(fData.HandCtl.Tempe);
			break;
		case dgTYPE_DIRECT_CTL:
			Str0->FromUInt4Dg(fData.DirectCtl.Voltage);
			Str1->FromUInt4Dg(fData.DirectCtl.Current);
			Str2->FromUInt3Dg(fData.DirectCtl.OnlineCount);
			Str3->FromUInt3Dg(fData.DirectCtl.Tempe);
			break;
		case dgTYPE_COMM_CAN:
			Str0->FromUInt4Dg(fData.CommBoard.iLinkSpeed);
			Str0->AddOnStr(cK);
			Str1->FromUInt4Dg(fData.CommBoard.oLinkSpeed);
			Str1->AddOnStr(cK);
			Str2->FromUInt3Dg(fData.CommBoard.LinkCount);

		case dgTYPE_COMM_MULTI:
			if(fData.MultiCommBoard.oLinkType & 0x01)
				Str0->FromStr(cCAN);
			if(fData.MultiCommBoard.oLinkType & 0x02)
				Str3->FromStr(cRS485);
			if(fData.MultiCommBoard.oLinkType & 0x04)
				Str4->FromStr(cEth);
			break;
		case dgTYPE_MOTHER_BOARD:
			Str0->FromUInt4Dg(fData.MotherBoard.Voltage);
			Str1->FromUInt4Dg(fData.MotherBoard.Current);
			Str2->FromUInt3Dg(fData.MotherBoard.OnlineCount);
			Str3->FromUInt3Dg(fData.MotherBoard.Tempe);	
			break;
		default:break;
	}
}

void TRootDevice::PrintPortIDnActiveCount(TMyString *Str0, TMyString *Str1)
{
	Str0->FromUInt3Dg(fData.Common.Id);
	Str1->FromUInt3Dg(fData.Port.OnlineCount);
}

void TRootDevice::PrintActiveCount(TMyString *Str0)
{
	Str0->FromUInt3Dg(fData.Port.OnlineCount);
}

void TRootDevice::PrintCarryCount(TMyString *Str0)
{
	Str0->FromUInt3Dg(fData.Port.ResistedCount);
}


void TRootDevice::PrintAllPrm(TMyString *StrKey[12], TMyString *StrVal[12])
{
	unsigned int i;
	for(i=0;i<12;i++){ StrKey[i]->Clear(); StrVal[i]->Clear(); }

	switch(fData.Common.dType){
		case dgTYPE_PORT:
			StrKey[0]->FromStr(cVoltage);
			StrVal[0]->AddOn4Dg(fData.Port.Voltage);
			StrKey[1]->FromStr(cCurrent);
			StrVal[1]->AddOn4Dg(fData.Port.Current);
			StrKey[2]->FromStr(cAvtive);
			StrVal[2]->AddOn3Dg(fData.Port.OnlineCount);
			StrKey[3]->FromStr(cCarry);
			StrVal[3]->AddOn3Dg(fData.Port.ResistedCount);
			StrKey[4]->FromStr(cTempe);
			StrVal[4]->AddOn3Dg(fData.Port.Tempe);
			StrKey[5]->FromStr(cVer);
			StrVal[5]->AddOn6Dg(fData.Port.Ver);
			break;
		case dgTYPE_HAND_CTL:
			StrKey[0]->FromStr(cVoltage);
			StrVal[0]->AddOn4Dg(fData.HandCtl.Voltage);
			StrKey[1]->FromStr(cCurrent);
			StrVal[1]->AddOn4Dg(fData.HandCtl.Current);
			StrKey[2]->FromStr(cAvtive);
			StrVal[2]->AddOn3Dg(fData.HandCtl.OnlineCount);
			StrKey[3]->FromStr(cCarry);
			StrVal[3]->AddOn3Dg(fData.HandCtl.ResistedCount);
			StrKey[4]->FromStr(cTempe);
			StrVal[4]->AddOn3Dg(fData.HandCtl.Tempe);
			StrKey[5]->FromStr(cVer);
			StrVal[5]->AddOn6Dg(fData.HandCtl.Ver);
			break;
		case dgTYPE_DIRECT_CTL:
			StrKey[0]->FromStr(cVoltage);
			StrVal[0]->AddOn4Dg(fData.DirectCtl.Voltage);
			StrKey[1]->FromStr(cCurrent);
			StrVal[1]->AddOn4Dg(fData.DirectCtl.Current);
			StrKey[2]->FromStr(cAvtive);
			StrVal[2]->AddOn3Dg(fData.DirectCtl.OnlineCount);
			StrKey[3]->FromStr(cCarry);
			StrVal[3]->AddOn3Dg(fData.DirectCtl.ResistedCount);
			StrKey[4]->FromStr(cTempe);
			StrVal[4]->AddOn3Dg(fData.DirectCtl.Tempe);
			StrKey[5]->FromStr(cVer);
			StrVal[5]->AddOn6Dg(fData.DirectCtl.Ver);
			break;
		case dgTYPE_COMM_CAN:

		case dgTYPE_COMM_MULTI:

			break;
		case dgTYPE_MOTHER_BOARD:
			
			break;
		default:break;
	}
}

void TRootDevice::GetDescp(TMyString *StrGot)
{
	
}

void TRootDevice::SetDescp(TMyString *StrPut)
{

}


void TPort::ResetCallBack()
{
	int i;
	for(i=0; i<256; i++){
		StateTable[i] &= dEpStateBitMask;
		LnkRdyGo[i] =0;
		HasSetLightOn[i] = 0;
		DelayTick[i] = 0;
		DelayToDoEventType[i] =0;
	}
	SyncRegisterReqStart =0;
	SyncMaskReqStart =0;
	SyncRegisterOnGo =0;
	SyncRegisterHasReportError =0;
	SyncMaskOnGo =0;
	SyncMaskHasReportError =0;
}

void TPort::InterLinkGoStartDev(unsigned char aCtlNum, unsigned char aP0, unsigned char aP1, unsigned char aType)
{
	InterLink.oBuf.WriteIndex++;
	if(InterLink.oBuf.WriteIndex >= dLinkageOutputBufMaxCOunt)InterLink.oBuf.WriteIndex = 0;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.CtlNum = aCtlNum;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.P0 = aP0;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.P1 = aP1;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.Action = dLNKSTART;
}

void TPort::AddRemoveMsgDelayStart(unsigned int IsAdd, unsigned char aP0, unsigned char aP1, unsigned char aType)
{
	aIm.Splite.Year = DateTime.Date.Split.Year;
	aIm.Splite.Month = DateTime.Date.Split.Month;
	aIm.Splite.Day = DateTime.Date.Split.Day;
	aIm.Splite.Hour = DateTime.Time.Split.Hour;
	aIm.Splite.Minute = DateTime.Time.Split.Minute;
	aIm.Splite.Second = DateTime.Time.Split.Second;
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;	
	
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
	aIm.Splite.P0 = aP0;
	aIm.Splite.P1 = aP1;
	aIm.Splite.P2 = 0;
	aIm.Splite.dType = aType;

	if(IsAdd){
		aIm.Splite.UserCode =0;
		aIm.Splite.AreaNum =0;
		if( aP0 && aP1 ){
			if(aP0 <= dPORT_MAX_COUNT){
				aP0--; 
				if(aP1 <= dEP_MAX_COUNT_PER_PORT){
					aP1--;
					aIm.Splite.UserCode = Port[aP0].UcList[aP1].Full;
					aIm.Splite.AreaNum = Port[aP0].Area[aP1];
				}
			}
		}
		
		aIm.Splite.mType = etLinkageStart;
		aIm.Splite.iByte0 = 0x0A;
		aIm.Splite.Data1 = 0;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStart(aIm);
			ExRecord.SetStateCodeStart();
			FecBusCRT.SetStateCodeStart();
			ProtoC2C.SlaveDoSend2MasterDelayStart(aIm, cmAutoStart);
		}
	}else{
		aIm.Splite.mType = etLinkageStartCancel;
		aIm.Splite.iByte0 = 0x0A;
		aIm.Splite.Data1 = 0;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStartCancel(aIm);
			ExRecord.SetStateCodeStart();
			FecBusCRT.SetStateCodeStart();
			ProtoC2C.SlaveDoSend2MasterDelayStart(aIm, cmAutoStop);
		}
	}
}

void TPort::AddRemoveMsgDelayStartSimulate(unsigned int IsAdd, unsigned char aP0, unsigned char aP1, unsigned char aType)
{
	aIm.Splite.Year = DateTime.Date.Split.Year;
	aIm.Splite.Month = DateTime.Date.Split.Month;
	aIm.Splite.Day = DateTime.Date.Split.Day;
	aIm.Splite.Hour = DateTime.Time.Split.Hour;
	aIm.Splite.Minute = DateTime.Time.Split.Minute;
	aIm.Splite.Second = DateTime.Time.Split.Second;
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;	
	
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
	aIm.Splite.P0 = aP0;
	aIm.Splite.P1 = aP1;
	aIm.Splite.P2 = 0;
	aIm.Splite.dType = aType;

	if(IsAdd){
		aIm.Splite.UserCode =0;
		aIm.Splite.AreaNum =0;
		if( aP0 && aP1 ){
			if(aP0 <= dPORT_MAX_COUNT){
				aP0--; 
				if(aP1 <= dEP_MAX_COUNT_PER_PORT){
					aP1--;
					aIm.Splite.UserCode = Port[aP0].UcList[aP1].Full;
					aIm.Splite.AreaNum = Port[aP0].Area[aP1];
				}
			}
		}
		
		aIm.Splite.mType = etLinkageStart;
		aIm.Splite.iByte0 = 0x0A;
		aIm.Splite.Data1 = TControlCenter::StartTypeSimulate;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStartSimulate(aIm);
			ProtoC2C.SlaveDoSend2MasterDelayStartSimulate(aIm, cmVIrtualStart);
		}
	}else{
		aIm.Splite.mType = etLinkageStartCancel;
		aIm.Splite.iByte0 = 0x0A;
		aIm.Splite.Data1 = TControlCenter::StartTypeSimulate;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStartCancelSimulate(aIm);
			ProtoC2C.SlaveDoSend2MasterDelayStartSimulate(aIm, smVIrtualStop);
		}
	}
}

void TPort::SortDisplayPad()
{
	int i, PadInx, Found;
	unsigned char tAddr;
	for(i=0; i<dDISPLAYPAD_MAX_COUNT; i++){
		for(int Gg=0; Gg<16; Gg++){
			tmpDisplayPadSet[i].MemBytes[Gg] = DisplayPadSet[i].MemBytes[Gg];
			DisplayPadSet[i].MemBytes[Gg] =0;;
		}
	}
	
	PadInx =0;
	for(i=0; i<dEP_MAX_COUNT_PER_PORT; i++){
		if( (ExistTable[i] == 0xA5) && (dTypeTable[i] == dgTYPE_DISPLAY_PAD) ) {
			tAddr =i+1;
			for(int x=0; x<dDISPLAYPAD_MAX_COUNT; x++){
				if(tmpDisplayPadSet[x].Addr == tAddr){
					for(int Gg=0; Gg<16; Gg++)DisplayPadSet[PadInx].MemBytes[Gg] = tmpDisplayPadSet[x].MemBytes[Gg];
					break;
				}
			}
			DisplayPadSet[PadInx].Addr = tAddr;
			PadInx++;
			if(PadInx >= 16)break;
		}
	}
}

void TPort::SetOneDisplayPadSetting(unsigned char *pByte)
{
	int Found =0;
	if(pByte[0] <1)return;	
	for(int x=0; x<dDISPLAYPAD_MAX_COUNT; x++){
		if(DisplayPadSet[x].Addr == pByte[0]){
			for(int Gg=0; Gg<16; Gg++)DisplayPadSet[x].MemBytes[Gg] = pByte[Gg];
			Found =1;
			break;
		}
	}
	if(Found == 0){
		for(int x=0; x<dDISPLAYPAD_MAX_COUNT; x++){
			if(DisplayPadSet[x].Addr == 0){
				for(int Gg=0; Gg<16; Gg++)DisplayPadSet[x].MemBytes[Gg] = pByte[Gg];
				break;
			}
		}	
	}
}

void TPort::sRpyRegDataSyncReqStart(class TPort *pPort)
{
	unsigned char Data[8];
	if (pPort == nullptr)return;
	Data[0] = 0;
	Data[1] = pPort->Num;
	Data[2] = 2;	//Ack 2 
	Data[3] = 0;
	Data[4] = 0;
	Data[5] = 0;
	Data[6] = 0;
	Data[7] = 0;
	InnerCan.OBufInsert(2, cmBusDataSyncRegisterReq, Data, 3);
}

void TPort::sRpyMaskDataSyncReqStart(class TPort *pPort)
{
	unsigned char Data[8];
	
	if (pPort == nullptr)return;
	Data[0] = 0;
	Data[1] = pPort->Num;
	Data[2] = 2;	//Ack 2 
	Data[3] = 0;
	Data[4] = 0;
	Data[5] = 0;
	Data[6] = 0;
	Data[7] = 0;
	InnerCan.OBufInsert(2, cmBusDataSyncIsolationReq, Data, 3);
}

void TPort::sSendRegDataSync(class TPort *pPort)
{
	unsigned char Data[8];
	unsigned char tP0;
	if(pPort == nullptr)return;
	pPort->SyncRegisterOnGo = 1;
	pPort->SyncRegisterTick = 0;
	pPort->SyncRegisterResult = 0;
	
	Data[0] = 0;
	Data[1] = pPort->Num;
	
	for(int i=0; i<50; i++){
		Data[2] = i+1;
		tP0 = i*5;
		int dInx=3;
		for(int x=0; x<5; x++){
			if(pPort->ExistTable[tP0] == 0xA5){
				Data[dInx] = pPort->dTypeTable[tP0];
			}else{
				Data[dInx] = 0;
			}				
			dInx++;
			tP0++;
		}
		InnerCan.OBufInsert(2, cmBusDataSyncRegister, Data, 8);
	}
}

void TPort::sSnedMaskDataSync(class TPort *pPort)
{
	unsigned char Data[8];
	unsigned char tP0;
	pPort->SyncMaskOnGo = 1;
	pPort->SyncMaskTick = 0;
	pPort->SyncMaskResult = 0;
	
	Data[0] = 0;
	Data[1] = pPort->Num;
	
	for(int i=0; i<50; i++){
		Data[2] = i+1;
		tP0 = i*5;
		int dInx=3;
		for(int x=0; x<5; x++){
			if(pPort->StateTable[tP0] & dEpStateBitMask){
				Data[dInx] = 1;
			}else{
				Data[dInx] = 0;
			}
			dInx++;
			tP0++;
		}
		InnerCan.OBufInsert(2, cmBusDataSyncIsolation, Data, 8);
	}
}

void TPort::SyncTaskIntv1000Ms()
{
	//CtlCenter.ieAddBrdFaultCancel(i+1, 10);
	//CtlCenter.ieAddBrdFault(i+1, 10);
	if(SyncRegisterOnGo){
		if(SyncRegisterResult){
			if(SyncRegisterResult == 1){
				//Sync Ok
				if(SyncRegisterHasReportError){
					//Cancel Fault Msg
					CtlCenter.ieAddBrdFaultCancel(Num, TBoardFaultType::RegisteredData);
					SyncRegisterHasReportError =0;
				}
			}else
			if(SyncRegisterResult == 2){
				//Sync Bad Data
				if(SyncRegisterHasReportError == 0){
					//Add Fault Msg
					CtlCenter.ieAddBrdFault(Num, TBoardFaultType::RegisteredData);
					SyncRegisterHasReportError =1;
				}
			}
			SyncRegisterOnGo = 0;
		}else{
			if(SyncRegisterTick > 180){
				//Sync Time out
				if(SyncRegisterHasReportError == 0){
					//Add Fault Msg
					CtlCenter.ieAddBrdFault(Num, TBoardFaultType::RegisteredData);
					SyncRegisterHasReportError =1;
				}
				SyncRegisterOnGo =0;
			}
		}
		if(SyncRegisterTick <200){
			SyncRegisterTick++;
		}
	}
	if(SyncMaskOnGo){
		if(SyncMaskResult){
			if(SyncMaskResult == 1){
				//Sync Ok
				if(SyncMaskHasReportError){
					//Cancel Fault Msg
					CtlCenter.ieAddBrdFaultCancel(Num, TBoardFaultType::MaskedData);
					SyncMaskHasReportError =0;
				}
			}else
			if(SyncMaskResult == 2){
				//Sync Bad Data
				if(SyncMaskHasReportError == 0){
					//Add Fault Msg
					CtlCenter.ieAddBrdFault(Num, TBoardFaultType::MaskedData);
					SyncMaskHasReportError =1;
				}
			}
			SyncMaskOnGo = 0;
		}else{
			if(SyncMaskTick > 180){
				//Sync Time out
				if(SyncMaskHasReportError == 0){
					//Add Fault Msg
					CtlCenter.ieAddBrdFault(Num, TBoardFaultType::MaskedData);
					SyncMaskHasReportError =1;
				}
				SyncMaskOnGo =0;
			}
		}
		if(SyncMaskTick <200){
			SyncMaskTick++;
		}
	}
}

void TPort::sRecallCrcFaultMsg(unsigned char aPort)
{
	int x, m;
	if(Port[aPort].CrcFlag.DevType){
		CtlCenter.ieAddBrdFault(aPort+1, TBoardFaultType::StorageEpDType);
	}	
	if(Port[aPort].CrcFlag.CrcDisplayPad){
		CtlCenter.ieAddBrdFault(aPort+1,TBoardFaultType::StoragePortDpSet);
	}
	if(Port[aPort].CrcFlag.AuxId){
		CtlCenter.ieAddBrdFault(aPort+1, TBoardFaultType::StorageEpAuxId);
	}
	if(Port[aPort].CrcFlag.AssignedType){
		CtlCenter.ieAddBrdFault(aPort+1, TBoardFaultType::StorageEpAssignedType);
	}
	if(Port[aPort].CrcFlag.SignalType){
		CtlCenter.ieAddBrdFault(aPort+1, TBoardFaultType::StorageEpSignalType);
	}
	if(Port[aPort].CrcFlag.Area){
		CtlCenter.ieAddBrdFault(aPort+1,TBoardFaultType::StorageEpArea);
	}
}

void THandCtlBoard::SetOutputStateViaUserCode(unsigned char aPadNum, unsigned char aKeyNum, unsigned char aDType, unsigned char aCtlNum, unsigned int aDoStop)
{
	unsigned int i, x;
	volatile unsigned int tAddr;
	TUserCodeStr tCode;
	TUserCodeStr cCode;
	
	if( (aDType == 0) || (aDType == 255) )return;
	
	tCode.Full = HandCtlBoard[aPadNum].UcList[aKeyNum].Full;
	if(tCode.Spl.BcdText_0 == 10)tCode.Spl.BcdText_0 = 0xF; 
	if(tCode.Spl.BcdText_1 == 10)tCode.Spl.BcdText_1 = 0xF;
	if(tCode.Spl.BcdText_2 == 10)tCode.Spl.BcdText_2 = 0xF; 
	if(tCode.Spl.BcdText_3 == 10)tCode.Spl.BcdText_3 = 0xF;
	if(tCode.Spl.BcdText_4 == 10)tCode.Spl.BcdText_4 = 0xF; 
	if(tCode.Spl.BcdText_6 == 10)tCode.Spl.BcdText_6 = 0xF; 
	if(tCode.Spl.BcdText_7 == 10)tCode.Spl.BcdText_7 = 0xF; 

	for(i=0; i<dPORT_MAX_COUNT; i++){
		if(MainCtl.fData.Split.ExistTablePort[i]){
			for(x=0; x<250; x++){
				if(Port[i].ExistTable[x]){ 
					if( (Port[i].dTypeTable[x] == aDType) || (Port[i].AssignType[x] == aDType) ){
						tAddr = dAddrSdRam_4UserCodeMatch + (i * 1024) + (x * 4);
						cCode.Full = *(volatile unsigned int *)(tAddr);
						cCode.Full |= HandCtlBoard[aPadNum].UcListNotAnd[aKeyNum].Full;
						if(cCode.Full == tCode.Full){
							if(	(Port[i].dTypeTable[x] == dgTYPE_INOUT_MODULE_NonSource) 	|| 
								(Port[i].dTypeTable[x] == dgTYPE_INOUT_MODULE_Source)    	||
								(Port[i].dTypeTable[x] == dgTYPE_OUT_MODULE)			||
								(Port[i].dTypeTable[x] == dgType_VAALRAM) )	{
									if( (Port[i].StateTable[x] & dEpStateBitMask) == 0){
										tData[0] = 0;
										tData[1] = aCtlNum;
										tData[2] = i +1;
										tData[3] = x +1;
										tData[4] = 0;
										tData[5] = Port[i].dTypeTable[x];
										tData[6] = 1;
										if(aDoStop == 0){
											InnerCan.OBufInsert(1, cmAutoStart, tData, 8);
										}else{
											InnerCan.OBufInsert(1, cmAutoStop, tData, 8);
										}
									}
							}
						}
					}
				}
			}
		}
	}
}

void THandCtlBoard::SetOutputStateViaAreaNum(unsigned char aPadNum, unsigned char aKeyNum, unsigned char aDType, unsigned char aCtlNum, unsigned int aDoStop)
{
	unsigned int i, x;
	volatile unsigned int tAddr;
	unsigned short tArea;
	unsigned short cArea;
	
	if( (aDType == 0) || (aDType == 255) )return;
	
	tArea = HandCtlBoard[aPadNum].Area[aKeyNum];

	for(i=0; i<dPORT_MAX_COUNT; i++){
		if(MainCtl.fData.Split.ExistTablePort[i]){
			for(x=0; x<250; x++){
				if(Port[i].ExistTable[x]){ 
					if( (Port[i].dTypeTable[x] == aDType) || (Port[i].AssignType[x] == aDType) ){
						cArea = Port[i].Area[x];
						if( (tArea == cArea) && (tArea) ){
							if(	(Port[i].dTypeTable[x] == dgTYPE_INOUT_MODULE_NonSource) 	|| 
								(Port[i].dTypeTable[x] == dgTYPE_INOUT_MODULE_Source)    	||
								(Port[i].dTypeTable[x] == dgTYPE_OUT_MODULE)			||
								(Port[i].dTypeTable[x] == dgType_VAALRAM) )	{
									if( (Port[i].StateTable[x] & dEpStateBitMask) == 0){
										tData[0] = 0;
										tData[1] = aCtlNum;
										tData[2] = i +1;
										tData[3] = x +1;
										tData[4] = 0;
										tData[5] = Port[i].dTypeTable[x];
										tData[6] = 1;
										if(aDoStop == 0){
											InnerCan.OBufInsert(1, cmAutoStart, tData, 8);
										}else{
											InnerCan.OBufInsert(1, cmAutoStop, tData, 8);
										}
									}
							}
						}
					}
				}
			}
		}
	}
}


void THandCtlBoard::KeyAction(unsigned char aCtlNum, unsigned char aPadInx, unsigned char aKeyInx)
{
	unsigned char aP0, aP1s, aP1e, aCmd;
	volatile unsigned int m;
	if(aPadInx >= dHANDCTL_MAX_COUNT)return;
	if(aKeyInx >= KeyCount)return;
	if(aKeyInx >= dHANDCTL_KEY_MAX_COUNT)return;
	
	if(KeyHasConfig[aKeyInx]){
		
			if(KeyState[aKeyInx] == 0){
				aCmd = cmAutoStart;
				Record.OperateAdd_BusPadOn(MainCtl.fData.Split.MyNum, aPadInx +1, aKeyInx+1);
				if(IsMatchAreaAssign[aKeyInx]){
					SetOutputStateViaAreaNum(aPadInx, aKeyInx, HandCtlBoard[aPadInx].AssignType[aKeyInx], aCtlNum, 0);
				}else{
					SetOutputStateViaUserCode(aPadInx, aKeyInx, HandCtlBoard[aPadInx].AssignType[aKeyInx], aCtlNum, 0);
				}
			}else{
				aCmd = cmAutoStop;
				Record.OperateAdd_BusPadOff(MainCtl.fData.Split.MyNum, aPadInx +1, aKeyInx+1);
				if(IsMatchAreaAssign[aKeyInx]){
					SetOutputStateViaAreaNum(aPadInx, aKeyInx, HandCtlBoard[aPadInx].AssignType[aKeyInx], aCtlNum, 1);
				}else{
					SetOutputStateViaUserCode(aPadInx, aKeyInx, HandCtlBoard[aPadInx].AssignType[aKeyInx], aCtlNum, 1);
				}
			}
	}
}

void THandCtlBoard::KeyPress(unsigned char aCtlNum, unsigned char aPadNum, unsigned char aKeyNum)
{
	unsigned char aPn,aKn;
	
	if(aPadNum == 0)return;
	if(aPadNum > dHANDCTL_MAX_COUNT)return;
	if(aKeyNum == 0)return;
	if(aKeyNum > KeyCount)return;
	if(aKeyNum > dHANDCTL_KEY_MAX_COUNT)return;
	
	aPn = aPadNum;
	aKn = aKeyNum;
	aPn--;
	aKn--;

	KeyAction(aCtlNum, aPn, aKn);
}

void THandCtlBoard::CheckKeyState(unsigned char aCtlNum, unsigned char aPadNum)
{
	unsigned int i,m,z,x;
	unsigned int FbTimes, NoFbTimes;
	unsigned char NewFbState;
	unsigned int NewStartTimes, NewStopTimes;
	unsigned char NewStartState;
	unsigned char NewLnkRdyState;
	volatile unsigned int tAddr;
	
	unsigned short tArea, cArea;
	
	TUserCodeStr tCode;
	TUserCodeStr cCode;
	
	
	int NeedToUpdata;
	
	if(aPadNum >= dHANDCTL_MAX_COUNT)return;
	
	if(KeyCount >dHANDCTL_KEY_MAX_COUNT)KeyCount = dHANDCTL_KEY_MAX_COUNT;
	for(i=0; i<KeyCount; i++){
		if(KeyHasConfig[i] && this->AssignType[i] && (this->AssignType[i] != 255) ){
			FbTimes = 0;
			NoFbTimes = 0;
			NewLnkRdyState = 0;
			NewStartTimes = 0;
			NewStopTimes = 0;
			
			if(IsMatchAreaAssign[i]){
				tArea = this->Area[i];
				for(z=0; z<dPORT_MAX_COUNT; z++){
					if(MainCtl.fData.Split.ExistTablePort[z]){
						for(x=0; x<256; x++){
							if(Port[z].ExistTable[x]) {
								if( (Port[z].dTypeTable[x] ==  this->AssignType[i]) || (Port[z].AssignType[x] == this->AssignType[i])){
									cArea = Port[z].Area[x];
									if( tArea && (tArea  == cArea) ){
										if( (Port[z].StateTable[x] & dEpStateBitMask) == 0){
											if(Port[z].LnkRdyGo[x]){
												NewLnkRdyState = 1;
											}
											if(Port[z].StateTable[x] & dEpStateBitStart){
												NewStartTimes ++;
											}else{
												NewStopTimes ++;
											}
										}
										if( (Port[z].StateTable[x] & dEpStateBitMask) == 0){
											if(Port[z].StateTable[x] & dEpStateBitFeedBack){
												FbTimes++;
											}else{
												NoFbTimes++;
											}
										}
									}
								}
							}
						}
					}
				}
			}else{
				tCode.Full = HandCtlBoard[aPadNum].UcList[i].Full;
				if(tCode.Spl.BcdText_0 == 10)tCode.Spl.BcdText_0 = 0xF; 
				if(tCode.Spl.BcdText_1 == 10)tCode.Spl.BcdText_1 = 0xF;
				if(tCode.Spl.BcdText_2 == 10)tCode.Spl.BcdText_2 = 0xF; 
				if(tCode.Spl.BcdText_3 == 10)tCode.Spl.BcdText_3 = 0xF;
				if(tCode.Spl.BcdText_4 == 10)tCode.Spl.BcdText_4 = 0xF;
				if(tCode.Spl.BcdText_5 == 10)tCode.Spl.BcdText_5 = 0xF; 
				if(tCode.Spl.BcdText_6 == 10)tCode.Spl.BcdText_6 = 0xF; 
				if(tCode.Spl.BcdText_7 == 10)tCode.Spl.BcdText_7 = 0xF; 

				for(z=0; z<dPORT_MAX_COUNT; z++){
					if(MainCtl.fData.Split.ExistTablePort[z]){
						for(x=0; x<256; x++){
							if(Port[z].ExistTable[x]) {
								if( (Port[z].dTypeTable[x] ==  this->AssignType[i]) || (Port[z].AssignType[x] == this->AssignType[i])){
									tAddr = dAddrSdRam_4UserCodeMatch + (z * 1024) + (x * 4);
									cCode.Full = *(volatile unsigned int *)(tAddr);
									cCode.Full |= HandCtlBoard[aPadNum].UcListNotAnd[i].Full;
									if(cCode.Full == tCode.Full){
										if( (Port[z].StateTable[x] & dEpStateBitMask) == 0){
											if(Port[z].LnkRdyGo[x]){
												NewLnkRdyState = 1;
											}
											if(Port[z].StateTable[x] & dEpStateBitStart){
												NewStartTimes ++;
											}else{
												NewStopTimes ++;
											}
										}
										if( (Port[z].StateTable[x] & dEpStateBitMask) == 0){
											if(Port[z].StateTable[x] & dEpStateBitFeedBack){
												FbTimes++;
											}else{
												NoFbTimes++;
											}
										}
									}
								}
							}
						}
					}
				}
			}
			
			NeedToUpdata = 0;
			//Check Start Modify
			if(NewStartTimes) NewStartState =2; else NewStartState =0;
			if(NewStartTimes && NewStopTimes)NewStartState = 1;
			if(KeyState[i] != NewStartState){
				NeedToUpdata = 1;
				KeyState[i] = NewStartState;
			}
			//Check FeedBack Modify
			if(1){
				if(FbTimes) NewFbState =2; else NewFbState =0;
				if(FbTimes && NoFbTimes)NewFbState = 1;
				
				if(KeyFbState[i] != NewFbState){
					NeedToUpdata = 1;
					KeyFbState[i] = NewFbState;
				}
			}else{
				KeyFbState[i] = 3;
			}
			//Check Linkage Rdy Modify
			if(LnkRdyGo[i] != NewLnkRdyState){
				NeedToUpdata = 1;
				LnkRdyGo[i] = NewLnkRdyState;
			}
			//Check Modify To Send
			if(NeedToUpdata){
				tData[0] = 0;
				tData[1] = aCtlNum;
				tData[2] = aPadNum + dADDR_HANDPAD_START;
				tData[3] = i +1;
				tData[4] = KeyState[i];
				tData[5] = KeyFbState[i];
				tData[6] = LnkRdyGo[i];
				InnerCan.OBufInsert(1, cmBusCtlPadState, tData, 7);
			}
		}
	}
}

void THandCtlBoard::SendPadCfg2Pad(unsigned char aPadNum)
{
	int i,x,p, Pst, Piece;
	unsigned char Val;
	
	tData[1] = aPadNum + dADDR_HANDPAD_START;
	
	if(KeyCount == 48)Piece = 1;
	else if(KeyCount == 64)Piece = 2;
	else if(KeyCount == 128)Piece = 3;
	else Piece = 0;
	
	for(p=0; p<Piece; p++){
		Pst = 2;
		if(p<2){
			for(i=0; i<6; i++){
				Val = 0;
				for(x=0; x<8; x++){
					if(KeyHasConfig[(p*48) + (i*8) +x]){
						Val |= 1<<x;
					}
				}
				tData[Pst] = Val;
				Pst++;
			}
		}else{
			for(i=0; i<4; i++){
				Val = 0;
				for(x=0; x<8; x++){
					if(KeyHasConfig[(p*48) + (i*8) +x]){
						Val |= 1<<x;
					}
				}
				tData[Pst] = Val;
				Pst++;
			}
		}
		tData[0] = 0;
		if(PadIsProhibit == 0)tData[0] |= 0x01;
		if(KeyCount == 48)tData[0] |= 0x02;
		else if(KeyCount == 64)tData[0] |= 0x04;
		else if(KeyCount == 128)tData[0] |= 0x06;
		
		tData[0] |= p<<4;
		
		InnerCan.OBufInsert(1, cmBusCtlPadConfig, tData, 8);
	}
}

void THandCtlBoard::ResetCallBack()
{
	int i;
	if(PadIsProhibit == 0){
		for(i=0; i<dHANDCTL_KEY_MAX_COUNT; i++){
			KeyState[i] 	=0;
			KeyFbState[i] 	=0;
			LnkRdyGo[i] 	=0;
		}
	}
}

void THandCtlBoard::sRecallCrcFaultMsg(unsigned char aPad)
{
	if(HandCtlBoard[aPad].CrcFlag){
		CtlCenter.ieAddBrdFault(aPad+1,TBoardFaultType::StorageBusPadCfg);
	}	
}

void TDirectCtlBoard::dUploadAllowState(unsigned char aCtlNum, unsigned char aP0, unsigned char aSta)
{
	int i;
	ManualAllow = aSta;
	/*if(ManualAllow)
		Record.OperateAdd_DirectPadManualAllowOn(MainCtl.fData.Split.MyNum, aP0+1);
	else
		Record.OperateAdd_DirectPadManualAllowOff(MainCtl.fData.Split.MyNum, aP0+1);*/

}

void TDirectCtlBoard::aImAddDateTime()
{
	aIm.Splite.Year = DateTime.Date.Split.Year;
	aIm.Splite.Month = DateTime.Date.Split.Month;
	aIm.Splite.Day = DateTime.Date.Split.Day;
	aIm.Splite.Hour = DateTime.Time.Split.Hour;
	aIm.Splite.Minute = DateTime.Time.Split.Minute;
	aIm.Splite.Second = DateTime.Time.Split.Second;
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;	
}

void TDirectCtlBoard::dUploadNodeState(unsigned char aCtlNum, unsigned char aP0, unsigned char aNodeNum, unsigned char aSta)
{
	int i;
	unsigned char NewOutputStaate, NewFbState, NewFaultState, aNode;
	
	aNode = aNodeNum;
	aNode--;
	if(aNode >= dDIRECTCTL_KEY_MAX_COUNT)return;
	//if(IsRegisted[aNode] == 0)return;
	
	//Add Record Here
	if(aSta & 0x01){
		NewOutputStaate = 1;
	}else{
		NewOutputStaate = 0;
	}
	
	if(aSta & 0x02){
		NewFbState = 1;
	}else{
		NewFbState = 0;
	}
	
	if(aSta & 0x04){
		NewFaultState = 1;
	}else{
		NewFaultState = 0;
	}
	
	if(OutputState[aNode] != NewOutputStaate){
		OutputState[aNode] = NewOutputStaate;
		if(OutputState[aNode]){
			aImAddDateTime();
			aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
			aIm.Splite.P0 = aP0 + dADDR_DIRECTPAD_START;
			aIm.Splite.P1 = aNode +1;
			aIm.Splite.P2 = 0;

			aIm.Splite.mType = etLinkageStart;
			aIm.Splite.dType = 0;
			
			GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
			
			if(aSta & 0x08){
				aIm.Splite.iByte0 = 0x05;
			}else{
				aIm.Splite.iByte0 = 0x01;
			}
			aIm.Splite.Data1 = 0;
			if(CtlCenter.IsMsgReseting == 0){
				CtlCenter.iePushOneMsgLinkageStart(aIm);
				ExRecord.SetStateCodeStart();
				FecBusCRT.SetStateCodeStart();
				Record.LinkageAdd(aIm);
			}
		}else{
			aImAddDateTime();
			aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
			aIm.Splite.P0 = aP0 + dADDR_DIRECTPAD_START;
			aIm.Splite.P1 = aNode +1;
			aIm.Splite.P2 = 0;
			aIm.Splite.dType = 0;
			aIm.Splite.Data1 = 0;
			
			GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
			
			if(CtlCenter.IsMsgReseting == 0){
				aIm.Splite.mType = etLinkageStart;
				aIm.Splite.iByte0 = 0x09;
				CtlCenter.iePushOneMsgLinkageStart(aIm);
			
				aIm.Splite.mType = etLinkageStartCancel;
				if(aSta & 0x08){
					aIm.Splite.iByte0 = 0xB5;
				}else{
					aIm.Splite.iByte0 = 0xB1;
				}
				ExRecord.SetStateCodeStart();
				FecBusCRT.SetStateCodeStart();
				Record.LinkageAdd(aIm);
			}
		}
		if( (CtlCenter.IsMsgReseting == 0) && (MainCtl.fData.Split.NetworkMode == 2) ){	
			tData.D8[0] = 0;
			tData.D8[1] = aIm.Splite.PCtlNum;
			tData.D8[2] = aIm.Splite.P0;
			tData.D8[3] = aIm.Splite.P1;
			tData.D8[4] = 0;
			tData.D8[5] = 0;
			tData.D8[6] = aSta;
			tData.D8[7] = 0;
			if(OutputState[aNode])
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmAutoStart, TProtoC2C::mtLink);
			else
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmAutoStop, TProtoC2C::mtLink);
		}			
	}
	if(FeedbackState[aNode] != NewFbState){
		FeedbackState[aNode] = NewFbState;
		if(FeedbackState[aNode]){
			aImAddDateTime();
			aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
			aIm.Splite.P0 = aP0 +dADDR_DIRECTPAD_START;
			aIm.Splite.P1 = aNode +1;
			aIm.Splite.P2 = 0;

			aIm.Splite.mType = etLinkageFeedBack;
			aIm.Splite.dType = 0;
			aIm.Splite.iByte0 = 0x03;
			aIm.Splite.Data1 = 0;
			GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
			if(CtlCenter.IsMsgReseting == 0){
				CtlCenter.iePushOneMsgLinkageFb(aIm);
				ExRecord.SetStateCodeFeedBack();
				FecBusCRT.SetStateCodeFeedBack();
				Record.LinkageAdd(aIm);
			}
		}else{
			aImAddDateTime();
			aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
			aIm.Splite.P0 = aP0 +dADDR_DIRECTPAD_START;
			aIm.Splite.P1 = aNode +1;
			aIm.Splite.P2 = 0;

			aIm.Splite.mType = etLinkageFeedBack;
			aIm.Splite.dType = 0;
			aIm.Splite.iByte0 = 0xB3;
			aIm.Splite.Data1 = 0;
			GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
			if(CtlCenter.IsMsgReseting == 0){
				CtlCenter.iePushOneMsgLinkageFbCancel(aIm);
				ExRecord.SetStateCodeFeedBack();
				FecBusCRT.SetStateCodeFeedBack();
				Record.LinkageAdd(aIm);
			}
		}
		if( (CtlCenter.IsMsgReseting == 0) && (MainCtl.fData.Split.NetworkMode == 2) ){
			tData.D8[0] = 0;
			tData.D8[1] = aIm.Splite.PCtlNum;
			tData.D8[2] = aIm.Splite.P0;
			tData.D8[3] = aIm.Splite.P1;
			tData.D8[4] = 0;
			tData.D8[5] = 0;
			tData.D8[6] = 0;
			tData.D8[7] = 0;
			if(FeedbackState[aNode])
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmAck, TProtoC2C::mtLink);
			else
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmAckStop, TProtoC2C::mtLink);
		}
	}
	if(FaultState[aNode] != NewFaultState){
		FaultState[aNode] = NewFaultState;
		if(FaultState[aNode]){
			aImAddDateTime();
			aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
			aIm.Splite.P0 = aP0 +dADDR_DIRECTPAD_START;
			aIm.Splite.P1 = aNode +1;
			aIm.Splite.P2 = 5;

			aIm.Splite.mType = etFault;
			aIm.Splite.dType = 0;
			aIm.Splite.iByte0 = 0x01;
			aIm.Splite.Data0 = 5;
			aIm.Splite.Data1 = 0x1;
			GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
			if(CtlCenter.IsMsgReseting == 0){
				CtlCenter.iePushOneMsgFault(aIm);
				Record.FaultAdd(aIm);
			}
		}else{
			aImAddDateTime();
			aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
			aIm.Splite.P0 = aP0 +dADDR_DIRECTPAD_START;
			aIm.Splite.P1 = aNode +1;
			aIm.Splite.P2 = 5;

			aIm.Splite.mType = etFault;
			aIm.Splite.dType = 0;
			aIm.Splite.iByte0 = 0x01;
			aIm.Splite.Data0 = 5;
			aIm.Splite.Data1 = 0x0;
			GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
			if(CtlCenter.IsMsgReseting == 0){
				CtlCenter.iePushOneMsgFaultCancel(aIm);
				Record.FaultAdd(aIm);
			}
		}
		if( (CtlCenter.IsMsgReseting == 0) && (MainCtl.fData.Split.NetworkMode == 2) ){
			tData.D8[0] = 0;
			tData.D8[1] = aIm.Splite.PCtlNum;
			tData.D8[2] = aIm.Splite.P0;
			tData.D8[3] = aIm.Splite.P1;
			tData.D8[4] = 5;
			tData.D8[5] = 0;
			tData.D8[6] = 5;
			tData.D8[7] = aIm.Splite.Data1;
			if(FaultState[aNode])
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmPortModuleErr, TProtoC2C::mtFault);
			else
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmPortModuleErrRecover, TProtoC2C::mtFault);
		}
	}
}

void TDirectCtlBoard::AddStartStopSimulate(unsigned int IsStart, unsigned char aP0, unsigned char aNode)
{
	if(aP0 >= dDIRECTCTL_MAX_COUNT)return;
	if(aNode == 0)return;
	if(aNode > dDIRECTCTL_KEY_MAX_COUNT)return;
	if(IsStart){
		aImAddDateTime();
		aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
		aIm.Splite.P0 = aP0 + dADDR_DIRECTPAD_START;
		aIm.Splite.P1 = aNode;
		aIm.Splite.P2 = 0;

		aIm.Splite.mType = etLinkageStart;
		aIm.Splite.dType = 0;
		
		GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
		
		aIm.Splite.iByte0 = 0x01;
		aIm.Splite.Data1 = TControlCenter::StartTypeSimulate;
		if(CtlCenter.IsMsgReseting == 0){
			if(CtlCenter.iePushOneMsgLinkageStartSimulate(aIm)){
				Record.LinkageAdd(aIm);
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmVIrtualStart, TProtoC2C::mtLink);
			}
		}
	}else{
		aImAddDateTime();
		aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
		aIm.Splite.P0 = aP0 + dADDR_DIRECTPAD_START;
		aIm.Splite.P1 = aNode;
		aIm.Splite.P2 = 0;

		aIm.Splite.mType = etLinkageStart;
		aIm.Splite.dType = 0;
		
		GetUserCodeAreaNumDevType(aIm.Splite.P0, aIm.Splite.P1, &aIm.Splite.UserCode, &aIm.Splite.AreaNum, &aIm.Splite.dType);
		
		aIm.Splite.iByte0 = 0x09;
		aIm.Splite.Data1 = TControlCenter::StartTypeSimulate;
		if(CtlCenter.IsMsgReseting == 0){
			if(CtlCenter.iePushOneMsgLinkageStartSimulate(aIm)){
				Record.LinkageAdd(aIm);
				ProtoC2C.SlaveDoSend2MasterMachine(aIm, cmVIrtualStart, TProtoC2C::mtLink);
			}
		}
	}
}

void TDirectCtlBoard::SendPadCfg2Pad(unsigned char aPadNum)
{
	int i,xst;
	if(18){
		tData.D8[0] = 0xF0;
		if(PadIsProhibit == 0)tData.D8[0] |= 0x01;
		if(AllowManual)tData.D8[0] |= 0x02;
		tData.D8[1] = aPadNum + dADDR_DIRECTPAD_START;
		tData.D8[2] =0; tData.D8[3] =0; tData.D8[4] =0; tData.D8[5] =0; tData.D8[6] =0; tData.D8[7] =0;
		for(i=0; i<8; i++){
			if(IsRegisted[i])tData.D8[2] |= 1<<i;
		}
		for(i=0; i<8; i++){
			if(IsCheckError[i])tData.D8[3] |= 1<<i;
		}
		for(i=0; i<8; i++){
			if(IsPump[i])tData.D8[4] |= 1<<i;
		}
		for(i=0; i<8; i++){
			if(IsProhibitLinkage[i])tData.D8[5] |= 1<<i;
		}
		for(i=0; i<8; i++){
			if(IsOutputState[i])tData.D8[6] |= 1<<i;
		}
		for(i=0; i<8; i++){
			if(IsRegisted[i])tData.D8[7] |= 1<<i;
		}
		InnerCan.OBufInsert(1, cmDirectCtlPadConfig, tData.D8, 8);
	}
}

void TDirectCtlBoard::ResetCallBack()
{
	int i;
	if(PadIsProhibit == 0){
		for(i=0; i<dDIRECTCTL_KEY_MAX_COUNT; i++){
			OutputState[i] =0;
			FeedbackState[i] =0;
			FaultState[i] =0;
			LnkRdyGo[i] =0;
			LnkRdyGoOld[i] =0;
			FeedBackMiss[i] = 0;
			DelayTick[i] = 0;
			DelayToDoEventType[i] =0;
		}
	}
}

void TDirectCtlBoard::InterLinkGoStartNode(unsigned char aCtlNum, unsigned char aP0, unsigned char aP1)
{
	InterLink.oBuf.WriteIndex++;
	if(InterLink.oBuf.WriteIndex >= dLinkageOutputBufMaxCOunt)InterLink.oBuf.WriteIndex = 0;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.CtlNum = aCtlNum;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.P0 = aP0;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.P1 = aP1;
	InterLink.oBuf.Body[InterLink.oBuf.WriteIndex].Spl.Action = dLNKSTART;
}

void TDirectCtlBoard::AddRemoveMsgDelayStart(unsigned int IsAdd, unsigned char aP0, unsigned char aP1)
{
	aIm.Splite.Year = DateTime.Date.Split.Year;
	aIm.Splite.Month = DateTime.Date.Split.Month;
	aIm.Splite.Day = DateTime.Date.Split.Day;
	aIm.Splite.Hour = DateTime.Time.Split.Hour;
	aIm.Splite.Minute = DateTime.Time.Split.Minute;
	aIm.Splite.Second = DateTime.Time.Split.Second;
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;	
	
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
	aIm.Splite.P0 = aP0;
	aIm.Splite.P1 = aP1;
	aIm.Splite.P2 = 0;
	aIm.Splite.dType = 0;

	if(IsAdd){
		aIm.Splite.UserCode =0;
		aIm.Splite.AreaNum =0;
		//#define dADDR_DIRECTPAD_START		66
		//#define dADDR_DIRECTPAD_END		85
		if( aP0 && aP1 ){
			if( (aP0 >= dADDR_DIRECTPAD_START) && (aP0 <= dADDR_DIRECTPAD_END) ){
				aP0-=dADDR_DIRECTPAD_START; 
				if(aP1 <= dDIRECTCTL_KEY_MAX_COUNT){
					aP1--;
					aIm.Splite.UserCode = DirectCtlBoard[aP0].UcList[aP1].Full;
					aIm.Splite.AreaNum = DirectCtlBoard[aP0].Area[aP1];
					aIm.Splite.dType = DirectCtlBoard[aP0].AssignType[aP1];
				}
			}
		}
		
		aIm.Splite.mType = etLinkageStart;
		aIm.Splite.iByte0 = 0x0A;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStart(aIm);
			ExRecord.SetStateCodeStart();
			FecBusCRT.SetStateCodeStart();
			ProtoC2C.SlaveDoSend2MasterDelayStart(aIm, cmAutoStart);
		}
	}else{
		aIm.Splite.mType = etLinkageStartCancel;
		aIm.Splite.iByte0 = 0x0A;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStartCancel(aIm);
			ExRecord.SetStateCodeStart();
			FecBusCRT.SetStateCodeStart();
			ProtoC2C.SlaveDoSend2MasterDelayStart(aIm, cmAutoStop);
		}
	}
}


void TDirectCtlBoard::AddRemoveMsgDelayStartSimulate(unsigned int IsAdd, unsigned char aP0, unsigned char aP1)
{
	aIm.Splite.Year = DateTime.Date.Split.Year;
	aIm.Splite.Month = DateTime.Date.Split.Month;
	aIm.Splite.Day = DateTime.Date.Split.Day;
	aIm.Splite.Hour = DateTime.Time.Split.Hour;
	aIm.Splite.Minute = DateTime.Time.Split.Minute;
	aIm.Splite.Second = DateTime.Time.Split.Second;
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;	
	
	aIm.Splite.PCtlNum = MainCtl.fData.Split.MyNum;
	aIm.Splite.P0 = aP0;
	aIm.Splite.P1 = aP1;
	aIm.Splite.P2 = 0;
	aIm.Splite.dType = 0;

	if(IsAdd){
		aIm.Splite.UserCode =0;
		aIm.Splite.AreaNum =0;
		//#define dADDR_DIRECTPAD_START		66
		//#define dADDR_DIRECTPAD_END		85
		if( aP0 && aP1 ){
			if( (aP0 >= dADDR_DIRECTPAD_START) && (aP0 <= dADDR_DIRECTPAD_END) ){
				aP0-=dADDR_DIRECTPAD_START; 
				if(aP1 <= dDIRECTCTL_KEY_MAX_COUNT){
					aP1--;
					aIm.Splite.UserCode = DirectCtlBoard[aP0].UcList[aP1].Full;
					aIm.Splite.AreaNum = DirectCtlBoard[aP0].Area[aP1];
					aIm.Splite.dType = DirectCtlBoard[aP0].AssignType[aP1];
				}
			}
		}
		
		aIm.Splite.mType = etLinkageStart;
		aIm.Splite.iByte0 = 0x0A;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStartSimulate(aIm);
			ProtoC2C.SlaveDoSend2MasterDelayStartSimulate(aIm, cmAutoStart);
		}
	}else{
		aIm.Splite.mType = etLinkageStartCancel;
		aIm.Splite.iByte0 = 0x0A;
		if(CtlCenter.IsMsgReseting == 0){
			CtlCenter.iePushOneMsgLinkageStartCancel(aIm);
			//ExRecord.SetStateCodeStart();
			//FecBusCRT.SetStateCodeStart();
			ProtoC2C.SlaveDoSend2MasterDelayStartSimulate(aIm, cmAutoStop);
		}
	}
}	

void TDirectCtlBoard::GetUserCodeAreaNumDevType(unsigned char aP0, unsigned char aP1, unsigned int *pUc, unsigned short *pAreaNum, unsigned char *pDType)
{
	if(aP0 ==0){*pUc =0; *pAreaNum =0; *pDType =0; return;}
	if(aP1 ==0){*pUc =0; *pAreaNum =0; *pDType =0; return;}

	if( (aP0 >= dADDR_DIRECTPAD_START) && (aP0 <= dADDR_DIRECTPAD_END) ){
		if(aP1 >dDIRECTCTL_KEY_MAX_COUNT){*pUc =0; *pAreaNum =0; *pDType =0; return;}
		aP0-=dADDR_DIRECTPAD_START; aP1--;
		*pUc = DirectCtlBoard[aP0].UcList[aP1].Full;
		*pAreaNum = DirectCtlBoard[aP0].Area[aP1];
		*pDType = DirectCtlBoard[aP0].AssignType[aP1]; 
	}else{
		*pUc = 0;
		*pAreaNum = 0;
		*pDType =0; 
	}
}

void TDirectCtlBoard::sRecallCrcFaultMsg(unsigned char aPad)
{
	if(DirectCtlBoard[aPad].CrcFlag.Config){
		CtlCenter.ieAddBrdFault(aPad+dADDR_DIRECTPAD_START, TBoardFaultType::StorageDirectPadCfg);
	}
	if(DirectCtlBoard[aPad].CrcFlag.AuxId){
		CtlCenter.ieAddBrdFault(aPad+dADDR_DIRECTPAD_START,TBoardFaultType::StorageEpAuxId);
	}
	if(DirectCtlBoard[aPad].CrcFlag.AssignedType){
		CtlCenter.ieAddBrdFault(aPad+dADDR_DIRECTPAD_START,TBoardFaultType::StorageEpAssignedType);
	}
	if(DirectCtlBoard[aPad].CrcFlag.Area){
		CtlCenter.ieAddBrdFault(aPad+dADDR_DIRECTPAD_START,TBoardFaultType::StorageEpArea);
	}
}

void TMotherBoard::CheckOnlineTask()
{
	int i;
	for(i=0; i<3; i++){
		if(Exist[i]){
			if(NoReportTick[i] == 0){
				if(ErrorHasReport[i]){
					//Clear Error
					ErrorHasReport[i] =0;
					CtlCenter.ieAddBrdFaultCancel(i+1, 10);
				}
			}else
			if(NoReportTick[i] > 50){
				if(ErrorHasReport[i] == 0){
					//Report Error
					ErrorHasReport[i] = 1;
					CtlCenter.ieAddBrdFault(i+1, 10);
				}
				NoReportTick[i] = 51;
			}
			NoReportTick[i]++;
		}
	}
}

void TMotherBoard::ResetCallBack()
{
	unsigned int i;
	for(i=0;i<8;i++){
		OffLine[i] =0;
		NoReportTick[i] =0;
		ErrorHasReport[i] =0;
	}
}

void TDevPrinter::AddRemoveMsgFaultOffline(int IsAdd)
{
	if(IsAdd) CtlCenter.ieAddDevFault(17,0);
	else CtlCenter.ieAddDevFaultCancel(17,0);
}

void TDevPrinter::AddRemoveMsgFaultNoPaper(int IsAdd)
{
	if(IsAdd) CtlCenter.ieAddDevFault(18,0);
	else CtlCenter.ieAddDevFaultCancel(18,0);			
}

void TDevPrinter::SetState(int aOffline, int aNoPaper)
{
	if(sOffline != aOffline){
		if(aOffline){
			//AddRemoveMsgFaultOffline(1);
		}else{
			//AddRemoveMsgFaultOffline(0);
		}
		sOffline = aOffline;
	}
	
	/*if(sOffline == 0){
		if(sNoPaper != aNoPaper){
			if(aNoPaper){
				AddRemoveMsgFaultNoPaper(1);
			}else{
				AddRemoveMsgFaultNoPaper(0);
			}
			sNoPaper = aNoPaper;
		}
	}*/
}

void TGeneralDev::LcdBlackLightSetOn()
{
	LcdCountDownTick = (static_cast<unsigned int>(ScreenAndKeyLock.SaveTime)) * 60;
	LcdScreenSaving = 0;
	lcd_bl_on();
}

void TGeneralDev::LcdBlackLightSetOnStartUp()
{
	LcdCountDownTick = (static_cast<unsigned int>(ScreenAndKeyLock.SaveTime)) * 60;
	LcdScreenSaving = 0;
	lcd_bl_on();
}

void TGeneralDev::LcdBlackLightSetOff()
{
	LcdScreenSaving = 1;
	lcd_bl_off();
}

void TGeneralDev::Task1000Ms()
{
	if(ScreenAndKeyLock.SaveOn){
		if(LcdCountDownTick){
			LcdCountDownTick--;
			if(LcdCountDownTick > 1200)LcdCountDownTick = 1200;
		}else{
			//0x01 Fire; 0x02 Sv; 0x04 Fault
			if( 	( (ScreenAndKeyLock.IsKeyLock & 0x01) && (CtlCenter.ieMsgFire.Count >0) ) ||
				( (ScreenAndKeyLock.IsKeyLock & 0x02) && (CtlCenter.ieMsgSv.Count >0) ) ||
				( (ScreenAndKeyLock.IsKeyLock & 0x04) && (CtlCenter.ieMsgFault.Count >0) ) ){
					LcdCountDownTick = 10;
			}else{
					LcdBlackLightSetOff();
			}
		}
	}
}













































