#include "UDS_DTC.h"

uint8_t isNeedSaveDTC = 0u;

/**
  *DTC�б�
  */
const uint32_t DTCList[27][2] = 
{
    {U300616, 1u},
    {U300617, 1u},
    {U007300, 1u},
    {U015687, 1u},
    {U014087, 1u},
    {U021487, 1u},
    {U029300, 1u},
    {U011287, 1u},
    {U012787, 1u},
    {U120387, 1u},
    {U012887, 1u},
    {U015987, 1u},
    {U011087, 1u},
    {U016487, 1u},
    {U015187, 1u},
    {U112887, 1u},
    {U012987, 1u},
    {U013187, 1u},
    {U012287, 1u},
    {U019887, 1u},
    {U010387, 1u},
    {U012187, 1u},
    {U026387, 1u},
    {B110015, 1u},
    {B110114, 1u},
    {B110215, 1u},
    {B110314, 1u},
};

/**
  *����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_B110015(timer);
                TestDTC_B110114(timer);
                TestDTC_B110215(timer);
                TestDTC_B110314(timer);                
                if(!getBusoffStatus())
                {
                    if(isDTCEnable())
                    {
                        TestDTC_U015687();
                        TestDTC_U014087();
                        TestDTC_U021487();
                        TestDTC_U029300();
                        TestDTC_U011287();
                        TestDTC_U012787();
                        TestDTC_U120387();
                        TestDTC_U012887();
                        TestDTC_U015987();
                        TestDTC_U011087();
                        TestDTC_U016487();
                        TestDTC_U015187();
                        TestDTC_U112887();
                        TestDTC_U012987();
                        TestDTC_U013187();
                        TestDTC_U012287();
                        TestDTC_U019887();
                        TestDTC_U010387();
                        TestDTC_U012187();
                        TestDTC_U026387();
                    }
                }
            }
            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] >= 1000)
            {
                DTCTimerList[cnU300616] = 3000u;
                ChangeDTCData(cnU300616, DTCError);
            }
            else
            {
                DTCTimerList[cnU300616] += timer;
            }
        }
        if(KL30Voltage > RestoreMinimumVoltage)
        {
            if(DTCTimerList[cnU300616] == 0u)
            {
                ChangeDTCData(cnU300616, DTCNoError);
            }
            else
            {
                DTCTimerList[cnU300616] -= timer;
            }
        }
    }
}

/**
  *������ģ�������ѹ��
  *@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] >= 1000u)
            {
                DTCTimerList[cnU300617] = 3000u;
                ChangeDTCData(cnU300617, DTCError);
            }
            else
            {
                DTCTimerList[cnU300617] += timer;
            }
        }
        if(KL30Voltage <= RestoreMaximumVoltage)
        {
            if(DTCTimerList[cnU300617] == 0u)
            {
                ChangeDTCData(cnU300617, DTCNoError);
            }
            else
            {
                DTCTimerList[cnU300617] -= timer;
            }
        }
    }
}

/**
  *Lost Communication with MMI Message 0x18FF4A41
  */
void TestDTC_U015687(void)
{
    if(DTCList[cnU015687][1u])
    {
        if(Val_EOL_F110_MMI())
        {
            if(getMSGStatus(cnMSGA41))
            {
                ChangeDTCData(cnU015687, DTCError);
            }
            else
            {
                ChangeDTCData(cnU015687, DTCNoError);
            }
        }
    }
}


/**
  *Lost Communication with BCM Message 0x18FE4021
  */
