#include "Services_ODO_User.h"
#include "Common_Interface.h"
#include "GaugesInterface.h"
#include "Gauges.h"
#include "Emulated_EEPROM.h"
#include "Watchdog.h"
#include "Data_FuelConsump.h"

#pragma ghs section bss=".myNonInitArea"
#pragma alignvar(8)
uint8_t DataMilleageBuf[Data_MEM_Block_Mileage];
uint8_t DataODOBuf[Data_MEM_Block_ODO];
uint8_t DataTripBuf[Data_MEM_Block_Trip * EM_TRIP_MAX];
uint8_t TripRetainFlag = 0;
#pragma ghs section bss=default

uint8_t ODO_Clear_Num_Value  = 0; /*清除次数EEP计数器*/

static void my_memset(uint32_t u32Data[], uint16_t u16Len, uint32_t value);
/*static uint32_t Data_User_EEPROM_Read(uint16_t u16BlockID, uint32_t u32Data[], uint16_t u16Len);
static void Data_User_EEPROM_Write(Data_EEPROM_Enum_t BlockID, uint32_t u32Data[], uint16_t u16Len);*/

/******************************************************************************
  Function:Data_ODO_KL30Init
  Description:
  Input:
  Output:
 ******************************************************************************/
void Data_User_Mileage_KL30Init(void)
{
    uint32_t TempBuf[EM_TRIP_MAX + 3] = {0};
    Mileage_Init_t MileInit = {0};
    Mileage_Func_t Func = {0};
    ODO_Init_t ODOInit = {0};
    Trip_Init_t TripInit[EM_TRIP_MAX] = {0};

    //以下数据从EEPROM中读取
    Data_User_EEPROM_Read(EEPROM_BLOCK_ODO, TempBuf, 1);
    MileInit.Mileage = TempBuf[0];
    Func.Get_Sys_IG_Sts = Common_Get_IG_Sts;
    Func.Get_Act_V_Speed_Valid = Common_Get_Act_V_Speed_Valid;
    Func.Get_Act_V_Speed = Common_Get_Act_V_Speed;
    Func.Get_TireSize = ( void * )0;
    Func.EEPromWrite_Cbk = Data_User_EEPROM_Write;  //暂时未设置
    Data_Mileage_KL30_Init(DataMilleageBuf, &MileInit, &Func);

    Data_User_EEPROM_Read(EEPROM_BLOCK_ODO_STAMP, TempBuf + 1, 2);
    ODOInit.Stamp = TempBuf[1];
    ODOInit.Offset = TempBuf[2];
    Data_ODO_KL30_Init(DataODOBuf, &ODOInit, Func.EEPromWrite_Cbk);

    Data_User_EEPROM_Read(EEPROM_BLOCK_TRIP_STAMP, TempBuf + 3, EM_TRIP_MAX);

    TripInit[EM_TRIP_A].Stamp = TempBuf[3];
    TripInit[EM_TRIP_A].MaxValue = 9999999u;
    TripInit[EM_TRIP_A].IsRestart = 1u;

    TripInit[EM_TRIP_B].Stamp = TempBuf[4];
    TripInit[EM_TRIP_B].MaxValue = 9999999u;
    TripInit[EM_TRIP_B].IsRestart = 1u;

    TripInit[EM_TRIP_JY].Stamp = TempBuf[5];
    TripInit[EM_TRIP_JY].MaxValue = 999999;
    TripInit[EM_TRIP_JY].IsRestart = 0u;

    TripInit[EM_TRIP_RY].Stamp = TempBuf[6];
    TripInit[EM_TRIP_RY].MaxValue = 999999;
    TripInit[EM_TRIP_RY].IsRestart = 0u;

    TripInit[EM_TRIP_BSX].Stamp = TempBuf[7];
    TripInit[EM_TRIP_BSX].MaxValue = 999999;
    TripInit[EM_TRIP_BSX].IsRestart = 0u;

    TripInit[EM_TRIP_CSQ].Stamp = TempBuf[8];
    TripInit[EM_TRIP_CSQ].MaxValue = 999999;
    TripInit[EM_TRIP_CSQ].IsRestart = 0u;

    TripInit[EM_TRIP_KQGZJ].Stamp = TempBuf[9];
    TripInit[EM_TRIP_KQGZJ].MaxValue = 999999;
    TripInit[EM_TRIP_KQGZJ].IsRestart = 0u;

    TripInit[EM_TRIP_DLZX].Stamp = TempBuf[10];
    TripInit[EM_TRIP_DLZX].MaxValue = 999999;
    TripInit[EM_TRIP_DLZX].IsRestart = 0u;

    TripInit[EM_TRIP_LT].Stamp = TempBuf[11];
    TripInit[EM_TRIP_LT].MaxValue = 999999;
    TripInit[EM_TRIP_LT].IsRestart = 0u;

    Data_Trip_KL30_Init(DataTripBuf, TripInit, EM_TRIP_MAX, Func.EEPromWrite_Cbk);
}

