#include "environment.h"
#include "timer.h"
#include "Laser_Mcbsp.h"
#include "com.h"
#include "system_setup.h"
#include "fa_server.h"
#include <csl_edma2.h>
#include <csl_intc.h>
#include <csl_intcAux.h>
#include <csl_mcbspAux.h>
#include <stdio.h>

volatile int volatileValue_mc1;
CSL_McbspHandle 		hMcbsp1;
CSL_McbspObj         	mcbsp1Obj;
TLaserMcbspPacket *Laser_RxPacket, *Laser_TxPacket;
int mc1_packetID = 0;
int nextCommandDelay = 0;
//int test_count_mc1[10];
//int rxbufferr[20];
int txbufferr[20];
int test_theta=1, test_x= 1, test_y = 1;
int mcbsp_timer_count = 0;
int LaserMcbspInit()
{
	CSL_McbspConfig mcbspCfg;      /* Config Structures */
	CSL_McbspContext     pContext;
	int i;
	CSL_Status           status = CSL_SOK;

	Laser_RxPacket = &(Laser_RXControlData.UPacket.Data);
	Laser_TxPacket = &(Laser_TXControlData.UPacket.Data);
//	memset(LaserTestResult,0x00, sizeof(LaserTestResult));
//	memset(test_count_mc1,0x00,sizeof(test_count_mc1));
//	memset(rxbufferr,0x00,sizeof(rxbufferr));
	memset(txbufferr,0x00,sizeof(txbufferr));
	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 = // pin control register
	CSL_FMK(MCBSP_PCR_XIOEN,0) |
	CSL_FMK(MCBSP_PCR_RIOEN,0) |
	CSL_FMK(MCBSP_PCR_FSXM,1) | //Transmit frame-synchronization mode bit(11)
	CSL_FMK(MCBSP_PCR_FSRM,0) | //Receive frame-stnchronization mode bit(10)
	CSL_FMK(MCBSP_PCR_CLKXM,0) | //Transmit clock mode bit. When CLKSP bit in SPCR is cleared to 0:
	CSL_FMK(MCBSP_PCR_CLKRM,0) | //Recive clock mode bit
	CSL_FMK(MCBSP_PCR_CLKSSTAT,0) |
	CSL_FMK(MCBSP_PCR_DXSTAT,0) |
	CSL_FMK(MCBSP_PCR_FSXP,1 ) | //Transmit frame-synchornization polarity bit
	CSL_FMK(MCBSP_PCR_FSRP,0) | //Transmit frame-stnchornization polarity bit
	CSL_FMK(MCBSP_PCR_CLKXP,1) | //Transmit clock 
	CSL_FMK(MCBSP_PCR_CLKRP,0);

    mcbspCfg.SRGR = // sample rate generator register
	CSL_FMK(MCBSP_SRGR_GSYNC,1) |
	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 = // Transmit control register
        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,0	) |						
        CSL_FMK(MCBSP_XCR_XDATDLY,0) |					
        CSL_FMK(MCBSP_XCR_XFRLEN1,0) |		
        CSL_FMK(MCBSP_XCR_XWDLEN1,5) |					
        CSL_FMK(MCBSP_XCR_XWDREVRS,0);			

    mcbspCfg.RCR = // receive control register
        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,2) |				 
        CSL_FMK(MCBSP_RCR_RFRLEN1,0) |		 
        CSL_FMK(MCBSP_RCR_RWDLEN1,5) |					 
        CSL_FMK(MCBSP_RCR_RWDREVRS,0);		 
		
    mcbspCfg.SPCR = // Serial port control register
        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_mc1 = 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_mc1 = 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_mc1 = 0;
	}
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);

	Laser_RXControlData.ReadCount = 0;
	Laser_RXControlData.PacketLength = 0;	
	Laser_TXControlData.WriteCount = 0;
	Laser_TXControlData.PacketLength = 0;	
	Laser_TXControlData.RetryEnabled = 1;

	
	LaserMcbspControlData.FSM = LASER_MCBSP_TRANSFER_READY;// LASER_MCBSP_TRANSFER_READY;



	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,1);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
	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;
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,1);	
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,1);
	Laser_TXControlData.TransmitStartTime = Board50usTimer;
	Laser_TXControlData.PacketLength = LASER_MCBSP_PACKET_SIZE;
	LaserMcbspControlData.FSM = LASER_MCBSP_TRANSMITTING;		
	return TRUE; 
}

