/*********************************************************************************
**										                                        **
** Name			:   CAN.c                                                       **
**										                                        **
** Description	:								                                **
**										                                        **
**                 								                                **
** Organization	:                                           			        **
**										                                        **
** Revision		:   1.00 						                                **
**********************************************************************************
** Revision History								                                **
**  Rev      Date         By                  	Reason for Change		        **
**------------------------------------------------------------------------------**
**  1.00    22/11/2024    Mohan       						                    **
**										                                        **
*********************************************************************************/


/*********************************************************************************
**                     I N C L U D E  F I L E S
*********************************************************************************/
#include 	"CAN.h"
#include    "Define.h"
#include    "Bootloader.h"
/*********************************************************************************
**                          F U N C T I O N S
*********************************************************************************/

/*********************************************************************************
**   I N T E R N A L   M A C R O   A N D   T Y P E   D E F I N I T I O N S
*********************************************************************************/

/*********************************************************************************
**      I N T E R N A L   F U N C T I O N   P R O T O T Y P E S
*********************************************************************************/
void VCAN_IRQHandler(void);
void ECAN_IRQHandler(void);
/*********************************************************************************
**                   		V A R I A B L E S
**********************************************************************************/
    uint8_t				    gUI8_Buffer[300];
volatile uint16_t			gUI16_Timeout=600;
volatile uint16_t 			gUI16_Index=0;
volatile uint16_t			gU16_MessageLength=9;
extern uint8_t				gUI8_SM_CAN_MODULE;
extern uint32_t				gUI32_RequestMessageID;
extern uint32_t				gUI32_ResponseMessageID;
extern uint8_t				gUI8_SM_CAN_Identifier_Type;
        uint8_t				gUI8_Can_RX_Data[2]={0xFF,0xFF};
extern  uint16_t			gU16_MaxRxSize;   
        uint16_t 			gUI16_RxBufferSize=0;
