#include "environment.h"
//#include "common.h"
//#include "process.h"
#include "timer.h"
//#include "order.h"
#include "master.h"
#include "com.h"
#include "system_setup.h"
#include "tablet_control.h"
#include "machineControl.h"
#include <csl_edma2.h>
#include <csl_intc.h>
#include <csl_intcAux.h>

#define MASTER_BUFFER_SIZE					MCBSP_PACKET_MAX_SIZE_WORD
#define RETRY_COUNT_LIMIT					3 // sjm Chg For RunTime 1 ==> 2

#define TX_TIMEOUT							5		// 50us * 9
#define RX_WAITING_TIME						10		// 50us * 20

// fsm
#define MCBSP_MASTER_FSM_NONE				0
#define MCBSP_MASTER_FSM_TRANSFER_READY		1
#define MCBSP_MASTER_FSM_TRANSMITTING		2
#define MCBSP_MASTER_FSM_TRANSMIT_RETRY		5
#define MCBSP_MASTER_FSM_RECEIVE_READY		7
#define MCBSP_MASTER_FSM_HEADER_RECEIVED	8
#define MCBSP_MASTER_FSM_RECEIVE_COMPLETE	9
#define MCBSP_MASTER_FSM_RECEIVE_ERROR		10

#define MCBSP_NEXT_TRANSFER_DELAY			2
#define MCBSP_RETRY_TRANSFER_DELAY			2

volatile int volatileValue;
int checksum_retry = 0;
struct
{
	unsigned int LastReceiveTime;
	unsigned short PacketLength;
	unsigned short ReadCount;
	union
	{
		unsigned int Buffer[MASTER_BUFFER_SIZE];
		TMcbspPacket Data;
	} UPacket;
} RXControlData;

struct
{
	unsigned int TransmitStartTime;
	unsigned int TransmitEndTime;
	int RetryCount;
	int RetryEnabled;
	unsigned short PacketLength;
	unsigned short WriteCount;
	union								
	{
		unsigned int Buffer[MASTER_BUFFER_SIZE];
		TMcbspPacket Data;
	} UPacket;
} TXControlData;


struct
{
	int FSM;
} MCBSPMasterControlData;


CSL_McbspHandle 		hMcbsp1;
CSL_McbspObj         	mcbsp1Obj;

TMcbspDebugInfo McbspDebugInfo;

int nextCommandDelay = 0;

unsigned char StatusListSW = 0;
unsigned char StatusCheckSW[SYSTEM_SPB_MAX_COUNT];
unsigned char StatusRetryCount[SYSTEM_SPB_MAX_COUNT];
int CurrentStatusSPBIndex;
int h_error;
unsigned char EchoTestCommandSW = 0;
int tx_error, rx_error;
struct
{
	int Enabled;
	int DataSize;
	int Frequency;
	int SPBMask;
	int NextTransferTime;
	unsigned int CurrentDataStartValue;
	int RequestExist[SYSTEM_SPB_MAX_COUNT];
} McBSPTestData;

TMcBSPTestResultData McBSPTestResultData;

TMcbspPacket *RxPacket, *TxPacket;

int MCBSP_Tx_EDMATCCNumber, MCBSP_Rx_EDMATCCNumber;
unsigned int StatusRequestID[SYSTEM_SPB_MAX_COUNT];
int current_time;
int tx_count=0,tx_pri;
int MasterInit(void);									// master 초기화
int MASTER_Retransmit(void);							// 재전송 함수 (제한 횟수 이상 전송시 return 1)
int MASTER_PacketInterpret(void);						// 패킷 분석

/* statuslist 관련 함수 */
int MASTER_RequestStatusList(int spbIndex);				// 하위 보드에 statusList 요청

void MASTER_Process(void);								// master loop