void TestDTC_U014087(void)
{
    if(DTCList[cnU014087][1u])
    {
        if(Val_EOL_F110_BCM())
        {
            if(getMSGStatus(cnMSG021))
            {
                ChangeDTCData(cnU014087, DTCError);
            }
            else
            {
                ChangeDTCData(cnU014087, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with PEPS Message 0x0CFF0ADF
  */
void TestDTC_U021487(void)
{
    if(DTCList[cnU021487][1u])
    {
        if(Val_EOL_F110_PEPS())
        {
            if(getMSGStatus(cnMSGADF))
            {
                ChangeDTCData(cnU021487, DTCError);
            }
            else
            {
                ChangeDTCData(cnU021487, DTCNoError);
            }
        }
    }
}


/**
  *Lost Communication with VCU Message 0x0CFAB127
  */
void TestDTC_U029300(void)
{
    if(DTCList[cnU029300][1u])
    {
        if(Val_EOL_F110_VCU())
        {
            if(getMSGStatus(cnMSG127))
            {
                ChangeDTCData(cnU029300, DTCError);
            }
            else
            {
                ChangeDTCData(cnU029300, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with BMS Message 0x18FA40F4
  */
void TestDTC_U011287(void)
{
    if(DTCList[cnU011287][1u])
    {
        if(Val_EOL_F110_BMS())
        {
            if(getMSGStatus(cnMSG0F4))
            {
                ChangeDTCData(cnU011287, DTCError);
            }
            else
            {
                ChangeDTCData(cnU011287, DTCNoError);
            }
        }
    }
}


/**
  *Lost Communication with TPMS Message 0x18FFE033
  */
void TestDTC_U012787(void)
{
    if(DTCList[cnU012787][1u])
    {
        if(Val_EOL_F110_TPMS())
        {
            if(getMSGStatus(cnMSG033))
            {
                ChangeDTCData(cnU012787, DTCError);
            }
            else
            {
                ChangeDTCData(cnU012787, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with FCS Message 0x10F007E8 �� 0x0CF02FA0
  */
void TestDTC_U120387(void)
{
    if(DTCList[cnU120387][1u])
    {
        if(Val_EOL_F110_FCS())
        {
            if(getMSGStatus(cnMSGFA0) && (getMSGStatus(cnMSG7E8)))
            {
                ChangeDTCData(cnU120387, DTCError);
            }
            else
            {
                ChangeDTCData(cnU120387, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with EPB Message Һɲ0x0CFABF8F/��ɲ0x18FFB88F
  */
void TestDTC_U012887(void)
{
    if(DTCList[cnU012887][1u])
    {
        //#if(IC_Current == LD02)
        //{
          if(Val_EOL_F110_EPB_Air())
          {
              if(getMSGStatus(cnMSG88F))
              {
                  ChangeDTCData(cnU012887, DTCError);
              }
              else
              {
                  ChangeDTCData(cnU012887, DTCNoError);
              }
          } 
          else if(Val_EOL_F110_EPB_Liquid())
          {
              if(getMSGStatus(cnMSGF8F))
              {
                  ChangeDTCData(cnU012887, DTCError);
              }
              else
              {
                  ChangeDTCData(cnU012887, DTCNoError);
              }
          }
        //}
        //#endif 
    }
}

/**
  *Lost Communication with PDC Message 0x0CFF1ADA
  */
void TestDTC_U015987(void)
{
    if(DTCList[cnU015987][1u])
    {
        if(Val_EOL_F110_PDC())
        {
            if(getMSGStatus(cnMSGADA))
            {
                ChangeDTCData(cnU015987, DTCError);
            }
            else
            {
                ChangeDTCData(cnU015987, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with MCU Message 0x18FA02EF
  */
void TestDTC_U011087(void)
{
    if(DTCList[cnU011087][1u])
    {
        if(Val_EOL_F110_MCU())
        {
            if(getMSGStatus(cnMSG2EF))
            {
                ChangeDTCData(cnU011087, DTCError);
            }
            else
            {
                ChangeDTCData(cnU011087, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with AC Message 0x18FF2319
  */
void TestDTC_U016487(void)
{
    if(DTCList[cnU016487][1u])
    {
        if(Val_EOL_F110_AC())
        {
            if(getMSGStatus(cnMSG319))
            {
                ChangeDTCData(cnU016487, DTCError);
            }
            else
            {
                ChangeDTCData(cnU016487, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with ACU Message 0x18FAC490
  */
void TestDTC_U015187(void)
{
    if(DTCList[cnU015187][1u])
    {
        if(Val_EOL_F110_ACU())
        {
            if(getMSGStatus(cnMSG490))
            {
                ChangeDTCData(cnU015187, DTCError);
            }
            else
            {
                ChangeDTCData(cnU015187, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with AVAS Message 0x18FFC095
  */
void TestDTC_U112887(void)
{
    if(DTCList[cnU112887][1u])
    {
        if(Val_EOL_F110_AVAS())
        {
            if(getMSGStatus(cnMSG095))
            {
                ChangeDTCData(cnU112887, DTCError);
            }
            else
            {
                ChangeDTCData(cnU112887, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with EBS Message 0x18F0010B
  */
void TestDTC_U012987(void)
{
    if(DTCList[cnU012987][1u])
    {
        if(Val_EOL_F110_EBS())
        {
            if(getMSGStatus(cnMSG10B))
            {
                ChangeDTCData(cnU012987, DTCError);
            }
            else
            {
                ChangeDTCData(cnU012987, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with EPS Message    0x0CFABA13
  */
void TestDTC_U013187(void)
{
    if(DTCList[cnU013187][1u])
    {
        if(Val_EOL_F110_EPS())
        {
            if(getMSGStatus(cnMSGA13))
            {
                ChangeDTCData(cnU013187, DTCError);
            }
            else
            {
                ChangeDTCData(cnU013187, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with ESC Message 0x18FE4F0B
  */
void TestDTC_U012287(void)
{
    if(DTCList[cnU012287][1u])
    {
        if((Val_EOL_F110_ESC_L() == 1) || (Val_EOL_F110_ESC_W() == 1))
        {
            if(getMSGStatus(cnMSGF0B))
            {
                ChangeDTCData(cnU012287, DTCError);
            }
            else
            {
                ChangeDTCData(cnU012287, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with T-BOX Message 0x18FEE69F
  */
void TestDTC_U019887(void)
{
    if(DTCList[cnU019887][1u])
    {
        if(Val_EOL_F110_TBOX())
        {
            if(getMSGStatus(cnMSG69F))
            {
                ChangeDTCData(cnU019887, DTCError);
            }
            else
            {
                ChangeDTCData(cnU019887, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with EGSM Message 0x0C012705
  */
void TestDTC_U010387(void)
{
    if(DTCList[cnU010387][1u])
    {
        if(Val_EOL_F110_EGSM())
        {
            if(getMSGStatus(cnMSG705))
            {
                ChangeDTCData(cnU010387, DTCError);
            }
            else
            {
                ChangeDTCData(cnU010387, DTCNoError);
            }
        }
    }
}

/**
  * Lost Communication with ABS Message 0x18F0010B
  */
void TestDTC_U012187(void)
{
    if(DTCList[cnU012187][1u])
    {
        if(Val_EOL_F110_ABS())
        {
            if(getMSGStatus(cnMSG10B))
            {
                ChangeDTCData(cnU012187, DTCError);
            }
            else
            {
                ChangeDTCData(cnU012187, DTCNoError);
            }
        }
    }
}

/**
  *Lost Communication with DDD Message 0x18FAD084
  没有配置
  */
void TestDTC_U026387(void)
{
    if(DTCList[cnU026387][1u])
    {
        if(getMSGStatus(cnMSG084))
        {
            ChangeDTCData(cnU026387, DTCError);
        }
        else
        {
            ChangeDTCData(cnU026387, DTCNoError);
        }
        
    }
}

/**
  * ��ѹ��������ǰ�ţ��źŶ�·
  */
void TestDTC_B110015(uint16_t timer)
{
    if(DTCList[cnB110015][1u])
    {
        if(AirPress_Front.u16Volt_Value >= 5000u) 
        {
            if(DTCTimerList[cnB110015] == 1000u) 
            {
                ChangeDTCData(cnB110015, DTCError);
            }
            else
            {
                DTCTimerList[cnB110015] += timer;
            }
        } 
        else 
        {
           if(DTCTimerList[cnB110015] == 0u) 
            {
                ChangeDTCData(cnB110015, DTCNoError);
            }
            else
            {
                DTCTimerList[cnB110015] -= timer;
            }        
        }
    }
}

/**
  * ��ѹ��������ǰ�ţ��źŶ�·
  */
void TestDTC_B110114(uint16_t timer)
{
    if(DTCList[cnB110114][1u])
    {
        if(AirPress_Front.u16Volt_Value <= 100u) 
        {
            if(DTCTimerList[cnB110114] == 1000u) 
            {
                ChangeDTCData(cnB110114, DTCError);
            }
            else
            {
                DTCTimerList[cnB110114] += timer;
            }
        } 
        else 
        {
           if(DTCTimerList[cnB110114] == 0u) 
            {
                ChangeDTCData(cnB110114, DTCNoError);
            }
            else
            {
                DTCTimerList[cnB110114] -= timer;
            }        
        }
    }
}

/**
  * ��ѹ�����������ţ��źŶ�·
  */
void TestDTC_B110215(uint16_t timer)
{
    if(DTCList[cnB110215][1u])
    {
        if(AirPress_Rear.u16Volt_Value >= 5000u) 
        {
            if(DTCTimerList[cnB110215] == 1000u) 
            {
                ChangeDTCData(cnB110215, DTCError);
            }
            else
            {
                DTCTimerList[cnB110215] += timer;
            }
        } 
        else 
        {
           if(DTCTimerList[cnB110215] == 0u) 
            {
                ChangeDTCData(cnB110215, DTCNoError);
            }
            else
            {
                DTCTimerList[cnB110215] -= timer;
            }        
        }
    }
}

/**
  * ��ѹ�����������ţ��źŶ�·
  */
void TestDTC_B110314(uint16_t timer)
{
    if(DTCList[cnB110314][1u])
    {
        if(AirPress_Rear.u16Volt_Value <= 100u) 
        {
            if(DTCTimerList[cnB110314] == 1000u) 
            {
                ChangeDTCData(cnB110314, DTCError);
            }
            else
            {
                DTCTimerList[cnB110314] += timer;
            }
        } 
        else 
        {
           if(DTCTimerList[cnB110314] == 0u) 
            {
                ChangeDTCData(cnB110314, DTCNoError);
            }
            else
            {
                DTCTimerList[cnB110314] -= timer;
            }        
        }
    }
}

/**
  *��ȡ30���ѹ״̬
  *@return 30���ѹ״̬ 0Ϊ��ѹ����,1Ϊ��ѹ,2Ϊ��ѹ
  */
uint8_t getPowerStatus(void)
{
    uint8_t  enResult = NormalVottage;
    uint16_t KL30Voltage = getKL30Voltage();
    
    if((KL30Voltage >= 18000u) && (KL30Voltage <= 32000u))
    {
        if(LVoltageStatus == 1u)
        {
            if(KL30Voltage < 19000u)
            {
                enResult = LowVottage;
                setDTCEnableTimer(H_LVoltageDTCEnableTimer);
            }
            else
            {
                LVoltageStatus = 0u;
                enResult = NormalVottage;
            }
        }
        else if(HVoltageStatus == 1u)
        {
            if(KL30Voltage > 31000u)
            {
                enResult = HightVottage;
                setDTCEnableTimer(H_LVoltageDTCEnableTimer);
            }
            else
            {
                HVoltageStatus = 0u;
                enResult = NormalVottage;
            }
        }
        else
        {
            enResult = NormalVottage;
        }
    }
    else if(KL30Voltage > 32000u)
    {
        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;
}
//uint8_t yearyear;
/**
  *����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 = (uint8_t)(getKL30Voltage() / 100u);
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.VehicleSpeed = Get_SigABS_VehicleSpeed();
                if(DTCToDFlashInfo.DTC[DTCNum].Snapshot.OccurrenceCounter == 0u)
                {
                    DTCToDFlashInfo.DTC[DTCNum].Snapshot.FirstMalfunction = (getTotalOdometer() / 10u);
                }
                if(DTCToDFlashInfo.DTC[DTCNum].Snapshot.OccurrenceCounter < 255u)
                {
                    DTCToDFlashInfo.DTC[DTCNum].Snapshot.OccurrenceCounter++;
                }
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.LastMalfunction = (getTotalOdometer() / 10u);
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.EngineSpeed = Get_SigEMS_EngSpeed(); 
                /*DTCToDFlashInfo.DTC[DTCNum].Snapshot.PowerRange = ;*/
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.TimeOfFailure_S = RTC_SECOND * 4;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.TimeOfFailure_Min = RTC_MINUTE ;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.TimeOfFailure_Hr = RTC_HOUR ;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.TimeOfFailure_Month = RTC_MONTH ;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.TimeOfFailure_Day = RTC_DATE * 4;
                DTCToDFlashInfo.DTC[DTCNum].Snapshot.TimeOfFailure_Year = RTC_YEAR ; 
                //yearyear = T_BOX_Year;
                NVM_Data_Update(NVM_DTC + DTCNum);
                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), NoNeedWait);
}