#include "UDS_Common.h"

uint8_t  SessionType = DefaultSession;

uint16_t S3_ServerCnt = S3_SERVER;
uint8_t  S3_ServerClear = 0u;
uint8_t  S3_ServerTimeOut = 1u;

uint8_t  UDSKL15Status = 0u;
uint8_t  UDSSleepStatus = 0u;

uint16_t UDSTimer10ms = 0u;

uint8_t  S31DIDC004RequestStatus = 0u;
uint8_t  S31DIDC005RequestStatus = 0u;
uint8_t  S31DIDC014RequestStatus = 0u;

uint8_t  isDTCOpen = 1u;
uint8_t  isReceive = 1u;
uint8_t  isEnable = 0u;
uint16_t enableTimer = 0u;
uint16_t enableMaxTimer = KL15DTCEnableTimer;

const uint8_t Ser22_DID_F187[13] = {'B', 'Z', '9', '0', '1', '4', '9', '5', '8', '0', '0', '3', '7'};                       /*IC 零件号*/
const uint8_t Ser22_DID_F18A[8] =  {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};                                        /*系统供应商编号*/
const uint8_t Ser22_DID_F18B[4] =  {0x20, 0x20, 0x20, 0x20};                                                                /*IC 生产日期*/
const uint8_t Ser22_DID_F18C[20] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};                                         
                                                                                                            /*IC 系列号*/
const uint8_t Ser22_DID_F190[17] = {'S', 'V', ':', '1', '.', '3', '.', '0', ' ', 'H', 'V', ':', '1', '.', '0', '.', '3'};                  
     	                                                                                                    /*车辆标识号 VIN*/
const uint8_t Ser22_DID_F193[6] =  {'V', '1', '.', '0', '.', '2'};                                          /*IC 硬件版本号*/
const uint8_t Ser22_DID_F195[6] =  {'V', '1', '.', '3', '.', '0'};                                          /*IC 逻辑程序软件版本号*/

DiagMSGUnion DiagMSG;
DiagFlagUnion DiagFlag;
Ser27_FlowCtrlUnion Ser27_FlowCtrl;
Ser27_FlowCtrlCntUnion Ser27_FlowCtrlCnt;
BootToDFlashInfoUnion BootToDFlashInfo;
Ser2EToDFlashInfoUnion Ser2EToDFlashInfo;
DTCToDFlashInfoUnion DTCToDFlashInfo;

/**
  *设置会话类型
  *@param status 会话类型
  */
void setSessionType(uint8_t status)
{
    if ((status == DefaultSession) || (status == ProgrammingSession) || (status == ExtendedDiagnosticSession))
    {
        SessionType = status;
    }
    else
    {
        SessionType = DefaultSession;
    }
}

/**
  *获取会话类型
  *@return 当前会话类型
  */
uint8_t getSessionType(void)
{
    return SessionType;
}

/**
  *设置诊断信息
  *@param Identifier 收到的诊断报文ID
  *@param dlc 收到的诊断报文长度
  *@param Data 收到的诊断报文数据
  */
void setDiagMSG(uint32_t Identifier, uint16_t dlc, uint8_t Data[])
{
    uint16_t i;
    DiagMSG.msgID = Identifier;
    DiagMSG.msgDLC = dlc;
    for (i = 0u; i < dlc; ++i)
    {
        DiagMSG.msgData.Data[i] = Data[i];
    }
}

/**
  *清除诊断信息
  */
void clearDiagMSG(void)
{
    uint16_t i;
    DiagMSG.msgID = 0u;
    DiagMSG.msgDLC = 0u;
    for (i = 0u; i < 500u; ++i)
    {
        DiagMSG.msgData.Data[i] = 0u;
    }
}

/**
  *获取当前车速
  *@return 返回当前车速
  */
uint16_t getSpeed(void)
{
    uint16_t VSpeed = Common_Get_Act_V_Speed();
    if(VSpeed == 0xFFFFu)
    {
        VSpeed = 0u;
    }
    return (VSpeed / 10u);
}

/**
  *获取当前转速
  *@return 返回当前转速
  */
uint16_t getESpeed(void)
{
    uint16_t ESpeed = DrvMtrSpd_Get_ActualValue();//Common_Get_Act_E_Speed();
    if(ESpeed == 0xFFFFu)
    {
        ESpeed = 0u;
    }
    return ESpeed;
}

/**
  *获取当前30电压
  *@return 返回当前30电压
  */
uint32_t getKL30Voltage(void)
{
    uint32_t res;
    res = RTE_Read_KL30_Voltage();
    return res;
}

/**
  *获取15电状态
  *@return 15点状态 0为IGN OFF,1为IGN ON
  */
uint8_t getKL15Status(void)
{
    
    return System_LINE_KL15();
}

/**
  *获取当前安全级别
  *@return 返回当前安全级别
  */