/*********************************************************************************
** Name			:	SM_VCAN_Init										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void SM_VCAN_Init(void)
{
    SYSCFG_DL_VCAN_init();
}
/*********************************************************************************
** Name			:	SM_BCAN_Init										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void SM_ECAN_Init(void)
{ 
    SYSCFG_DL_ECAN_init();
}
/*********************************************************************************
** Name			:	SM_VCAN_Start										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void SM_VCAN_Start(void)
{
    /* Initialize interrupts in NVIC */
    NVIC_ClearPendingIRQ(VCAN_INST_INT_IRQN);        
    DL_Interrupt_registerInterrupt(
        ((uint32_t) VCAN_INST_INT_IRQN), VCAN_IRQHandler);
    NVIC_EnableIRQ(VCAN_INST_INT_IRQN);   

}
/*********************************************************************************
** Name			:	SM_BCAN_Start										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void SM_ECAN_Start(void)
{
    /* Initialize interrupts in NVIC */
    NVIC_ClearPendingIRQ(ECAN_INST_INT_IRQN);        
    DL_Interrupt_registerInterrupt(
        ((uint32_t) ECAN_INST_INT_IRQN), ECAN_IRQHandler);
    NVIC_EnableIRQ(ECAN_INST_INT_IRQN);
}
/*********************************************************************************
** Name			:	SM_VCAN_Stop										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void SM_VCAN_Stop(void)
{
    /*  unregister interrupt */
    DL_Interrupt_unregisterInterrupt(
        ((uint32_t) VCAN_INST_INT_IRQN));
    /*  Reset the MCAN */
    DL_MCAN_reset(VCAN_INST);
    /*  Disable interrupt */
    NVIC_DisableIRQ(VCAN_INST_INT_IRQN);
}
/*********************************************************************************
** Name			:	ReframeMessage										    **
** Description	:																**
** Inputs		:	id : CAN Identifier										    **
** Outputs		:																**
** Returns		:	id : Masked CAN ID											**
Note: There are no remote frames in CAN FD format. In case a CAN
FD frame was received (FDF = 1), RTR bit reflects the state of the
reserved r1 bit (RES[23]). 
In CAN FD frames (FDF=1), the dominant RRS (Remote Request Substitution) bit replaces 
the RTR (Remote Transmission Request) bit.28:0 ID[28:0]Identifier Standard or extended 
identifier depending on XTD bit.
A standard identifier is stored into ID[28:18]
*********************************************************************************/
static void ReframeMessage(DL_MCAN_RxBufElement  *lstr_CAN_RxMsg)
{
    if(lstr_CAN_RxMsg->xtd == 0)
    {
        lstr_CAN_RxMsg->id = ((lstr_CAN_RxMsg->id >> 18) & (uint32_t)0x7FF);
    }
    else 
    {
        /*Nothing*/
    }
}
/*********************************************************************************
** Name			:	SM_BCAN_Stop										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void SM_ECAN_Stop(void)
{
    /*  Disable and Unregister the interrupt */
    DL_Interrupt_unregisterInterrupt((uint32_t) ECAN_INST_INT_IRQN);
    /*  Reset the MCAN */
    DL_MCAN_reset(ECAN_INST);
    NVIC_DisableIRQ(ECAN_INST_INT_IRQN);
}
/*********************************************************************************
** Name			:	SM_VCAN_Send										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
uint8_t Send_VCAN_Data(const uint8_t lUI8_CANIDtype,const uint32_t lUI32_MessageId,const uint8_t lUI8_DLC,const uint8_t *laUI8_Data)
{
    uint32_t lUI32_DelayusTimeout = 0;
    uint8_t lUI8_DataIndex = 0;     

    DL_MCAN_TxBufElement lstr_TxMsg;
    DL_MCAN_TxFIFOStatus  lstr_TxfifoStatus;
    if(0x00==lUI8_CANIDtype)
    {
        lstr_TxMsg.id=((uint32_t)(lUI32_MessageId<<18));  
    }
    else 
    {
        lstr_TxMsg.id = lUI32_MessageId;    
    }  
    lstr_TxMsg.xtd = lUI8_CANIDtype;

    /* Transmit data frame. */
    lstr_TxMsg.rtr = 0U;
    /* ESI bit in CAN FD format depends only on error passive flag. */
    lstr_TxMsg.esi = 0U;
    /* data length */
    lstr_TxMsg.dlc = lUI8_DLC;
    /* CAN FD frames transmitted without bit rate switching */
    lstr_TxMsg.brs = 0U;
    /* Frame transmitted in Classic CAN format */
    lstr_TxMsg.fdf = 0U;
    /* Store Tx events. */
    lstr_TxMsg.efc = 0U;
    /* Message Marker. */
    lstr_TxMsg.mm = 0x00U;

    /* Data bytes. */
    for(lUI8_DataIndex = 0; lUI8_DataIndex < lUI8_DLC; lUI8_DataIndex++)
    {
        lstr_TxMsg.data[lUI8_DataIndex] = laUI8_Data[lUI8_DataIndex];
    }

    /* Write Tx Message to the Message RAM (FIFO). */
    DL_MCAN_writeMsgRam(VCAN_INST, DL_MCAN_MEM_TYPE_FIFO, 0, &lstr_TxMsg);
 
    /* Get put index and other TxFIFO details in txfifoStatus*/
    DL_MCAN_getTxFIFOQueStatus(VCAN_INST, &lstr_TxfifoStatus);
 
    /* Enable Transmission interrupt.*/
    //DL_MCAN_TXBufTransIntrEnable(VCAN_INST, txfifoStatus.putIdx, 1U);
 
    /* Add request for transmission. */
    DL_MCAN_TXBufAddReq(VCAN_INST, lstr_TxfifoStatus.putIdx);

    /*if fifo gets full wait for next transmission
      Based on 32MHZ 100us delay is added to wait*/
    while((1 == lstr_TxfifoStatus.fifoFull) && (lUI32_DelayusTimeout++ > 3200));

    return 0;
}
/*********************************************************************************
** Name			:	SM_BCAN_Send										        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
uint8_t Send_ECAN_Data(const uint8_t lUI8_CANIDtype,const uint32_t lUI32_MessageId,const uint8_t lUI8_DLC,const uint8_t *laUI8_Data)
{
    uint32_t lUI32_DelayusTimeout = 0;
    uint8_t lUI8_DataIndex = 0;     
    uint8_t lUI8_Status = 1;  
    int8_t  lIN8_TxStatus = -1;

    DL_MCAN_TxBufElement lstr_TxMsg;
    DL_MCAN_TxFIFOStatus  lstr_TxfifoStatus;

    if(0x00==lUI8_CANIDtype)
    {
        lstr_TxMsg.id=((uint32_t)(lUI32_MessageId<<18));  
    }
    else 
    {
        lstr_TxMsg.id = lUI32_MessageId;    
    }
    
    lstr_TxMsg.xtd = lUI8_CANIDtype;

    /* Transmit data frame. */
    lstr_TxMsg.rtr = 0U;
    /* ESI bit in CAN FD format depends only on error passive flag. */
    lstr_TxMsg.esi = 0U;
    /* data length */
    lstr_TxMsg.dlc = lUI8_DLC;
    /* CAN FD frames transmitted without bit rate switching */
    lstr_TxMsg.brs = 0U;
    /* Frame transmitted in Classic CAN format */
    lstr_TxMsg.fdf = 0U;
    /* Store Tx events. */
    lstr_TxMsg.efc = 0U;
    /* Message Marker. */
    lstr_TxMsg.mm = 0x00U;

    /* Data bytes. */
    for(lUI8_DataIndex = 0; lUI8_DataIndex < lUI8_DLC; lUI8_DataIndex++)
    {
        lstr_TxMsg.data[lUI8_DataIndex] = laUI8_Data[lUI8_DataIndex];
    }
    /* Write Tx Message to the Message RAM (FIFO). */
    DL_MCAN_writeMsgRam(ECAN_INST, DL_MCAN_MEM_TYPE_FIFO, 0, &lstr_TxMsg);
 
    /* Get put index and other TxFIFO details in txfifoStatus*/
    DL_MCAN_getTxFIFOQueStatus(ECAN_INST, &lstr_TxfifoStatus);
 
    /* Enable Transmission interrupt.*/
    //DL_MCAN_TXBufTransIntrEnable(VCAN_INST, txfifoStatus.putIdx, 1U);
 
    /* Add request for transmission. */
    lIN8_TxStatus=DL_MCAN_TXBufAddReq(ECAN_INST, lstr_TxfifoStatus.putIdx);

    /*if fifo gets full wait for next transmission
      Based on 32MHZ 100us delay is added to wait*/
    while((1 == lstr_TxfifoStatus.fifoFull) && (lUI32_DelayusTimeout++ > 3200));

    if(lIN8_TxStatus == 0)
    {
        lUI8_Status = 0;
    }
    else 
    {
        lUI8_Status = 1;
    }

    return lUI8_Status;
}
/*********************************************************************************
** Name			:	VCAN_IRQHandler     								        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void VCAN_IRQHandler(void)
{
    DL_MCAN_RxFIFOStatus lstr_VCAN_RxMsgFifoStatus;
    DL_MCAN_RxBufElement lstr_VCAN_RxMsg;
    volatile uint32_t   lUI32_InterruptLine1Status = 0;
    switch (DL_MCAN_getPendingInterrupt(VCAN_INST)) 
    {
        case DL_MCAN_IIDX_LINE1:
            /* Check MCAN interrupts fired during TX/RX of CAN package */
            lUI32_InterruptLine1Status = DL_MCAN_getIntrStatus(VCAN_INST);
            DL_MCAN_clearIntrStatus(VCAN_INST, lUI32_InterruptLine1Status,
                DL_MCAN_INTR_SRC_MCAN_LINE_1);


            if ((lUI32_InterruptLine1Status & MCAN_IR_RF0N_MASK) == MCAN_IR_RF0N_MASK) 
            {
                lstr_VCAN_RxMsgFifoStatus.num = DL_MCAN_RX_FIFO_NUM_0;
                DL_MCAN_getRxFIFOStatus(VCAN_INST, &lstr_VCAN_RxMsgFifoStatus); 
                DL_MCAN_readMsgRam(VCAN_INST, DL_MCAN_MEM_TYPE_FIFO, 0U, lstr_VCAN_RxMsgFifoStatus.num, &lstr_VCAN_RxMsg);
                DL_MCAN_writeRxFIFOAck(VCAN_INST, lstr_VCAN_RxMsgFifoStatus.num, lstr_VCAN_RxMsgFifoStatus.getIdx); 
                ReframeMessage(&lstr_VCAN_RxMsg);
                if(lstr_VCAN_RxMsg.id==gUI32_RequestMessageID)
                {
                    
                    if(gUI8_Can_RX_Data[0]==0xFF || gUI8_Can_RX_Data[0]==SM_VCAN)
                    {
                        gUI8_Can_RX_Data[0]=SM_VCAN;	
                        if(gUI32_RequestMessageID<0x7FF)
                        {
                            gUI8_SM_CAN_Identifier_Type=0;
                        }
                        else
                        {
                            gUI8_SM_CAN_Identifier_Type=1;
                        }
                        gUI8_SM_CAN_MODULE=SM_VCAN;
                        ReceiveData((uint16_t *)lstr_VCAN_RxMsg.data,lstr_VCAN_RxMsg.dlc);
                    }
                    else
                    {
                        /*Mothing*/
                    }
                        
                }
                else
                {
                    /*Nothing*/
                }
            }            
            break;
        default:
            break;
    }
}
/*********************************************************************************
** Name			:	ECAN_INST_IRQHandler								        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void ECAN_IRQHandler(void)
{ 
    DL_MCAN_RxFIFOStatus lstr_ECAN_RxMsgFifoStatus;
    DL_MCAN_RxBufElement lstr_ECAN_RxMsg;
    volatile uint32_t   lUI32_InterruptLine0Status = 0;
    switch (DL_MCAN_getPendingInterrupt(ECAN_INST)) 
    {
        case DL_MCAN_IIDX_LINE0:
            /* Check MCAN interrupts fired during TX/RX of CAN package */
            lUI32_InterruptLine0Status = DL_MCAN_getIntrStatus(ECAN_INST);
            DL_MCAN_clearIntrStatus(ECAN_INST, lUI32_InterruptLine0Status,
                DL_MCAN_INTR_SRC_MCAN_LINE_0);

            if ((lUI32_InterruptLine0Status & MCAN_IR_RF1N_MASK) == MCAN_IR_RF1N_MASK) 
            {
                lstr_ECAN_RxMsgFifoStatus.num = DL_MCAN_RX_FIFO_NUM_1;
                DL_MCAN_getRxFIFOStatus(ECAN_INST, &lstr_ECAN_RxMsgFifoStatus); 
                DL_MCAN_readMsgRam(ECAN_INST, DL_MCAN_MEM_TYPE_FIFO, 0U, lstr_ECAN_RxMsgFifoStatus.num, &lstr_ECAN_RxMsg);
                DL_MCAN_writeRxFIFOAck(ECAN_INST, lstr_ECAN_RxMsgFifoStatus.num, lstr_ECAN_RxMsgFifoStatus.getIdx);
                ReframeMessage(&lstr_ECAN_RxMsg);
                switch(lstr_ECAN_RxMsg.id)
                {
                    case SM_ECAN_DIAGNOSTIC_REQUEST:
                        if(gUI8_Can_RX_Data[0]==0xFF || gUI8_Can_RX_Data[0]==SM_ECAN)
                        {
                            gUI8_Can_RX_Data[0]=SM_ECAN;
                            gUI8_SM_CAN_MODULE=SM_ECAN;					
                            ReceiveData((uint16_t *)lstr_ECAN_RxMsg.data,lstr_ECAN_RxMsg.dlc);	
                        }
                        else
                        {
                            /*Mothing*/
                        }					
                        break;
                }               
            }            
            break;
        default:
            break;
    }
}



