#include "Services_ODO.h"


extern uint32_t Factory_ClearOdo_Display_Flag;
/*KL15初始化,每次上电调用*/
void Data_ODO_KL15Init ( void )
{
    Input_ODO_Para.PowerSts = DataPowerOn;
    DataODOCalc.UpdateDisable = 0u;
}
/*放在EEPROM初始化之后,只调用一次*/
void Data_ODO_KL30Init ( uint32_t Val_ODO , uint8_t Valid_ODO)
{

    Input_ODO_Para.PowerSts = DataPowerOFF;
    Input_ODO_Para.V_Speed_Valid = 0u;
    Input_ODO_Para.Act_V_Speed = 0u;
    Input_ODO_Para.E_Speed_Valid = 0u;
    Input_ODO_Para.Act_E_Speed = 0u;
    Input_ODO_Para.TireSize = 0u;

    /*里程滚动计数器*/
    DataMileageRollingCounter    = 0u;
    DataMileage.mmRollingCounter = 0u;
    DataMileage.mmRoCBackup      = 0u;

    /*总计里程*/
    DataODOValid = Valid_ODO;
    DataODOCalc.UpdateDisable = 0u;
    DataODOCalc.RoCBackup     = 0u;
    if (Valid_ODO == DataValid)
    {
        Data_ODO_Val = Val_ODO;
        EEPROM_St = 0u;
    }
    else
    {
        EEPROM_St = 0xffu;
        Data_ODO_Val = 0u;
    }
    DataODOCalc.LastSaved     = Val_ODO;
}



/******************************************************************************
函数名：Data_ODO_Processing
功  能: 总计里程数据处理
参  数: 无
返回值：无
******************************************************************************/
void Data_ODO_Processing ( void )
{
    uint16_t RollingCounter = 0u;
    uint16_t Inc = 0u;
    uint16_t m_Diff = 0u;

    if ( EEPROM_St == 0xffu )
    {
        DataODOValid = 0u;
    }
    else
    {
        RollingCounter = DataMileageRollingCounter;

        if ( DataODOCalc.UpdateDisable == 1u)
        {
            if (( Input_ODO_Para.V_Speed_Valid ) && ( Input_ODO_Para.Act_V_Speed >= 1880u ))
            {
                DataODOCalc.RoCBackup = RollingCounter;
            }
            else
            {
                DataODOCalc.UpdateDisable = 0u;
            }
        }
        else
        {
            if ( DataODOValid == 0u )
            {
                DataODOCalc.RoCBackup = RollingCounter;
                DataODOValid = 1u;
            }

            if ( RollingCounter >= DataODOCalc.RoCBackup )
            {
                m_Diff = RollingCounter - DataODOCalc.RoCBackup;
            }
            else
            {
                m_Diff = 65535u - DataODOCalc.RoCBackup + RollingCounter + 1u;
            }

            if ( m_Diff >= 100u )
            {
                Inc = m_Diff / 100u;
                DataODOCalc.RoCBackup += Inc * 100u;

                Data_ODO_Val += Inc;
                if ( Data_ODO_Val > 9999999ul)
                {
                    Data_ODO_Val = 9999999ul;
                }
                if (( Data_ODO_Val - DataODOCalc.LastSaved) >= 1u)
                {
                    Services_ODO_SaveCall(Data_ODO_Val);
                    Services_ODO_PulseCbk(Inc);
                    DataODOCalc.LastSaved = Data_ODO_Val;
                }
            }
        }
    }
}

/******************************************************************************
函数名：Data_ODO_Update_Disable
功  能: 禁止总计里程数据更新
参  数: 无
返回值：无
******************************************************************************/
void Data_ODO_Update_Disable ( void )
{
    DataODOCalc.UpdateDisable = 1u;
}

void Data_ODO_Modify ( uint32_t Val_ODO )
{
    if (Val_ODO >= 9999999ul)
    {
        Val_ODO=9999999ul;
    }
    Services_ODO_SaveCall(Val_ODO);
    Data_ODO_Val = Val_ODO;
    DataODOCalc.LastSaved     = Data_ODO_Val;
    DataODOValid = 1u;
    DataODOCalc.RoCBackup = DataMileageRollingCounter;
    DataODOCalc.UpdateDisable = 0u;
    DataMileage.mmRoCBackup = DataMileage.mmRollingCounter ;
}
/*保证在中断函数上方调用*/
void Data_Mileage_Set_Para(_DataODOInputStruct *m_Para)
{
    Input_ODO_Para.PowerSts = m_Para->PowerSts;
    Input_ODO_Para.V_Speed_Valid = m_Para->V_Speed_Valid;
    Input_ODO_Para.Act_V_Speed = m_Para->Act_V_Speed;
    Input_ODO_Para.E_Speed_Valid = m_Para->E_Speed_Valid;
    Input_ODO_Para.Act_E_Speed = m_Para->Act_E_Speed;
    Input_ODO_Para.TireSize = m_Para->TireSize;
}


/*Core Process*/
/*place 100ms task*/
void Data_Mileage_Rolling_Counter_Update_ISR ( void )
{
    uint16_t Mileage;
    uint16_t m_ActSpeed;
    uint16_t m_diff;

    if ( Input_ODO_Para.PowerSts == DataPowerOn)
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
            if ( Input_ODO_Para.V_Speed_Valid )
            {
                m_ActSpeed = Input_ODO_Para.Act_V_Speed;
                m_ActSpeed = (uint16_t)((((uint32_t)Input_ODO_Para.TireSize) * m_ActSpeed) / 10000u);
                if (( m_ActSpeed >= 20u )&& (m_ActSpeed <= 1880u))
                {
                    Mileage = ( m_ActSpeed * 25u ) / 9u;
                }
                else
                {
                    Mileage = 0u;
                }
                DataMileage.mmRollingCounter += Mileage;
                /*将原始的mm单位的Rolling Counter变换为以m为单位*/
                if ( DataMileage.mmRollingCounter >= DataMileage.mmRoCBackup )
                {
                    m_diff = DataMileage.mmRollingCounter - DataMileage.mmRoCBackup;

                    if ( m_diff  >= 1000u )
                    {
                        Mileage = m_diff;
                        Mileage /= 1000u;
                        DataMileage.mmRoCBackup += Mileage * 1000u;
                        DataMileageRollingCounter += Mileage;
                    }
                }
                else
                {
                    m_diff = 65535u - DataMileage.mmRoCBackup + DataMileage.mmRollingCounter + 1u;

                    if ( m_diff >= 1000u )
                    {
                        Mileage = m_diff ;
                        Mileage /= 1000u;
                        DataMileage.mmRoCBackup += Mileage * 1000u;
                        DataMileageRollingCounter += Mileage;
                    }
                }
            }
        }
        
    }
}


uint32_t Data_ODO_Read(void)
{
    return Data_ODO_Val;
}
uint16_t Data_MileageRollingCounter_Read(void)
{
    return DataMileageRollingCounter;
}
uint8_t Valid_ODO_Read(void)
{
    return DataODOValid;
}

/*
增加回调函数接口
*/
uint16_t Services_ODO_Version(void)
{
    return 0x0002u;
}

uint16_t Services_ODO_mmRollingCounter(void)
{
    return DataMileage.mmRollingCounter;
}