#include "environment.h"
#include "com.h"
#include "hardware.h"
#include "system_control.h"
#include "timer.h"
#include <csl_mcbsp.h>
#include <csl_gpio.h>
#include <csl_intcAux.h>
#include <csl_tmr.h>
#include <csl_tmrAux.h>

#define GPIO_MCBSP_0		CSL_GPIO_PIN9


#define SLAVE_BUFFER_SIZE				MCBSP_PACKET_MAX_SIZE_WORD

// fsm
#define MCBSP_SLAVE_FSM_NONE				0
#define MCBSP_SLAVE_FSM_RECEIVE_READY		1
#define MCBSP_SLAVE_FSM_HEADER_RECEIVED		2
#define MCBSP_SLAVE_FSM_RECEIVE_COMPLETE	3
#define MCBSP_SLAVE_FSM_TRANSMITTING		6
#define MCBSP_SLAVE_FSM_TRANSMIT_ERROR		8


#define MCBSP_EDMA_RX_OPT_CONF 0x20300000
#define MCBSP_EDMA_TX_OPT_CONF 0x22200000

#define TX_TIMEOUT					10		// 50us * 10
//#define RX_TIMEOUT					5		// 50us * 5
#define RX_TIMEOUT					10		// 50us * 10

#define MCBSP_RESPONSE_DELAY		1		// 50us * 5

/*
#pragma FUNC_EXT_CALLED(IsrMcbspRxSlave);
#pragma FUNC_EXT_CALLED(IsrMcbspTxSlave);
*/
void IsrMcbspRxSlave(void);
void IsrMcbspTxSlave(void);

struct
{
	unsigned int LastReceiveTime;
	unsigned short PacketLength;
	unsigned short ReadCount;
	union								
	{
		unsigned int Buffer[SLAVE_BUFFER_SIZE];
		TMcbspPacket Data;
	} UPacket;
} RXControlData;

struct
{
	unsigned int TransmitStartTime;
	unsigned short PacketLength;
	unsigned short WriteCount;
	union								
	{
		unsigned int Buffer[SLAVE_BUFFER_SIZE];
		TMcbspPacket Data;
	} UPacket;
} TXControlData;

struct
{
	int FSM;
} MCBSPSlaveControlData;


int StatusLampCounter = 332;

volatile int volatileValue;
unsigned int LastResponseStatusID;
unsigned int StatusRequestID;
extern CSL_TmrHandle TimerHandle1;
CSL_McbspHandle hMcbsp0;
CSL_McbspObj         mcbsp0Obj;

int Response(void);
void MCBSP_SlaveProcess(void);
TErrorCode McbspSLAVE_PacketInterpret(void);

TMcbspPacket *RxPacket, *TxPacket;
int mcbsp0_tx_error;
int mc_tx_count;
int mc_rx_count;
int checksum_retry =0;



int InitMCBSP(void)
{
	int i;
	CSL_McbspConfig mcbspCfg;      /* Config Structures */
	CSL_McbspContext     pContext;
	unsigned int clkdv;
	int readData;
	CSL_Status           status = CSL_SOK;
	
	RxPacket = &(RXControlData.UPacket.Data);
	TxPacket = &(TXControlData.UPacket.Data);
	mcbsp0_tx_error = mc_tx_count = mc_rx_count = 0;
	// CSL 3.0 MCBSP Init
	status = CSL_mcbspInit(&pContext);
	if (status != CSL_SOK) {
		return 0;
	}
	// CSL 3.0 MCBSP Open
	memset (&mcbsp0Obj, 0, sizeof(CSL_McbspObj));
	//    *handle = MCBSP_open(mcbspDeviceIndex, MCBSP_OPEN_RESET);
	hMcbsp0 = CSL_mcbspOpen (&mcbsp0Obj, CSL_MCBSP_0,NULL, &status);
	
	

	if( (hMcbsp0 == NULL) || (status != CSL_SOK)) {
		return 0;
	}
	
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);
	//sample rate set
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_GRST,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_FRST,0);
	
	status = CSL_mcbspHwSetupRaw(hMcbsp0, &mcbspCfg);
	
    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,0) |
	CSL_FMK(MCBSP_PCR_CLKRM,0) |
	CSL_FMK(MCBSP_PCR_CLKSSTAT,0) |
	CSL_FMK(MCBSP_PCR_DXSTAT,0) |
	CSL_FMK(MCBSP_PCR_FSXP,1) |
	CSL_FMK(MCBSP_PCR_FSRP,0) |
	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,0) |
	CSL_FMK(MCBSP_SRGR_FSGM,0) |
	CSL_FMK(MCBSP_SRGR_FPER,95) |
	CSL_FMK(MCBSP_SRGR_FWID,15) |
	CSL_FMK(MCBSP_SRGR_CLKGDV,0);

    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(hMcbsp0, &mcbspCfg);


	// 3. wait for two CLKSRG cycles (at least 200ns for 10MHz FSG clock)
	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(hMcbsp0->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(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,1);
	for (i = 0; i < 1000; i++)
	{
		volatileValue = 0;
	}
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);

	ResetGPIOVal(GPIO_MCBSP_0);

	// clear receive control
	RXControlData.PacketLength = 0;
	RXControlData.ReadCount = 0;
	// clear transmit control
	TXControlData.PacketLength = 0;
	TXControlData.WriteCount = 0;
	CSL_mcbspRead(hMcbsp0,CSL_MCBSP_WORDLEN_32,&readData);
	CSL_mcbspRead(hMcbsp0,CSL_MCBSP_WORDLEN_32,&readData);

	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_FRST,1);

	MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;

	LastResponseStatusID = -1;
	StatusRequestID = 0;	
    return (0);
}