void Data_User_Mileage_KL15Init(void)
{
    Mileage_Func_t Func = {0};

    Func.Get_Sys_IG_Sts = Common_Get_IG_Sts;
    Func.Get_Act_V_Speed_Valid = Common_Get_Act_V_Speed_Valid;
    Func.Get_Act_V_Speed = Common_Get_Act_V_Speed;
    Func.Get_TireSize = ( void * )0;
    Func.EEPromWrite_Cbk = Data_User_EEPROM_Write;  //暂时未设置
    Data_Mileage_Wakeup_Init(DataMilleageBuf, &Func);

    Data_ODO_Wakeup_Init(DataODOBuf, Func.EEPromWrite_Cbk);

    Data_Trip_Wakeup_Init(DataTripBuf, EM_TRIP_MAX, Func.EEPromWrite_Cbk);
}

/******************************************************************************
  Function:Data_ODO_Clear_KL30Init
  Description:
  Input:
  Output:
 ******************************************************************************/
void Data_ODO_Clear_KL30Init(void)
{
    ODO_Clear_Num_Value = 0u;   /*从EEP读取次数赋值*/
}

/******************************************************************************
  Function:Data_ODO_Clear_KL15Init
  Description:3
  Input:
  Output:
 ******************************************************************************/
void Data_ODO_Clear_KL15Init(void)
{

}

/******************************************************************************
  Function:TYW_Data_ODO_Clear
  Description:天有为清总计里程策略
  Input:
  Output:
 ******************************************************************************/
void TYW_Data_ODO_Clear(void)
{
    /*条件控制 1 按键控制(在按键处做处理)
        此处只除按键外其他条件进行处理
        2 燃油 车速最大 转速最大
        3 电车 车速最大 转速最大 电量最低 等等*/
    uint16_t Get_Data_Veh_value = 0u ;
    uint16_t Get_Data_Rev_value = 0u ;
    uint16_t Get_Data_Veh_valueMax = 0u;
    uint16_t Get_Data_Rev_valueMax = 0u;

    /*获取的是步数,与当前步数*/
    Get_Data_Veh_value    = GetGaugesCurrentPos(VehGauges) ;
    Get_Data_Veh_valueMax = GetGaugesMaxOutVal(VehGauges) ;

    Get_Data_Rev_value    = GetGaugesCurrentPos(RevGauges) ;
    Get_Data_Rev_valueMax = GetGaugesMaxOutVal(RevGauges) ;

    //if (( Get_Data_Veh_value >= Get_Data_Veh_valueMax ) && ( Get_Data_Rev_value >= Get_Data_Rev_valueMax ))
    {
        Data_Mileage_Clear();
    }
}

