#include "Common_include.h"

uint8_t g_uiBufIndex = BUF_0;
void InitBuf(void)
{
    g_uiBufIndex = BUF_0;
}

uint8_t bufSend[8];
Multiple_CAN_FRAME MultiplePack;
Core_CAN_FRAME CorePack;
uint8_t RxFinish;
uint8_t MyRecvCount = 0;
uint8_t CAN_0x430 = 0;
uint8_t CAN_0x4F1 = 0;
uint8_t CAN_0x391 = 0;
uint8_t CAN_0x50C = 0;
uint8_t CAN_0x5b0 = 0;
uint8_t CAN_0x52A = 0;
uint8_t CAN_0x225 = 0;
uint8_t CAN_0x486 = 0;
uint8_t CAN_0x4A6 = 0;
uint8_t CAN_0x2FC = 0;
uint8_t CAN_0x478 = 0;

uint8_t CAN_0x51B = 0;
uint8_t CAN_0x5C2 = 0;

uint8_t CAN_0x1AA = 0;
uint8_t CAN_0x180 = 0;

uint8_t CAN_0x1DF = 0;
uint8_t CAN_0x1D4 = 0;
uint8_t CAN_0x1D5 = 0;

uint8_t CAN_0x620 = 0;

uint8_t CAN_0x7F0 = 0;
uint8_t CAN_0x7F1 = 0;
uint8_t CAN_0x7F2 = 0;
uint8_t CAN_0x7F3 = 0;
uint8_t CAN_0x7F4 = 0;
uint8_t CAN_0x7F5 = 0;
uint8_t CAN_0x7F6 = 0;
uint8_t CAN_0x7F7 = 0;
uint8_t CAN_0x7F8 = 0;
uint8_t CAN_0x7F9 = 0;
uint8_t CAN_0x7FA = 0;
uint8_t CAN_0x7FB = 0;
uint8_t CAN_0x7FC = 0;
uint8_t CAN_0x7FD = 0;
uint8_t CAN_0x7FE = 0;
uint8_t CAN_0x7FF = 0;

uint32_t g_CAN_SEND_ID = 0;
uint32_t g_CAN_RECV_ID = 0;

//�жϵ��ú��������ɳ�ʱ����ʱ
uint32_t SendCanMessage20msTimer;
uint32_t SendCanMessage100msTimer;
uint32_t SendCanMessage10msTimer;
uint32_t SendCanMessage50msTimer;
uint32_t SendCanMessage200msTimer;
uint32_t SendCanMessage250msTimer;
uint32_t SendCanMessage500msTimer;
uint32_t SendCanMessage1000msTimer;
uint32_t SendCanMessage2000msTimer;
uint32_t SendCanMessage3000msTimer;

uint8_t UdsLenth = 0;
RECV_CAN_FRAME DmsCanFrame;
RECV_CAN_FRAME g_recvCanFrame;

uint8_t g_uiCommState = 0;
uint8_t g_szSendData[8];
uint8_t g_szRecvData[256+1];
unsigned int  g_uiRecvDataLen;
uint8_t g_szFrameData[8];
uint8_t g_BufferRecv[256+1];
uint8_t g_uiSendLen = 0;
uint16_t g_BufferRecvCnt;
uint8_t g_CommandSendFlag = CMD_IDLE;
#define IS_COMMAD(str) (strcmp(g_UartBuffer_RX,str) == 0)
#define CLEAR_CMD()  (memset(g_UartBuffer_RX,0,sizeof(g_UartBuffer_RX)))

ST_CHECK_RESULT g_stCheckResult;
uint16_t g_uiCheckResultRecordCnt = 0;
uint8_t SendCheckResultData[64];
uint8_t SendCheckResultLen = 0;
uint32_t g_uiRecordAddr = 0;
uint32_t g_uiRecordCnt = 0;
uint32_t g_uiRecordIdx = 0;
uint8_t  g_uiExportFlag = 0;

void SendCanFrame(uint32_t ID, uint8_t *data, uint8_t len)
{
    CanSendCan2Msg(ID, data, len, 1);
}

