#include "rs485.h"
#include <csl_mcbsp.h>
#include <csl_intcAux.h>
#include "environment.h"
#include "timer.h"
#include "hardware.h"


#define EOT_TYPE_NONE				0
#define EOT_TYPE_CHAR				1
#define EOT_TYPE_COUNT				2
#define EOT_TYPE_TIME				3


#define OSC_CLK						50000000		// 50MHz
#define CPU_CLK						600000000		// 600MHz

CSL_McbspObj         mcbspObj;
CSL_McbspHandle hMcbsp0;
volatile int volatileValue_mc0;
int mc0_count[10] = {0,0,0,0,0,0,0,0,0,0};
const unsigned char abCrcHi[] =
{
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};

const unsigned char abCrcLo[] =
{
	0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04,
	0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
	0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
	0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,
	0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
	0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,	0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
	0x28, 0xE8, 0xE9, 0x29,	0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,	0xEC, 0x2C,
	0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,	0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,
	0xA0, 0x60,	0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,	0xA5, 0x65, 0x64, 0x44,
	0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,	0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
	0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C,
	0xB4, 0x74, 0x75, 0xB5,	0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,	0x70, 0xB0,
	0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,	0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
	0x9C, 0x5C,	0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,	0x99, 0x59, 0x58, 0x98,
	0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,	0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
	0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,	0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};

