#include "CAN_User.h"

#include "can.h"
#include "CAN_Communication_Matrix.h"
#include "gpio.h"
#include "uds_includes.h"
#include "U2_uds_includes.h"
#include <string.h>
#include "PowerManagement_user.h"
#include "Data_Gear.h"
#include "Common_Interface.h"

#include "BGLInterface.h"
#include "Fuel.h"
#include "Telltales_user.h"


#include "Services_Mileage_User.h"
#include "U2_app_Service.h"
#include "System_Monitor.h"

#include "Flash_synchronizer.h"

static int16_t SendTempValue = 0;
static RSCAN0BusoffMonitorStruct     RSCAN0Busoff;
uint8_t BusOffEvent;
uint8_t BUS_OFF_FLAG;
uint32_t CanSleepDelayTime = 0;
static uint8_t UDSSendStep = 0;
volatile uint16_t ReqSilentTimer = 0; //  静默计时�?

static uint32_t CurFault[25];
static uint32_t HisFault[25];
static uint8_t CurFaultNum = 0;
static uint8_t HisFaultNum = 0;


uint16_t Get_ReqSilentTimer(void)
{
    return ReqSilentTimer;
}
uint8_t Get_RSCAN0Busoff_Status(void)
{
    return RSCAN0Busoff.Status;
}
void Set_ReqSilentTimer(uint16_t data)
{
    ReqSilentTimer = data;
}
void ReqSilentTimer100mSService(void)
{
    if (ReqSilentTimer > 0)
        ReqSilentTimer--;
}
void Set_CanSleepDelayTime(uint32_t data)
{
    CanSleepDelayTime = data;

}

uint32_t Get_CanSleepDelayTime(void)
{
    return CanSleepDelayTime;

}

void Can_Set_Buff_105(uint8_t CopyData[])
{
    //uint8_t temp8 = 0;
    uint16_t temp16 = 0;

    CopyData[0] = 9;  /* 1  */

    temp16 = Common_Get_Disp_E_Speed();
    
    CopyData[1] = temp16>>8;
    CopyData[2] = temp16&0xff;

    CopyData[3] = 0u; /* 4  */
    CopyData[4] = 0u; /* 5  */
    CopyData[5] = 0u; /* 6  */

    temp16 = Common_Get_Disp_V_Speed();
		if(temp16>1990)		temp16=1990;
    temp16 /= 10;    
    CopyData[6] = temp16>>8;
    CopyData[7] = temp16&0xff;    
}

