

uint8_t isNeedSaveDTC = 0u;
uint8_t HVoltageStatus = 0u;
uint8_t LVoltageStatus = 0u;
uint8_t KEYStatus = 0u;

/**
  *DTC列表
  */
const uint32_t DTCList[19][2] =
{
    {U10A187, 1u},
    {U108087, 1u},
    {U108387, 1u},
    {U108A87, 1u},
    {U108287, 1u},
    {U108987, 0u},
    {U108B87, 0u},
    {U108487, 1u},
    {U108587, 1u},
    {U108687, 1u},
    {U108787, 1u},
    {U108887, 1u},
    {U109287, 1u},
    {B110516, 1u},
    {B110617, 1u},
    {B110762, 1u},
    {B110880, 1u},
    {B110915, 1u},
    {B110A15, 1u},
};

/**
  *DTC状态
  */
uint8_t DTCUpdataStatusList[19] = {0u};

/**
  *DTC发生时间
  */
uint16_t DTCTimerList[19] = {0u};

/**
  *msg列表
  */
uint16_t msgList[12][4] =
{
    {0x288u, 8u,   40u, 0u},
    {0x330u, 8u,  100u, 0u},
    {0x2E0u, 8u,  100u, 0u},
    {0x501u, 8u, 1000u, 0u},
    {0x35Eu, 8u,  100u, 0u},
    {0x2D9u, 8u,  100u, 0u},
    {0x32Au, 8u,  100u, 0u},
    {0x262u, 8u,   40u, 0u},
    {0x258u, 8u,   40u, 0u},
    {0x268u, 8u,   50u, 0u},
    {0x326u, 8u,  100u, 0u},
    {0x347u, 8u,  500u, 0u},
    /*{0x217u, 8u,  100u, 0u},
    {0x257u, 8u,  100u, 0u},
    {0x65Fu, 8u,  500u, 0u},*/


};

/**
  *测试DTC
  *@param timer 计时器增加的时间，单位：ms
  */
void TestDTC(uint16_t timer)
{
    TestDTC_B110762(timer);                                                 /*点火信号异常*/
    if(getKL15Status())
    {
        if(!getEngStatus())
        {
            TestDTC_B110516(timer);                                         /*检测控制模块输入电压低*/
            TestDTC_B110617(timer);                                         /*检测控制模块输入电压高*/
            if(!getPowerStatus())
            {
                TestDTC_U10A187();                                          /*检测can总线关闭*/
                TestDTC_B110880();                                          /*方向盘按键卡住*/
                TestDTC_B110915(timer);                                     /*燃油输入信号无效(低于正常值)*/
                TestDTC_B110A15(timer);                                     /*燃油输入信号无效(高于正常值)*/
                if(!getBusoffStatus())
                {
                    if(isDTCEnable())
                    {
                        TestDTC_U108087();                                  /*BCM节点丢失*/
                        TestDTC_U108387();                                  /*AC节点丢失*/
                        TestDTC_U108A87();                                  /*RRS节点丢失*/
                        TestDTC_U108287();                                  /*HU节点丢失*/
                        TestDTC_U108987();                                  /*自适应巡航控制器节点丢失*/
                        TestDTC_U108B87();                                  /*车道辅助系统节点丢失*/
                        TestDTC_U108487();                                  /*与网关通讯丢失*/
                        TestDTC_U108587();                                  /*与车身控制模块通讯丢失*/
                        TestDTC_U108687();                                  /*与驻车制动系统通讯丢失*/
                        TestDTC_U108787();                                  /*与自动变速箱控制单元系统通讯丢失*/
                        TestDTC_U108887();                                  /*与发动机管理系统通讯丢失*/
                        TestDTC_U109287();                                  /*与轮胎压力监视系统通讯丢失*/
                    }
                }
            }
            if(isNeedSaveDTC)
            {
                SaveDTCData();
                isNeedSaveDTC = 0u;
            }
        }
    }
}

/**
  *检测can总线关闭
  */
void TestDTC_U10A187(void)
{

}

/**
  *检测控制模块输入电压低
  *@param timer 计时器增加的时间，单位：ms
  */
void TestDTC_B110516(uint16_t timer)
{

}

/**
  *检测控制模块输入电压高
  *@param timer 计时器增加的时间，单位：ms
  */
void TestDTC_B110617(uint16_t timer)
{

}

/**
  *BCM节点丢失
  */
void TestDTC_U108087(void)
{
    if(DTCList[cnU108087][1u])
    {
        if(getMSGStatus(cnMSG288))
        {
            ChangeDTCData(cnU108087, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108087, DTCNoError);
        }
    }
}

/**
  *AC节点丢失
  */
void TestDTC_U108387(void)
{
    if(DTCList[cnU108387][1u])
    {
        if(getMSGStatus(cnMSG330))
        {
            ChangeDTCData(cnU108387, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108387, DTCNoError);
        }
    }
}