int Response(void)
{
	int retValue = 0;

	if (TxPacket->length >= SLAVE_BUFFER_SIZE)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_MESSAGE, ERROR_CODE_MCBSP_WRONG_SIZE, __LINE__, TxPacket->command , TxPacket->length);		
		retValue = -1;
		return retValue;
	}
	// ready to transfer a packet
	TXControlData.PacketLength = TxPacket->length;
	SetGPIOVal(GPIO_MCBSP_0);

	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,1);
//	Config_TX_EDMA_Channel(TXControlData.PacketLength);
//	while(TXControlData.PacketLength +3 <= TXControlData.WriteCount){
//		CSL_mcbspWrite(hMcbsp0,CSL_MCBSP_WORDLEN_32 ,&TXControlData.UPacket.Buffer[TXControlData.WriteCount++]);
//	}
	TXControlData.TransmitStartTime = Board50usTimer;

	return retValue;
}

void InitTxData(int size, int error)
{
	unsigned int *buffer = (unsigned int *)TxPacket;

	TxPacket->header = MCBSP_PACKET_HEADER;
	TxPacket->mode = RxPacket->mode;	
	TxPacket->type = RxPacket->type;
	if (error)
	{
		BIT16_SET(TxPacket->type, PACKET_TYPE_ERROR, YES);
	}
	TxPacket->command = RxPacket->command;
	TxPacket->destination = RxPacket->source;
	TxPacket->source = BoardID;
	TxPacket->packetID = RxPacket->packetID;
	TxPacket->length = size;
	*(buffer + size - 1) = CheckSum(buffer, size - 1);
	*(buffer + size) = 0xFFFFFFFF;
}

void MakeDefaultResponse(TErrorCode result)
{
	TxPacket->data[0] = result;
	if (result)
	{
		InitTxData(MCBSP_RESPOND_DEFAULT_SIZE, 1);
	}
	else
	{
		InitTxData(MCBSP_RESPOND_DEFAULT_SIZE, 0);
	}		
}