void Can_Set_Buff_51C(uint8_t CopyData[])
{
    CopyData[0] = 0;  /* 1  */
    CopyData[1] = 0;  /* 2  */
    CopyData[2] = 0;  /* 3  */
    CopyData[3] = 0u; /* 4  */
    CopyData[4] = 0u; /* 5  */

    CopyData[6] = 0u; /* 7  */
    CopyData[7] = 0u; /* 8  */
    //外销状�?�（此信号外发应�?0�?    
    //0 = 内销
    //1 = 外销
    CopyData[5] |= 0;
    
    //仪表类型外发（此信号外发应发1�?
    //0 = 保留
    //1 = LCD
    //2 = TFT
    CopyData[5] |= 1<<1;    
}
extern uint16_t FuelR;
void Can_Set_Buff_510(uint8_t CopyData[])
{
    uint16_t temp16 = 0;
    //    Receive_ID_12_Struct * msg_0x12;
    //    Get_Msg_0x12(&msg_0x12);



    CopyData[0] = 0u; /* 1  */
    // CopyData[1] = 0u; /* 2  */
    // CopyData[2] = 0u; /* 3  */
    // CopyData[3] = 0u; /* 4  */
    // CopyData[4] = 0u; /* 5  */
    CopyData[5] = 0u; /* 6  */
    CopyData[6] = 0u; /* 7  */
    CopyData[7] = 0u; /* 8  */

    if(Get_Fuel_Sensor_State() == FuelSensorShortCircuit){
        CopyData[0] = 0x07;
    }
    else if(Get_Fuel_Sensor_State() == FuelSensorOpenCircuit){
        CopyData[0] = 0x0A;
    }
    else { /*FuelSensorNormal*/
        CopyData[0] = Get_CurFuelSetp();
    }



    temp16 = FuelR/10;
    if(FuelR>3100){
        temp16 = 320;
    }
    CopyData[2] = (temp16>>8)&0xff;
    CopyData[3] = temp16&0xff;



}
void Can_Set_Buff_523(uint8_t CopyData[])
{
    uint32_t temp32;

    CopyData[6] = 0u; /* 7  */
    CopyData[7] = 0u; /* 8  */
    temp32 = Data_Read_Trip(EM_TRIP_A);
    temp32 /= 100;
    CopyData[0] = temp32/10000;
    
    CopyData[1] = (temp32%10000)/1000;
    CopyData[1] <<= 4;
    CopyData[1] |= (temp32%1000)/100;
    
    CopyData[2]  = (temp32%100)/10;
    CopyData[2] <<= 4;
    CopyData[2] |= (temp32%10);    

    temp32 = Data_Read_Trip(EM_TRIP_B);
    temp32 /= 100;
    CopyData[3] = temp32/10000;
    
    CopyData[4] = (temp32%10000)/1000;
    CopyData[4] <<= 4;
    CopyData[4] |= (temp32%1000)/100;
    
    CopyData[5]  = (temp32%100)/10;
    CopyData[5] <<= 4;
    CopyData[5] |= (temp32%10); 
    
}
void Can_Set_Buff_450(uint8_t CopyData[])
{
	uint8_t i = 6;
    uint8_t temp8 = 0;

    CopyData[0] = 0;  /* 1  */
    // CopyData[1] = 0;  /* 2  */
    CopyData[2] = 0u; /* 3  */
    CopyData[3] = 0u; /* 4  */
    CopyData[4] = 0u; /* 5  */
    CopyData[5] = 0u; /* 6  */
    CopyData[6] = 0u; /* 7  */
    CopyData[7] = 0u; /* 8  */


    

    CopyData[1] = temp8 & 0x0f;

}
void Can_Set_Buff_515(uint8_t CopyData[])
{
    uint16_t temp16 = 0;
    uint32_t temp32 = 0;
//    static uint32_t CurFault[25];
//    static uint32_t HisFault[25];
//    static uint8_t CurFaultNum = 0;
//    static uint8_t HisFaultNum = 0;
    static uint8_t FauleSendStep = 0;
    static uint8_t CurFaultSendCount = 0;
    static uint8_t HisFaultSendCount = 0;
    //_BCM_Module bcm_module_temp;

    
    GetAllDtcFault(CurFault, &CurFaultNum, HisFault, &HisFaultNum);
    




    if ((CAN_SIG_LOST == CAN_MSG_Status(ID_ECU_Count)) && (CAN_SIG_LOST == CAN_MSG_Status(ID_ECU_DTC_Count)))
    {
        temp16 = 1;
    }
    else
    {
        temp16 = 0;
    }
    CopyData[0] = temp16 & 0x01;

    CopyData[1] = 0;  /* 2  */
    CopyData[2] = 0u; /* 3  */
    CopyData[3] = 0u; /* 4  */
    

   

    SendTempValue = get_CoolantTempVal();
    if(SendTempValue >= (-40)){
        temp16 = (uint16_t)(SendTempValue + 40);
    }
    else{
        temp16 = 0;
    }
    CopyData[4] = temp16>>8;
    CopyData[5] = temp16&0xff;
    
    //step0:判断是否有故�?
    if(FauleSendStep == 0){
        if(CurFaultNum || HisFaultNum){
            FauleSendStep = 1;
        }
        else{
            temp32 = 0;
            goto SEND_FAULT_END;
        }
    }
    //发�?�当前故�? 
    //step1:发�??7777标志
    if(FauleSendStep == 1){
        if(CurFaultNum){
            temp32 = 0x77770000;
            FauleSendStep = 2;
            CurFaultSendCount = 0;
            goto SEND_FAULT_END;
        }
        else{
            FauleSendStep = 4;
        }
    }
    //step2:连续发�?�故�?
    if(FauleSendStep == 2){
        if(CurFaultSendCount < CurFaultNum){
            temp32 = CurFault[CurFaultSendCount];
            CurFaultSendCount++;
            goto SEND_FAULT_END;
        }
        else{
            FauleSendStep = 3;
        }
    }
    //step3:发�?�结束标�?
    if(FauleSendStep == 3){
        temp32 = 0x99990000;
        if(HisFaultNum){
            FauleSendStep = 4;
        }
        else{
            FauleSendStep = 0;
        }
        goto SEND_FAULT_END;
    }

    //发�?�历史故�?
    //step4:发�??8888标志
    if(FauleSendStep == 4){
        if(HisFaultNum){
            temp32 = 0x88880000;
            FauleSendStep = 5;
            HisFaultSendCount = 0;
            goto SEND_FAULT_END;
        }
        else{
            FauleSendStep = 0;
            temp32 = 0;
            goto SEND_FAULT_END;
        }
    }
    //step5:连续发�?�故�?
    if(FauleSendStep == 5){
        if(HisFaultSendCount < HisFaultNum){
            temp32 = HisFault[HisFaultSendCount];
            HisFaultSendCount++;
            goto SEND_FAULT_END;
        }
        else{
            FauleSendStep = 6;
        }
    }
    //step6:发�?�结束标�?
    if(FauleSendStep == 6){
        temp32 = 0x99990000;
        FauleSendStep = 0;
        goto SEND_FAULT_END;
    }

SEND_FAULT_END:    
    temp32 >>= 16;
    CopyData[6] = temp32>>8;
    CopyData[7] = temp32&0xff;
}
extern uint8_t ModfyODORemainTimes;
void Can_Set_Buff_522(uint8_t CopyData[])
{
    uint32_t temp32 = 0;
    uint16_t temp16 = 0;

     CopyData[4] = 0u; /* 5  */
     CopyData[5] = 0u; /* 6  */

 
     temp32 = Data_ODO_Read( );
     temp32 /= 100;
     
     CopyData[0] = temp32/1000000;
     
     CopyData[1] = (temp32%1000000)/100000;
     CopyData[1] <<= 4;
     CopyData[1] |= (temp32%100000)/10000;
     
     CopyData[2]  = (temp32%10000)/1000;
     CopyData[2] <<= 4;
     CopyData[2] |= (temp32%1000)/100;     

     CopyData[3]  = (temp32%100)/10;
     CopyData[3] <<= 4;
     CopyData[3] |= (temp32%10);     

    CopyData[4] |= ModfyODORemainTimes&0x0f;
     temp16 = Common_Get_Disp_V_Speed();
		 if(temp16>1990)		temp16=1990;
     temp16 /= 10;    
     CopyData[6] = temp16>>8;
     CopyData[7] = temp16&0xff;  

}

void Can_Set_Buff_502(uint8_t CopyData[])
{
	uint8_t temp8 = 0;
	CopyData[1] = 0U;
	CopyData[2] = 0U;
	CopyData[3] = 0U;
	CopyData[4] = 0U;
	CopyData[5] = 0U;
	CopyData[6] = 0U;
	CopyData[7] = 0U;


	CopyData[0] = temp8 << 2;
		


}


void Send_22_ID0005(void)
{
  /*  uint8_t SendUdsData[8];
    SendUdsData[0] = 0x03;
    SendUdsData[1] = 0x22;
    SendUdsData[2] = 0x62;
    SendUdsData[3] = 0x02;
    SendUdsData[4] = 0u;
    SendUdsData[5] = 0u;
    SendUdsData[6] = 0u;
    SendUdsData[7] = 0u;
    g_bReturn = bsp_CANSendFrame(0x767, txResNum, (uint8_t *)&SendUdsData[0], 8);*/
    st_CAN_Msg canMag;
    canMag.MsgID = U2_ID_BCM_PhyAddr;
    canMag.Msg[0] = 0x03u;
    canMag.Msg[1] = 0x22u;
    canMag.Msg[2] = 0x00;
    canMag.Msg[3] = 0x05;
    canMag.Msg[4] = 0;
    canMag.Msg[5] = 0;
    canMag.Msg[6] = 0;
    canMag.Msg[7] = 0;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 9u;
    canMag.MsgStd = 0;
    Can_Write(&canMag);
}

