#include "ProtoInnerCan.h"
#include "ProtoCrt.h"

#include "CnCpp.h"
#include "record.h"
#include "Runtime.h"
#include "server.h"

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

void TProtoCrt::Init()
{
	unsigned int i;
	unsigned int aAddr;
	
	iBuf.ReadIndex = 0;
	iBuf.WriteIndex = 0;
	oBuf.ReadIndex = 0;
	oBuf.WriteIndex = 0;
	
	for(i=0; i<dCRT_BufLen_Tx; i++){
		aAddr = dAddrSdram_CrtTxBuf + (i * dCRT_BufEntrySize_Tx);
		*(volatile unsigned int *)(aAddr + (i*4 + 0) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 + 4) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 + 8) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 +12) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 +16) ) = 0;
	}
	for(i=0; i<dCRT_BufLen_Rx; i++){
		aAddr = dAddrSdram_CrtRxBuf + (i * dCRT_BufEntrySize_Rx);
		*(volatile unsigned int *)(aAddr + (i*4 + 0) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 + 4) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 + 8) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 +12) ) = 0;
		*(volatile unsigned int *)(aAddr + (i*4 +16) ) = 0;
	}
	
	OnTransmite.State = 0;
	OnTransmite.OnGoing = 0;
	OnTransmite.CrtAckState = 0;
	OnTransmite.WaitTick = 0;
	OnTransmite.NoCommTick = 0;
	
	Err.TransferBoardOffline = 0;
	Err.CrtOffline =0;
	ErrReport.TransferBoardOffline = 0;
	ErrReport.CrtOffline = 0;
}

void TProtoCrt::iBufInsert(unsigned int *pD)
{
	unsigned int aAddr;
	iBuf.WriteIndex++;
	if(iBuf.WriteIndex >= dCRT_BufLen_Rx)iBuf.WriteIndex = 0;
	aAddr = dAddrSdram_CrtRxBuf + (iBuf.WriteIndex * dCRT_BufEntrySize_Rx);
	*(volatile unsigned int *)(aAddr +  0 ) = pD[0];
	*(volatile unsigned int *)(aAddr +  4 ) = pD[1];
	*(volatile unsigned int *)(aAddr +  8 ) = pD[2];
	*(volatile unsigned int *)(aAddr +  12) = pD[3];
	*(volatile unsigned int *)(aAddr +  16) = pD[4];
}

void TProtoCrt::iBufProcess()
{
	unsigned int aAddr;
	if(iBuf.ReadIndex != iBuf.WriteIndex){
		iBuf.ReadIndex++;
		if(iBuf.ReadIndex >= dCRT_BufLen_Rx)iBuf.ReadIndex = 0;
		aAddr = dAddrSdram_CrtRxBuf + (iBuf.ReadIndex * dCRT_BufEntrySize_Rx);
		iBuf.rBody.D32[0] = *(volatile unsigned int *)(aAddr +  0 );
		iBuf.rBody.D32[1] = *(volatile unsigned int *)(aAddr +  4 );
		iBuf.rBody.D32[2] = *(volatile unsigned int *)(aAddr +  8 );
		iBuf.rBody.D32[3] = *(volatile unsigned int *)(aAddr +  12);
		iBuf.rBody.D32[4] = *(volatile unsigned int *)(aAddr +  16);
		
		if(iBuf.rBody.Splite.Cmd == dCRT_CMD_ACK){
			//Get Ack State
			OnTransmite.CrtAckState = iBuf.rBody.Splite.Ack;
		}else
		if(iBuf.rBody.Splite.Cmd == dCRT_CMD_OPA){
			//Get Operate
			DoCrtReqOperate();
		}
	}
}

void TProtoCrt::oBufInsert()
{
	unsigned int aAddr;
	
	oBuf.WriteIndex++;
	if(oBuf.WriteIndex >= dCRT_BufLen_Tx)oBuf.WriteIndex = 0;
	
	aAddr = dAddrSdram_CrtTxBuf + (oBuf.WriteIndex * dCRT_BufEntrySize_Tx);
	* (volatile unsigned int *)(aAddr +  0) = oBuf.wBody.D32[0];
	* (volatile unsigned int *)(aAddr +  4) = oBuf.wBody.D32[1];
	* (volatile unsigned int *)(aAddr +  8) = oBuf.wBody.D32[2];
	* (volatile unsigned int *)(aAddr + 12) = oBuf.wBody.D32[3];
	* (volatile unsigned int *)(aAddr + 16) = oBuf.wBody.D32[4];
}

void TProtoCrt::oBufInsert(unsigned int *pD)
{
	unsigned int aAddr;
	
	oBuf.WriteIndex++;
	if(oBuf.WriteIndex >= dCRT_BufLen_Tx)oBuf.WriteIndex = 0;
	
	aAddr = dAddrSdram_CrtTxBuf + (oBuf.WriteIndex * 16);
	* (volatile unsigned int *)(aAddr +  0) = pD[0];
	* (volatile unsigned int *)(aAddr +  4) = pD[1];
	* (volatile unsigned int *)(aAddr +  8) = pD[2];
	* (volatile unsigned int *)(aAddr + 12) = pD[3];
	* (volatile unsigned int *)(aAddr + 16) = pD[4];	
}