int MasterInit()
{
	CSL_McbspConfig mcbspCfg;      /* Config Structures */
	CSL_McbspContext     pContext;
	int i;
	CSL_Status           status = CSL_SOK;
	h_error=0;
	tx_error = tx_pri=current_time=0;
	McbspDebugInfo.CurrentSPBIndex = 0;
	for (i = 0; i < SYSTEM_SPB_MAX_COUNT; i ++)
	{
		McbspDebugInfo.SendPacketCount[i] = 0;
		McbspDebugInfo.ReceivedPacketCount[i] = 0;
		McbspDebugInfo.SendTimeoutPacketCount[i] = 0;
		McbspDebugInfo.ReceiveTimeoutPacketCount[i] = 0;
	}

	RxPacket = &(RXControlData.UPacket.Data);
	TxPacket = &(TXControlData.UPacket.Data);
	
	status = CSL_mcbspInit(&pContext);
	if (status != CSL_SOK) {
		return 0;
	}	

	hMcbsp1 = CSL_mcbspOpen (&mcbsp1Obj, CSL_MCBSP_1,NULL, &status);

	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);
	//sample rate set
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_GRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
	
    mcbspCfg.PCR = 
	CSL_FMK(MCBSP_PCR_XIOEN,0) |
	CSL_FMK(MCBSP_PCR_RIOEN,0) |
	CSL_FMK(MCBSP_PCR_FSXM,1) |
	CSL_FMK(MCBSP_PCR_FSRM,0) |
	CSL_FMK(MCBSP_PCR_CLKXM,1) |
	CSL_FMK(MCBSP_PCR_CLKRM,0) |
	CSL_FMK(MCBSP_PCR_CLKSSTAT,0) |
	CSL_FMK(MCBSP_PCR_DXSTAT,0) |
	CSL_FMK(MCBSP_PCR_FSXP,0) |
	CSL_FMK(MCBSP_PCR_FSRP,1) |
	CSL_FMK(MCBSP_PCR_CLKXP,0) |
	CSL_FMK(MCBSP_PCR_CLKRP,0);

    mcbspCfg.SRGR = 
	CSL_FMK(MCBSP_SRGR_GSYNC,0) |
	CSL_FMK(MCBSP_SRGR_CLKSP,0) |
	CSL_FMK(MCBSP_SRGR_CLKSM,1) |
	CSL_FMK(MCBSP_SRGR_FSGM,1) |//22
	CSL_FMK(MCBSP_SRGR_FPER,31) |//31) |
	CSL_FMK(MCBSP_SRGR_FWID,15) |
	CSL_FMK(MCBSP_SRGR_CLKGDV,31); //31);

    mcbspCfg.XCR =
        CSL_FMK(MCBSP_XCR_XPHASE,0) |				
        CSL_FMK(MCBSP_XCR_XFRLEN2,0) |		
        CSL_FMK(MCBSP_XCR_XWDLEN2,0) |				
        CSL_FMK(MCBSP_XCR_XCOMPAND,0) |				
        CSL_FMK(MCBSP_XCR_XFIG,1) |						
        CSL_FMK(MCBSP_XCR_XDATDLY,1) |					
        CSL_FMK(MCBSP_XCR_XFRLEN1,0) |		
        CSL_FMK(MCBSP_XCR_XWDLEN1,5) |					
        CSL_FMK(MCBSP_XCR_XWDREVRS,0);			

    mcbspCfg.RCR =
        CSL_FMK(MCBSP_RCR_RPHASE,0) |					
        CSL_FMK(MCBSP_RCR_RFRLEN2,0) |		
        CSL_FMK(MCBSP_RCR_RWDLEN2,0) |				
        CSL_FMK(MCBSP_RCR_RCOMPAND,0) |			 
        CSL_FMK(MCBSP_RCR_RFIG,1) |							 
        CSL_FMK(MCBSP_RCR_RDATDLY,1) |				 
        CSL_FMK(MCBSP_RCR_RFRLEN1,0) |		 
        CSL_FMK(MCBSP_RCR_RWDLEN1,5) |					 
        CSL_FMK(MCBSP_RCR_RWDREVRS,0);		 
		
    mcbspCfg.SPCR =
        CSL_FMK(MCBSP_SPCR_FREE,0) | 
        CSL_FMK(MCBSP_SPCR_SOFT,0) | 
        CSL_FMK(MCBSP_SPCR_XINTM,0) |
        CSL_FMK(MCBSP_SPCR_XSYNCERR,0) | 
        CSL_FMK(MCBSP_SPCR_DLB,0) |
        CSL_FMK(MCBSP_SPCR_RJUST,0) |
        CSL_FMK(MCBSP_SPCR_CLKSTP,0) |
        CSL_FMK(MCBSP_SPCR_DXENA,0) |
        CSL_FMK(MCBSP_SPCR_RINTM,0) |
        CSL_FMK(MCBSP_SPCR_RSYNCERR,0);
  
	mcbspCfg.MCR= 0;
	mcbspCfg.RCERE0 = 0;
	mcbspCfg.XCERE0 = 0;
	mcbspCfg.RCERE1 = 0;
	mcbspCfg.XCERE1 = 0;
	mcbspCfg.RCERE2 = 0;
	mcbspCfg.XCERE2 = 0;
	mcbspCfg.RCERE3 = 0;
	mcbspCfg.XCERE3 = 0; 
	
	status = CSL_mcbspHwSetupRaw(hMcbsp1, &mcbspCfg);

	for (i = 0; i < 1000; i++)
	{
		volatileValue = 0;
	}

	// 4. Start the sample rate generator and wait for two CLKG(because HCB is clock master)
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_GRST,1);
	for (i = 0; i < 1000; i++)
	{
		volatileValue = 0;
	}

	// 5. set the XRST bit to 1 and wait for any unexpected frame sync error. if any occurs, skip it.
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,1);
	for (i = 0; i < 1000; i++)
	{
		volatileValue = 0;
	}
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);


	for (i = 0; i < SYSTEM_SPB_MAX_COUNT; i++)
	{
		StatusCheckSW[i] = 0;
		StatusRetryCount[i] = 0;

		StatusRequestID[i] = 0;
	}
	CurrentStatusSPBIndex = 0;

	McBSPTestData.Enabled = 0;
	RXControlData.ReadCount = 0;
	RXControlData.PacketLength = 0;	
	TXControlData.WriteCount = 0;
	TXControlData.PacketLength = 0;	
	TXControlData.RetryEnabled = 1;

	
	MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSFER_READY;

    CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
	CSL_intcCombinedEventClear(1,CSL_INTC_EVTCLR_EC10_MASK);
	CSL_intcCombinedEventClear(1,CSL_INTC_EVTCLR_EC11_MASK);
    CSL_intcInterruptEnable(CSL_INTC_VECTID_4);

    return (0);
}