void RS485_ProcessRx(unsigned int *buffer, char *rxchar);
void RS485_ProcessTx(unsigned int *buffer, char txchar, int stopBitCount);
void RS485_SetBaudRate(TRS485Handle *handle, int baudRate, char isInternalCLK);
//---------------------------------------------------------------------------
void RS485_McBSP_Init(CSL_McbspHandle handle, int bps, int tx_stop_bits, int tx_data_bits,
	int rx_stop_bits, int rx_data_bits, int mcbspDeviceIndex, char isInternalCLK)
{
	CSL_McbspConfig mcbspCfg;      /* Config Structures */
	CSL_McbspContext     pContext;
	unsigned int clkdv;
	CSL_Status           status = CSL_SOK;
	unsigned int mc0_dummy;
	int i;


	hMcbsp0 = CSL_mcbspOpen (&mcbspObj, CSL_MCBSP_0,NULL, &status);

	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_GRST,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_FRST,0);
	
	handle = hMcbsp0;
	clkdv = (unsigned int)(OSC_CLK / (bps * 32)) - 1;
    if (clkdv > 0xff) {
        return;
    }
     mcbspCfg.PCR = 
		CSL_FMK(MCBSP_PCR_XIOEN,0x00) |
		CSL_FMK(MCBSP_PCR_RIOEN,0x00) |
		CSL_FMK(MCBSP_PCR_FSXM,0x01) |
		CSL_FMK(MCBSP_PCR_FSRM,0x00) |
		CSL_FMK(MCBSP_PCR_CLKXM,0x01) |
		CSL_FMK(MCBSP_PCR_CLKRM,0x01) |
		CSL_FMK(MCBSP_PCR_CLKSSTAT,0x00) |
		CSL_FMK(MCBSP_PCR_DXSTAT,0x00) |
		CSL_FMK(MCBSP_PCR_FSXP,0x01) |
		CSL_FMK(MCBSP_PCR_FSRP,0x01) |
		CSL_FMK(MCBSP_PCR_CLKXP,0x00) |
		CSL_FMK(MCBSP_PCR_CLKRP,0x00);

    mcbspCfg.SRGR = 
		CSL_FMK(MCBSP_SRGR_GSYNC,0x00) |
		CSL_FMK(MCBSP_SRGR_CLKSP,0x00) |
		CSL_FMK(MCBSP_SRGR_FSGM,0x00) |
		CSL_FMK(MCBSP_SRGR_FPER,0x00) |
		CSL_FMK(MCBSP_SRGR_FWID,0) |
		CSL_FMK(MCBSP_SRGR_CLKGDV,clkdv+1);

	if(isInternalCLK)
	{
		mcbspCfg.SRGR|= CSL_FMK(MCBSP_SRGR_CLKSM,0x01);		//0x00000001u
	}
	else
	{
		mcbspCfg.SRGR|= CSL_FMK(MCBSP_SRGR_CLKSM,0x00);		//0x00000000u
	}

    mcbspCfg.XCR =

        CSL_FMK(MCBSP_XCR_XPHASE,0x01) |					//0x00000001u
        CSL_FMK(MCBSP_XCR_XFRLEN2,tx_stop_bits - 1) |		// tx_stop_bits - 1
        CSL_FMK(MCBSP_XCR_XWDLEN2,0x05) |					//0x00000002u
        CSL_FMK(MCBSP_XCR_XCOMPAND,0x00) |				//0x00000000u
        CSL_FMK(MCBSP_XCR_XFIG,0x01) |							//0x00000001u
        CSL_FMK(MCBSP_XCR_XDATDLY,0x0) |					//0x00000000u
        CSL_FMK(MCBSP_XCR_XFRLEN1,(Uint32)tx_data_bits) |		//tx_data_bits
        CSL_FMK(MCBSP_XCR_XWDLEN1,0x05) |					//0x00000005u
        CSL_FMK(MCBSP_XCR_XWDREVRS,0x00);			//0x00000000u

    mcbspCfg.RCR =
        CSL_FMK(MCBSP_RCR_RPHASE,0x01) |					//0x00000001u
        CSL_FMK(MCBSP_RCR_RFRLEN2,rx_stop_bits-1) |		//rx_stop_bits - 1
        CSL_FMK(MCBSP_RCR_RWDLEN2,0x2) |					//0x00000002u
        CSL_FMK(MCBSP_RCR_RCOMPAND,0x00) |				//0x00000000u
        CSL_FMK(MCBSP_RCR_RFIG,0x01) |							//0x00000001u
        CSL_FMK(MCBSP_RCR_RDATDLY,0x00) |					//0x00000001u
        CSL_FMK(MCBSP_RCR_RFRLEN1,(Uint32)rx_data_bits) |		//rx_data_bits
        CSL_FMK(MCBSP_RCR_RWDLEN1,0x05) |					//0x00000005u
        CSL_FMK(MCBSP_RCR_RWDREVRS,0x00);			//0x00000000u

    mcbspCfg.SPCR =
        CSL_FMK(MCBSP_SPCR_FREE,0x01) |				// NO  0x00000001u
        CSL_FMK(MCBSP_SPCR_SOFT,0x00) |			// YES  0x00000000u
        CSL_FMK(MCBSP_SPCR_FRST,0x00) |			// YES  0x00000000u
        CSL_FMK(MCBSP_SPCR_GRST,0x00) |			// YES  0x00000000u
        CSL_FMK(MCBSP_SPCR_XINTM,0x00) | 				//0x00000000u
        CSL_FMK(MCBSP_SPCR_XSYNCERR,0x00) |	// NO  0x00000000u
        CSL_FMK(MCBSP_SPCR_XRST,0x00) |		//	0x00000000u
        CSL_FMK(MCBSP_SPCR_DLB,0x00) |					//  0x00000000u
        CSL_FMK(MCBSP_SPCR_RJUST,0x00) |				//  0x00000000u
        CSL_FMK(MCBSP_SPCR_CLKSTP,0x00) |		//  0x00000000u
        CSL_FMK(MCBSP_SPCR_DXENA,0x00) | 				//  0x00000000u
        CSL_FMK(MCBSP_SPCR_RINTM,0x00) |     		// EOS  0x00000000u
        CSL_FMK(MCBSP_SPCR_RSYNCERR,0x00) |	//  0x00000000u
        CSL_FMK(MCBSP_SPCR_RRST,0x0);		//  0x00000000u
        
	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);

	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);

}
//---------------------------------------------------------------------------
void RS485_McBSP_Close(CSL_McbspHandle handle)
{
	CSL_mcbspClose(hMcbsp0);
}
//---------------------------------------------------------------------------
void RS485_McBSP_Enable(CSL_McbspHandle handle)
{
	CSL_intcCombinedEventClear(1,CSL_INTC_EVTCLR_EC8_MASK);
	CSL_intcCombinedEventClear(1,CSL_INTC_EVTCLR_EC9_MASK);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_GRST,1);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_FRST,1);	
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,1);
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
}
//---------------------------------------------------------------------------
void RS485_Init(TRS485Handle *handle, int bps, int tx_stop_bits, int tx_data_bits,
	int tx_total_bits, int rx_stop_bits, int rx_data_bits, int rx_total_bits, int mcbspDeviceIndex, char isInternalCLK)
{
	handle->TX.BitBufferPosition = 0;
	handle->TX.DataPosition = 0;
	handle->TX.DataLength = 0;
	handle->TX.Status = RS485_TX_STATUS_NONE;	
	handle->TX.BitCount = tx_total_bits;
	handle->TX.DataBitCount = tx_data_bits;
	handle->TX.StopBitCount = tx_stop_bits;
	handle->RX.BitBufferPosition = 0;
	handle->RX.DataPosition = 0;
	handle->RX.Status = RS485_RX_STATUS_NONE;
	handle->RX.BitCount = rx_total_bits;
	handle->RX.DataBitCount = rx_data_bits;
	handle->RX.StopBitCount = rx_stop_bits;

	RS485_McBSP_Init(handle->McbspHandle, bps, tx_stop_bits, tx_data_bits, rx_stop_bits, rx_data_bits, mcbspDeviceIndex, isInternalCLK);
	RS485_SetBaudRate(handle, bps, FALSE);

	handle->TX.Status = RS485_TX_STATUS_READY;
} 
//---------------------------------------------------------------------------
void RS485_Close(TRS485Handle *handle)
{
	RS485_McBSP_Close(handle->McbspHandle);
	handle->McbspHandle = NULL;
}
//---------------------------------------------------------------------------
void RS485_Enable(TRS485Handle *handle)
{
	RS485_McBSP_Enable(handle->McbspHandle);
}
//---------------------------------------------------------------------------
void RS485_SetAddr(TRS485Handle *handle, char *txAddr, int txMaxSize, char *rxAddr, int rxMaxSize)
{
	handle->TX.DataBufferAddr = txAddr;
	handle->TX.DataBufferSize = txMaxSize;
	handle->RX.DataBufferAddr = rxAddr;
	handle->RX.DataBufferSize = rxMaxSize;
}
//---------------------------------------------------------------------------
void RS485_ClearRX(TRS485Handle *handle)
{
	handle->RX.BitBufferPosition = 0;
	handle->RX.DataPosition = 0;
} 
//---------------------------------------------------------------------------
void RS485_SetEOT_Time(TRS485Handle *handle)
{
	handle->RX.EOT_Type = EOT_TYPE_TIME;
}
//---------------------------------------------------------------------------
void RS485_SetEOT_None(TRS485Handle *handle)
{
	handle->RX.EOT_Type = EOT_TYPE_NONE;
}
//---------------------------------------------------------------------------
void RS485_SetEOT_Count(TRS485Handle *handle, int count)
{
	handle->RX.EOT_Type = EOT_TYPE_COUNT;
	handle->RX.EOT_DataSize = count;
}
//---------------------------------------------------------------------------
void RS485_SetEOT_Char(TRS485Handle *handle, char eotChar)
{
	handle->RX.EOT_Type = EOT_TYPE_CHAR;
	handle->RX.EOT_Char = eotChar;
}
//---------------------------------------------------------------------------
void RS485_TxStart(TRS485Handle *handle, int length)
{
	char temp = 0x1;
	handle->TX.DataPosition = 0;	
	handle->TX.DataLength = length;
	handle->TX.BitBufferPosition = 0;
	handle->TX.Status = RS485_TX_STATUS_SENDING;
	handle->RX.Status = RS485_RX_STATUS_READY;
	RS485_ClearRX(handle);

	RS485_ProcessTx(handle->TX.BitBuffer, handle->TX.DataBufferAddr[handle->TX.DataPosition], handle->TX.StopBitCount);
//	RS485_ProcessTx(handle->TX.BitBuffer,temp,1);
	CSL_mcbspWrite(hMcbsp0,CSL_MCBSP_WORDLEN_32,&handle->TX.BitBuffer[handle->TX.BitBufferPosition++]);
}
//---------------------------------------------------------------------------

