
#include "Services_ODO_User.h"
#include "Common_Interface.h"
#include "GaugesInterface.h"
#include "Gauges.h"
#include "Emulated_EEPROM.h"
#include "Watchdog.h"
#include "Data_VehicleSpeed.h"
#include "Data_DrvMtrSpd.h"
#include "Key.h"
#include "FlashCheckSum.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;
_Menu_Configure_Value Menu_Con_EEP_Value;
#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[7] = {0};
    Mileage_Init_t MileInit = {0};
    Mileage_Func_t Func = {0};
    ODO_Init_t ODOInit = {0};
    Trip_Init_t TripInit[4] = {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, 4);
    TripInit[EM_TRIP_A].Stamp = TempBuf[3];
    TripInit[EM_TRIP_A].MaxValue = 100000ul;
    TripInit[EM_TRIP_A].IsRestart = 1u;

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

    TripInit[EM_TRIP_C].Stamp = TempBuf[5];
    TripInit[EM_TRIP_C].MaxValue = 100000ul;
    TripInit[EM_TRIP_C].IsRestart = 1u; 

    TripInit[EM_TRIP_D].Stamp = TempBuf[6];
    TripInit[EM_TRIP_D].MaxValue = 100000ul;
    TripInit[EM_TRIP_D].IsRestart = 1u; 

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

    Data_User_EEPROM_Read(EEPROM_BLOCK_UE_INFO, &Menu_Con_EEP_Value, (sizeof(Menu_Con_EEP_Value) / 4u));

    if (Menu_Con_EEP_Value.K_Value_Num_Value4 != 0xA5u)
    {
        Menu_Con_EEP_Value.K_Value_Num_Value4 = 0xA5u;
        Menu_Con_EEP_Value.Set_VdoFmtTyp      = 0u;
        VdoFmtTyp_Set(0u);
        Common_Set_VdoFmtTyp(0u);
    }
    else
    {
        VdoFmtTyp_Set(Menu_Con_EEP_Value.Set_VdoFmtTyp);
    
        if (VdoFmtTyp_Get() > 2u)
        {
            VdoFmtTyp_Set(0u); //20230906由2改成0
        }
    }
    /*20230906增加限速报警初始值设定*/
    if (Menu_Con_EEP_Value.K_Value_Num_Value5 != 0x5Au)
    {
        Menu_Con_EEP_Value.K_Value_Num_Value5 = 0x5Au;
        Menu_Con_EEP_Value.Set_LitSpdTyp      = 1u;
        LitSpdTyp_Set(1u);
        Common_Set_LitSpdTyp(1u);
    }
    else
    {
        LitSpdTyp_Set(Menu_Con_EEP_Value.Set_LitSpdTyp);

        if (LitSpdTyp_Get() > 2u)
        {
            LitSpdTyp_Set(1u);
        }
    }
    /* 语言初始值设置 */
    if (Menu_Con_EEP_Value.K_Value_Num_Value3 != 0x5Au)
    {
        Menu_Con_EEP_Value.K_Value_Num_Value3 = 0x5Au;
        Menu_Con_EEP_Value.Set_LanguageTyp    = 0u;
        LanguageTyp_Set(0u);
        Common_Set_LanguageTyp(0u);
    }
    else
    {
        LanguageTyp_Set(Menu_Con_EEP_Value.Set_LanguageTyp);

        if (LanguageTyp_Get() > 1u)
        {
            LanguageTyp_Set(0u);
        }
    }
}

#if 0 //20230830按领导要求恢复原样
void VdoFmtTyp_Read(void)
{
    uint8_t temp = 0u;

    Data_User_EEPROM_Read(EEPROM_BLOCK_UE_INFO, &Menu_Con_EEP_Value, (sizeof(Menu_Con_EEP_Value) / 4u));

    temp = Menu_Con_EEP_Value.Set_VdoFmtTyp;

    if (temp > 2u)
    {
        temp = VdoFmtTyp_Get();
        Common_Set_VdoFmtTyp(temp);
    }
    else
    {
        if (temp != VdoFmtTyp_Get())
        {
            VdoFmtTyp_Set(temp);
        }
    }
}
#endif

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:
 ******************************************************************************/

extern void loc_Test_Red(void);

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    = Speed_Get_Display_Value();
    Get_Data_Veh_valueMax = 1200;

    Get_Data_Rev_value    = DrvMtrSpd_Get_DisplayValue();
    Get_Data_Rev_valueMax = 15000;

    if ((Get_Data_Veh_value >= Get_Data_Veh_valueMax) && (Get_Data_Rev_value >= Get_Data_Rev_valueMax) && (Key3_Press_Time_Get() >= 300))
    {
        Data_Mileage_Clear();
        
        if (Data_ODO_Read() == 0)
        {
            if (CheckSpiFlashCRC() == 0u)
            {
                loc_Test_Red();
            }
        }
    }
}

/******************************************************************************
 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();
    }
#endif

#if  ONLY_CLEAR_ODO_NUM

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

        Data_ODO_Clear();
    }
#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();
    }
#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();
        }
    }
}