/******************************************************************************
 Function:TYW_Data_ODO_Clear
 Description:固定距离固定次数 清总计里程
 Input:
 Output:
******************************************************************************/
void Data_ODO_Clear_Mileage_Num(void)
{

#if  ONLY_CLEAR_ODO_MIL

    if ( Data_ODO_Read() <= ODO_CLEAR_MIL )   /*0.1KM*/
    {
        Data_ODO_Clear();
        Data_Clear_Trip(EM_TRIP_A);
    }
#endif

#if  ONLY_CLEAR_ODO_NUM

    if ( ODO_Clear_Num_Value <= ODO_CLEAR_NUM )
    {
        ODO_Clear_Num_Value ++;
        /*数据需要保存,需要进行RRP存储*/

        Data_ODO_Clear();
        Data_Clear_Trip(EM_TRIP_A);
    }
#endif

#if  CLEAR_ODO_NUM_MIL

    if (( Data_ODO_Read() <= ODO_CLEAR_MIL ) && ( ODO_Clear_Num_Value <= ODO_CLEAR_NUM ))
    {
        ODO_Clear_Num_Value ++;
        /*数据需要保存,需要进行RRP存储*/

        Data_ODO_Clear();
        Data_Clear_Trip(EM_TRIP_A);
    }
#endif

    /*
    #if defined  (ONLY_CLEAR_ODO_NUM)
    #include "debugger.h"
    #else
    #error NO_ONLY_CLEAR_ODO_NUM_found
    #endif
    */

    /*
    void dhd_debug_panic( const dhd_char_t *a_message, const dhd_char_t *a_file, dhd_uint32_t a_line ) {
      dhd_debug_out("DHD_PANIC (ros platform handler): %s (in %s: %d) -> halting thread execution NOW!\n", a_message, a_file, a_line);
      for (;;) {
      }
    } */
}

void Data_User_EEPROM_Read(uint16_t u16BlockID, uint32_t u32Data[], uint16_t u16Len)
{
    EEPROM_RW_Result_en_t enResult = EEPROM_RW_PASS;

    if (EEPROM_Get_Block_Status(u16BlockID) == EEPROM_STAT_ACTIVE)
    {
        while (EEPROM_Get_Status() == EEPROM_STAT_BUSY)
        {
            WDT_Clear();
        }
        enResult = EEPROM_Read_Data(u16BlockID, u32Data, u16Len);
        if (enResult == EEPROM_RW_FAIL)
        {
            my_memset(u32Data, u16Len, 0);
        }
    }
    else
        my_memset(u32Data, u16Len, 0);
}

static void my_memset(uint32_t u32Data[], uint16_t u16Len, uint32_t value)
{
    uint16_t i = 0;

    for (i = 0; i < u16Len; i++)
    {
        u32Data[i] = value;
    }
}

void Data_User_EEPROM_Write(Data_EEPROM_Enum_t BlockID, uint32_t u32Data[], uint16_t u16Len)
{
    uint16_t u16BlockID = 0;

    switch (BlockID)
    {
    case EM_MILEAGE_BLOCK:
        u16BlockID = EEPROM_BLOCK_ODO;
        break;

    case EM_ODO_BLOCK:
        u16BlockID = EEPROM_BLOCK_ODO_STAMP;
        break;

    case EM_TRIP_BLOCK:
        u16BlockID = EEPROM_BLOCK_TRIP_STAMP;
        break;
    case EM_Maintenance_BLOCK :
        u16BlockID = EEPROM_BLOCK_SERVICE_INFO ;
        break;
    default:
        break;
    }

    if (EEPROM_Get_Block_Status(u16BlockID) != EEPROM_STAT_ERROR)
    {
        while (EEPROM_Get_Status() == EEPROM_STAT_BUSY)
        {
            WDT_Clear();
        }
        EEPROM_Write_Data(u16BlockID, u32Data, u16Len);

        while (EEPROM_Get_Status() == EEPROM_STAT_BUSY)
        {
            WDT_Clear();
        }
    }
}