TErrorCode McbspSLAVE_PacketInterpret(void)
{
	TErrorCode result = ERROR_CODE_NONE;
	
	if (RxPacket->length < MCBSP_PACKET_DEFAULT_SIZE || RxPacket->length > MCBSP_PACKET_MAX_SIZE_WORD) 
	{		
		ErrorUnit_Put(BoardID, ERROR_TYPE_MESSAGE, ERROR_CODE_MCBSP_WRONG_SIZE, __LINE__, RxPacket->command , RxPacket->length);
		return ERROR_CODE_WRONG_SIZE;
	}
		
	if (*((unsigned int *)RxPacket + RxPacket->length - 1) == CheckSum((unsigned int *)RxPacket, RxPacket->length - 1))	
	{		
		if (RxPacket->command == CMD_STATUSLIST)
		{
			StatusLampCounter--;
			if (StatusLampCounter == 0)
			{
				Lamp1Toggle();
				StatusLampCounter = 332;
			}
		}
		else
		{
			Lamp1Toggle();
		}

		if (RxPacket->command == CMD_STATUSLIST)
		{
			int sensor1TabletNumber, sensor2TabletNumber;
			int sensor1TabletNumberValid, sensor2TabletNumberValid;
			//unsigned int statusRequestID;
			sensor1TabletNumber = RxPacket->data[0];
			sensor2TabletNumber = RxPacket->data[1];
			sensor1TabletNumberValid = RxPacket->data[2];
			sensor2TabletNumberValid = RxPacket->data[3];
			StatusRequestID = RxPacket->data[4];
			OnReceiveTabletNumber(sensor1TabletNumber, sensor2TabletNumber, sensor1TabletNumberValid, sensor2TabletNumberValid);
		}

		if (RxPacket->destination != MCBSP_BROADCAST_DESTINATION)
		{
			if (RxPacket->command == CMD_STATUSLIST)
			{
				TxPacket->data[0] = result;
				TxPacket->data[1] = LastResponseStatusID;
				memcpy(TxPacket->data + 2, &SPBProcessingResultData, sizeof(TSPBProcessingResultData));
				InitTxData(MCBSP_RESPOND_DEFAULT_SIZE + 1 + sizeof(TSPBProcessingResultData) / 4, 0);
			}
			else if (RxPacket->command == CMD_ECHO)
			{
				memcpy(TxPacket->data, RxPacket->data, (RxPacket->length - MCBSP_PACKET_HEADER_SIZE - 1) * 4);
				InitTxData(MCBSP_RESPOND_DEFAULT_SIZE + RxPacket->length, 0);
			}
			else
			{
				MakeDefaultResponse(ERROR_CODE_NONE);
			}
		}		
	}
	else 	// checksum is not match
	{
		//ErrorUnit_Put(BoardID,  ERROR_TYPE_MESSAGE, ERROR_CODE_CHECKSUM, __LINE__, RXControlData.ReadCount, RXControlData.PacketLength);
		result = ERROR_CODE_CHECKSUM;		
	}

	if (result != ERROR_CODE_NONE)
	{
		if (RxPacket->destination != MCBSP_BROADCAST_DESTINATION)
		{
			MakeDefaultResponse(result);
		}
	}
	return result;
}

void MCBSP_SlaveProcess(void)
{
	TErrorCode ec;
//	unsigned int readData;
	unsigned int oldDataLength;
	unsigned int currentReadPosition;
	unsigned char packetError;
	CSL_IntcGlobalEnableState 	state;
	CSL_intcGlobalDisable(&state);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RSYNCERR,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XSYNCERR,0);
//	CSL_mcbspRead(hMcbsp0,CSL_MCBSP_WORDLEN_32,&readData);

	if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_RECEIVE_READY || MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_HEADER_RECEIVED)
	{
		if (RXControlData.ReadCount != 0)
		{
			if (Board50usTimer - RXControlData.LastReceiveTime >= RX_TIMEOUT)		// receive timeout
			{	// just clear buffer and reset state 
				//ErrorUnit_Put(BoardID,  ERROR_TYPE_MESSAGE, ERROR_CODE_MCBSP_TRANSMIT_TIMEOUT, __LINE__, RXControlData.ReadCount, RXControlData.PacketLength);
				RXControlData.ReadCount = 0;
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
				MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;				
			}
		}
		else
		{
			if (Board50usTimer - RXControlData.LastReceiveTime >= 1000)		// receive timeout
			{	// just clear buffer and reset state 
				//ErrorUnit_Put(BoardID,  ERROR_TYPE_MESSAGE, ERROR_CODE_MCBSP_TRANSMIT_TIMEOUT, __LINE__, RXControlData.ReadCount, RXControlData.PacketLength);
				RXControlData.ReadCount = 0;
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
				MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;				
			}
		}
	}
	else if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_RECEIVE_COMPLETE)
	{
		if (Board50usTimer - RXControlData.LastReceiveTime > MCBSP_RESPONSE_DELAY)
		{
			if (RxPacket->destination != BoardID && RxPacket->destination != MCBSP_BROADCAST_DESTINATION)		// RX packet is neither a my packet nor a broadcasting packet
			{	
				RXControlData.ReadCount = 0;	// clear read buffer
				MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;
			}
			else
			{
				oldDataLength = TxPacket->length;
				TxPacket->length = 0;
				ec = McbspSLAVE_PacketInterpret();
				if (ec == ERROR_CODE_ALREADY_PACKET)
				{
					TxPacket->length = oldDataLength;
					if (RxPacket->destination != MCBSP_BROADCAST_DESTINATION)	// RX packet is not a broadcasting packet
					{
						if (Response() == 0) // 기존에 생성했던 응답을 보낸다.
						{
							MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_TRANSMITTING;
						}
						else
						{
							MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_TRANSMIT_ERROR;
						}
					}
					else
					{
						RXControlData.ReadCount = 0;
						MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;
					}
				}
				else
				{
					if (RxPacket->destination != MCBSP_BROADCAST_DESTINATION && TxPacket->length > 0)
					{
						if (Response() == 0)
						{
							MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_TRANSMITTING;
						}
						else
						{
							MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_TRANSMIT_ERROR;
						}
					}
					else
					{
						RXControlData.ReadCount = 0;
						MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;
					}
				}
			}
			CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
			CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
		}
	}
	
	else if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_TRANSMIT_ERROR)
	{
		ResetGPIOVal(GPIO_MCBSP_0);
		RXControlData.ReadCount = 0;
		MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;
	}

	else if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_TRANSMITTING)
	{
		if (Board50usTimer - TXControlData.TransmitStartTime >= TX_TIMEOUT)
		{
//			CSL_intcEventSet(CSL_INTC_EVENTID_XINT0);
			CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);
			ResetGPIOVal(GPIO_MCBSP_0);
			RXControlData.ReadCount = 0;
			TXControlData.WriteCount = 0;
			MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;
			mcbsp0_tx_error++;
		}		
	}
	CSL_intcGlobalEnable(&state);
}