void Send_19_0209(void)
{
    /*uint8_t SendUdsData[8];
    SendUdsData[0] = 0x03;
    SendUdsData[1] = 0x19;
    SendUdsData[2] = 0x02;
    SendUdsData[3] = 0x09;
    SendUdsData[4] = 0u;
    SendUdsData[5] = 0u;
    SendUdsData[6] = 0u;
    SendUdsData[7] = 0u;
    g_bReturn = bsp_CANSendFrame(0x747, txResNum, (uint8_t *)&SendUdsData[0], 8);*/
    st_CAN_Msg canMag;
    canMag.MsgID = U2_ID_BCM_PhyAddr;
    canMag.Msg[0] = 0x03;
    canMag.Msg[1] = 0x19;
    canMag.Msg[2] = 0x02;
    canMag.Msg[3] = 0x21;
    canMag.Msg[4] = 0;
    canMag.Msg[5] = 0;
    canMag.Msg[6] = 0;
    canMag.Msg[7] = 0;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 10u;
    canMag.MsgStd = 0;
    Can_Write(&canMag);
}
void Send_01_01(void)
{
    /*uint8_t SendUdsData[8];
    SendUdsData[0] = 0x02;
    SendUdsData[1] = 0x01;
    SendUdsData[2] = 0x01;
    SendUdsData[3] = 0x00;
    SendUdsData[4] = 0u;
    SendUdsData[5] = 0u;
    SendUdsData[6] = 0u;
    SendUdsData[7] = 0u;
    g_bReturn = bsp_CANSendFrame(0x7DF, txResNum, (uint8_t *)&SendUdsData[0], 8);*/

    st_CAN_Msg canMag;
    canMag.MsgID = 0X7df;
    canMag.Msg[0] = 0x02;
    canMag.Msg[1] = 0x01;
    canMag.Msg[2] = 0x01;
    canMag.Msg[3] = 0;
    canMag.Msg[4] = 0;
    canMag.Msg[5] = 0;
    canMag.Msg[6] = 0;
    canMag.Msg[7] = 0;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 11u;
    canMag.MsgStd = 0;
    Can_Write(&canMag);
}
void CAN_SendAppMesageOpinion(void)
{

    CAN_TX_SetEnable(CAN_APP_TX_ENABLE);
}
uint8_t CanLibSendFlag=0;
uint8_t Can_Write(st_CAN_Msg *Msg)
{
    if (CanSendLock == 0)
    {
        CanSendLock = 1;
        switch (Msg->MsgPro)
        {

        case 2:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 3:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 4:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 5:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 6:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 7:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 8:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 9:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
        case 10:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;
         case 11:
            g_bReturn = bsp_CANSendFrame(Msg->MsgID, txCommon, Msg->Msg, Msg->MsgDLC);
            break;    
        default:
            //CAN_CH0_Data_Request(Msg->MsgID, Msg->MsgStd, Msg->MsgRTR, Msg->MsgDLC, Msg->Msg);
            break;
        }
    }
    else
    {
        return 1;
    }
    CanLibSendFlag = 1;
    return 0;
}
static uint32_t pTXBuff[CAN_TX_MSG_Block * ID_SEND_TOTAL];


static uint32_t pRXBuff[CAN_RX_MSG_Block * ID_TOTAL_MAX];

static _BCM_Module BCM_Module = BCM_UNKNOW;
uint8_t LianDianModuleFlg = 0;
uint8_t DelfuModuleFlg = 0;
void LianDianModuleIn(void)
{
    LianDianModuleFlg = 1;
}
void DelfuModuleIn(void)
{
    DelfuModuleFlg = 1;
}

_BCM_Module Get_Bcm_Module(void)
{
    return BCM_Module;
}
void CAN_Check_Liandian(void)
{
    if(LianDianModuleFlg){
        /*if(CAN_SIG_LOST == CAN_MSG_Status(ID_ECU_Engine_Data_M2_Msg_Count)){
            LianDianModuleFlg = 0;
        }*/
        BCM_Module = BCM_LIANDIAN;
    }
  //  else if(DelfuModuleFlg){
    else{//不检测德尔福识别标志，只要不是联电，就认为是德尔�?
        DelfuModuleFlg = 0;
        BCM_Module = BCM_DELFU;
    }
}
uint8_t CAN_Initflag = 0;
void APP_CAN_Init(void)
{
    /*CAN APP BUFFER INIT*/
    Can_TX_BuffInit((uint8_t *)pTXBuff, st_CANSendAttr, ID_SEND_TOTAL, Can_Write);
    Can_RX_BuffInit((uint8_t *)pRXBuff, CAN_MSG_CONST_ARRAY, ID_TOTAL_MAX);
    CAN_RX_SetEnable(0u);
    CAN_TX_SetEnable(CAN_APP_TX_ENABLE);
    PORT_ClrBit(CAN0_STB);
    BCM_Module = BCM_UNKNOW;
    SendTempValue = 0;
    UDSSendStep = 0;
    CAN_Initflag = 0xeb;
}
void CAN_Init(void)
{
    /*CAN APP BUFFER INIT*/
    Can_TX_BuffInit((uint8_t *)pTXBuff, st_CANSendAttr, ID_SEND_TOTAL, Can_Write);
    Can_RX_BuffInit((uint8_t *)pRXBuff, CAN_MSG_CONST_ARRAY, ID_TOTAL_MAX);
    CAN_RX_SetEnable(0u);
    CAN_TX_SetEnable(CAN_APP_TX_ENABLE);
    PORT_ClrBit(CAN0_STB);
}

void CAN_RX_Tick(void)
{
    CanMSg_XMS_Analysis(5U);
}

void CAN_TX_Tick(void)
{
    Can_Write_Fun(2000UL);
}