void CanFrame_DataSend_Begin(void)
{
    g_CAN_SEND_ID = 0x7FB;
    memset(g_szSendData,0,sizeof(g_szSendData));
    memcpy(g_szSendData,"11111111",8);
    SendCanFrame(g_CAN_SEND_ID,  g_szSendData, 8);
}

void CanFrame_DataSend_Proc(void)
{
    g_CAN_SEND_ID = 0x7FD;
    SendCanFrame(g_CAN_SEND_ID,  g_szSendData, 8);//�ⲿ�޸ķ�������
}


void CanFrame_DataSend_End(void)
{
    g_CAN_SEND_ID = 0x7FE;
    memset(g_szSendData,0,sizeof(g_szSendData));
    memcpy(g_szSendData,"22222222",8);
    SendCanFrame(g_CAN_SEND_ID,  g_szSendData, 8);
}

void CanFrame_7F1(char *pData)
{
    g_CAN_SEND_ID = 0x7F1;
    if (pData != NULL) {
        memset(g_szSendData,0,sizeof(g_szSendData));
        memcpy(g_szSendData,pData,strlen(pData));
    }
    SendCanFrame(g_CAN_SEND_ID,  g_szSendData, 8);
}

void CanFrame_7F2(char *pData)
{
    g_CAN_SEND_ID = 0x7F2;
    if (pData != NULL) {
        memset(g_szSendData,0,sizeof(g_szSendData));
        memcpy(g_szSendData,pData,strlen(pData));
    }
    SendCanFrame(g_CAN_SEND_ID,  g_szSendData, 8);
}

void CanFrame_7F3(char *pData)
{
    g_CAN_SEND_ID = 0x7F3;
    if (pData != NULL) {
        memset(g_szSendData,0,sizeof(g_szSendData));
        memcpy(g_szSendData,pData,strlen(pData));
    }
    SendCanFrame(g_CAN_SEND_ID,  g_szSendData, 8);
}

void LedOffAll(void)
{
//    LedCtrl(LED1,STATE_OFF);
//    LedCtrl(LED2,STATE_OFF);
    LedCtrl(LED3,STATE_OFF);
    LedCtrl(LED4,STATE_OFF);
    LedCtrl(LED5,STATE_OFF);
    LedCtrl(LED6,STATE_OFF);
    LedCtrl(LED7,STATE_OFF);
    LedCtrl(LED8,STATE_OFF);
}

void InitStateMachine(uint8_t uiInitType)
{
    if (uiInitType == INIT_SEND) {
        g_uiCommState = SM_SEND_INIT;
        g_CAN_SEND_ID = 0;
    }
    else if (uiInitType == INIT_RECV) {
        g_CAN_RECV_ID = 0;
        CAN_0x7FB = 0;
        CAN_0x7FD = 0;
        CAN_0x7FE = 0;
    }
}

void ExecStateMachine(uint8_t *data, uint8_t len)
{
    g_uiSendLen = 0;
    uint8_t uiSendFlag = 1;
    while (g_uiSendLen <= len && uiSendFlag) {
        bsp_HDOG_Feed();
        LedCtrl(LED1,STATE_OFF);
        switch(g_uiCommState) {
            case SM_SEND_INIT:
                g_uiCommState = SM_SEND_BEGIN;   
                break;
            case SM_SEND_BEGIN:
                Delay(20);
                memset(g_szSendData,0,sizeof(g_szSendData));
                g_szSendData[0] = len;
                CanFrame_DataSend_Begin();
                g_uiCommState = SM_SEND_DATA;
                break;
            case SM_SEND_DATA:
                Delay(20);
                LedCtrl(LED1,STATE_ON);
                if (len - g_uiSendLen >= 8) {
                    memcpy(g_szSendData,data+g_uiSendLen,8);
                    g_uiSendLen += 8;
                } else {
                    memset(g_szSendData,0,sizeof(g_szSendData));
                    memcpy(g_szSendData,data+g_uiSendLen,len - g_uiSendLen);
                    g_uiCommState = SM_SEND_END;
                }
                CanFrame_DataSend_Proc();
                if (g_uiSendLen == len) {
                    g_uiCommState = SM_SEND_END;
                }
                break;
            case SM_SEND_END:
                Delay(20);
                CanFrame_DataSend_End();
                uiSendFlag = 0;
                break;            
        }
        Delay(20);
    }
    LedCtrl(LED1,STATE_OFF);
}