uint8_t getSecurityLevel(uint8_t SecurityLevel)
{
    if(SecurityLevel == requestSeed_LV1){
        return Ser27_FlowCtrl.LV1SafetyStatus;
    }
    return Ser27_FlowCtrl.LV3SafetyStatus;
}

/**
  *重置安全等级
  */
void Ser27_ChangeSessionHandle(void)
{
    Ser27_FlowCtrl.LV1Ctrl = SER27_CLEAR_REQ_SEEDED;
    Ser27_FlowCtrl.LV1Key[0]  = 0x00u;
    Ser27_FlowCtrl.LV1Key[1]  = 0x00u;
    Ser27_FlowCtrl.LV1SafetyStatus = NormalKeyLock;
    Ser27_FlowCtrl.LV1Seed[0] = 0x00u;
    Ser27_FlowCtrl.LV1Seed[1] = 0x00u;
    Ser27_FlowCtrl.LV3Ctrl = SER27_CLEAR_REQ_SEEDED;
    Ser27_FlowCtrl.LV3Key[0]  = 0x00u;
    Ser27_FlowCtrl.LV3Key[1]  = 0x00u;
    Ser27_FlowCtrl.LV3SafetyStatus = NormalKeyLock;
    Ser27_FlowCtrl.LV3Seed[0] = 0x00u;
    Ser27_FlowCtrl.LV3Seed[1] = 0x00u;
}

/**
 *上电/复位 1s不可请求种子 
 */ 
void Ser27_IgOnDelayTimerService(uint16_t timer)
 {
     if(!Ser27_FlowCtrl.AllowRequestSeedFlag){
         Ser27_FlowCtrl.Counter_1000ms += timer;
         if(Ser27_FlowCtrl.Counter_1000ms >= 1000u){
             Ser27_FlowCtrl.AllowRequestSeedFlag = 1u;
             Ser27_FlowCtrl.Counter_1000ms = 0;
         }
     }

 }

 /**
  * 获取是否允许请求种子
  */
uint8_t GetRequestSeedFlag(void)
{
    return Ser27_FlowCtrl.AllowRequestSeedFlag;
}
 

/**
  *复位函数
  */
void UDS_RESET(void)
{
    ControlMessageCommunication(networkManagementMsgAndnormalMsg, disableRxAndTx);
    UDS_Delay(6000u);
    hardware_reset();
}

/**
  *诊断延时
  *@param count 延时次数
  */
void UDS_Delay(uint16_t count)
{
    uint16_t tmpcnt;
    tmpcnt = count;
    WDT_Clear();
    while (tmpcnt--)
    {
        nop();
    }
    WDT_Clear();
}

/**
  *发送诊断11服务正反馈
  */
void UDS_S11_Sand(uint8_t subid)
{
    _CAN_Msg canMag;
    canMag.MsgID = DIAG_ID_Tx;
    canMag.Msg[0] = 0x02u;
    canMag.Msg[1] = 0x51u;
    canMag.Msg[2] = subid;
    canMag.Msg[3] = FILLER_BYTE;
    canMag.Msg[4] = FILLER_BYTE;
    canMag.Msg[5] = FILLER_BYTE;
    canMag.Msg[6] = FILLER_BYTE;
    canMag.Msg[7] = FILLER_BYTE;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 9u;
    canMag.MsgStd = 1u;
    Can_Write(&canMag);
    UDS_S11_Confirm();
}

/**
  *诊断11服务正反馈确认
  */
void UDS_S11_Confirm(void)
{
    UDS_RESET();
}

/**
  *发送诊断78负反馈
  */
void UDS_NRC78_Sand(uint8_t sid)
{
    _CAN_Msg canMag;
    canMag.MsgID = DIAG_ID_Tx;
    canMag.Msg[0] = 0x03u;
    canMag.Msg[1] = 0x7Fu;
    canMag.Msg[2] = sid;
    canMag.Msg[3] = 0x78u;
    canMag.Msg[4] = FILLER_BYTE;
    canMag.Msg[5] = FILLER_BYTE;
    canMag.Msg[6] = FILLER_BYTE;
    canMag.Msg[7] = FILLER_BYTE;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 9u;
    canMag.MsgStd = 1u;
    Can_Write(&canMag);
}

/**
  *发送诊断78负反馈
  */
void UDS_14_SendRsp(uint8_t sid)
{
    _CAN_Msg canMag;
    canMag.MsgID = DIAG_ID_Tx;
    canMag.Msg[0] = 0x01u;
    canMag.Msg[1] = 0x54u;
    canMag.Msg[2] = FILLER_BYTE;
    canMag.Msg[3] = FILLER_BYTE;
    canMag.Msg[4] = FILLER_BYTE;
    canMag.Msg[5] = FILLER_BYTE;
    canMag.Msg[6] = FILLER_BYTE;
    canMag.Msg[7] = FILLER_BYTE;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 9u;
    canMag.MsgStd = 1u;
    Can_Write(&canMag);
}