int TransmitStart(void)
{
	int i;
	TXControlData.WriteCount = 0;
	TXControlData.PacketLength = TxPacket->length;
//	RXControlData.ReadCount = 0;
//	RXControlData.PacketLength = 0;

	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,1);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,1);
	TXControlData.TransmitStartTime = board50usTmr;
	tx_count++;
	return TRUE; 

}


int MASTER_Retransmit(void)
{
	return TransmitStart();
}

int MASTER_PacketInterpret(void)
{
	int clientIndex;
	int dataIndex;
	int returnValue;
	int spbIndex;

	returnValue = TRUE;
//	if (RxPacket->length > MCBSP_PACKET_MAX_SIZE_WORD *8) return FALSE;

	if (CheckSum((unsigned int *)RxPacket, RxPacket->length - 1) == *((unsigned int *)RxPacket + RxPacket->length - 1))
	{
		//복사한 내용 처리
		clientIndex = ((RxPacket->source >> 6) & 0x3F) - 1;// * (SYSTEM_CPB_COUNT + 1) + 1;
		McbspDebugInfo.ReceivedPacketCount[clientIndex]++;
		if (BIT16_GET(RxPacket->type, PACKET_TYPE_ERROR))	// error packet 처리를 packetID 비교보다 먼저 해야 한다.
		{
			if (RxPacket->data[0] == ERROR_CODE_CHECKSUM)
			{
				McBSPTestResultData.ErrorCount_SPB_CheckSum++;
			}
			else
			{
				McBSPTestResultData.ErrorCount_Data++;
			}
			returnValue = FALSE;
		}
		else if (RxPacket->packetID != TxPacket->packetID)
		{
			if (McBSPTestData.Enabled)
			{
				McBSPTestResultData.ErrorCount_PacketID++;
			}
			returnValue = FALSE;

		}			
		else
		{
			if (RxPacket->command == CMD_ECHO)
			{
				for (dataIndex = 0; dataIndex < McBSPTestData.DataSize; dataIndex++)
				{
					if (RxPacket->data[dataIndex] != McBSPTestData.CurrentDataStartValue + dataIndex)
					{
						McBSPTestResultData.ErrorCount_Data++;
						break;
					}						
				}
				if (dataIndex == McBSPTestData.DataSize)
				{
					McBSPTestData.CurrentDataStartValue += McBSPTestData.DataSize;
				}
			}
			if (RxPacket->command == CMD_STATUSLIST)
			{
				for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
				{
					if (RxPacket->source == BOARD_ID_SPB(spbIndex + 1))
					{
						if (StatusRequestID[spbIndex] == RxPacket->data[1])
						{
							memcpy(&SPBProcessingResultData[spbIndex], RxPacket->data + 2, sizeof(TSPBProcessingResultData));
							StatusRequestID[spbIndex]++;
						}
						break;
					}
				}
			}
		} 
	} 
	else
	{
		if (McBSPTestData.Enabled)
		{
			McBSPTestResultData.ErrorCount_CheckSum++;
		}
		returnValue = FALSE;
	}
	return returnValue;
}