/**
  *RRS节点丢失
  */
void TestDTC_U108A87(void)
{
    if(DTCList[cnU108A87][1u])
    {
        if(getMSGStatus(cnMSG2E0))
        {
            ChangeDTCData(cnU108A87, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108A87, DTCNoError);
        }
    }
}

/**
  *HU节点丢失
  */
void TestDTC_U108287(void)
{
    if(DTCList[cnU108287][1u])
    {
        if(getMSGStatus(cnMSG501))
        {
            ChangeDTCData(cnU108287, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108287, DTCNoError);
        }
    }
}

/**
  *自适应巡航控制器节点丢失
  */
void TestDTC_U108987(void)
{
    if(DTCList[cnU108987][1u])
    {
        if(getMSGStatus(cnMSG35E))
        {
            ChangeDTCData(cnU108987, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108987, DTCNoError);
        }
    }
}

/**
  *车道辅助系统节点丢失
  */
void TestDTC_U108B87(void)
{
    if(DTCList[cnU108B87][1u])
    {
        if(getMSGStatus(cnMSG2D9))
        {
            ChangeDTCData(cnU108B87, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108B87, DTCNoError);
        }
    }
}

/**
  *与网关通讯丢失
  */
void TestDTC_U108487(void)
{
    if(DTCList[cnU108487][1u])
    {
        if(getMSGStatus(cnMSG32A))
        {
            ChangeDTCData(cnU108487, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108487, DTCNoError);
        }
    }
}

/**
  *与车身控制模块通讯丢失
  */
void TestDTC_U108587(void)
{
    if(DTCList[cnU108587][1u])
    {
        if(getMSGStatus(cnMSG262))
        {
            ChangeDTCData(cnU108587, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108587, DTCNoError);
        }
    }
}

/**
  *与无钥匙进入系统通讯丢失
  */
void TestDTC_U108687(void)
{
    if(DTCList[cnU108687][1u])
    {
        if(getMSGStatus(cnMSG258))
        {
            ChangeDTCData(cnU108687, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108687, DTCNoError);
        }
    }
}

/**
  *与自动变速箱控制单元系统通讯丢失
  */
void TestDTC_U108787(void)
{
    if(DTCList[cnU108787][1u])
    {
        if(getMSGStatus(cnMSG268))
        {
            ChangeDTCData(cnU108787, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108787, DTCNoError);
        }
    }
}

/**
  *与发动机管理系统通讯丢失
  */
void TestDTC_U108887(void)
{
    if(DTCList[cnU108887][1u])
    {
        if(getMSGStatus(cnMSG326))
        {
            ChangeDTCData(cnU108887, DTCError);
        }
        else
        {
            ChangeDTCData(cnU108887, DTCNoError);
        }
    }
}

/**
  *与轮胎压力监视系统通讯丢失
  */
void TestDTC_U109287(void)
{
    if(DTCList[cnU109287][1u])
    {
        if(getMSGStatus(cnMSG347))
        {
            ChangeDTCData(cnU109287, DTCError);
        }
        else
        {
            ChangeDTCData(cnU109287, DTCNoError);
        }
    }
}

/**
  *点火信号异常
  */
void TestDTC_B110762(uint16_t timer)
{
    uint8_t Status = Get_ID_288_Sig_BCM_PowerStatusFeedback();
    if(Status > 1u)
    {
        Status = 1u;
    }
    else
    {
        Status = 0u;
    }
    if(DTCList[cnB110762][1u])
    {
        if(getKL15Status() != Status)
        {
            if(DTCTimerList[cnB110762] == 1000u)
            {
                ChangeDTCData(cnB110762, DTCError);
            }
            else
            {
                DTCTimerList[cnB110762] += timer;
            }
        }
        else
        {
            DTCTimerList[cnB110762] = 0u;
            ChangeDTCData(cnB110762, DTCNoError);
        }
    }
}

/**
  *方向盘按键卡住
  */
void TestDTC_B110880(void)
{
    if(DTCList[cnB110880][1u])
    {
        if(KEYStatus != 0u)
        {
            ChangeDTCData(cnB110880, DTCError);
        }
        else
        {
            ChangeDTCData(cnB110880, DTCNoError);
        }
    }
}

/**
  *燃油输入信号无效(低于正常值)
  */
void TestDTC_B110915(uint16_t timer)
{

}

/**
  *燃油输入信号无效(高于正常值)
  */
void TestDTC_B110A15(uint16_t timer)
{

}

/**
  *获取30电电压状态
  *@return 30电电压状态 0为电压正常,1为低压,2为高压
  */
uint8_t getPowerStatus(void)
{

    return 0;
}

/**
  *获取busoff状态
  *@return busoff状态 0为正常,1为异常
  */
uint8_t getBusoffStatus(void)
{

    return 0;//();
}