/**
  *发送负反馈
  */
void UDS_SendNRCRsp(uint8_t sid,uint8_t status)
{
    _CAN_Msg canMag;
    canMag.MsgID = DIAG_ID_Tx;
    canMag.Msg[0] = 0x03u;
    canMag.Msg[1] = 0x7fu;
    canMag.Msg[2] = sid;
    canMag.Msg[3] = status;
    canMag.Msg[4] = FILLER_BYTE;
    canMag.Msg[5] = FILLER_BYTE;
    canMag.Msg[6] = FILLER_BYTE;
    canMag.Msg[7] = FILLER_BYTE;
    canMag.MsgDLC = 8u;
    canMag.MsgPro = 9u;
    canMag.MsgStd = 1u;
    Can_Write(&canMag);
}

/**
  *诊断50us任务
  */
void UDS_50us_Service(void)
{
    //if(UDSSleepStatus == 1u)
    {
        ++UDSTimer10ms;
    }
}

/**
  *诊断10ms任务
  */
void UDS_10ms_Service(void)
{
    uint16_t count;
    if (UDSTimer10ms >= 200u)
    {
        count = UDSTimer10ms / 200u;
        UDSTimer10ms %= 200u;
        enableDTCTimer(count * 10u);
        MsgLostTimer(count * 10u);
        TestDTC(count * 10u);
        S3_Service(count * 10u);
        Ser27_ErrDelayTimerService(count * 10u);
        Ser27_IgOnDelayTimerService(count * 10u);
    }
}

/**
  *诊断KL15init
  */
void UDS_KL15_init(void)
{
    uint8_t KL15Status;
    KL15Status = getKL15Status();
    if(UDSKL15Status == 0u)
    {
        if((KL15Status == 1u))
        {
            UDSKL15Status = 1u;
            UDSSleepStatus = 1u;
            setDTCEnableTimer(KL15DTCEnableTimer);
            S3_ServiceTimeOut();
            DTCAgeing();
        }
    }
    else
    {
        if(KL15Status == 0u)
        {
            UDSKL15Status = 0u;
            setDTCEnableTimer(KL15DTCEnableTimer);
        }
    }
}

void UDS_Slepp(void)
{
    UDSSleepStatus = 0u;
    UDSTimer10ms = 0u;
}

/**
  *报文掉线计时器
  *@param timer 计时器增加的时间，单位：ms
  */
void MsgLostTimer(uint16_t timer)
{
    uint8_t i;
    uint8_t BUS_OFF_Status = getBusoffStatus();
    if((isEnable == 1u) && (isReceive == 1u) && (UDSKL15Status == 1u) && (BUS_OFF_Status == 0u) && (HVoltageStatus == 0u) && (LVoltageStatus == 0u))
    {
        for(i = 0u; i < (sizeof(msgList) / sizeof(msgList[0u])); ++i)
        {
            
            if(msgList[i][3u] < msgList[i][2u] * OfflineLoopMultiple)
            {
                msgList[i][3u] += timer;
            }
            
        }
    }
}

/**
  *收到报文清除计时器
  *@param MsgID 报文ID
  *@param DLC   报文长度
  */
void ReceivedMsg(uint32_t MsgID, uint8_t DLC)
{
    uint8_t i;
    if(isReceive == 1u)
    {
        for(i = 0u; i < (sizeof(msgList) / sizeof(msgList[0u])); ++i)
        {
            if((MsgID == msgList[i][0u]) && (DLC == msgList[i][1u]))
            {
                msgList[i][3u] = 0u;
                break;
            }
        }
    }
}

/**
  *S3服务
  */
void S3_Service(uint16_t timer)
{
    if (S3_ServerClear == 1u)
    {
        S3_ServerClear = 0u;
        S3_ServerCnt = 0u;
        S3_ServerTimeOut = 0u;
    }
    else
    {
        if (S3_ServerCnt < S3_SERVER)
        {
            S3_ServerCnt += timer;
        }
        else
        {
            if (S3_ServerTimeOut == 0u)
            {
                S3_ServerTimeOut = 1u;
                S3_ServiceTimeOut();
            }
        }
    }
}

/**
  *S3重置服务
  */
void S3_ServiceClear(void)
{
    S3_ServerClear = 1u;
}

/**
  *S3等待服务
  */
void S3_ServiceWait(void)
{
    S3_ServerClear = 0u;
    S3_ServerCnt = S3_SERVER;
    S3_ServerTimeOut = 1u;
}

/**
  *S3超时服务
  */