void MakePacket(unsigned short command, int spbIndex, int wDataLength)
{
	unsigned short destBoardID;
	destBoardID = BOARD_ID_SPB(spbIndex + 1);
	TxPacket->header = MCBSP_PACKET_HEADER;
	TxPacket->mode	= PACKET_MODE_MCBSP;
	TxPacket->command = command;
	TxPacket->type = 0;
	TxPacket->source = BoardID;
	TxPacket->destination = destBoardID;
	TxPacket->packetID = packetID++;
	TxPacket->length = MCBSP_PACKET_HEADER_SIZE + wDataLength+1;
	TxPacket->data[wDataLength] = CheckSum((unsigned int *)TxPacket, TxPacket->length - 1);
}

int MASTER_RequestEcho(int spbIndex)
{
	int dataIndex;
	int returnValue;   

	returnValue = TRUE;


	for (dataIndex = 0; dataIndex < McBSPTestData.DataSize; dataIndex++)
	{
//		TxPacket->data[dataIndex] = 0xFFFFFFFF;
		TxPacket->data[dataIndex] = McBSPTestData.CurrentDataStartValue + dataIndex;
	}
	MakePacket(CMD_ECHO, spbIndex, McBSPTestData.DataSize);

	McbspDebugInfo.CurrentSPBIndex = spbIndex;
	McbspDebugInfo.SendPacketCount[spbIndex]++;

	TXControlData.RetryCount = 0;
	if (!TransmitStart())
	{
		returnValue = FALSE;
	}	

	return returnValue;
}


int MASTER_RequestStatusList(int spbIndex)
{
	int returnValue;   

	returnValue = TRUE;

	TxPacket->data[0] = TabletCaptureInformation.Sensor1TabletNumber;
	TxPacket->data[1] = TabletCaptureInformation.Sensor2TabletNumber;
	TxPacket->data[2] = TabletCaptureInformation.Sensor1TabletNumberValid;
	TxPacket->data[3] = TabletCaptureInformation.Sensor2TabletNumberValid;
	TxPacket->data[4] = StatusRequestID[spbIndex];

	MakePacket(CMD_STATUSLIST, spbIndex, 5);

	McbspDebugInfo.CurrentSPBIndex = spbIndex;
	McbspDebugInfo.SendPacketCount[spbIndex]++;

	TXControlData.RetryCount = 0;
	if (!TransmitStart())
	{
		returnValue = FALSE;
	}	

	return returnValue;

}