void Can_Receive_Msg(uint32_t m_id, uint8_t m_dlc, uint8_t m_Msg[])
{
    // ReceivedMsg(m_id, m_dlc);

    Co_Can_Buff_Set(Co_Can_ConvertSubID(m_id), m_dlc, m_Msg);
}
uint32_t SendUdsTimeCount_190209 = 0;
uint32_t SendUdsTimeCount_220005 = 0;
uint32_t SendUdsTimeCount_0101 = 0;

void SetSendUdsTimeCount_190209(uint32_t data)
{
    SendUdsTimeCount_190209 = data;
}
void SetSendUdsTimeCount_220005(uint32_t data)
{
    SendUdsTimeCount_220005 = data;
}
void SetSendUdsTimeCount_0101(uint32_t data)
{
    SendUdsTimeCount_0101 = data;
}
uint32_t DTCCurFaultTimes = 0;
uint32_t DTCHisFaultTimes = 0;
extern COMMON_PowerStatus_t Common_Get_IG_Sts(void);
void Diag_Req_Send(uint16_t Diag_Time_SendCn) /* Trainmit 2ms */
{
    COMMON_PowerStatus_t Diag_PowerState;
    _BCM_Module Module;

    Module = Get_Bcm_Module();
   // if((Module  == BCM_UNKNOW) || (Module  == BCM_DELFU))
    {
        Diag_PowerState = Common_Get_IG_Sts();
        if (Diag_PowerState == COMMON_POWER_ON)
        {
            if (DTCCurFaultTimes < 0xffffffff)
            {

                DTCCurFaultTimes += Diag_Time_SendCn;
            }
            else
                ;
            if (DTCHisFaultTimes < 0xffffffff)
            {

                DTCHisFaultTimes += Diag_Time_SendCn;
            }
            else
                ;

            if ((CanSendLock == 0) && (DiagnoCtl.CommCtl == 0) && (Get_ReqSilentTimer() == 0))
            {
             //   CanLibSendFlag = 0;

                switch(UDSSendStep){
                    case 0:
                        Send_19_0209();
                        Set_UDS_59_MsgRecFlg(0);
                        UDSSendStep = 1;
                        SendUdsTimeCount_190209 = 0;
                        break;
                    case 1:
                        if(Get_UDS_59_MsgRecFlg() || (SendUdsTimeCount_190209>500)){
                            UDSSendStep = 2;
                        }
                        break;
                    case 2:
                        if((Module  == BCM_UNKNOW) || (Module  == BCM_DELFU)){
                            Send_22_ID0005();
                            Set_UDS_62_MsgRecFlg(0);
                            UDSSendStep = 3;
                            SendUdsTimeCount_220005 = 0;                            
                        }
                        else{
                            UDSSendStep = 4;
                        }

                        break;
                    case 3:
                        if(Get_UDS_62_MsgRecFlg() || (SendUdsTimeCount_220005>500)){
                            UDSSendStep = 4;
                        }
                        break;
                    case 4:
                        if((Module  == BCM_UNKNOW) || (Module  == BCM_DELFU)){
                            Send_01_01();
                            Set_UDS_01_MsgRecFlg(0);
                            UDSSendStep = 5;
                            SendUdsTimeCount_0101 = 0;                            
                        }
                        else{
                            UDSSendStep = 0;
                        }

                        break;
                    case 5:
                        if(Get_UDS_01_MsgRecFlg() || (SendUdsTimeCount_0101>500)){
                            UDSSendStep = 0;
                        }
                        break;
                    default:
                        UDSSendStep = 0;
                        break;
                }
                SendUdsTimeCount_190209 += Diag_Time_SendCn;
                SendUdsTimeCount_220005 += Diag_Time_SendCn;
                SendUdsTimeCount_0101 += Diag_Time_SendCn;
            }
            else
                ;
        }
        else
        {
            DTCCurFaultTimes = 0;
            DTCHisFaultTimes = 0;
        }
    }
}

/* CAN Parameter  */

uint16_t Mil_Signal_Time = 0;
uint8_t Mil_Signal_Connect = 0;

void Reset_Mil_Signal_Time(void)
{
    Mil_Signal_Time = 0;
    Mil_Signal_Connect = 1;
}


void Can_User_Time_Service(uint8_t deltaTime)
{
    uint8_t u8Condition1;
    Mil_Signal_Time += deltaTime;
    if(Mil_Signal_Time > 3000){ //3秒超�?
        Mil_Signal_Connect = 0;
    }

    u8Condition1 = Common_Get_IG_Sts() ;
    if( u8Condition1 == COMMON_POWER_OFF ){
        CAN_TX_SetEnable(CAN_APP_TX_DISABLE);
        if(CanSleepDelayTime > deltaTime){
            CanSleepDelayTime -= deltaTime;
        }
        else{
            if( CanSleepDelayTime > 0 ){
                bsp_tx_msgbuf_abort(txResNum);
								//bsp_tx_msgbuf_abort(U2_txResNum);//20221026  CANH与CANL短路/CANH接地不睡�? 
                bsp_tx_msgbuf_abort(txCommon);
                bsp_CAN_Sleep();
                CanSleepDelayTime = 0;
            }
        }
    }
    else{
			if(DiagnoCtl.CommCtl==1)	//20220922
                CAN_TX_SetEnable(CAN_APP_TX_DISABLE);
			else
				CAN_TX_SetEnable(CAN_APP_TX_ENABLE);
    }
}
uint8_t Get_Mil_Signal_Connect(void)
{
    return Mil_Signal_Connect;
}


