#include "Services_ODO.h"
#include "Services_ODO_Internal.h"
#include "Common_Interface.h"
#include "Work_Flash.h"
#include "Communication_Over_CAN.h"
#include "EOL_Para.h"
#include "Services_Interval.h"
#include "Services_TripA.h"
#include "Non_volatile_Memorys.h"

typedef struct
{
    uint32_t ODO_Save;
    uint8_t  ODO_Save_Counter;
} ODO_BackupStruct;


/*** 里程滚动计数器 ***/
#pragma location="BACKUP_RAM_CONTENT"
uint16_t                DataMileageRollingCounter;
#pragma location="BACKUP_RAM_CONTENT"
DataMileageCalcStruct   DataMileage;

/*** 总计里程 ***/
#pragma location="BACKUP_RAM_CONTENT"
DataODOStruct           DataODOCalc;
#pragma location="BACKUP_RAM_CONTENT"
uint32_t   Data_ODO_Val;
#pragma location="BACKUP_RAM_CONTENT"
uint8_t                 DataODOValid;
#pragma location="BACKUP_RAM_CONTENT"
uint8_t  EEPROM_St;
_DataODOInputStruct Input_ODO_Para;
#pragma location="BACKUP_RAM_CONTENT"
uint32_t  Data_ODO_ClearCnt;
#pragma location="BACKUP_RAM_CONTENT"
uint32_t  Data_ODO_ClearKM;



uint8_t ODO_Sync_DelayTimer;
uint8_t ODO_Sync_Enable;
uint8_t ODO_Sync_Enable_Lock;

uint8_t EMS_ODO_Counter;
uint8_t VCU_ODO_Counter;

ODO_BackupStruct    EMS_ODO[5U];
ODO_BackupStruct    VCU_ODO[5U];




uint32_t Services_Read_ODO_ClearCnt(void)
{
    return Data_ODO_ClearCnt;
}

/*864007-3*/ /*864007-7*/
void Services_ODO_SaveCall(uint32_t Val_ODO)
{
    uint32_t Temp[3];
    Temp[0] = Val_ODO; /*总计*/
    Temp[1] = Data_ODO_ClearCnt; /*总计清零次数*/
    Temp[2] = Data_ODO_ClearKM; /*总计已清零公里数*/

    NVM_ODO_VALUE       = Temp [ 0 ];
    NVM_ODO_CLEAR_COUNT = Temp [ 1 ];
    NVM_ODO_CLEARED     = Temp [ 2 ];

    NVM_Data_Update(NVM_ODO_DATA);
}

/*
0-OK
1-500KM
2-3次
 */
uint8_t Services_ODO_Clear(void)
{
    uint8_t Res;
    Data_ODO_ClearKM += Data_ODO_Read();
    if (Data_ODO_ClearCnt != 0u)
    {
        if (Data_ODO_ClearKM <= 5000u)
        {
            Data_ODO_ClearCnt--;
            Services_ODO_Modify_Sync(3u);
            Data_ODO_Modify(0u);
            Res = 0u;
        }
        else
        {
            Res = 1u;
        }
    }
    else
    {
        Res = 2u;
    }
    return Res;
}

void Services_ODO_ClearFactory(void)
{
    Data_ODO_ClearCnt = 1u;
    Data_ODO_ClearKM = 0u;
    Services_ODO_Modify_Sync(4u);
    Data_ODO_Modify(0u);
}

void Services_ODO_ISR(void)
{
    _DataODOInputStruct m_ODOPara;
    m_ODOPara.PowerSts = Common_Get_IG_Sts();
    /*864007-1*/
    m_ODOPara.V_Speed_Valid = Common_Get_Act_V_Speed_Valid();/*864004*/ /*864004-1*/ /*864004-2*/ /*864004-3*/ /*864005-2*/
    m_ODOPara.E_Speed_Valid = Common_Get_Act_E_Speed_Valid();
    m_ODOPara.Act_E_Speed = Common_Get_Act_E_Speed();
    m_ODOPara.Act_V_Speed = Common_Get_Act_V_Speed();/*864005-1*/
    m_ODOPara.TireSize = 10000u;
    Data_Mileage_Set_Para(&m_ODOPara);
    /*864007-2*/
    Data_Mileage_Rolling_Counter_Update_ISR();
}
void Services_ODO_100MS_Cbk(void)
{
    _DataODOInputStruct m_ODOPara;
    m_ODOPara.PowerSts = Common_Get_IG_Sts();
    m_ODOPara.V_Speed_Valid = Common_Get_Act_V_Speed_Valid();/*864004-1*/ /*864004-2*/ /*864004-3*/ /*864005-2*/
    m_ODOPara.E_Speed_Valid = Common_Get_Act_E_Speed_Valid();
    m_ODOPara.Act_E_Speed = Common_Get_Act_E_Speed();
    m_ODOPara.Act_V_Speed = Common_Get_Act_V_Speed();/*864005-1*/
    m_ODOPara.TireSize = 1u;
    Data_Mileage_Set_Para(&m_ODOPara);
    Data_ODO_Processing();   /*864007-2*/
}

