

#include "Services_Mileage_User.h"
#include "Common_Interface.h"
#include "eepromManage.h"

#include "CAN_Communication_Matrix.h"
#include "wdt.h"
uint32_t TotalODOTemp = 0;
uint16_t ODORemainder = 0;
Mileage_t   g_WriteMileage __attribute__ ((aligned (4)));
Mileage_t   g_ReadMileage __attribute__ ((aligned (4)));
uint8_t SaveODOValid = 0;
uint16_t   odoVaild = 0;
uint8_t ModfyODORemainTimes = 0;
uint16_t ModfyODOTimeDelay_ms = 0;
#define EEPROM_BLOCK_00 0   //用来储存总计清零次数
#define EEPROM_BLOCK_01 16
#define EEPROM_BLOCK_02 32
#define EEPROM_BLOCK_03 48
#define EEPROM_BLOCK_04 64
#define EEPROM_BLOCK_05 80
void Mileage_Delay_ms(uint32_t u32Ms)
{
    uint32_t  i, Counter;

    for(Counter = 0; Counter < u32Ms; Counter++) {
        for(i = 0; i < 44; i++) {
            __NOP();
            __NOP();
            __NOP();
        }
        WDT_Restart();
    }
}
void CalcODOKL30Init(void)
{
    odoVaild = eeprom_ReadODO(&g_ReadMileage);
    if(g_ReadMileage.Odo>= g_WriteMileage.Odo)
    {
        g_WriteMileage.Odo = g_ReadMileage.Odo;
    }
    if(g_ReadMileage.Trip>= g_WriteMileage.Trip)
    {
        g_WriteMileage.Trip = g_ReadMileage.Trip;
    }
    if(g_ReadMileage.Trip1>= g_WriteMileage.Trip1)
    {
        g_WriteMileage.Trip1 = g_ReadMileage.Trip1;
    }

    eeprom_ReadRecord(EEPROM_BLOCK_00,(uint8_t*)&ModfyODORemainTimes,1);
    if(ModfyODORemainTimes == 0xff){
        ModfyODORemainTimes = 3;
    }
}
void CalcODOKL15Init(void)
{
    SaveODOValid = 1;

}
void CalcODOIgnOffInit(void)
{
    SaveODOValid = 1;

}
//=======================================
//+++++++50ms任务调度+++++++++++++++++
//
//根据车速计算里程数			
//=======================================
void CalcODO_50ms_Services(void)
{
  uint32_t mVspeed=0;
  
  if(Common_Get_IG_Sts() == COMMON_POWER_OFF){
    return;
  }
  mVspeed = Common_Get_Act_V_Speed();
  if(mVspeed > 3600){
        mVspeed = 3600;
  }

  TotalODOTemp   +=   (mVspeed * 25) / 18;  //50ms cycle
  /*取余数*/
  ODORemainder += (mVspeed * 25) % 18; 
  
  if(ODORemainder >= 18 )
  {
      ODORemainder -= 18;
      TotalODOTemp ++;
  } 
      
    
    if (TotalODOTemp > 10000) 
    {
        TotalODOTemp -= 10000;
        g_WriteMileage.Odo += 10;
        
        if ((g_WriteMileage.Odo % 100) == 0) 
        {
            SaveODOValid = 1;
        }

        g_WriteMileage.Trip += 10;
        g_WriteMileage.Trip1 += 10;
        
        
        if (g_WriteMileage.Odo > 1609343999) {  //999999mile
            g_WriteMileage.Odo = 1609343999;
        }        
    }
}
void CalcODO_100ms_Services(void)
{
    uint8_t PwSts = 0;
    uint32_t temp32 = 0;
    static uint8_t clearEnFlag = 0;
    static uint8_t TripClearCommandBak = 0;

  if(odoVaild == 0)
  {
      /* qitiancun 防止上电读取失败 */
      odoVaild = eeprom_ReadODO(&g_ReadMileage);
      if(g_ReadMileage.Odo >= g_WriteMileage.Odo)
      {
          g_WriteMileage.Odo = g_ReadMileage.Odo;
      }
      if(g_ReadMileage.Trip>= g_WriteMileage.Trip)
      {
          g_WriteMileage.Trip = g_ReadMileage.Trip;
      }
      if(g_ReadMileage.Trip1>= g_WriteMileage.Trip1)
      {
          g_WriteMileage.Trip1 = g_ReadMileage.Trip1;
      }
  }

    if (SaveODOValid) {
        SaveODOValid = 0;

        if(Common_Get_IG_Sts() == COMMON_POWER_ON) {
            PwSts = 1;
        }
        else {
            PwSts = 0;
        }

        eeprom_WriteODO( &g_WriteMileage , distance_100m , PwSts);
    }

    //厂家清大计，
    //200km ODO以内，可以清除总里程，ODO可以改大，不能改小。
    //两者共享次数为3次，仪表两次里程操作响应间隔时间为10s。触发后连发3次。
    if(ModfyODOTimeDelay_ms >= 100){
        ModfyODOTimeDelay_ms -= 100;
    }    
    else{
        if(ModfyODORemainTimes){
            //0x01= 清零总里程（小于200km）
            if((Get_ID_55C_Sig_ModifyODOSts() == 1) && (g_WriteMileage.Odo) && (g_WriteMileage.Odo < 200000)){
                ModfyODOTimeDelay_ms = 10000;
                g_WriteMileage.Odo = 0u;
                g_WriteMileage.Trip = 0;
                g_WriteMileage.Trip1 = 0;
                TotalODOTemp = 0;
                ModfyODORemainTimes--;
                eeprom_ClearOdoSection();
                Mileage_Delay_ms(40);
                eeprom_WriteRecord(EEPROM_BLOCK_00,(uint8_t*)&ModfyODORemainTimes,1);            
            }

            //0x02= 设置总里程（只能改大，改小不响应）
            temp32 = Get_ID_55C_Sig_ModifyODOValue();
            temp32 *= 100;
            if((Get_ID_55C_Sig_ModifyODOSts() == 2) && (g_WriteMileage.Odo < temp32)){
                ModfyODOTimeDelay_ms = 10000;
                
                g_WriteMileage.Trip = 0;
                g_WriteMileage.Trip1 = 0;
                TotalODOTemp = 0;
                ModfyODORemainTimes--;
                
                for(uint32_t i=0; i<20; i++){
                    if(temp32 > i*100){
                        g_WriteMileage.Odo = temp32-((19-i)*100);
                    }
                    else{
                        g_WriteMileage.Odo = 0;
                    }
                    eeprom_WriteODO( &g_WriteMileage , distance_100m , 1);
                    Mileage_Delay_ms(20);
                }
                eeprom_WriteRecord(EEPROM_BLOCK_00,(uint8_t*)&ModfyODORemainTimes,1);
            }            
        }
    }

    //TBOX控制清小计
    temp32 = Get_ID_55C_Sig_ClearTrip();

    //一定要判断数据发生变化再清一次，避免频繁写EEPROM
    if((temp32 == 0) || (temp32 != TripClearCommandBak)){
        clearEnFlag = 1;
    }

    if(clearEnFlag){

        if(temp32 == 0x01){    //清零TRIPA
            Data_Clear_Trip ( EM_TRIP_A );
            clearEnFlag = 0;
        }
        else if(temp32 == 0x02){   //清零TRIPB
            Data_Clear_Trip ( EM_TRIP_B );
            clearEnFlag = 0;
        }
        else if(temp32 == 0x03){   //全部清零
            Data_Clear_Trip ( EM_TRIP_A );
            Data_Clear_Trip ( EM_TRIP_B );
            clearEnFlag = 0;
        }
    }
    TripClearCommandBak = temp32;
    
}
uint32_t Data_Read_Trip(DataTripEnum_t TripN)
{
    uint32_t temp32 = 0;
    if(TripN == EM_TRIP_A){
        temp32 = g_WriteMileage.Trip;
    }
    else if(TripN == EM_TRIP_B){
        temp32 = g_WriteMileage.Trip1;
    }
    
    return temp32;
}

uint32_t Data_ODO_Read ( void )
{
    return g_WriteMileage.Odo;
}

void Data_Clear_Trip ( DataTripEnum_t TripN )
{
    if(TripN == EM_TRIP_A){
         g_WriteMileage.Trip = 0u;
         g_WriteMileage.IsTripClear = 1;
    }
    else if(TripN == EM_TRIP_B){
         g_WriteMileage.Trip1 = 0u;
         g_WriteMileage.IsTrip1Clear = 1;
    }
    
    SaveODOValid = 1;

}
void Data_Mileage_Clear(void)
{
    /*产线 清大计和flash校验使用*/
    g_WriteMileage.Odo = 0u;
    g_WriteMileage.Trip = 0;
    g_WriteMileage.Trip1 = 0;
    TotalODOTemp = 0;
    ModfyODORemainTimes = 3;
    eeprom_ClearOdoSection();
    Mileage_Delay_ms(40);
    eeprom_WriteRecord(EEPROM_BLOCK_00,(uint8_t*)&ModfyODORemainTimes,1);

}