void S3_ServiceTimeOut(void)
{
    /*10服务重置*/
    setSessionType(DefaultSession);
    /*27服务重置*/
    Ser27_ChangeSessionHandle();
    /*28服务重置*/
    ControlMessageCommunication(networkManagementMsgAndnormalMsg, enableRxAndTx);
    /*2F服务重置*/

    /*85服务重置*/
    OpenDTCTest();
    /*诊断发送重置*/
    clearDiagMSG();
}

/**
  *27服务10s延时
  */
void Ser27_ErrDelayTimerService(uint16_t timer)
{
    if ( ( Ser27_FlowCtrl.LV1DelayCtrl == SER27_ERR_DELAY_TIMER_EN ) )
    {
        if (Ser27_FlowCtrl.LV1DelayTimer < 0xfff0u )
        {
            Ser27_FlowCtrl.LV1DelayTimer += timer;
            if (Ser27_FlowCtrl.LV1DelayTimer >= SER27_ERR_DELAY_TIMEOUT)
            {               
                Ser27_FlowCtrlCnt.LV1ReqSeedCnt  = SER27_MAX_REQ_SEED_NUM - 1u;
                Ser27_FlowCtrl.LV1Ctrl = SER27_CLEAR_REQ_SEEDED;
                Ser27_FlowCtrl.LV1DelayTimer = 0u;
                Ser27_FlowCtrl.LV1DelayCtrl = 0u;
                /*调用向DFlash写入函数。*/
                WriteDFlashData(0x02u, (uint32_t *)&Ser27_FlowCtrlCnt.Flag, sizeof(Ser27_FlowCtrlCnt) / 4u, NoNeedWait);
            }
        }
    }
    if ( ( Ser27_FlowCtrl.LV3DelayCtrl == SER27_ERR_DELAY_TIMER_EN ) )
    {
        if (Ser27_FlowCtrl.LV3DelayTimer < 0xfff0u )
        {
            Ser27_FlowCtrl.LV3DelayTimer += timer;
            if (Ser27_FlowCtrl.LV3DelayTimer >= SER27_ERR_DELAY_TIMEOUT)
            {
                Ser27_FlowCtrlCnt.LV3ReqSeedCnt  = SER27_MAX_REQ_SEED_NUM - 1u;
                Ser27_FlowCtrl.LV3Ctrl = SER27_CLEAR_REQ_SEEDED;
                Ser27_FlowCtrl.LV3DelayTimer = 0u;
                Ser27_FlowCtrl.LV3DelayCtrl = 0u;
                /*调用向DFlash写入函数。*/
                WriteDFlashData(0x02u, (uint32_t *)&Ser27_FlowCtrlCnt.Flag, sizeof(Ser27_FlowCtrlCnt) / 4u, NoNeedWait);
            }
        }
    }
}

/**
  *控制报文通信
  *@param Type 控制报文的类型
  *@param Status 控制的标志位
  */
void ControlMessageCommunication(uint8_t Type, uint8_t Status)
{
    if ((uint8_t)(Type & normalMsg) == normalMsg)
    {
        switch (Status)
        {
        case enableRxAndTx:
            RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_ENABLE);
           //RTE_CAN_SetAPP_RX_Mode(CAN_APP_RX_ENABLE);
           isReceive = 1;
        break;
        case enableRxAndDisableTx:
            RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_DISABLE);
           //RTE_CAN_SetAPP_RX_Mode(CAN_APP_RX_ENABLE);
           isReceive = 1;
        break;
        case disableRxAndEnableTx:
            RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_ENABLE);
           //RTE_CAN_SetAPP_RX_Mode(CAN_APP_RX_DISABLE);
           isReceive = 0;
        break;
        case disableRxAndTx:
            RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_DISABLE);
           //RTE_CAN_SetAPP_RX_Mode(CAN_APP_RX_DISABLE);
           isReceive = 0;
        break;      
        default:
        break;
        }
        /*if ((uint8_t)(Status & enableRxAndDisableTx) == enableRxAndTx)
        {
           // RTE_CAN_SetAPP_TX_Status(RTE_CAN_TX_DISABLE);
           // RTE_CAN_SetAPP_RX_Status(RTE_CAN_RX_ENABLE);
           
        }
        else if ((uint8_t)(Status & enableRxAndDisableTx) == enableRxAndTx)
        {     
           // RTE_CAN_SetAPP_TX_Status(RTE_CAN_TX_ENABLE);
           // RTE_CAN_SetAPP_RX_Status(RTE_CAN_RX_ENABLE);
           RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_ENABLE);

        }
        if ((uint8_t)(Status & disableRxAndEnableTx) == disableRxAndEnableTx)
        { 
           // RTE_CAN_SetAPP_TX_Status(RTE_CAN_TX_ENABLE);
           // RTE_CAN_SetAPP_RX_Status(RTE_CAN_RX_DISABLE);
           RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_ENABLE);
            isReceive = 0u;
        }
        else
        {
            isReceive = 1u;
            RTE_CAN_SetAPP_TX_Mode(CAN_APP_TX_DISABLE);
           // RTE_CAN_SetAPP_TX_Status(RTE_CAN_TX_ENABLE);
          //  RTE_CAN_SetAPP_RX_Status(RTE_CAN_RX_ENABLE);
        }*/
    }
    if ((uint8_t)(Type & networkManagementMsg) == networkManagementMsg)
    {
        if ((uint8_t)(Status & enableRxAndDisableTx) == enableRxAndDisableTx)
        {

        }
        else
        {

        }
        if ((uint8_t)(Status & disableRxAndEnableTx) == disableRxAndEnableTx)
        {

        }
        else
        {

        }
    }
}