/*
ODO km -----------UINT32
ODO CLEAR KM     -UINT32
ODO CLEAR count---UINT32
 */
void Services_ODO_KL30Init(void)
{
    uint32_t Temp[3];
    Temp[0] = 0ul; /*总计*/
    Temp[1] = 0ul; /*总计清零次数*/
    Temp[2] = 0ul; /*总计已清零公里数*/

  
    Temp [ 0 ]=NVM_ODO_VALUE;
    Temp [ 1 ]=NVM_ODO_CLEAR_COUNT;
    Temp [ 2 ]=NVM_ODO_CLEARED;
    Data_ODO_KL30Init(Temp[0], DataValid);
    Data_ODO_ClearCnt = Temp[1];
    Data_ODO_ClearKM = Temp[2];

}



void Services_ODOSync_KL15Init(void)
{
    uint8_t i;
    ODO_Sync_DelayTimer = 0u;
    ODO_Sync_Enable_Lock = 0u;
    VCU_ODO_Counter = 0u;
    EMS_ODO_Counter = 0u;
    for (i = 0u; i < 5u; i++)
    {
        EMS_ODO[i].ODO_Save = 0u;
        EMS_ODO[i].ODO_Save_Counter = 0u;
        VCU_ODO[i].ODO_Save = 0u;
        VCU_ODO[i].ODO_Save_Counter = 0u;
    }
}

void  Services_ODO_EMS_Set(uint32_t m_EMS_ODO)
{
    if (ODO_Sync_DelayTimer > 10u)
    {
        if (EMS_ODO_Counter < 5u)
        {
            EMS_ODO[EMS_ODO_Counter].ODO_Save = m_EMS_ODO;
            EMS_ODO[EMS_ODO_Counter].ODO_Save_Counter = 1u;
        }
    }
}
void  Services_ODO_VCU_Set(uint32_t m_EMS_ODO)
{
    if (ODO_Sync_DelayTimer > 10u)
    {
        if (VCU_ODO_Counter < 5u)
        {
            VCU_ODO[VCU_ODO_Counter].ODO_Save = m_EMS_ODO;
            VCU_ODO[VCU_ODO_Counter].ODO_Save_Counter = 1u;
        }
    }
}

void Services_EMS_CounterAdd(void)
{
    if (ODO_Sync_DelayTimer > 10u)
    {
        if (EMS_ODO_Counter < 10u)
        {
            EMS_ODO_Counter++;
        }
    }
}

void Services_VCU_CounterAdd(void)
{
    if (ODO_Sync_DelayTimer > 10u)
    {
        if (VCU_ODO_Counter < 10u)
        {
            VCU_ODO_Counter++;
        }
    }
}

uint8_t Services_ODO_Read_DelayTimer(void)
{
    return ODO_Sync_DelayTimer;
}

/*
1---- 无效,没收满数据
2---- 无效,收满了,但是5帧不连续
0---- 有效
 */
uint8_t Services_ODO_SyncValid(void)
{
    uint8_t i;
    uint8_t Result;

    if ((VCU_ODO_Counter >= 5u) && (EMS_ODO_Counter >= 5u))
    {
        Result = 0u;
        for (i = 0u; i < 4u; i++)
        {
            if (EMS_ODO[i].ODO_Save != EMS_ODO[i + 1u].ODO_Save)
            {
                Result = 2u;
            }
            if (VCU_ODO[i].ODO_Save != VCU_ODO[i + 1u].ODO_Save)
            {
                Result = 2u;
            }
            if (Result == 2u)
            {
                break;
            }
        }
    }
    else
    {
        Result = 1u;
    }
    return Result;
}