void TxData2PC(uint8_t uiType)
{
#if (ROLE_TYPE_CAN_BOARD)
    if (uiType == 0){
        memset(g_UartBuffer_TX,0,sizeof(g_UartBuffer_TX));
        memcpy(g_UartBuffer_TX, g_szRecvData, g_uiRecvDataLen);
        Mfs_Uart_Write(UART0_Type, g_UartBuffer_TX, sizeof(g_UartBuffer_TX), TRUE);
    }
    else if (uiType == 1) {
        memset(g_UartBuffer_TX,0,sizeof(g_UartBuffer_TX));
        strcpy(g_UartBuffer_TX,"ERROR:����̨ͨѶʧ��");
        Mfs_Uart_Write(UART0_Type, g_UartBuffer_TX, strlen(g_UartBuffer_TX), TRUE);
    }
    else if (uiType == 2) {
        memset(g_UartBuffer_TX,0,sizeof(g_UartBuffer_TX));
        strcpy(g_UartBuffer_TX,"ERROR:���̨�����ݵ���");
        Mfs_Uart_Write(UART0_Type, g_UartBuffer_TX, strlen(g_UartBuffer_TX), TRUE);
    }
    else if (uiType == 3) {
        memset(g_UartBuffer_TX,0,sizeof(g_UartBuffer_TX));
        strcpy(g_UartBuffer_TX,"SUCCESS:���̨���ݵ������");
        Mfs_Uart_Write(UART0_Type, g_UartBuffer_TX, strlen(g_UartBuffer_TX), TRUE);
    }
#endif    
}

void SendCheckResultRecordByIdx(uint32_t uiIdx)
{
#if (ROLE_TYPE_CHECK_BENCH)
    uint32_t tmp = 0;
    if (uiIdx < UsmUserRecordPack.ID) {
        if(g_uiRecordAddr < 0x0E000000u + (WORK_FLASH_SA24 * WORK_FLASH_SECTOR_SIZE)){
            tmp = *(uint32_t*)g_uiRecordAddr;
            if(tmp != 0xffffffff){
                InitStateMachine(INIT_SEND);
                memset(SendCheckResultData,0,sizeof(SendCheckResultData));
                memcpy(SendCheckResultData,(uint8_t*)g_uiRecordAddr,64);
                ExecStateMachine(SendCheckResultData,64);
            }
            g_uiRecordAddr += 64;           
        }
    }
#endif    
}

void SendCan2Message(void)
{
#if (ROLE_TYPE_CAN_BOARD)
    if (g_CAN_RECV_ID == 0x7F2 && g_uiRecordCnt == 0) {
        TxData2PC(2);//���̨�����ݵ���
         g_CAN_RECV_ID = 0;
    }
    else if (CAN_0x7FB == 1 && CAN_0x7FD == 1 && CAN_0x7FE == 1) {
        TxData2PC(0);//�������ݷ��͸���λ��
        InitStateMachine(INIT_RECV);
    }
    else if (CAN_0x7FB == 0 && CAN_0x7FD == 0 && CAN_0x7FE == 0) {
        if (0 == g_uiCommTimer) {
            if (g_CAN_SEND_ID == 0x7F1 && CAN_0x7F2 == 0) {
                TxData2PC(1);//����̨ͨѶʧ��
                g_CAN_SEND_ID = 0;
            }
            if (g_uiExportFlag == 0 && CAN_0x7F2 == 1) {
                TxData2PC(3);//���̨���ݵ������
                CAN_0x7F2 = 0;
            }
            g_uiCommTimer = 1000;
        }
        else if (0 < g_uiCommTimer && g_uiCommTimer < 500) {
            LedCtrl(LED1,STATE_ON);
        }
        else if (500 < g_uiCommTimer && g_uiCommTimer <= 1000) {
            LedCtrl(LED1,STATE_OFF);
        }
    }
#endif
#if (ROLE_TYPE_CHECK_BENCH)
    if (CAN_0x7F3 == 1) {
        CAN_0x7F3 = 0;
        SendCheckResultRecordByIdx(atoi(g_szFrameData));
    }
#endif
}