/**
  *DTC使能定时
  */
void enableDTCTimer(uint16_t Timer)
{
    uint8_t BUS_OFF_Status = getBusoffStatus();
    if((UDSKL15Status == 1u) && (BUS_OFF_Status == 0u) && (HVoltageStatus == 0u) && (LVoltageStatus == 0u))
    {
        if(isEnable == 0u)
        {
            if(enableTimer >= enableMaxTimer)
            {
                isEnable = 1u;
                enableTimer = 0u;
            }
            else
            {
                enableTimer += Timer;
            }
        }
    }
}

/**
  *DTC是否使能
  *@return DTC使能状态 0为未使能,1为使能
  */
uint8_t isDTCEnable(void)
{
    return isEnable;
}

/**
  *设置DTC使能时间
  */
void setDTCEnableTimer(uint16_t Timer)
{
    uint8_t i;
    if(isEnable == 1u)
    {
        isEnable = 0u;
        enableTimer = 0u;
        enableMaxTimer = Timer;
        for(i = 0u; i < (sizeof(msgList) / sizeof(msgList[0u])); ++i)
        {
            msgList[i][3] = 0u;
        }
    }
    else
    {
        if(enableMaxTimer == Timer)
        {
            enableTimer = 0u;
        }
        else
        {
            if(enableMaxTimer < enableTimer + Timer)
            {
                enableMaxTimer = enableTimer + Timer;
            }
        }
    }
}

/**
  *开启DTC检测
  */
void OpenDTCTest(void)
{
    isDTCOpen = 1u;
}

/**
  *关闭DTC检测
  */
void CloseDTCTest(void)
{
    isDTCOpen = 0u;
}

/**
  *DTC是否开启
  *@return DTC状态 0关闭,1开启
  */
uint8_t DTCTestIsOpen(void)
{
    return isDTCOpen;
}

/**
  *DTC老化
  */
void DTCAgeing(void)
{
    uint8_t i;
    for (i = 0u; i < sizeof(DTCToDFlashInfo.DTC) / sizeof(DTCUnion); ++i)
    {
        DTCToDFlashInfo.DTC[i].DTCStatus |= (DTCNoTestThisCycle);
        if ((uint8_t)(DTCToDFlashInfo.DTC[i].DTCStatus & DTCErrorThisCycle) != DTCErrorThisCycle)
        {
            DTCToDFlashInfo.DTC[i].DTCStatus &= (~DTCPending);
            DTCToDFlashInfo.DTC[i].DTCPendingCount = 0u;
            if ((uint8_t)(DTCToDFlashInfo.DTC[i].DTCStatus & DTCConfirmed) == DTCConfirmed)
            {
                DTCToDFlashInfo.DTC[i].DTCAgeing++;
                if (DTCToDFlashInfo.DTC[i].DTCAgeing >= AgeingCount)
                {
                    DTCToDFlashInfo.DTC[i].DTCStatus &= (~DTCConfirmed);
                }
            }
        }
        else
        {
            DTCToDFlashInfo.DTC[i].DTCStatus &= (~DTCErrorThisCycle);
        }
        DTCToDFlashInfo.DTC[i].DTCStatus &= DTCNoError;
    }
}

/**
  *读取所有的诊断信息
  */