void MASTER_Process(void)
{
	int spbIndex;
	TMcbspPacket *txPacket;
	unsigned int ier, iet;
	EDMA_Config edmaConfig;
	unsigned int currentReadPosition;
	unsigned char packetError;
	CSL_IntcGlobalEnableState 	state;
	CSL_intcGlobalDisable(&state);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RSYNCERR,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XSYNCERR,0);
	if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_TRANSFER_READY)
	{

		if (nextCommandDelay) 
		{
			nextCommandDelay--;
		}
		else
		{			
			if (McBSPTestData.Enabled)
			{
				if (McBSPTestData.NextTransferTime <= Board1MSTmr)
				{
					for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
					{
						if (McBSPTestData.SPBMask & (0x0001 << spbIndex))
						{
							if (McBSPTestData.RequestExist[spbIndex] != 0)
							{					
								McBSPTestResultData.OverflowCount++;
							}
							McBSPTestData.RequestExist[spbIndex] = 1;
						}
					}		
					McBSPTestData.NextTransferTime = Board1MSTmr + McBSPTestData.Frequency;
				}

				for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
				{
					if (McBSPTestData.RequestExist[spbIndex] != 0)
					{					
						McBSPTestResultData.TransferCount++;
						McBSPTestData.RequestExist[spbIndex] = 0;					
						if (MASTER_RequestEcho(spbIndex))
						{
							MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMITTING;
						}
						else
						{
							MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;
						}
						break;
					}
				}
			}
			else
			{

				if (StatusListSW)
				{
					for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
					{
						StatusCheckSW[spbIndex] = 1;
						StatusRetryCount[spbIndex] = 0;
					}		
					StatusListSW = 0;
				}

				for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
				{
					if (StatusCheckSW[CurrentStatusSPBIndex])
					{
						StatusCheckSW[CurrentStatusSPBIndex] = 0;
						if (MASTER_RequestStatusList(CurrentStatusSPBIndex))
						{
							MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMITTING;
						}
						else
						{
							MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;
							StatusRetryCount[CurrentStatusSPBIndex]++;
						}
						CurrentStatusSPBIndex++;
						
						if (CurrentStatusSPBIndex == MachineSetupData.IPB_BoardCount)
						{
							CurrentStatusSPBIndex = 0;								
						}
						break;
					}
				}
			}
		}
	}

	else if(MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_RECEIVE_READY || MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_HEADER_RECEIVED)
	{
		if (board50usTmr - TXControlData.TransmitEndTime >= RX_WAITING_TIME)
		{
			McbspDebugInfo.ReceiveTimeoutPacketCount[McbspDebugInfo.CurrentSPBIndex]++;
			if (McBSPTestData.Enabled)
			{
				McBSPTestResultData.ErrorCount_ReceiveTO++;
			}
			RXControlData.ReadCount = 0;
//			RXControlData.PacketLength = 0;
			CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
			CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;
		}
	}
	else if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_RECEIVE_COMPLETE)
	{
		if (!MASTER_PacketInterpret())
		{
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;
		}
		else
		{
			nextCommandDelay = MCBSP_NEXT_TRANSFER_DELAY - 1;		
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSFER_READY;
			BlackoutInfo.MasterLastComTime = Board1MSTmr;			
		}
	}
	else if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_RECEIVE_ERROR)
	{		
		nextCommandDelay = MCBSP_RETRY_TRANSFER_DELAY - 1;
		MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;	
	}
	else if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_TRANSMITTING)
	{

		if (board50usTmr - TXControlData.TransmitStartTime >= TX_TIMEOUT)
		{
			McbspDebugInfo.SendTimeoutPacketCount[McbspDebugInfo.CurrentSPBIndex]++;
			if (McBSPTestData.Enabled)
			{
				McBSPTestResultData.ErrorCount_SendTO++;
			}
			CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,1);
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;
		}
	}
	else if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_TRANSMIT_RETRY)
	{
		if (TXControlData.RetryEnabled)
		{
			if (nextCommandDelay) 
			{
				nextCommandDelay--;
			}
			else
			{				
				txPacket = &(TXControlData.UPacket.Data);
				if (txPacket->command == CMD_STATUSLIST)
				{
					for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
					{
						if (txPacket->destination == BOARD_ID_SPB(spbIndex + 1))
						{
							StatusRetryCount[spbIndex]++;
							if (StatusRetryCount[spbIndex] < RETRY_COUNT_LIMIT)
							{
								StatusCheckSW[spbIndex] = 1;
							}
							else
							{
								ErrorUnit_Put(BoardID, ERROR_TYPE_CRITICAL, ERROR_CODE_MCBSP_RETRY_COUNT_OVER, __LINE__, spbIndex, 0);
							}						
							break;
						}					
					}
					MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSFER_READY;
				}
				else
				{
					TXControlData.RetryCount++;
					if (TXControlData.RetryCount < RETRY_COUNT_LIMIT)
					{
						if (MASTER_Retransmit())
						{
							MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMITTING;
						}
						else
						{
							MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSMIT_RETRY;
						}
					}
					else
					{
						//ErrorUnit_Put(BoardID, ERROR_TYPE_CRITICAL, ERROR_CODE_MCBSP_RETRY_COUNT_OVER, __LINE__, spbIndex, 1);
						MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSFER_READY;
					}
				}
			}
		}		
		else
		{
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSFER_READY;
		}
	}

	CSL_intcGlobalEnable(&state);
}

void Master_Pending_EchoTestCommand(void)
{
	if (EchoTestCommandSW == 0)
	{
		EchoTestCommandSW = 1;
	}
}