static uint8_t g_uiRemainLen = 0;
static uint8_t g_uiRecvLen = 0;
void RequestOneRecordData(void)
{
#if (ROLE_TYPE_CAN_BOARD)
    if (g_uiRecordIdx < g_uiRecordCnt) {
        g_uiRemainLen = 0;
        g_uiRecvLen  = 0;
        memset(g_szSendData,0,sizeof(g_szSendData));
        sprintf(g_szSendData,"%u",g_uiRecordIdx++);
        CanFrame_7F3(NULL);
    }
#endif    
}

void DoMessageProc(void)
{
#if (ROLE_TYPE_CAN_BOARD)
    if (IS_COMMAD("CMD:EXPO")) {//CAN����յ���λ����������ָ��
        CLEAR_CMD();
        InitStateMachine(INIT_RECV);
        g_uiRecordCnt = 0;
        g_uiRecordIdx = 0;
        g_uiExportFlag = 1;
        CanFrame_7F1("00000001");//CAN������̨���͵�������ָ��
    }
    if (IS_COMMAD("CMD:ACK")) {//CAN����յ���λ����������ָ��
        CLEAR_CMD();
        if (g_uiRecordIdx < g_uiRecordCnt) {
            InitStateMachine(INIT_RECV);
            RequestOneRecordData();
        } else {
            if (g_uiRecordIdx ==  g_uiRecordCnt) {
                g_uiExportFlag = 0;
            }
        }
    }
    if (g_CAN_RECV_ID == 0x7F2) {
        CAN_0x7F2 = 1;
        g_uiRecordCnt = atoi(g_szFrameData);
        if (g_uiRecordCnt > 0) {
            InitStateMachine(INIT_RECV);
            RequestOneRecordData();
        }
    }

//��֡�����շ���ʼ
    if (g_CAN_RECV_ID == 0x7FB) {//CAN�����̨���յ����ݷ��Ϳ�ʼָ��
        CAN_0x7FB = 1;
        g_uiRemainLen = 0;
        g_uiRecvLen  = 0;
        memset(g_szRecvData,0,sizeof(g_szRecvData));
        g_uiRemainLen = g_szFrameData[0]; 
        g_uiRecvDataLen = g_uiRemainLen;
    }

    if (g_CAN_RECV_ID == 0x7FD) {//CAN�����̨��������
        CAN_0x7FD = 1;
        if (g_uiRemainLen <= 8) {
            memcpy(g_szRecvData+g_uiRecvLen,g_szFrameData,g_uiRemainLen);
            g_uiRecvLen   += g_uiRemainLen;
            g_uiRemainLen -= g_uiRemainLen;
        } else {
            memcpy(g_szRecvData+g_uiRecvLen,g_szFrameData,8);
            g_uiRecvLen   += 8;
            g_uiRemainLen -= 8;
        }
    }

    if (g_CAN_RECV_ID == 0x7FE) {//CAN�����̨���յ����ݷ��ͽ���ָ��
        CAN_0x7FE = 1;
    }
//��֡�����շ�����  
#endif

#if (ROLE_TYPE_CHECK_BENCH)
    if (g_CAN_RECV_ID == 0x7F1) {//���̨���յ�CAN�嵼������ָ��
        g_uiRecordAddr = 0x0E000000u + (WORK_FLASH_SA7 * WORK_FLASH_SECTOR_SIZE);
        memset(g_szSendData,0,sizeof(g_szSendData));
        sprintf(g_szSendData,"%u",UsmUserRecordPack.ID);
        CanFrame_7F2(NULL);
    }
    if (g_CAN_RECV_ID == 0x7F3) {
        CAN_0x7F3 = 1;
    }
#endif    
}

void CheckRecvCan2Frame(stc_canfd_msg_t *stc_msg)//��CAN��ͨ��CAN2 ͨ�Żص�����
{
    RECV_CAN_FRAME data;
    data.ID = stc_msg->stcIdentifier.u32Identifier;
    data.DataLen = stc_msg->stcData.u8DataLengthCode > 0xf ? 0 : CanDlcInCanFDDlc[stc_msg->stcData.u8DataLengthCode];
    memcpy((void*)data.Data, (void*)stc_msg->stcData.au32Data, 64);
    RecvCanFrame(&data);
    memcpy(g_szFrameData,(void*)data.Data,8);
    g_CAN_RECV_ID = data.ID;
    DoMessageProc();
}

