#include "UDS_DTC.h"

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

/**
  *DTC列表
  */
const uint32_t DTCList[14][2] = 
{
    {U300616, 1u},
    {U300617, 1u},
    {U007300, 1u},
    {U012187, 0u},
    {U013187, 0u},
    {U011087, 1u},
    {U011287, 1u},
    {U111587, 0u},
    {U029300, 0u},
    {U019887, 1u},
    {B13AE96, 0u},
    {B13AF96, 0u},
    {B13B196, 0u},
    {U015987, 0u},
};

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

/**
  *msg列表
  */
uint32_t msgList[7][4] = 
{
    {0x18F0120Bu, 8u,  10u ,0u},
    {0x0CFABA13u, 8u,  20u ,0u},
    {0x18FA02EFu, 8u, 100u ,0u},
    {0x18FA40F4u, 8u, 100u ,0u},
    {0x18FA7049u, 8u, 500u ,0u},
    {0x0CFAB127u, 8u,  10u ,0u},
    {0x18FEE69Fu, 8u, 1000u ,0u},
};

/**
  *测试DTC
  *@param timer 计时器增加的时间，单位：ms
  */
void TestDTC(uint16_t timer)
{
    if(getKL15Status())
    {
        if(!getEngStatus())
        {
            TestDTC_U300616(timer);                                         /*检测控制模块输入电压低*/
            TestDTC_U300617(timer);                                         /*检测控制模块输入电压高*/
            if(!getPowerStatus())
            {
                TestDTC_U007300();                                          /*检测can总线关闭*/
                TestDTC_B13AE96();                                          /*后左雷达探头故障（UART雷达）*/
                TestDTC_B13AF96();                                          /*后中雷达探头故障（UART雷达）*/
                TestDTC_B13B196();                                          /*后右雷达探头故障（UART雷达）*/
                TestDTC_U015987();                                          /* 与 PAS 丢失通信丢失*/
                if(!getBusoffStatus())
                {
                    if(isDTCEnable())
                    {
                        TestDTC_U012187();                                  /*与ABS通信丢失*/
                        TestDTC_U013187();                                  /*与EPS通信丢失*/
                        TestDTC_U011087();                                  /*与MCU通信丢失*/
                        TestDTC_U011287();                                  /*与BMS通信丢失*/
                        TestDTC_U111587();                                  /*与OBC通信丢失*/
                        TestDTC_U029300();                                  /*与VCU通信丢失*/
                        TestDTC_U019887();                                  /*与TBOX通信丢失*/
                    }
                }
            }
            if(isNeedSaveDTC)
            {
                SaveDTCData();
                isNeedSaveDTC = 0u;
            }
        }
    }
}

/**
  *检测can总线关闭
  */
void TestDTC_U007300(void)
{
    if(DTCList[cnU007300][1u])
    {
        if(getBUS_OFF_FLAG())
        {
            ChangeDTCData(cnU007300, DTCError);
        }
        else
        {
            ChangeDTCData(cnU007300, DTCNoError);
        }
    }
}

/**
  *检测控制模块输入电压低
  *@param timer 计时器增加的时间，单位：ms
  */
void TestDTC_U300616(uint16_t timer)
{
    uint16_t KL30Voltage = 0u;
    if(DTCList[cnU300616][1u])
    {
        KL30Voltage = getKL30Voltage();
        if(KL30Voltage <= MinimumVoltage)
        {
            if(DTCTimerList[cnU300616] == LowVoltageTimer)
            {
                ChangeDTCData(cnU300616, DTCError);
            }
            else
            {
                DTCTimerList[cnU300616] += timer;
            }
        }
        if(KL30Voltage >= RestoreMinimumVoltage)
        {
            if(DTCTimerList[cnU300616] == 0u)
            {
                ChangeDTCData(cnU300616, DTCNoError);
            }
            else
            {
                if(DTCTimerList[cnU300616] > timer)
                {
                    DTCTimerList[cnU300616] -= timer;
                }
                else
                {
                    DTCTimerList[cnU300616] = 0u;
                }
            }
        }
    }
}

/**
  *检测控制模块输入电压高
  *@param timer 计时器增加的时间，单位：ms
  */
void TestDTC_U300617(uint16_t timer)
{
    uint16_t KL30Voltage = 0u;
    if(DTCList[cnU300617][1u])
    {
        KL30Voltage = getKL30Voltage();
        if(KL30Voltage >= MaximumVoltage)
        {
            if(DTCTimerList[cnU300617] == HightVoltageTimer)
            {
                ChangeDTCData(cnU300617, DTCError);
            }
            else
            {
                DTCTimerList[cnU300617] += timer;
            }
        }
        if(KL30Voltage <= RestoreMaximumVoltage)
        {
            if(DTCTimerList[cnU300617] == 0u)
            {
                ChangeDTCData(cnU300617, DTCNoError);
            }
            else
            {
                if(DTCTimerList[cnU300617] > timer)
                {
                    DTCTimerList[cnU300617] -= timer;
                }
                else
                {
                    DTCTimerList[cnU300617] = 0u;
                }
            }
        }
    }
}