void Master_McBSPTest_Start(int dataSize, int frequency, int spbMask)
{
	int spbIndex;
	McBSPTestData.Enabled = 1;
	McBSPTestData.DataSize = dataSize;
	if (McBSPTestData.DataSize > MASTER_BUFFER_SIZE - MCBSP_PACKET_DEFAULT_SIZE - 1) McBSPTestData.DataSize = MASTER_BUFFER_SIZE - MCBSP_PACKET_DEFAULT_SIZE - 1;
	McBSPTestData.Frequency = frequency;
	McBSPTestData.SPBMask = spbMask;
	McBSPTestData.NextTransferTime = Board1MSTmr + McBSPTestData.Frequency;
	McBSPTestData.CurrentDataStartValue = 0;
	McBSPTestResultData.TransferCount = 0;
	McBSPTestResultData.ErrorCount_PacketID = 0;
	McBSPTestResultData.ErrorCount_CheckSum = 0;
	McBSPTestResultData.ErrorCount_SPB_CheckSum = 0;
	McBSPTestResultData.ErrorCount_Data = 0;
	McBSPTestResultData.ErrorCount_SendTO = 0;
	McBSPTestResultData.ErrorCount_ReceiveTO = 0;
	McBSPTestResultData.ErrorCount_MSBLost = 0;
	McBSPTestResultData.ErrorCount_LSBLost = 0;
	McBSPTestResultData.OverflowCount = 0;
	for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		McBSPTestData.RequestExist[spbIndex] = 0;
	}
}

void Master_McBSPTest_Stop(void)
{
	McBSPTestData.Enabled = 0;

}

void IsrMcbspTxMaster()
{
	CSL_IntcGlobalEnableState 	state;
	CSL_intcGlobalDisable(&state);
	if (TXControlData.WriteCount > TXControlData.PacketLength+3)		// include dummy tail
	{
		TXControlData.TransmitEndTime = board50usTmr;
		
		if (TxPacket->destination == MCBSP_BROADCAST_DESTINATION)
		{
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_TRANSFER_READY;
		}
		else
		{	
			RXControlData.ReadCount = 0;	
			MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_RECEIVE_READY;
			TXControlData.TransmitEndTime = board50usTmr;
		}
		CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
		CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);
	}
	else
	{
		CSL_mcbspWrite(hMcbsp1,CSL_MCBSP_WORDLEN_32, (&TXControlData.UPacket.Buffer[TXControlData.WriteCount++]));
	}
	CSL_intcGlobalEnable(&state);
}

void IsrMcbspRxMaster()
{
	CSL_IntcGlobalEnableState 	state;
	unsigned int readData;
	unsigned char packetError;
	CSL_intcGlobalDisable(&state);
	CSL_mcbspRead(hMcbsp1,CSL_MCBSP_WORDLEN_32,&readData);

	if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_RECEIVE_READY)	
	{
		RXControlData.LastReceiveTime = board50usTmr;
		if (RXControlData.ReadCount < MASTER_BUFFER_SIZE) 
		{
			RXControlData.UPacket.Buffer[RXControlData.ReadCount++] = readData;	
		} 

		if (RXControlData.ReadCount == 1)
		{
			if (RXControlData.UPacket.Data.header != MCBSP_PACKET_HEADER)
			{
				RXControlData.ReadCount = 0;
				RXControlData.PacketLength = 0;
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
			}
			h_error++;
		}

		if (RXControlData.ReadCount >= 2)	// header and length read
		{
			packetError = FALSE;
			if (RXControlData.UPacket.Data.header != MCBSP_PACKET_HEADER)
			{
				packetError = TRUE;
			}
			else if (RXControlData.UPacket.Data.length >= MASTER_BUFFER_SIZE || RXControlData.UPacket.Data.length == 0)
			{
				packetError = TRUE;
			}
			else
			{
				RXControlData.PacketLength = RXControlData.UPacket.Data.length;
				MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_HEADER_RECEIVED;

			}
			if (packetError)
			{
				RXControlData.ReadCount = 0;
				RXControlData.PacketLength = 0;
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
			}
		}

		
	}
	else if (MCBSPMasterControlData.FSM == MCBSP_MASTER_FSM_HEADER_RECEIVED)
	{

		if (RXControlData.ReadCount < MASTER_BUFFER_SIZE) 
		{
			RXControlData.UPacket.Buffer[RXControlData.ReadCount++] = readData;	
		} 
		
		if (RXControlData.ReadCount >= RXControlData.PacketLength)	//	receive complete
		{
			if(readData==0)
			{
				RXControlData.ReadCount--;
				checksum_retry++;
				if(checksum_retry > 3)
				{
					CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
					RXControlData.LastReceiveTime = board50usTmr;
					MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_RECEIVE_COMPLETE;
					RXControlData.ReadCount = 0;
					RXControlData.PacketLength = 0;
				}
			}
			else
			{
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
				RXControlData.LastReceiveTime = board50usTmr;
				MCBSPMasterControlData.FSM = MCBSP_MASTER_FSM_RECEIVE_COMPLETE;
				RXControlData.ReadCount = 0;
				RXControlData.PacketLength = 0;
			}
		}
	}
	CSL_intcGlobalEnable(&state);
}