void IsrMcbspRxSlave()
{
	unsigned int readData;
	unsigned int ie;
	unsigned int oldDataLength;
	unsigned int currentReadPosition;
	unsigned char packetError;

	CSL_IntcGlobalEnableState 	state;
	
	CSL_intcGlobalDisable(&state);	
	CSL_mcbspRead(hMcbsp0,CSL_MCBSP_WORDLEN_32,&readData);
	
	if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_RECEIVE_READY)
	{
		RXControlData.LastReceiveTime = Board50usTimer;
		if (RXControlData.ReadCount < SLAVE_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(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
			}
		}
		else 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 >= SLAVE_BUFFER_SIZE || RXControlData.UPacket.Data.length == 0)
			{
				packetError = TRUE;
			}
			else
			{
				RXControlData.PacketLength = RXControlData.UPacket.Data.length;
				MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_HEADER_RECEIVED;
			}
			if (packetError)
			{
				RXControlData.ReadCount = 0;
				RXControlData.PacketLength = 0;
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
			}
		}

	}
	else if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_HEADER_RECEIVED)
	{
		RXControlData.LastReceiveTime = Board50usTimer;
		if (RXControlData.ReadCount < SLAVE_BUFFER_SIZE) 
		{
			RXControlData.UPacket.Buffer[RXControlData.ReadCount++] = readData;	
//			CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
//			CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
		} 

		if (RXControlData.ReadCount > RXControlData.PacketLength)	//	receive complete
		{
		
			if(readData==0)
			{
				RXControlData.ReadCount--;
				checksum_retry++;
				mcbsp0_tx_error++;
				if(checksum_retry > 3)
				{
					CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
					RXControlData.LastReceiveTime = Board50usTimer;
					MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_COMPLETE;
					RXControlData.ReadCount = 0;
					RXControlData.PacketLength = 0;
					checksum_retry=0;
					
				}
			}	
			else
			{
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
				RXControlData.LastReceiveTime = Board50usTimer;
				MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_COMPLETE;
				RXControlData.ReadCount = 0;
				RXControlData.PacketLength = 0;
				checksum_retry=0;
			}
		}
	}
	CSL_intcGlobalEnable(&state);
}

void IsrMcbspTxSlave()
{
	CSL_IntcGlobalEnableState 	state;
	CSL_intcGlobalDisable(&state);
	 if (MCBSPSlaveControlData.FSM == MCBSP_SLAVE_FSM_TRANSMITTING)
	{
			if (TXControlData.WriteCount > TXControlData.PacketLength+3)		// include dummy tail
			{
				CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);
				TXControlData.PacketLength = 0;
				TXControlData.WriteCount = 0;
				MCBSPSlaveControlData.FSM = MCBSP_SLAVE_FSM_RECEIVE_READY;
				ResetGPIOVal(GPIO_MCBSP_0);
			}
			else
			{
				 CSL_mcbspWrite(hMcbsp0,CSL_MCBSP_WORDLEN_32, &TXControlData.UPacket.Buffer[TXControlData.WriteCount++]);
			}
//		}
	}
	CSL_intcGlobalEnable(&state);
}