void swap32(uint32_t *DwData)
{
    uint8_t *ptmp = (uint8_t *)DwData;
    ptmp[0] ^= ptmp[3];
    ptmp[3] ^= ptmp[0];
    ptmp[0] ^= ptmp[3];

    ptmp[1] ^= ptmp[2];
    ptmp[2] ^= ptmp[1];
    ptmp[1] ^= ptmp[2];
}
void DtcFaultTimeInit(void)
{
    DTCCurFaultTimes = 0;
}
_DTCReturnVal GetDtcFault(void)
{
  #if  1
    static uint32_t DtcCurFault1 = 0;
    static uint32_t DtcCurFault2 = 0;
    static uint8_t CurrentDispPosition = 1;
    _DTCReturnVal DTCReturnFaultVal;
    static uint8_t FaultNumber = 0;



    DTCCurFaultTimes++;
    if(DTCCurFaultTimes >= 9){
        DTCCurFaultTimes = 0;
        DtcCurFault1 = Get_ID_402_ECU_DTCH1();
        DtcCurFault1 <<= 8;
        DtcCurFault1 |= Get_ID_402_ECU_DTCM1();
        DtcCurFault1 <<= 16;

        DtcCurFault2 = Get_ID_402_ECU_DTCH2();
        DtcCurFault2 <<= 8;
        DtcCurFault2 |= Get_ID_402_ECU_DTCM2();
        DtcCurFault2 <<= 16;

        FaultNumber = Get_ID_402_ECU_DTC1Amnt();
    
        if(CurrentDispPosition == 1){
            if((DtcCurFault2) && (FaultNumber > 1)){
                CurrentDispPosition = 2;
            }
        }
        else if(CurrentDispPosition == 2){
            if(DtcCurFault1){
                CurrentDispPosition = 1;
            }
        }
    }



    if((CurrentDispPosition == 1) && FaultNumber){
        DTCReturnFaultVal.StructDtcCurFault = DtcCurFault1;
        DTCReturnFaultVal.StructDtcHisFault = DtcCurFault1;
    }
    else if(CurrentDispPosition == 2){
        DTCReturnFaultVal.StructDtcCurFault = DtcCurFault2;
        DTCReturnFaultVal.StructDtcHisFault = DtcCurFault2;
    }
    else{
        DTCReturnFaultVal.StructDtcCurFault = 0;
        DTCReturnFaultVal.StructDtcHisFault = 0;
    }

    return DTCReturnFaultVal;
  #endif
}
/*
_DTCReturnVal GetDtcFault(void)
{

    uint8_t i = 0;
    uint8_t DtcCurFaultCn = 0;
    uint8_t DtcHisFaultCn = 0;
    uint32_t DtcFaultTmp= 0;
    uint32_t DtcCurFaultGrpup[25] = {0};
    uint32_t DtcHisFaultGrpup[25] = {0};
    _DTCReturnVal DTCReturnFaultVal;
    for (i = 0; i < 25; i++)
    {
        DtcFaultTmp = U2_DiagReciveDTC.SubDTC.StructDTC[i];
        swap32(&DtcFaultTmp);
        if ((DtcFaultTmp & 0x01) == 0x01)
        {
            DtcCurFaultGrpup[DtcCurFaultCn] =DtcFaultTmp;
            DtcCurFaultCn++;
        }
        if ((DtcFaultTmp & 0x20) == 0x20)
        {
            DtcHisFaultGrpup[DtcHisFaultCn] = DtcFaultTmp;
            DtcHisFaultCn++;
        }
    }
    if (DtcCurFaultCn)
    {
        if (DTCCurFaultTimes >= (DtcCurFaultCn * 1000))
        {
            DTCCurFaultTimes = 0;
        }
        else
            ;
    }
    else
    {
        DTCCurFaultTimes = 0;
    }

    if (DtcHisFaultCn)
    {
        if (DTCHisFaultTimes >= (DtcHisFaultCn * 1000))
        {
            DTCHisFaultTimes = 0;
        }
        else
            ;
    }
    else
    {
        DTCHisFaultTimes = 0;
    }
     

    DTCReturnFaultVal.StructDtcCurFault=DtcCurFaultGrpup[DTCCurFaultTimes / 1000];
    DTCReturnFaultVal.StructDtcHisFault= DtcHisFaultGrpup[DTCHisFaultTimes / 1000];
    return DTCReturnFaultVal;
}
*/

void GetAllDtcFault(uint32_t* pCurFault, uint8_t* pCurFaultNum, uint32_t* pHisFault, uint8_t* pHisFaultNum)
{//8.0
    uint8_t  i = 0;
    uint8_t  j = 0;
    uint32_t  NewDTC1 = 0;
    uint32_t  NewDTC2 = 0;
    uint8_t  NewDTCNums = 0;
    uint8_t  OldDTCNums = 0;
    uint8_t  OldDTCNums1 = 0;
    uint32_t  TemDTC = 0;


    /* Current_DTC  */
    NewDTC1 = Get_ID_402_ECU_DTCH1();
    NewDTC1 <<= 8;
    TemDTC = Get_ID_402_ECU_DTCM1();
    NewDTC1 = NewDTC1 + TemDTC;
    NewDTC1 <<= 16;

    NewDTC2 = Get_ID_402_ECU_DTCH2();
    NewDTC2 <<= 8;
    TemDTC = Get_ID_402_ECU_DTCM2();
    NewDTC2 = NewDTC2 + TemDTC;
    NewDTC2 <<= 16;
    NewDTCNums = Get_ID_402_ECU_DTC1Amnt();
    OldDTCNums = * pCurFaultNum;
    if( NewDTCNums > 25 )
    { NewDTCNums = 25; }
    if( OldDTCNums < NewDTCNums )
    {
        /* 比较是否有相同故障码 */
        for( i = 0; i < OldDTCNums; i++ )
        {
            if( pCurFault[ i ] == NewDTC1 )
            { break; }
        }
        for( j = 0; j < OldDTCNums; j++ )
        {
            if( pCurFault[ j ] == NewDTC2 )
            { break; }
        }

        if(( i >= OldDTCNums ) && ( j >= OldDTCNums ))
        {
            pCurFault[ OldDTCNums ] = NewDTC1;
            pCurFault[ OldDTCNums+1 ] = NewDTC2;
            * pCurFaultNum = OldDTCNums + 2 ;
        }
        else if(( i >= OldDTCNums ) && ( j < OldDTCNums ))
        {
            pCurFault[ OldDTCNums ] = NewDTC1;
            * pCurFaultNum = OldDTCNums + 1 ;            
        }
        else if(( i < OldDTCNums ) && ( j >= OldDTCNums ))
        {
            pCurFault[ OldDTCNums ] = NewDTC2;
            * pCurFaultNum = OldDTCNums + 1 ;            
        }
    }
    if( OldDTCNums >= NewDTCNums ) 
    {
        if( NewDTCNums == 0 )
        {
            pCurFault[ NewDTCNums ] = 0;
            * pCurFaultNum = 0 ;            
        }
        else
        {
            /* 比较是否有相同故障码 */
            for( i = ( OldDTCNums - NewDTCNums ) ; i < OldDTCNums; i++ )
            {
                if( pCurFault[ i ] == NewDTC1 )
                { break; }
            }
            for( j = ( OldDTCNums - NewDTCNums ) ; j < OldDTCNums; j++ )
            {
                if( pCurFault[ j ] == NewDTC2 )
                { break; }
            }


            if(( i < OldDTCNums ) && (j < OldDTCNums))
            {
                /* 有相同报文,只移位 */
                for( i = 0; i < NewDTCNums; i++ )
                {
                    pCurFault[ i ] = pCurFault[ OldDTCNums - NewDTCNums + i ];
                }            
            }
            else if(( i < OldDTCNums ) && (j >= OldDTCNums))
            {
                /* 有相同报文,只移位 */
                for( i = 0; i < NewDTCNums; i++ )
                {
                    pCurFault[ i ] = pCurFault[ OldDTCNums - NewDTCNums + i + 1 ];
                }            
                pCurFault[ NewDTCNums - 1 ] = NewDTC2;
                * pCurFaultNum = NewDTCNums ;
            }
            else if(( i >= OldDTCNums ) && (j < OldDTCNums))
            {
                /* 有相同报文,只移位 */
                for( i = 0; i < NewDTCNums; i++ )
                {
                    pCurFault[ i ] = pCurFault[ OldDTCNums - NewDTCNums + i + 1 ];
                }            
                pCurFault[ NewDTCNums - 1 ] = NewDTC1;
                * pCurFaultNum = NewDTCNums ;
            }
            else if(( i >= OldDTCNums ) && (j >= OldDTCNums))
            {
                /* 没有相同报文,移位并保存新值 */
                for( i = 0; i < ( NewDTCNums - 2 ) ; i++ )
                {
                    pCurFault[ i ] = pCurFault[ OldDTCNums - NewDTCNums + i + 2 ];
                } 
                pCurFault[ NewDTCNums - 2 ] = NewDTC1;
                pCurFault[ NewDTCNums - 1 ] = NewDTC2;
                * pCurFaultNum = NewDTCNums ;
            }
        }
    }

}