/*********************************************************************************
** Name			:	CAN_Reset_Handler     								        **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void CAN_Reset_Handler(void)
{
    uint16_t        lUI16_Timeout=0;
    DL_MCAN_ProtocolStatus  lstr_VcanProtocolStatus;
    DL_MCAN_ProtocolStatus  lstr_EcanProtocolStatus;

    uint32_t lUI32_InterruptLine0Status = 0;
    uint32_t lUI32_InterruptLine1Status = 0;
 
      /* Get protocol  status for VCAN module*/
    DL_MCAN_getProtocolStatus(VCAN_INST,&lstr_VcanProtocolStatus);

     /*Check for the error passive or the bus-off status of  VCAN*/
    if(lstr_VcanProtocolStatus.act == 0)
   // if(lstr_VcanProtocolStatus.act == 0 || lstr_VcanProtocolStatus.busOffStatus == 1)
    {
        if(DL_MCAN_OPERATION_MODE_SW_INIT == DL_MCAN_getOpMode(VCAN_INST))
        {
        DL_MCAN_setOpMode(VCAN_INST, DL_MCAN_OPERATION_MODE_NORMAL);
        while (DL_MCAN_OPERATION_MODE_NORMAL != DL_MCAN_getOpMode(VCAN_INST) && (lUI16_Timeout++<6400));
        lUI32_InterruptLine1Status = DL_MCAN_getIntrStatus(VCAN_INST);
        DL_MCAN_clearIntrStatus(VCAN_INST, lUI32_InterruptLine1Status,DL_MCAN_INTR_SRC_MCAN_LINE_1);
        }
        else 
        {
        /*Nothing*/
        }
       
    }
    else 
    {
    /*Nothing*/
    }


    /* Get protocol  status for MCAN module*/
    DL_MCAN_getProtocolStatus(ECAN_INST,&lstr_EcanProtocolStatus);
    /*Check for the error passive or the bus-off status of  ECAN*/
    if(lstr_EcanProtocolStatus.act == 0)
    //if(lstr_EcanProtocolStatus.act == 0 || lstr_EcanProtocolStatus.busOffStatus == 1)
    {     
        lUI16_Timeout=0;  
        if(DL_MCAN_OPERATION_MODE_SW_INIT == DL_MCAN_getOpMode(ECAN_INST))
        {
        DL_MCAN_setOpMode(ECAN_INST, DL_MCAN_OPERATION_MODE_NORMAL);
        while (DL_MCAN_OPERATION_MODE_NORMAL != DL_MCAN_getOpMode(ECAN_INST) && (lUI16_Timeout++<6400));
        lUI32_InterruptLine0Status = DL_MCAN_getIntrStatus(ECAN_INST);
        DL_MCAN_clearIntrStatus(ECAN_INST, lUI32_InterruptLine0Status,DL_MCAN_INTR_SRC_MCAN_LINE_0);
        }
        else
        {
        /*Nothing*/
        }
    }
    else 
    {
        /*Nothing*/
    }


}