/*
 *  ======== decodeBit ========
 *
 *  This function decoded the received character by testing the     
 *  center 4 bits of the baud. A majority rule is used for the      
 *  decoding
 */
int RS485_DecodeBit(unsigned int value)
{
    /* Test middle 4 bits in received raw data */
    value = ((value >> 14) & 0x0F);

    if ((value == 7) || (value > 10))           // sampled bit 0111, 1011, 1100, 1101, 1110 and 1111 are equal to 1
    {
        return (1);
    }
    else 
    {
        return (0);
    }
}


/*
 *  ======== processRx ========
 *  Process Reception function : Reception of a buffer from the 
 *  McBSP and reformat it to get the associated character value 
 */

// decode 1 start word(32bits) + 8 data word(8 * 32bits) + n stop words(n * 32bits)
// to 1 start bit + 8 data bits + n stop bits
void RS485_ProcessRx(unsigned int *buffer, char *rxchar)
{
    unsigned int rawData = 0;
    int bitValue;
    unsigned int bitCnt;

	*rxchar = 0;

	// skip start bit
    rawData = *buffer++;
	
        
    /* Walk through each data bit */
    for (bitCnt = 0; bitCnt < 8; bitCnt++) 
    {
        /* read raw bit (word) from dma buffer */
        rawData = *buffer++;

        /* get the value of the majority of the bits */
        bitValue = RS485_DecodeBit(rawData);
                        
        /* put received bit into proper place */
        *rxchar += bitValue << bitCnt;
    }
}
//---------------------------------------------------------------------------
/*
 *  ======== processTx ========
 *
 *  Process transmission function : this function is filling the
 *  xmitbuffer with appropriate data or 0xFFFF if idle mode.
 */