/*
void GetAllDtcFault(uint32_t* pCurFault, uint8_t* pCurFaultNum, uint32_t* pHisFault, uint8_t* pHisFaultNum)
{

    uint8_t i = 0;
    uint8_t DtcCurFaultCn = 0;
    uint8_t DtcHisFaultCn = 0;
    uint32_t DtcFaultTmp= 0;
    
    
    for (i = 0; i < 25; i++)
    {
        DtcFaultTmp = U2_DiagReciveDTC.SubDTC.StructDTC[i];
        swap32(&DtcFaultTmp);
        if ((DtcFaultTmp & 0x01) == 0x01)
        {
            pCurFault[DtcCurFaultCn] =DtcFaultTmp;
            DtcCurFaultCn++;
        }
        if ((DtcFaultTmp & 0x20) == 0x20)
        {
            pHisFault[DtcHisFaultCn] = DtcFaultTmp;
            DtcHisFaultCn++;
        }
    }
    *pCurFaultNum = DtcCurFaultCn;
    *pHisFaultNum = DtcHisFaultCn;
}
*/

uint32_t OldDtcAmnt = 0;
uint8_t Dtctotal = 0;
uint8_t DtcCleanflag = 0;

void SetDtcFault(void)
{
    uint32_t DtcFaultTmp1 = 0;
    uint32_t DtcFaultTmp2 = 0;
	uint32_t DtcFaultTmp3 = 0;
    uint32_t DtcFaultTmp4 = 0;
	uint32_t DtcFaultTmp5 = 0;
    uint32_t DtcFaultTmp6 = 0;
	
    uint32_t DtcAmnt = 0;
    uint8_t samejump = 0;

	//DtcFaultTmp1 = Get_ID_402_ECU_DTC1();
    //DtcFaultTmp2 = Get_ID_402_ECU_DTC2();

    DtcFaultTmp1 = Get_ID_402_ECU_DTCH1();
    DtcFaultTmp2 = Get_ID_402_ECU_DTCM1();
    DtcFaultTmp3 = Get_ID_402_ECU_DTCL1();
    DtcFaultTmp4 = Get_ID_402_ECU_DTCH2();
    DtcFaultTmp5 = Get_ID_402_ECU_DTCM2();
    DtcFaultTmp6 = Get_ID_402_ECU_DTCL2();

    DtcAmnt = Get_ID_402_ECU_DTC1Amnt();

    if (OldDtcAmnt != DtcAmnt)
    {
        DtcCleanflag++;
        if (DtcCleanflag > 20)
        {
            DtcCleanflag = 0;

            OldDtcAmnt = DtcAmnt;
            Dtctotal = 0;
            (void)memset((uint8_t *)&U2_DiagReciveDTC.UnionDTC, 0, sizeof(_U2_DiagReciveDTC));
        }
    }
    else
    {
        DtcCleanflag = 0;
    }

    if (Dtctotal < OldDtcAmnt)
    {
        samejump = 0;
        for (uint8_t j = 0; j < DtcAmnt; j++)
        {
            if ((DtcFaultTmp1 == U2_DiagReciveDTC.SubDTC.StructDTC[j]) || (DtcFaultTmp1 == 0))
            {
                samejump = 1;
                break;
            }
        }

        if (samejump == 0)
        {
            U2_DiagReciveDTC.SubDTC.StructDTC[Dtctotal] = DtcFaultTmp1;
            Dtctotal++;
        }

        samejump = 0;
        for (uint8_t j = 0; j < DtcAmnt; j++)
        {
            if ((DtcFaultTmp2 == U2_DiagReciveDTC.SubDTC.StructDTC[j]) || (DtcFaultTmp2 == 0))
            {
                samejump = 1;
                break;
            }
        }

        if (samejump == 0)
        {
            U2_DiagReciveDTC.SubDTC.StructDTC[Dtctotal] = DtcFaultTmp2;
            Dtctotal++;
        }
/******************************2023_12_05************************************
        samejump = 0;
        for (uint8_t j = 0; j < DtcAmnt; j++)
        {
            if ((DtcFaultTmp3 == U2_DiagReciveDTC.SubDTC.StructDTC[j]) || (DtcFaultTmp3 == 0))
            {
                samejump = 1;
                break;
            }
        }

        if (samejump == 0)
        {
            U2_DiagReciveDTC.SubDTC.StructDTC[Dtctotal] = DtcFaultTmp3;
            Dtctotal++;
        }

        samejump = 0;
        for (uint8_t j = 0; j < DtcAmnt; j++)
        {
            if ((DtcFaultTmp4 == U2_DiagReciveDTC.SubDTC.StructDTC[j]) || (DtcFaultTmp4 == 0))
            {
                samejump = 1;
                break;
            }
        }

        if (samejump == 0)
        {
            U2_DiagReciveDTC.SubDTC.StructDTC[Dtctotal] = DtcFaultTmp4;
            Dtctotal++;
        }

        samejump = 0;
        for (uint8_t j = 0; j < DtcAmnt; j++)
        {
            if ((DtcFaultTmp5 == U2_DiagReciveDTC.SubDTC.StructDTC[j]) || (DtcFaultTmp5 == 0))
            {
                samejump = 1;
                break;
            }
        }

        if (samejump == 0)
        {
            U2_DiagReciveDTC.SubDTC.StructDTC[Dtctotal] = DtcFaultTmp5;
            Dtctotal++;
        }

        samejump = 0;
        for (uint8_t j = 0; j < DtcAmnt; j++)
        {
            if ((DtcFaultTmp6 == U2_DiagReciveDTC.SubDTC.StructDTC[j]) || (DtcFaultTmp6 == 0))
            {
                samejump = 1;
                break;
            }
        }

        if (samejump == 0)
        {
            U2_DiagReciveDTC.SubDTC.StructDTC[Dtctotal] = DtcFaultTmp6;
            Dtctotal++;
        }
*********************************************************************************************/
    }
}
void DtcFaultInit(void)
{
    OldDtcAmnt = 0;
    Dtctotal = 0;
    DtcCleanflag = 0;
}