/**
  *获取发动机启动状态
  *@return EngStatus 0为未启动,1为启动
  */
uint8_t getEngStatus(void)
{
    uint8_t status = 0u;

    if (status>0)
    {
        status = 1u;
    }
    return status;
}

/**
  *设置按键状态
  *@param Statues 最高位 1为卡滞 0为松开, 后7为位按键类型
  */
void set_DTC_Key_Statues(uint8_t Statues)
{
    if((Statues & 0x80u) == 0x80u)
    {
        KEYStatus = KEYStatus | (Statues & 0x7Fu);
    }
    else
    {
        KEYStatus = KEYStatus & (~Statues);
    }
}

/**
  *获取报文状态
  *@param cnMsgID 报文数组下标
  *@return 报文状态 0为在线,1为掉线
  */
uint8_t getMSGStatus(uint8_t cnMsgID)
{
    uint8_t enResult;
    if(msgList[cnMsgID][2] < 200u)
    {
        if(msgList[cnMsgID][3] < 200u * OfflineLoopMultiple)
        {
            enResult = 0u;
        }
        else
        {
            enResult = 1u;
        }
    }
    else
    {
        if(msgList[cnMsgID][3] < msgList[cnMsgID][2] * OfflineLoopMultiple)
        {
            enResult = 0u;
        }
        else
        {
            enResult = 1u;
        }
    }
    return enResult;
}

/**
  *更改DTC状态
  *@param DTCNum DTC编号
  *@param DTCStatus DTC状态
  */
void ChangeDTCData(uint8_t DTCNum, uint8_t DTCStatus)
{
    if(DTCTestIsOpen())
    {
        if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCNoTestLastClear) == DTCNoTestLastClear)
        {
            DTCToDFlashInfo.DTC[DTCNum].DTCStatus = (uint8_t) (DTCToDFlashInfo.DTC[DTCNum].DTCStatus & (~DTCNoTestLastClear));
        }
        if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCNoTestThisCycle) == DTCNoTestThisCycle)
        {
            DTCToDFlashInfo.DTC[DTCNum].DTCStatus = (uint8_t) (DTCToDFlashInfo.DTC[DTCNum].DTCStatus & (~DTCNoTestThisCycle));
        }
        if(DTCStatus == DTCError)
        {
            if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCError) != DTCError)
            {
                DTCToDFlashInfo.DTC[DTCNum].DTCStatus |= DTCError;
                if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCErrorThisCycle) != DTCErrorThisCycle)
                {
                    DTCToDFlashInfo.DTC[DTCNum].DTCStatus |= DTCErrorThisCycle;
                    DTCToDFlashInfo.DTC[DTCNum].DTCAgeing = 0u;
                    DTCToDFlashInfo.DTC[DTCNum].DTCPendingCount++;
                    if(DTCToDFlashInfo.DTC[DTCNum].DTCPendingCount >= MaxDTCPendingCount)
                    {
                        if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCConfirmed) != DTCConfirmed)
                        {
                            DTCToDFlashInfo.DTC[DTCNum].DTCStatus |= DTCConfirmed;
                        }
                    }
                }
                if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCPending) != DTCPending)
                {
                    DTCToDFlashInfo.DTC[DTCNum].DTCStatus |= DTCPending;
                }
                if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCErrorLastClear) != DTCErrorLastClear)
                {
                    DTCToDFlashInfo.DTC[DTCNum].DTCStatus |= DTCErrorLastClear;
                }
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.OdometerValue = 0;//() / 10u;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.SystemSupplyVoltage = (uint8_t)(getKL30Voltage() / 100u);
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.VehicleSpeed = getSpeed();
                //DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime = (year<<26)|(month<<22)|(hour<<17)|(hour<<12)|(minute<<6)|second;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime_second = Get_ID_501_Sig_HU_LocalTimeSecond();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime_minute = Get_ID_501_Sig_HU_LocalTimeMinute();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime_hour   = Get_ID_501_Sig_HU_LocalTimeHour();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime_day    = Get_ID_501_Sig_HU_LocalTimeDate();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime_month  = Get_ID_501_Sig_HU_LocalTimeMonth();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.DTCLocalTime_year   = Get_ID_501_Sig_HU_LocalTimeYear();
                DTCUpdataStatusList[DTCNum] = 1u;
                isNeedSaveDTC = 1u;
            }
        }
        else
        {
            if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCError) == DTCError)
            {
                DTCToDFlashInfo.DTC[DTCNum].DTCStatus &= DTCNoError;
                DTCUpdataStatusList[DTCNum] = 1u;
                isNeedSaveDTC = 1u;
            }
        }
    }
}

/**
  *保存DTC状态
  */
void SaveDTCData(void)
{
    (void)WriteDFlashData(0x05u, (uint32_t *)&DTCToDFlashInfo.Flag, sizeof(DTCToDFlashInfo) , NoNeedWait);
}