void CheckRecvCan0Frame(stc_canfd_msg_t *stc_msg)//C CAN ��Ϣ���ջص�����
{
    RECV_CAN_FRAME data;
    //    if (UdsParameter.CommNormalMessageDisableRx == 0) {
    //recv
    data.ID = stc_msg->stcIdentifier.u32Identifier;
    data.DataLen = stc_msg->stcData.u8DataLengthCode > 0xf ? 0 : CanDlcInCanFDDlc[stc_msg->stcData.u8DataLengthCode];
    memcpy((void*)data.Data, (void*)stc_msg->stcData.au32Data, 64);       //data.DataLen
    RecvCanFrame(&data);
    
#if (CAN_2ND)
    if(data.ID == 0x430)
    {
        CanFrameAnlysisFunc_0x430(data.Data);
        CAN_0x430 = 1;
    }
    if(data.ID == 0x452)
    {
        CanFrameAnlysisFunc_0x452(data.Data);
        
    }
#endif    
#if (CAN_3RD)    
#endif		
	/* UDS */
	if (stc_msg->stcIdentifier.u32Identifier == 0x789) 
	{   
		data.DataLen = CanDlcInCanFDDlc[stc_msg->stcData.u8DataLengthCode];
		Can_Clear((uint8_t*)&Receive_7CE_Data.data,sizeof(Receive_7CE_Data));
		memcpy((void*)Receive_7CE_Data.data, (void*)stc_msg->stcData.au32Data, data.DataLen);//LHY      
		/*20200818Change By FJY*/
		if(RxFinish != FINISH )
		{
			if(data.Data[0] == 0x10)  /*������֡*/
			{
				//memset((void*)MultiplePack.Data, 0, 256);
				memcpy((void*)MultiplePack.Data, (void*)stc_msg->stcData.au32Data, data.DataLen); 
				memcpy((void*)Key27Buffer, (void*)data.Data, data.DataLen);    
				UdsLenth = data.Data[1];
				if(((UdsLenth - 6) % 7) == 0)
				{
					UdsLenth = ((UdsLenth - 6) / 7) | 0x20; 
				}
				else
				{
					UdsLenth = ((((UdsLenth - 6) / 7) + 1)) | 0x20; 
				}
				if(MultiplePack.Data[1] > 6) 
				{
					RxFinish = UNFINISH;
					bufSend[0]= 0x30;
					CanFD_Send_StandMsg(CANFD0_Type, 0x781, BUF_40, TX_ISR_EN, (uint8_t*)&bufSend, 8);
				}
				else
				{
					RxFinish = FINISH;
				}
				if(data.Data[2] == 0x62 && data.Data[3] == 0xF1 && data.Data[4] == 0x95)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
				if(data.Data[2] == 0x62 && data.Data[3] == 0xF1 && data.Data[4] == 0x93)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
				if(data.Data[2] == 0x62 && data.Data[3] == 0xF1 && data.Data[4] == 0x80)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
				if(data.Data[2] == 0x62 && data.Data[3] == 0xF1 && data.Data[4] == 0x87)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
                if(data.Data[2] == 0x62 && data.Data[3] == 0x10 && data.Data[4] == 0x24)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
                if(data.Data[2] == 0x62 && data.Data[3] == 0x50 && data.Data[4] == 0x00)
				{
					memcpy(MultiplePack.Data, data.Data, 8);
					MyRecvCount=8;
				}
                if(data.Data[2] == 0x62 && data.Data[3] == 0x00 && data.Data[4] == 0x07)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
                if(data.Data[2] == 0x62 && data.Data[3] == 0x00 && data.Data[4] == 0x08)
				{
					memcpy(MultiplePack.Data, data.Data + 5, 3);
					MyRecvCount+=3;
				}
			}
            else if((data.Data[0] > 0x20) &&(RxFinish == UNFINISH)) {
				memcpy(MultiplePack.Data+MyRecvCount, data.Data+1, data.DataLen - 1);
				memcpy((void*)&Key27Buffer[8], (void*)data.Data, data.DataLen);   
				MyRecvCount = MyRecvCount + data.DataLen - 1;               
				
				if (UdsLenth == data.Data[0]) {
					RxFinish = FINISH;   
					UdsLenth = 0;
				}
			}
            else {
                if(data.Data[1] == 0x62 && data.Data[2] == 0xFE && data.Data[3] == 0xDC)
				{
                    FuelResTest = data.Data[4];
                    FuelResTest = FuelResTest << 8;
                    FuelResTest |= data.Data[5];
					// memcpy(MultiplePack.Data, data.Data + 5, 3);
					// MyRecvCount+=3;
				}
                if(data.Data[1] == 0x62 && data.Data[2] == 0xF1 && data.Data[3] == 0x8B) 
                {
                        memset(g_CompileDateTime,0,sizeof(g_CompileDateTime));
                        memcpy(g_CompileDateTime, data.Data + 4, 4);
                        RxFinish = FINISH;
                }
                else if(data.Data[1] == 0x62 && data.Data[2] == 0xF1 && data.Data[3] == 0x7F)
                {
                    memcpy(CorePack.Data, data.Data, 8);
                    MyRecvCount+=3;
                    RxFinish = FINISH;
                }
                else if(data.Data[1] == 0x67 && data.Data[2] == 0x03) 
                {
                       RxFinish = FINISH;   
                       memcpy((void*)Key27Buffer, (void*)data.Data, data.DataLen);    
					   UdsLenth = 0;
                }
                else if(data.Data[1] == 0x67 && data.Data[2] == 0x04) 
                {
                       RxFinish = FINISH;   
					   UdsLenth = 0;
                }
                else if(data.Data[1] == 0x67 && data.Data[2] == 0x11) 
                {
                       RxFinish = FINISH;   
					   UdsLenth = 0;
                }
                else if(data.Data[1] == 0x67 && data.Data[2] == 0x12) 
                {
                       RxFinish = FINISH;   
					   UdsLenth = 0;
                }
            }
		}   
	}   
	/* UDS END */    
}