void TProtoCrt::oBufInsert(unsigned char aCmd, unsigned char aMsgType, TRecordCommon aBufBody)
{
	unsigned int aAddr;
	TDMix aDMix;
	
	oBuf.WriteIndex++;
	if(oBuf.WriteIndex >= dCRT_BufLen_Tx)oBuf.WriteIndex = 0;
	
	aDMix.D32 = 0;
	aDMix.D8[0] = aCmd;
	aDMix.D8[1] = aMsgType;
	
	aAddr = dAddrSdram_CrtTxBuf + (oBuf.WriteIndex * 16);
	* (volatile unsigned int *)(aAddr +  0) = aDMix.D32;
	* (volatile unsigned int *)(aAddr +  4) = aBufBody.D32[0];
	* (volatile unsigned int *)(aAddr +  8) = aBufBody.D32[1];
	* (volatile unsigned int *)(aAddr + 12) = aBufBody.D32[2];
	* (volatile unsigned int *)(aAddr + 16) = aBufBody.D32[3];	
}

void TProtoCrt::oBufTryTxNewMsg()
{
	unsigned int aAddr;
	if(oBuf.ReadIndex != oBuf.WriteIndex){
		if(get_excan_linkage_tx_complete()){
			oBuf.ReadIndex++;
			if(oBuf.ReadIndex >= dCRT_BufLen_Tx)oBuf.ReadIndex = 0;
			aAddr = dAddrSdram_C2cOutBuf + (oBuf.ReadIndex * 16);
			
			tData.D32[0] = * (volatile unsigned int *)(aAddr +  0);
			//Do Send Data Here

			OnTransmite.NoCommTick = 0;
			OnTransmite.WaitTick = 0;
			OnTransmite.RetryTimes = 0;
			OnTransmite.CrtAckState = 0;
			
			OnTransmite.OnGoing = 1;
		}
	}
}

void TProtoCrt::PublishOperate(TRecordCommon aIm)
{
	oBufInsert(0, 5, aIm);
}

void TProtoCrt::ResetCoomm()
{
	Init();
}

void TProtoCrt::PrcErrMsg()
{
	if(Err.TransferBoardOffline != ErrReport.TransferBoardOffline){
		if(Err.TransferBoardOffline){
			//Add Fault Msg Here
		}else{
			//Cancel Fault Msg Here
		}
		ErrReport.TransferBoardOffline = Err.TransferBoardOffline;
	}
	
	if(Err.CrtOffline != ErrReport.CrtOffline){
		if(Err.CrtOffline){
			//Add Fault Msg Here
		}else{
			//Cancel Fault Msg Here
		}
		ErrReport.CrtOffline = Err.CrtOffline;
	}
}

void TProtoCrt::oBufProcess()
{
	OnTransmite.NoCommTick++;
	if(OnTransmite.OnGoing){
		if(OnTransmite.CrtAckState == 0){
			//No Rpy Here
			OnTransmite.WaitTick++;
			if(OnTransmite.WaitTick > 100){
				//Resend Old Pkg Here
				OnTransmite.WaitTick =0;
				if(OnTransmite.RetryTimes < 20){
					OnTransmite.RetryTimes++;
				}else{
					//Report Err Here
					Err.TransferBoardOffline =1;
					PrcErrMsg();
				}
			}
		}else
		if(OnTransmite.CrtAckState == 1){
			//Rpy Ack Ok Here, Load Next 
			OnTransmite.OnGoing = 0;
		}else
		if(OnTransmite.CrtAckState == 2){
			//Rpy No Need Ack Here, Load Next 
			OnTransmite.OnGoing = 0;
		}else
		if(OnTransmite.CrtAckState == 3){
			//Rpy Not Found Crt
			OnTransmite.OnGoing = 0;
			Err.CrtOffline = 1;
			PrcErrMsg();
		}
	}
		
	if(OnTransmite.OnGoing == 0){
		if(oBuf.ReadIndex != oBuf.WriteIndex){
			oBufTryTxNewMsg();
		}else{
			if(OnTransmite.NoCommTick > 2999){
				//Add a Dump Buf Here For Check Online
			}
		}
	}
}

void TProtoCrt::DoCrtReqOperate()
{
	unsigned char aOpaCode;
	aOpaCode = iBuf.rBody.Splite.OpaCode;
	switch(aOpaCode){
		case 0:
			break;
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		default:
			break;
	}
}

void TProtoCrt::Task10Ms()
{
	if(GraphUsing == 0)return;
	if(MainCtl.fData.Split.NetworkMode == 2)return;
	
	oBufProcess();
}