void ReadAllDFlashData(void)
{
    ReadDFlashData(EEPROM_BLOCK_UDS_FLAG, (uint32_t *)&DiagFlag.Flag         , sizeof(DiagFlag)          / 4u, AllFlagInit);
    ReadDFlashData(EEPROM_BLOCK_UDS_S27, (uint32_t *)&Ser27_FlowCtrlCnt.Flag, sizeof(Ser27_FlowCtrlCnt) / 4u, Ser27ToDFlashInfoInit);
    ReadDFlashData(EEPROM_BLOCK_UDS_CONFIG, (uint32_t *)&EOL_Data_Type.Flag , sizeof(EOL_Data_Type)  / 4u, EOL_InitVal);
    ReadDFlashData(EEPROM_BLOCK_UDS_S2E, (uint32_t *)&Ser2EToDFlashInfo.Flag, sizeof(Ser2EToDFlashInfo) / 4u, Ser2EToDFlashInfoInit);
    //ReadDFlashData(0x05u, (uint32_t *)&DTCToDFlashInfo.Flag  , sizeof(DTCToDFlashInfo)   / 4u, DTCToDFlashInfoInit);

    if (Ser27_FlowCtrlCnt.LV1ReqSeedCnt >= SER27_MAX_REQ_SEED_NUM )
    {
        Ser27_FlowCtrl.LV1DelayCtrl = SER27_ERR_DELAY_TIMER_EN;
    }
    if (Ser27_FlowCtrlCnt.LV3ReqSeedCnt >= SER27_MAX_REQ_SEED_NUM)
    {
        Ser27_FlowCtrl.LV3DelayCtrl = SER27_ERR_DELAY_TIMER_EN;
    }
    
    DTCConfigurationInit();
    BootReadFlahInit();
}

/**
  *读取信息
  */
uint8_t ReadDFlashData(uint8_t u8BlockNum, uint32_t u32Data[], uint16_t u16Len, InitFunction initFunction)
{
    uint8_t enResult = EEPROM_RW_FAIL;
    enResult = EEPROM_Get_Block_Status(u8BlockNum);
    if (enResult == EEPROM_STAT_BLANK)
    {
        initFunction();
        enResult = WriteDFlashData(u8BlockNum, u32Data, u16Len, NeedWait);
    }
    else if (enResult == EEPROM_STAT_ACTIVE)
    {
        enResult = EEPROM_Read_Data(u8BlockNum, u32Data, u16Len);
        if (enResult == EEPROM_RW_PASS)
        {
            while (EEPROM_Get_Status() == EEPROM_STAT_BUSY)
            {
                WDT_Clear();
            }
            if (u32Data[0] != 0x7AA7A55Au)
            {
                initFunction();
                enResult = WriteDFlashData(u8BlockNum, u32Data, u16Len, NeedWait);
            }
        }
    }
    else
    {
        initFunction();
        enResult = WriteDFlashData(u8BlockNum, u32Data, u16Len, NeedWait);
    }/**/
    return enResult;
}

/**
  *写入信息
  */
uint8_t WriteDFlashData(uint8_t u8BlockNum, uint32_t u32Data[], uint16_t u16Len, uint8_t isWait)
{
    uint8_t enResult = EEPROM_RW_FAIL;
    if (EEPROM_Get_Block_Status (u8BlockNum) != EEPROM_STAT_ERROR)
    {
        while (EEPROM_Get_Status() == EEPROM_STAT_BUSY)
        {
            WDT_Clear();
        }
        enResult = EEPROM_Write_Data(u8BlockNum, u32Data, u16Len);
        if (isWait == 1u)
        {
            while (EEPROM_Get_Status() == EEPROM_STAT_BUSY)
            {
                WDT_Clear();
            }
        }
    }
    /*enResult = EEPROM_Write_Data(u8BlockNum, u32Data, u16Len);*/
    return enResult;
}

/**
  *所有标志位初始化
  */
void AllFlagInit(void)
{
    DiagFlag.Flag = 0x7AA7A55Au;
    DiagFlag.JumpToBootFlag = 0x00000000u;
    DiagFlag.AppValidFlag = 0x00000000u;
    DiagFlag.S11Flag = 0x00000000u;
}

/**
  *27信息初始化
  */
void Ser27ToDFlashInfoInit(void)
{
    Ser27_FlowCtrlCnt.Flag = 0x7AA7A55Au;
    Ser27_FlowCtrlCnt.LV1InvaidKyeCnt = 0u;
    Ser27_FlowCtrlCnt.LV1ReqSeedCnt = 0u;
    Ser27_FlowCtrlCnt.RandNum = 0u;
}

/**
  *boot信息初始化
  */