void Can1_Init(void)
{
    StartNM();
    ResetAllCanFrameTime();
}

void CheckRecvCan1Frame(stc_canfd_msg_t *stc_msg)//M CAN ���ջص�����
{
    RECV_CAN_FRAME data;
    //recv
    data.ID = stc_msg->stcIdentifier.u32Identifier;
    data.DataLen = stc_msg->stcData.u8DataLengthCode > 8 ? 8 : stc_msg->stcData.u8DataLengthCode;
    memcpy((void*)data.Data, (void*)stc_msg->stcData.au32Data, data.DataLen);
    RecvCanFrame(&data);
    //recv end
#if (CAN_2ND)	    
	if(data.ID == 0x1DF) //�Ǳ�����M CAN �ⷢ
	{
		CanFrameAnlysisFunc_0x1DF(data.Data);
		CAN_0x1DF = 1;
        if(g_uiUpdateStep == 3) {
            ClusterValidTimerCnts = CLUSTER_CHECK_TIME;
            CheckClusterValid = 1;
        }
        else if(g_uiUpdateStep == 4) {
            ClusterValidTimerCnts = CLUSTER_CHECK_TIME;
            CheckClusterValid = 0;
        }
	}
    
    if (data.ID == 0x1D4) {        
        CanFrameAnlysisFunc_0x1D4(data.Data);
		CAN_0x1D4 = 1;
	}
	if(data.ID == 0x1D5)
	{
		CAN_0x1D5 = 1;
	}
#endif    
#if (CAN_3RD)
    if  (data.ID == 0x620) //�Ǳ�����M CAN �ⷢ
	{
        CAN_0x620 = 1;
        if(g_uiUpdateStep == 3) {
            ClusterValidTimerCnts = CLUSTER_CHECK_TIME;
            CheckClusterValid = 1;
        }
        else if(g_uiUpdateStep == 4) {
            ClusterValidTimerCnts = CLUSTER_CHECK_TIME;
            CheckClusterValid = 0;
        }

    }    
#endif
        
}