/**
  *与ABS通信丢失
  */
void TestDTC_U012187(void)
{
    if(DTCList[cnU012187][1u])
    {
        //if(Val_EOL_F110_EMS())
        {
            if(getMSGStatus(cnMSG18F0120B))
            {
                ChangeDTCData(cnU012187, DTCError);
            }
            else
            {
                ChangeDTCData(cnU012187, DTCNoError);
            }
        }
    }
}

/**
  *与EPS通信丢失
  */
void TestDTC_U013187(void)
{
    if(DTCList[cnU013187][1u])
    {
        //if(Val_EOL_F110_TCU())
        {
            if(getMSGStatus(cnMSG0CFABA13))
            {
                ChangeDTCData(cnU013187, DTCError);
            }
            else
            {
                ChangeDTCData(cnU013187, DTCNoError);
            }
        }
    }
}

/**
  *与MCU通信丢失
  */
void TestDTC_U011087(void)
{
    if(DTCList[cnU011087][1u])
    {
        //if(Val_EOL_F110_ESC())
        {
            if(getMSGStatus(cnMSG18FA02EF))
            {
                ChangeDTCData(cnU011087, DTCError);
            }
            else
            {
                ChangeDTCData(cnU011087, DTCNoError);
            }
        }
    }
}

/**
  *与BMS通信丢失
  */
void TestDTC_U011287(void)
{
    if(DTCList[cnU011287][1u])
    {
        //if(Val_EOL_F110_EPS())
        {
            if(getMSGStatus(cnMSG18FA40F4))
            {
                ChangeDTCData(cnU011287, DTCError);
            }
            else
            {
                ChangeDTCData(cnU011287, DTCNoError);
            }
        }
    }
}

/**
  *与OBC通信丢失
  */
void TestDTC_U111587(void)
{
    if(DTCList[cnU111587][1u])
    {
        //if(Val_EOL_F110_BCM())
        {
            if(getMSGStatus(cnMSG18FA7049))
            {
                ChangeDTCData(cnU111587, DTCError);
            }
            else
            {
                ChangeDTCData(cnU111587, DTCNoError);
            }
        }
    }
}

/**
  *与VCU通信丢失
  */
void TestDTC_U029300(void)
{
    if(DTCList[cnU029300][1u])
    {
        //if(Val_EOL_F110_GW())
        {
            if(getMSGStatus(cnMSG0CFAB127))
            {
                ChangeDTCData(cnU029300, DTCError);
            }
            else
            {
                ChangeDTCData(cnU029300, DTCNoError);
            }
        }
    }
}

/**
  *与TBOX通信丢失
  */
void TestDTC_U019887(void)
{
    if(DTCList[cnU019887][1u])
    {
        //if(Val_EOL_F110_ACU())
        {
            if(getMSGStatus(cnMSG18FF639F))
            {
                ChangeDTCData(cnU019887, DTCError);
            }
            else
            {
                ChangeDTCData(cnU019887, DTCNoError);
            }
        }
    }
}

/**
  *后左雷达探头故障（UART雷达）
  */
void TestDTC_B13AE96(void)
{
    if(DTCList[cnB13AE96][1u])
    {
        //if(Val_EOL_F110_AC())
        {
            if(Radra_Get_SEG_L() == 3u)
            {
                if(DTCTimerList[cnB13AE96] == 20u)
                {
                    ChangeDTCData(cnB13AE96, DTCError);
                }
                else
                {
                    DTCTimerList[cnB13AE96] += 10u;
                }
            }
            else
            {
                DTCTimerList[cnB13AE96] = 0u;
                ChangeDTCData(cnB13AE96, DTCNoError);
            }
        }
    }
}

/**
  *后中雷达探头故障（UART雷达）
  */
void TestDTC_B13AF96(void)
{
    if(DTCList[cnB13AF96][1u])
    {
        //if(Val_EOL_F110_AC())
        {
            if(Radra_Get_SEG_M() == 3u)
            {
                if(DTCTimerList[cnB13AF96] == 20u)
                {
                    ChangeDTCData(cnB13AF96, DTCError);
                }
                else
                {
                    DTCTimerList[cnB13AF96] += 10u;
                }
            }
            else
            {
                DTCTimerList[cnB13AF96] = 0u;
                ChangeDTCData(cnB13AF96, DTCNoError);
            }
        }
    }
}

/**
  *后右雷达探头故障（UART雷达）
  */
void TestDTC_B13B196(void)
{
    if(DTCList[cnB13B196][1u])
    {
        //if(Val_EOL_F110_AC())
        {
            if(Radra_Get_SEG_R() == 3u)
            {
                if(DTCTimerList[cnB13B196] == 20u)
                {
                    ChangeDTCData(cnB13B196, DTCError);
                }
                else
                {
                    DTCTimerList[cnB13B196] += 10u;
                }
            }
            else
            {
                DTCTimerList[cnB13B196] = 0u;
                ChangeDTCData(cnB13B196, DTCNoError);
            }
        }
    }
}