int LaserMcbsp_SendPacket(short theta, short x_coordinate, short y_coordinate)
{
	CSL_IntcGlobalEnableState 	state;
	unsigned int *buffer = (unsigned int *)Laser_TxPacket;
	
	if(LaserMcbspControlData.FSM != LASER_MCBSP_TRANSFER_READY)
	{
		return 0;
	}
	Laser_TxPacket->header = LASER_MCBSP_PACKET_HEADER; 
	Laser_TxPacket->theta	= theta; 			//°¢µµ
	Laser_TxPacket->x_coordinate = x_coordinate;   // XÁÂÇ¥
	Laser_TxPacket->y_coordinate = y_coordinate;   // YÁÂÇ¥
	Laser_TxPacket->reserved = 0xFF;
	
 	if(((unsigned short)x_coordinate == 0xFFFF) && ((unsigned short)y_coordinate == 0xFFFF))
 	{
		Laser_TxPacket->print_status = 0;   //ÀÎ¼â¿©ºÎ :¹ÌÀÎ¼â
//		ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_NONE, (unsigned short)x_coordinate,(unsigned short)y_coordinate,Laser_TxPacket->print_status);
		Laser_TxPacket->checksum = 111;	
 	}
	else
	{
		Laser_TxPacket->print_status = 1;   //ÀÎ¼â¿©ºÎ: ÀÎ¼â
//		ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_NONE, (unsigned short)x_coordinate,(unsigned short)y_coordinate,Laser_TxPacket->print_status);		
		Laser_TxPacket->checksum = CheckSum(buffer, LASER_MCBSP_PACKET_SIZE - 1);	
	}
//	Laser_TxPacket->checksum = CheckSum(buffer, LASER_MCBSP_PACKET_SIZE - 1);	
	Laser_TxPacket->dummy = 0x00;
	Laser_TXControlData.WriteCount = 0;
	mcbsp_timer_count = 0;
	
	TransmitStart();
	return 1;
}

void LaserMcbsp_Process(void)
{
	CSL_IntcGlobalEnableState 	state;
	unsigned int temp = 0;
	unsigned int mc_state;
	CSL_intcGlobalDisable(&state);

 	if(LaserMcbspControlData.FSM == LASER_MCBSP_TRANSFER_READY)
	{
		Laser_TXControlData.WriteCount = 0;
	}
	else if(LaserMcbspControlData.FSM == LASER_MCBSP_TRANSMITTING && Board50usTimer>Laser_TXControlData.TransmitStartTime+1)
	{
		if(mcbsp_timer_count>3)
		{
			if(Laser_TXControlData.WriteCount > LASER_MCBSP_PACKET_SIZE)
			{
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
				CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);				
				Laser_TXControlData.WriteCount = 0;
				Laser_TXControlData.TransmitEndTime = Board50usTimer;
				test_Laser_MC_Count++;
				mcbsp_timer_count = 0;
				LaserMcbspControlData.FSM = LASER_MCBSP_TRANSFER_READY;
			}
			else
			{
				CSL_mcbspGetDevStatus(hMcbsp1, &mc_state);
				if((mc_state&0x2) && !(mc_state&0x8))
				{			
					CSL_mcbspWrite(hMcbsp1,CSL_MCBSP_WORDLEN_32,(&Laser_TXControlData.UPacket.Buffer[Laser_TXControlData.WriteCount++]));
					TEMP = 1;
					mcbsp_timer_count = 0;
				}
				else
				{
					CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XSYNCERR,0);
					CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
					CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);
					CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,1);
					CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,1);
				}
			}
		}
		if(Board50usTimer > Laser_TXControlData.TransmitStartTime + LASER_MCBSP_TIMEOUT )
		{
			ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_MCBSP_TRANSMIT_TIMEOUT, Laser_TXControlData.WriteCount, Laser_TXControlData.TransmitStartTime,Board50usTimer-Laser_TXControlData.TransmitStartTime);
			CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_FRST,0);
			CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XRST,0);				
			Laser_TXControlData.WriteCount = 0;
			Laser_TXControlData.TransmitEndTime = Board50usTimer;
			mcbsp_timer_count = 0;
			LaserMcbspControlData.FSM = LASER_MCBSP_TRANSFER_READY;
			test_Laser_MC_Count++;
		}
		mcbsp_timer_count++;
	}
	
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RSYNCERR,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_XSYNCERR,0);
	CSL_intcGlobalEnable(&state);
}

void LaserMcbspTxIsr()
{

}

void LaserMcbspRxIsr()
{
/*
	CSL_IntcGlobalEnableState 	state;
	unsigned int readData;
	unsigned char packetError;
	CSL_mcbspRead(hMcbsp1,CSL_MCBSP_WORDLEN_32,&readData);
	rxbufferr[(test_count_mc1[1]%20)] = readData;
	test_count_mc1[1]++;
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,0);
	CSL_FINS(hMcbsp1->regs->SPCR,MCBSP_SPCR_RRST,1);
*/
}