uint32_t GetDtcDispNum(uint8_t DispNum)
{
    return CurFault[DispNum];
}

uint8_t GetDtcAmnt(void)
{
    return CurFaultNum;
}

// uint32_t GetDtcDispNum(uint8_t DispNum)
// {
//     return U2_DiagReciveDTC.SubDTC.StructDTC[DispNum];
// }

// uint8_t GetDtcAmnt(void)
// {
//     return OldDtcAmnt;
// }


void Can_BusOffRecover(void)
{
    BusOffEvent = 0u;
    RSCAN0Busoff.Cnt = 0u;
    RSCAN0Busoff.ReportDTCCnt = 0u;
    RSCAN0Busoff.Status = 0u;
    RSCAN0Busoff.Timer = 0u;
}


// must set in 10ms task;
void Can_BusOff_Fun(uint8_t deltaTime)
{
    if (Get_CH0_BusOffStatus() != 0u)
    {
        bsp_tx_msgbuf_abort(txResNum);
        CanSendLock = 0;
        BusOffEvent = 1U;
        if (RSCAN0Busoff.ReportDTCCnt < 100u)
        {
            RSCAN0Busoff.ReportDTCCnt++;
        }
        else
        {
            BUS_OFF_FLAG = 1U;
        }
        if (RSCAN0Busoff.Status == RSCAN0_BUS_STABLE)
        {
            RSCAN0Busoff.Status = RSCAN0_BUS_OFF_LV1;
        }

        if (RSCAN0Busoff.Status == RSCAN0_BUS_OFF_LV1)
        {
            RSCAN0Busoff.Timer++;
            if (RSCAN0Busoff.Timer >= RSCAN0_BUS_OFF_LV1_RECOVERY_TIME / deltaTime)
            {
                RSCAN0Busoff.Timer = 0U;

                RSCAN0Busoff.Cnt++;
                if (RSCAN0Busoff.Cnt >= 10U)
                {

                    RSCAN0Busoff.Cnt = 0U;

                    RSCAN0Busoff.Status = RSCAN0_BUS_OFF_LV2;
                }
                bsp_CAN_BusOff_Recover();
            }
        }
        else if (RSCAN0Busoff.Status == RSCAN0_BUS_OFF_LV2)
        {
            RSCAN0Busoff.Timer++;

            if (RSCAN0Busoff.Timer >= RSCAN0_BUS_OFF_LV2_RECOVERY_TIME / deltaTime)
            {
                RSCAN0Busoff.Timer = 0U;
                bsp_CAN_BusOff_Recover();

            }
        }
        else
        {

        }
    }
    else                                          /* 总线正常,没有Bus-off发生*/
    {
        Can_BusOffRecover();
    }
}



/**
  *获取busoff状�??
  *@return busoff状�?? 0正常,1异常
  */
uint8_t getBUS_OFF_Status(void)
{
    return BusOffEvent;
}


uint32_t tempclk = 0;
uint32_t tempclk1 = 0;
uint8_t TCS_WorkModeFlsh = 0;

uint16_t Get_TCS_WorkModeFlash(void)
{
   
    
    return TCS_WorkModeFlsh;
}

void Set_TCS_WorkModeFlsh(uint16_t Time)
{
    TCS_WorkModeFlsh = Time;
}

void Set_TCS_WorkModeFlshTime(uint16_t Time)
{
    tempclk = Time;
}

uint8_t get_ECU_Battery_Voltage(void)
{
    uint16_t tmp;
    tmp = Get_ID_401_Sig_ECU_Battery_Voltage();
    if (tmp > 255)
    {
        tmp = 255;
    }
    return tmp;
}