void BootToDFlashInfoInit(void)
{
    /*
    BootToDFlashInfo.Flag = 0x7AA7A55Au;
    BootToDFlashInfo.DID_0200 = 0u;
    BootToDFlashInfo.DID_0201 = 0u;
    
    memset(BootToDFlashInfo.DID_F180, 0x20, 7u);
    BootToDFlashInfo.DID_F180[0] = '1';
    BootToDFlashInfo.DID_F180[1] = '0';
    BootToDFlashInfo.DID_F180[2] = '3';

    memset(BootToDFlashInfo.DID_F181, 0x20, 7u);
    BootToDFlashInfo.DID_F181[0] = '1';
    BootToDFlashInfo.DID_F181[1] = '0';
    BootToDFlashInfo.DID_F181[2] = '3';
    
    memset(BootToDFlashInfo.DID_F187, 0x20, 10u);
    BootToDFlashInfo.DID_F187[0] = '8';
    BootToDFlashInfo.DID_F187[1] = '8';
    BootToDFlashInfo.DID_F187[2] = '9';
    BootToDFlashInfo.DID_F187[3] = '1';
    BootToDFlashInfo.DID_F187[4] = '1';
    BootToDFlashInfo.DID_F187[5] = '2';
    BootToDFlashInfo.DID_F187[6] = '8';
    BootToDFlashInfo.DID_F187[7] = '9';
    BootToDFlashInfo.DID_F187[8] = '7';
    BootToDFlashInfo.DID_F187[9] = '0';
    
    memset(BootToDFlashInfo.DID_F189, 0x20, 16u);
    BootToDFlashInfo.DID_F189[0] = '0';
    BootToDFlashInfo.DID_F189[1] = '0';
    BootToDFlashInfo.DID_F189[2] = '0';
    BootToDFlashInfo.DID_F189[3] = '7';
    BootToDFlashInfo.DID_F189[4] = '2';
    BootToDFlashInfo.DID_F189[5] = '1';
    BootToDFlashInfo.DID_F189[6] = '1';
    BootToDFlashInfo.DID_F189[7] = 'C';
    BootToDFlashInfo.DID_F189[8] = '4';
    BootToDFlashInfo.DID_F189[9] = '0';
    BootToDFlashInfo.DID_F189[10] = '/';
    BootToDFlashInfo.DID_F189[11] = 'A';
    BootToDFlashInfo.DID_F189[12] = 'A';
    
    memset(BootToDFlashInfo.DID_F193, '0', 16u);
    BootToDFlashInfo.DID_F193[0] = '1';
    BootToDFlashInfo.DID_F193[1] = '0';
    BootToDFlashInfo.DID_F193[2] = '4';
    
    memset(BootToDFlashInfo.DID_F198, 0x20, 16u);

    BootToDFlashInfo.DID_F199[0] = 0x20u;
    BootToDFlashInfo.DID_F199[1] = 0x00u;
    BootToDFlashInfo.DID_F199[2] = 0x01u;
    BootToDFlashInfo.DID_F199[3] = 0x01u;
    */
}

/**
  *2E信息初始化
  */
void Ser2EToDFlashInfoInit(void)
{ Ser2EToDFlashInfo.Flag = 0x7AA7A55Au;
    /*
    uint8_t i;
    _EOL_F101 EOL_F101;
    _EOL_F110 EOL_F110;
   
    
    memset(Ser2EToDFlashInfo.DID_DFEC, 0, 64u);

    memset(Ser2EToDFlashInfo.DID_DFED, 0, 64u);
    
    memset(Ser2EToDFlashInfo.DID_DFEE, 0, 64u);
    
    memset(Ser2EToDFlashInfo.DID_DFEF, 0, 64u);
    
    memset(Ser2EToDFlashInfo.DID_F112, 0x20, 8u);
    Ser2EToDFlashInfo.DID_F112[0] = 'F';
    Ser2EToDFlashInfo.DID_F112[1] = 'E';
    Ser2EToDFlashInfo.DID_F112[2] = '_';
    Ser2EToDFlashInfo.DID_F112[3] = '7';
    Ser2EToDFlashInfo.DID_F112[4] = 'B';
    
    memset(Ser2EToDFlashInfo.DID_F190, 0x20, 17u);

    memset(Ser2EToDFlashInfo.DID_F197, 0x20, 8u);
    Ser2EToDFlashInfo.DID_F197[0] = 'I';
    Ser2EToDFlashInfo.DID_F197[1] = 'P';
    Ser2EToDFlashInfo.DID_F197[2] = 'K';
    
    Ser2EToDFlashInfo.DID_F19D[0] = 0x20u;
    Ser2EToDFlashInfo.DID_F19D[1] = 0x00u;
    Ser2EToDFlashInfo.DID_F19D[2] = 0x01u;
    Ser2EToDFlashInfo.DID_F19D[3] = 0x01u;
    
    EOL_InitVal();
    EOL_F101 = EOL_GetF101();
    EOL_F110 = EOL_GetF110();
    for (i = 0u; i < 16u; ++i)
    {
        Ser2EToDFlashInfo.DID_F101[i] = EOL_F101.F101_Byte[i];
    }
    for (i = 0u; i < 8u; ++i)
    {
        Ser2EToDFlashInfo.DID_F110[i] = EOL_F110.F110_Byte[i];
    }
    memset(Ser2EToDFlashInfo.DID_6208, 0, 3u);
    Ser2EToDFlashInfo.DID_620A[0] = 0u;
    */
}

/**
  *DTC信息初始化
  */