/* 里程同步功能 100ms task */
void Services_ODO_Sync(void)
{
   uint8_t m_Condition_1;
   uint8_t m_Condition_2;
   uint16_t V1_ODO;
   uint16_t V2_ODO;
   uint32_t m_Temp;
   uint8_t i;

   if (Common_Get_IG_Sts() == 1u)
   {
       if (Val_EOL_F101_ODOBack() == 1u)/*864008-1*/
       {
           if (ODO_Sync_Enable_Lock == 0u)/*864008-2*/
           {
               if (ODO_Sync_DelayTimer <= 10u)/*864008-4*/
               {
                   ODO_Sync_DelayTimer++;
               }
               else
               {
                    m_Condition_1 = CAN_MSG_Status(ID_PMS_OdometerInfo_Msg_Count); /*EMS*/
                    m_Condition_2 = CAN_MSG_Status(ID_MCU_OdometerInfo_Msg_Count); /*BCM*//*864008-2*/
                   if ((m_Condition_1 != 0x55u) && (m_Condition_2 != 0x55u))
                   {
                       if (Services_ODO_SyncValid() == 0u)
                       {
                           V1_ODO = Get_ID_18FAA827_Sig_PMS_Odometerbackup();
                           V2_ODO = Get_ID_18FA09EF_Sig_MCU_Odometerbackup();
                           if ((V1_ODO == 0u) || (V1_ODO == 0x3fffu) || (V2_ODO == 0u) || (V2_ODO == 0x3fffu))
                           {
                               ODO_Sync_Enable_Lock = 2u;
                           }
                           else
                           {
                               if (V1_ODO >= V2_ODO)/* 1 >2 *//*864008-3*/
                               {
                                   m_Temp = (uint32_t)((uint32_t)V1_ODO - (uint32_t)V2_ODO);
                                   m_Temp *= 100u;/*864008-5*/
                                   if (m_Temp <= 300u)/* 差值在300km,可以与仪表里程进行判断 */
                                   {
                                       m_Temp = V1_ODO * 100u;
                                       if (m_Temp >= (Data_ODO_Read() / 10u))
                                       {
                                           m_Temp -= Data_ODO_Read() / 10u;
                                           if (m_Temp > 300u)
                                           {
                                               /*改写大计*/
                                               m_Temp = V1_ODO * 1000u;
                                               if (Services_Read_ODO_ClearCnt1() <= 10000ul)
                                               {
                                                   Services_ODO_Modify_Sync(1u);
                                                   Data_ODO_Modify(m_Temp);
                                               }
                                               ODO_Sync_Enable_Lock = 2u;
                                           }
                                       }
                                   }
                               }
                               else /* 1<2 */
                               {
                                   m_Temp = (uint32_t)((uint32_t)V2_ODO - (uint32_t)V1_ODO);/*864008-3*/
                                   m_Temp *= 100u;/*864008-5*/
                                   if (m_Temp <= 300u)/* 差值在300km,可以同步 */
                                   {
                                       m_Temp = V2_ODO * 100u;
                                       if (m_Temp >= (Data_ODO_Read() / 10u))
                                       {
                                           m_Temp -= Data_ODO_Read() / 10u;
                                           if (m_Temp > 300u)
                                           {
                                               /*改写大计*/
                                               m_Temp = V2_ODO * 1000u;
                                               if (Services_Read_ODO_ClearCnt1() <= 10000ul)
                                               {
                                                   Services_ODO_Modify_Sync(2u);
                                                   Data_ODO_Modify(m_Temp);
                                               }
                                               ODO_Sync_Enable_Lock = 2u;
                                           }
                                       }
                                   }
                               }
                           }
                           ODO_Sync_Enable = 1u;
                       }
                       else  if (Services_ODO_SyncValid() == 2u)
                       {
                           ODO_Sync_Enable_Lock = 1u;
                           ODO_Sync_Enable = 0u;
                           for (i = 0u; i < 5u; i++)
                           {
                               EMS_ODO[i].ODO_Save = 0u;
                               EMS_ODO[i].ODO_Save_Counter = 0u;
                               VCU_ODO[i].ODO_Save = 0u;
                               VCU_ODO[i].ODO_Save_Counter = 0u;
                           }
                       }
                       else
                       {
                           /*do nothing*/
                       }
                   }
                   else
                   {
                       ODO_Sync_Enable = 0u;
                       /*ODO_Sync_Enable_Lock = 1u;*/
                   }
               }
           }
           else if (ODO_Sync_Enable_Lock == 2u)
           {
               ODO_Sync_Enable = 1u;
           }
           else
           {
               ODO_Sync_Enable = 0u;
           }
       }
       else
       {
           ODO_Sync_Enable = 0u;
       }
   }
   else
   {
       ODO_Sync_Enable = 0u;
   }
}
void Services_ODO_PulseCbk(uint16_t m_Inc)
{

}

uint8_t Services_ODO_Enable(void)
{
    return ODO_Sync_Enable;
}

void Services_ODO_PMS_Read(uint8_t val [])
{
    uint32_t V1_ODO;
    V1_ODO = Get_ID_18FAA827_Sig_PMS_Odometerbackup( );
    Services_ODO_EMS_Set(V1_ODO);
    Services_EMS_CounterAdd( );
}

void Services_ODO_MCU_Read(uint8_t val [])
{
    uint32_t V2_ODO;
    V2_ODO = Get_ID_18FA09EF_Sig_MCU_Odometerbackup( );

    Services_ODO_VCU_Set(V2_ODO);
    Services_VCU_CounterAdd( );
}