void RS485_ProcessTx(unsigned int *buffer, char txchar, int stopBitCount)
{
    unsigned int bitCnt;

    /* Set start bit in buffer */
    *buffer++ = 0x00000000;
//	*buffer++ = 0xFFFFFFFF;

    /* Walk through each data bit */
    for (bitCnt = 0; bitCnt < 8; bitCnt++) 
    {
        /* determine state of bit and set dma buffer value */
        if ((txchar >> bitCnt & 0x1) == 1 ) 
        {
            *buffer++ = 0xFFFFFFFF;
//			*buffer++ = 0x00000000;
        }
        else 
        {
            *buffer++ = 0x00000000;
//            *buffer++ = 0xFFFFFFFF;
        }
    }

	for (bitCnt = 0; bitCnt < stopBitCount; bitCnt++)
	{
	    *buffer++ = 0xFFFFFFFF;
//	    *buffer++ = 0x00000000;
	}
}
//---------------------------------------------------------------------------
void IsrRS485Rx(TRS485Handle *handle)
{
	unsigned int mc0_dummy;
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,0);
	mc0_count[1]++;
	CSL_mcbspRead(hMcbsp0,CSL_MCBSP_WORDLEN_32,&mc0_dummy);
	mc0_count[4] = mc0_dummy;
	if (handle->RX.Status == RS485_RX_STATUS_RECEIVING)
	{
	   	if (handle->RX.BitBufferPosition < handle->RX.BitCount)
	   	{
			if (handle->RX.BitBufferPosition == 0)
			{
				if (RS485_DecodeBit(mc0_dummy) == 0)	// checking start bit
				{
					handle->RX.BitBuffer[handle->RX.BitBufferPosition++] = mc0_dummy;
				}
			}
			else
			{
				handle->RX.BitBuffer[handle->RX.BitBufferPosition++] = mc0_dummy;
			}
		} 

	   	if (handle->RX.BitBufferPosition >= handle->RX.BitCount)
		{
			if (handle->RX.DataPosition < handle->RX.DataBufferSize) 
			{
				RS485_ProcessRx(handle->RX.BitBuffer, &(handle->RX.DataBufferAddr[handle->RX.DataPosition]));
				if (handle->RX.EOT_Type == EOT_TYPE_CHAR)
				{
					if (handle->RX.DataBufferAddr[handle->RX.DataPosition] == handle->RX.EOT_Char) 
					{
						handle->RX.Status = RS485_RX_STATUS_RECEIVED;
					}
				}
				else if (handle->RX.EOT_Type == EOT_TYPE_COUNT)
				{
					if (handle->RX.DataPosition + 1 == handle->RX.EOT_DataSize) 
					{
						handle->RX.Status = RS485_RX_STATUS_RECEIVED;
					}
				}
				else if (handle->RX.EOT_Type == EOT_TYPE_TIME)
				{
					handle->RX.LastReceivedTime = Board1MSTmr;
				}
				handle->RX.DataPosition++;
			}
			else
			{
				handle->RX.Status = RS485_RX_STATUS_RECEIVED;		// received, but overflowed
			}
			handle->RX.BitBufferPosition = 0;
		}
	}
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_XRST,1);
}
//---------------------------------------------------------------------------
void IsrRS485Tx(TRS485Handle *handle)
{
	char temp = 0x1;
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,0);
	if (handle->TX.Status == RS485_TX_STATUS_SENDING)
	{
		if (handle->TX.BitBufferPosition >= handle->TX.BitCount)
		{
			handle->TX.BitBufferPosition = 0;
			handle->TX.DataPosition++;
			if (handle->TX.DataPosition >= handle->TX.DataLength)
			{
				//handle->TX.Status = RS485_TX_STATUS_READY;		// tx complete
				handle->TX.CompleteTime = Board1MSTmr;
				handle->TX.Status = RS485_TX_STATUS_SENT;
				
				ResetGPIOVal(GPIO_MCBSP_2_RS485);
				RS485_ClearRX(handle);				
				handle->RX.LastReceivedTime = Board1MSTmr;
				handle->RX.Status = RS485_RX_STATUS_RECEIVING;
				handle->TX.Status = RS485_TX_STATUS_READY;	
				mc0_count[0]++;	
			}
			else
			{
				RS485_ProcessTx(handle->TX.BitBuffer, handle->TX.DataBufferAddr[handle->TX.DataPosition], handle->TX.StopBitCount);
//				RS485_ProcessTx(handle->TX.BitBuffer,temp,1);
				CSL_mcbspWrite(hMcbsp0,CSL_MCBSP_WORDLEN_32,&handle->TX.BitBuffer[handle->TX.BitBufferPosition++]);
			}
		}
		else
		{
			CSL_mcbspWrite(hMcbsp0,CSL_MCBSP_WORDLEN_32,&handle->TX.BitBuffer[handle->TX.BitBufferPosition++]);
		}
	}
	CSL_FINS(hMcbsp0->regs->SPCR,MCBSP_SPCR_RRST,1);
}
//---------------------------------------------------------------------------
void RS485_SetBaudRate(TRS485Handle *handle, int baudRate, char isInternalCLK)
{
	unsigned int clkdv=0;
    

	if (isInternalCLK)
	{
		CSL_FINS(hMcbsp0->regs->SRGR,MCBSP_SRGR_CLKSM,1);
		clkdv = (unsigned int)(((float)CPU_CLK / (float)(baudRate * 32)) + 0.75) - 1;
		CSL_FINS(hMcbsp0->regs->SRGR,MCBSP_SRGR_CLKGDV,clkdv);
	}
	else
	{
		CSL_FINS(hMcbsp0->regs->SRGR,MCBSP_SRGR_CLKSM,0);
		clkdv = (unsigned int)(((float)OSC_CLK / (float)(baudRate * 32)) + 0.75) - 1;
		CSL_FINS(hMcbsp0->regs->SRGR,MCBSP_SRGR_CLKGDV,clkdv);
	}
	mc0_count[2] = clkdv;
}
//---------------------------------------------------------------------------
unsigned short Generate_CRC16(unsigned char *data, int len)
{
	unsigned char bCrcHi = 0xFF;
	unsigned char bCrcLo = 0xFF;
	unsigned short index;
	unsigned char *pData = data;

	int length = len;
	while (length--)
	{
		index = bCrcHi ^ *pData++;
		bCrcHi = bCrcLo ^ abCrcHi[index];
		bCrcLo = abCrcLo[index];
	}
	return (bCrcHi << 8 | bCrcLo);
}