void DTCToDFlashInfoInit(void)
{
    uint8_t i;
    DTCToDFlashInfo.Flag = 0x7AA7A55Au;
    for (i = 0u; i < sizeof(DTCToDFlashInfo.DTC) / sizeof(DTCUnion); ++i)
    {
        DTCToDFlashInfo.DTC[i].DTCStatus = DTCNoTestLastClear | DTCNoTestThisCycle;
        DTCToDFlashInfo.DTC[i].DTCAgeing = 0x00u;
        DTCToDFlashInfo.DTC[i].DTCCount = 0x00u;
        DTCToDFlashInfo.DTC[i].DTCPendingCount = 0x00u;
        /*DTCToDFlashInfo.DTC[i].Snapshot.ECUPowerVoltage = 0x00u;
        DTCToDFlashInfo.DTC[i].Snapshot.VehicleSpeed = 0x0000u;
        DTCToDFlashInfo.DTC[i].Snapshot.OccurrenceCounter = 0x00u;
        DTCToDFlashInfo.DTC[i].Snapshot.FirstMalfunction = 0x00000000u;
        DTCToDFlashInfo.DTC[i].Snapshot.LastMalfunction = 0x00000000u;*/
    }
    for(i = 0u; i < (sizeof(msgList) / sizeof(msgList[0u])); ++i)
    {
        msgList[i][3] = 0u;
    }
    for(i = 0u; i < (sizeof(DTCTimerList) / sizeof(DTCTimerList[0u])); ++i)
    {
        DTCTimerList[i] = 0u;
    }
}

/**
  *DTC信息配置初始化
  */
void DTCConfigurationInit(void)
{
    if(!Val_EOL_605C_LDWS())
    {
        DTCToDFlashInfo.DTC[cnU100706].DTCStatus = DTCNoTestLastClear | DTCNoTestThisCycle;
        DTCToDFlashInfo.DTC[cnU100706].DTCAgeing = 0x00u;
        DTCToDFlashInfo.DTC[cnU100706].DTCCount = 0x00u;
        DTCToDFlashInfo.DTC[cnU100706].DTCPendingCount = 0x00u;
    }
    
    /*    DTCToDFlashInfo.DTC[cnU010087].Snapshot.ECUPowerVoltage = 0x00u;
        DTCToDFlashInfo.DTC[cnU010087].Snapshot.VehicleSpeed = 0x0000u;
        DTCToDFlashInfo.DTC[cnU010087].Snapshot.OccurrenceCounter = 0x00u;
        DTCToDFlashInfo.DTC[cnU010087].Snapshot.FirstMalfunction = 0x00000000u;
        DTCToDFlashInfo.DTC[cnU010087].Snapshot.LastMalfunction = 0x00000000u;*/
}

void BootReadFlahInit(void)
{
    uint8_t i;
    uint8_t WriteFlag = 0;
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F187);i++)
    {
      if(Ser2EToDFlashInfo.DID_F187[i] != Ser22_DID_F187[i])
      {
          Ser2EToDFlashInfo.DID_F187[i] = Ser22_DID_F187[i];
          WriteFlag = 1;
      }
    }
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F18A);i++)
    {
      if(Ser2EToDFlashInfo.DID_F18A[i] != Ser22_DID_F18A[i])
      {
          Ser2EToDFlashInfo.DID_F18A[i] = Ser22_DID_F18A[i];
          WriteFlag = 1;
      }
    }
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F18B);i++)
    {
      if(Ser2EToDFlashInfo.DID_F18B[i] != Ser22_DID_F18B[i])
      {
          Ser2EToDFlashInfo.DID_F18B[i] = Ser22_DID_F18B[i];
          WriteFlag = 1;
      }
    }
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F18C);i++)
    {
      if(Ser2EToDFlashInfo.DID_F18C[i] != Ser22_DID_F18C[i])
      {
          Ser2EToDFlashInfo.DID_F18C[i] = Ser22_DID_F18C[i];
          WriteFlag = 1;
      }
    }
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F193);i++)
    {
      if(Ser2EToDFlashInfo.DID_F193[i] != Ser22_DID_F193[i])
      {
          Ser2EToDFlashInfo.DID_F193[i] = Ser22_DID_F193[i];
          WriteFlag = 1;
      }
    }
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F195);i++)
    {
      if(Ser2EToDFlashInfo.DID_F195[i] != Ser22_DID_F195[i])
      {
          Ser2EToDFlashInfo.DID_F195[i] = Ser22_DID_F195[i];
          WriteFlag = 1;
      }
    }
    for(i = 0;i < sizeof(Ser2EToDFlashInfo.DID_F190);i++)
    {
      if(Ser2EToDFlashInfo.DID_F190[i] != Ser22_DID_F190[i])
      {
          Ser2EToDFlashInfo.DID_F190[i] = Ser22_DID_F190[i];
          WriteFlag = 1;
      }
    }
    if(WriteFlag)
    {
        write2EData(Write2EData);
    }
}