/******************************************************************************
* Function Name : ReceiveData
* Description   : This function is INTRCANGRECC interrupt processing. (Table Reference)
* Argument      : none
* Return Value  : none
******************************************************************************/
void ReceiveData(uint16_t *laUI8_Data,uint8_t lUI8_DLC)
{
	gUI16_Timeout=DATA_TIMEOUT;			
	/*added to handle commandlength define within 5secs, if it is not issued sequential manner*/
	if(gUI16_RxBufferSize==0x00)
	{
		switch(laUI8_Data[0])
		{
			case BOOT_ENTRY:/*Boot Entry*/
				gU16_MaxRxSize=8;
				break;
			case READ_BOOT_VERSION:/*Read Boot Version*/	
				gU16_MaxRxSize=9;
				break;
			case ERASE_FLASH:/*Erase flash*/
				gU16_MaxRxSize=9;
				break;
			case PROGRAM_FLASH:/*Write flash*/
                /*Get the Data Length from the Command*/
				gU16_MaxRxSize= SM_COMMAND_DATA_LENGTH+ (laUI8_Data[2]<<8|laUI8_Data[1]);			
				break;	
			case VERIFY_FLASH:/*Verify flash CRC*/
				gU16_MaxRxSize=13;			
				break;	
			case JUMP_TO_APP:/*Reset Device*/
				gU16_MaxRxSize=9;
				break;
			default:
				/*Nothing*/
				break;
		}	
	}
	else
	{
		/*Nothing*/
	}
	/*********************************************************************/
	switch(lUI8_DLC)
	{
		case 1:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			break;
		case 2:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];   
			break;
		case 3:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];  
			gUI8_Buffer[gUI16_RxBufferSize+2] = laUI8_Data[2];  
			break;
		case 4:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];  
			gUI8_Buffer[gUI16_RxBufferSize+2] = laUI8_Data[2]; 
			gUI8_Buffer[gUI16_RxBufferSize+3] = laUI8_Data[3];     
			break;
		case 5:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];  
			gUI8_Buffer[gUI16_RxBufferSize+2] = laUI8_Data[2]; 
			gUI8_Buffer[gUI16_RxBufferSize+3] = laUI8_Data[3];     
			gUI8_Buffer[gUI16_RxBufferSize+4] = laUI8_Data[4];  
			break;
		case 6:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];  
			gUI8_Buffer[gUI16_RxBufferSize+2] = laUI8_Data[2]; 
			gUI8_Buffer[gUI16_RxBufferSize+3] = laUI8_Data[3];     
			gUI8_Buffer[gUI16_RxBufferSize+4] = laUI8_Data[4];    
			gUI8_Buffer[gUI16_RxBufferSize+5] = laUI8_Data[5]; 
			break;
		case 7:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];  
			gUI8_Buffer[gUI16_RxBufferSize+2] = laUI8_Data[2]; 
			gUI8_Buffer[gUI16_RxBufferSize+3] = laUI8_Data[3];     
			gUI8_Buffer[gUI16_RxBufferSize+4] = laUI8_Data[4];    
			gUI8_Buffer[gUI16_RxBufferSize+5] = laUI8_Data[5];
			gUI8_Buffer[gUI16_RxBufferSize+6] = laUI8_Data[6]; 
			break;
		default:
			gUI8_Buffer[gUI16_RxBufferSize+0] = laUI8_Data[0];
			gUI8_Buffer[gUI16_RxBufferSize+1] = laUI8_Data[1];  
			gUI8_Buffer[gUI16_RxBufferSize+2] = laUI8_Data[2]; 
			gUI8_Buffer[gUI16_RxBufferSize+3] = laUI8_Data[3];     
			gUI8_Buffer[gUI16_RxBufferSize+4] = laUI8_Data[4];    
			gUI8_Buffer[gUI16_RxBufferSize+5] = laUI8_Data[5];
			gUI8_Buffer[gUI16_RxBufferSize+6] = laUI8_Data[6];
			gUI8_Buffer[gUI16_RxBufferSize+7] = laUI8_Data[7];
			break;
	}
	gUI16_RxBufferSize=gUI16_RxBufferSize+lUI8_DLC;
	if(gUI16_RxBufferSize>=gU16_MaxRxSize)
	{
		/*Process Bootloader*/	
		SM_Bootloader_Process(gUI8_Buffer,gU16_MaxRxSize);		
		gUI16_RxBufferSize=0;
	}
	else
	{
		/*Nothing*/
	}
}

/*********************************************************************************
** Name			:	ReceiveDataTimeOut  					                    **
** Description	:																**
** Inputs		:	None														**
** Outputs		:																**
** Returns		:	None														**
*********************************************************************************/
void ReceiveDataTimeOut(void)
{
	if(gUI16_Timeout)
	{
		gUI16_Timeout=gUI16_Timeout-1;
	}
	else
	{
		gUI16_Index=0;
		gU16_MessageLength=9;
		gUI8_Can_RX_Data[0]=0xFF;
		gUI8_Can_RX_Data[1]=0xFF;
        gUI16_RxBufferSize=0;
	}
}