/**
  *后右雷达探头故障（UART雷达）
  */
void TestDTC_U015987(void)
{
    if(DTCList[cnU015987][1u])
    {
        //if(Val_EOL_F110_AC())
        {
            if(Radra_Get_Warning() == 6u)
            {
                if(DTCTimerList[cnU015987] == 2000u)
                {
                    ChangeDTCData(cnU015987, DTCError);
                }
                else
                {
                    DTCTimerList[cnU015987] += 10u;
                }
            }
            else
            {
                DTCTimerList[cnU015987] = 0u;
                ChangeDTCData(cnU015987, DTCNoError);
            }
        }
    }
}

/**
  *获取30电电压状态
  *@return 30电电压状态 0为电压正常,1为低压,2为高压
  */
uint8_t getPowerStatus(void)
{
    uint8_t  enResult = NormalVottage;
    uint16_t KL30Voltage = getKL30Voltage();
    
    if((KL30Voltage >= 9000u) && (KL30Voltage <= 16000u))
    {
        if(LVoltageStatus == 1u)
        {
            if(KL30Voltage < 10000u)
            {
                enResult = LowVottage;
                setDTCEnableTimer(H_LVoltageDTCEnableTimer);
            }
            else
            {
                LVoltageStatus = 0u;
                enResult = NormalVottage;
            }
        }
        else if(HVoltageStatus == 1u)
        {
            if(KL30Voltage > 15000u)
            {
                enResult = HightVottage;
                setDTCEnableTimer(H_LVoltageDTCEnableTimer);
            }
            else
            {
                HVoltageStatus = 0u;
                enResult = NormalVottage;
            }
        }
        else
        {
            enResult = NormalVottage;
        }
    }
    else if(KL30Voltage > 16000u)
    {
        HVoltageStatus = 1u;
        enResult = HightVottage;
        setDTCEnableTimer(H_LVoltageDTCEnableTimer);
    }
    else
    {
        LVoltageStatus = 1u;
        enResult = LowVottage;
        setDTCEnableTimer(H_LVoltageDTCEnableTimer);
    }
    return enResult;
}

/**
  *获取busoff状态
  *@return busoff状态 0为正常,1为异常
  */
uint8_t getBusoffStatus(void)
{
    if(getBUS_OFF_Status())
    {
        setDTCEnableTimer(BusOffDTCEnableTimer);
    }
    return getBUS_OFF_Status();
}

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

/**
  *获取报文状态
  *@param cnMsgID 报文数组下标
  *@return 报文状态 0为在线,1为掉线
  */
uint8_t getMSGStatus(uint8_t cnMsgID)
{
    uint8_t enResult;
    if(msgList[cnMsgID][2] < 50u)
    {
        if(msgList[cnMsgID][3] < 50u * 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)(~DTCNoTestLastClear);
        }
        if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCNoTestThisCycle) == DTCNoTestThisCycle)
        {
            DTCToDFlashInfo.DTC[DTCNum].DTCStatus &= (uint8_t)(~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.ECUPowerVoltage = (getKL30Voltage() / 100u);
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.VehicleSpeed = Get_ID_18FEBF0B_Sig_ABSFrontAxleSpeed();
                if(DTCToDFlashInfo.DTC[DTCNum].Snapshot.OccurrenceCounter == 0u)
                {
                    DTCToDFlashInfo.DTC[DTCNum].Snapshot.FirstMalfunction = (Data_ODO_Read() / 10u);
                }
                if(DTCToDFlashInfo.DTC[DTCNum].Snapshot.OccurrenceCounter < 255u)
                {
                    DTCToDFlashInfo.DTC[DTCNum].Snapshot.OccurrenceCounter++;
                }
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.LastMalfunction = (Data_ODO_Read() / 10u);
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.Time.min   = Get_RTC_MINUTE();//Get_ID_18FEE69F_Sig_TBOX_Minute();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.Time.sec   = Get_RTC_SECOND()*4;//Get_ID_18FEE69F_Sig_TBOX_Second();
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.Time.hour  = Get_RTC_HOUR();//Get_ID_18FEE69F_Sig_TBOX_Hour();  
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.Time.month = Get_RTC_MONTH();//Get_ID_18FEE69F_Sig_TBOX_Month(); 
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.Time.day   = Get_RTC_DATE()*4;//Get_ID_18FEE69F_Sig_TBOX_Day();   
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.Time.year  = Get_ID_18FEE69F_Sig_TBOX_Year();  //Get_RTC_YEAR();因为起始年份是1985与矩阵对应
                isNeedSaveDTC = 1u;
            }
        }
        else
        {
            if((uint8_t)(DTCToDFlashInfo.DTC[DTCNum].DTCStatus & DTCError) == DTCError)
            {
                DTCToDFlashInfo.DTC[DTCNum].DTCStatus &= DTCNoError;
                isNeedSaveDTC = 1u;
            }
        }
    }
}

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