uint8_t ECU_Battery_VoltageFlag = 0;
uint8_t Get_LED_ECU_Battery_VoltageFlag(void)
{
    return ECU_Battery_VoltageFlag;
}
void SET_LED_ECU_Battery_VoltageFlag(uint8_t Flag)
{
    ECU_Battery_VoltageFlag = Flag;
}

void CAN_LED_Check_50msTask(void)
{
    if (SYS_OPR_STAT_IGN_ON)
    {
        //TCS
        if (Get_TCS_WorkModeFlash() == 1)
        {
            if (Get_ID_125_Sig_TCS_WorkMode() != 1)
            {
                tempclk++;
            }
            else
            {
                tempclk = 0;
            }
            
            if (tempclk >= 120 )
            {
                tempclk = 0;
                Set_TCS_WorkModeFlsh(0);
            }
        }

        //Battery_Voltage
        if ((get_ECU_Battery_Voltage() <= 123) && (CAN_SIG_NORMAL == CAN_MSG_Status(ID_ECU_Battery_Count)))
        {
            if (tempclk1 < 200)
            {
                tempclk1++;
            }
        }
        else if(get_ECU_Battery_Voltage() >= 126)
        {
            tempclk1 = 0;
        }

        if (tempclk1 >= 100)
        {
            SET_LED_ECU_Battery_VoltageFlag(1);
        }
        else
        {
            SET_LED_ECU_Battery_VoltageFlag(0);
        }
    }
    else
    {
        tempclk = 0;
        tempclk1 = 0;
        Set_TCS_WorkModeFlsh(0);
        SET_LED_ECU_Battery_VoltageFlag(0);
    }
}

int16_t get_CoolantTempVal(void)
{
    int16_t tmp = 0;
    /*_BCM_Module bcm_module_temp;

    bcm_module_temp = Get_Bcm_Module();
    if(bcm_module_temp == BCM_DELFU){
        tmp = U2_DiagReciveGaugePara.CoolantTemp[0];
        tmp -= 40;
    }
    else if(bcm_module_temp == BCM_LIANDIAN){
        tmp = get_ECU_Temperature_WaterVal();
    }
    else{
        tmp = 0;
    }*/
    tmp = get_ECU_Temperature_WaterVal();

    return (int16_t)tmp;
}

int16_t Sig_ECU_Temperature_Water;
int16_t get_ECU_Temperature_WaterVal(void)
{
    int16_t tmp;
    tmp = Get_ID_101_ECU_Engine_Temperature();
    tmp /= 10; /* 0.1*/
    Sig_ECU_Temperature_Water = tmp - 273;

    return Sig_ECU_Temperature_Water;
}

int16_t get_ID_ISG_BATT(void)
{
    int16_t tmp;

    tmp = Get_ID_113_Tbatt();
    if (tmp >= 50)
    {
        tmp = tmp - 50;
    }
    else
    {
        tmp = 0;
    }

    return tmp;
}

int16_t get_ID_ISG_Power(void)
{
    int16_t tmp;
    tmp = Get_ID_111_ISG_Power_Enable();
    if (tmp > 2)
    {
        tmp = 2;
    }
    return tmp;
}

// 蓄电池电压显示
static uint16_t BatteryClearnflag = 0u;
static uint16_t Oldget_ECU_Battery_Voltage = 0u;
int8_t get_Delay_ECU_Battery_Voltage(void)
{
    static int16_t tmp = 0;
    uint16_t Get_ECU_Battery_Voltage = 0u;

    Get_ECU_Battery_Voltage = get_ECU_Battery_Voltage();

    if ((CAN_MSG_Status(ID_ECU_Battery_Count) == CAN_SIG_NORMAL))
    {
        if (Oldget_ECU_Battery_Voltage != Get_ECU_Battery_Voltage)
        {
            BatteryClearnflag++;
            if (BatteryClearnflag > 20)
            {
                Oldget_ECU_Battery_Voltage = Get_ECU_Battery_Voltage;
                BatteryClearnflag = 0;
                tmp = get_ECU_Battery_Voltage();
            }
        }
        else
        {
            BatteryClearnflag = 0;
            tmp = get_ECU_Battery_Voltage();
        }
    }
    else
    {
        BatteryClearnflag = 20;
        tmp = get_ECU_Battery_Voltage();
    }
    
    return tmp;
}

void BatteryVoltageDelayInit(void)
{
    BatteryClearnflag = 20;
    Oldget_ECU_Battery_Voltage = 0xFFFF;
}


/* Test */
uint16_t CANTest[30];
uint32_t CANDTC[2];
_DTCReturnVal DTCShowFaultVal;
void Test(void)
{
//
//    CANTest[0] = get_CoolantTempVal();
//    CANTest[1] = get_MilLampState();
//    CANTest[2] = get_ECU_Fuel_ConsumptionVal();
//
//    CANTest[3] = get_ECU_Eng_TansVal();
//
//    CANTest[4] = get_ECU_Dash_Drive_Mode_AckVal();
//
//    CANTest[5] = get_ECU_VBatteryVal();
//
//    CANTest[6] = get_ECU_Side_Stand_PositionVal();
//
//    CANTest[7] = get_240_MILLampSts();
//
//    CANTest[8] = get_ECU_Temperature_Water_MalfVal();
//
//    CANTest[9] = get_ECU_Eng_Tans_MalfVal();
//
//    CANTest[10] = get_ECU_Eng_Rpm_Signal_FailureVal();
//
//    CANTest[11] = get_ECU_Eng_Rpm_120Val();
//
//    CANTest[12] = get_ECU_Temperature_WaterVal();
//
//
//    CANTest[13] = Get_ID_55D_Sig_TBOX_GearboxMode();
//
//    CANTest[14] = Get_ID_55D_Sig_TBOX_Maintain();
//
//    CANTest[15] = Get_ID_55C_Sig_TBOX_ThemeMode();
//
//    CANTest[16] = Get_ID_55C_Sig_TBOX_Theme();
//
//    CANTest[17] = Get_ID_55C_Sig_TBOX_ClearTrip();
//
//    CANTest[18] = Get_ID_125_TCS_WarningLamp();
//    CANTest[19] = Get_ID_125_TCS_WorkMode();
//
//    DTCShowFaultVal = GetDtcFault();

   
}
