#include "Components.h"
__align(4)
uint8_t DataMilleageBuf[Data_MEM_Block_Mileage];
uint8_t DataODOBuf[Data_MEM_Block_ODO];
uint8_t DataTripBuf[Data_MEM_Block_Trip * EM_TRIP_MAX];
Mileage_t g_WriteMileage;
Mileage_t g_ReadMileage;
uint16_t odo_writeState;
uint16_t odoclr_writeState;
uint16_t trip_writeState;
uint16_t trip_readState;
uint16_t odo_readState;
//uint8_t odo_readState;
uint32_t Milleage_InitFlag = 0U;
/******************************************************************************
  Function:Data_ODO_KL30Init
  Description:
  Input:
  Output:
 ******************************************************************************/
void Data_User_Mileage_KL30Init(void)
{
    uint32_t TempBuf[20] = {0};
    uint8_t TempBufUser[20] = {0};
    Mileage_Init_t MileInit = {0};
    Mileage_Func_t Func = {0};
    ODO_Init_t ODOInit = {0};
    uint32_t Maintenance_Firstflg[1u] = {0};
    Trip_Init_t TripInit[4] = {0};
    uint8_t TPMSLearn[2] = {0,0};
    Milleage_InitFlag = 0U;
    // �������ݴ�EEPROM�ж�ȡ
    (void)Data_User_EEPROM_Read(EM_MILEAGE_BLOCK, TempBuf, 1);
    if (TempBuf[0] == 0xFFFFFFFF)
    {
        MileInit.Mileage = 0u;
    }          
    else                           
    {             
        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_ODO;
    Func.Get_TireSize = (void *)0;
    Func.EEPromWrite_Cbk = Data_User_EEPROM_Write; // ��ʱδ����
    Data_Mileage_KL30_Init(DataMilleageBuf, &MileInit, &Func);

    (void)Data_User_EEPROM_Read(EM_ODO_BLOCK, TempBuf + 1, 2);
    if (TempBuf[1] == 0xFFFFFFFF)
    {
        ODOInit.Stamp = 0;
    }
    else
    {
        ODOInit.Stamp = TempBuf[1];
    }
    if (TempBuf[1] == 0xFFFFFFFF)
    {
        ODOInit.Offset = 0;
    }
    else
    {
        ODOInit.Offset = TempBuf[1];
    }
    ODOInit.MaxValue = 3218672;//英里199999
    Data_ODO_KL30_Init(DataODOBuf, &ODOInit, Func.EEPromWrite_Cbk);

    (void)Data_User_EEPROM_Read(EM_TRIP_BLOCK, TempBuf + 3, 2);
    if (TempBuf[3] == 0XFFFFFFFF)
    {
        TripInit[EM_TRIP_A].Stamp = 0;
    }
    else
    {
        TripInit[EM_TRIP_A].Stamp = TempBuf[3];
    }
    if (TempBuf[4] == 0XFFFFFFFF)
    {
        TripInit[EM_TRIP_A].Offset = 0;
    }
    else
    {
        TripInit[EM_TRIP_A].Offset = TempBuf[4];
    }
    //TripInit[EM_TRIP_A].Offset = TempBuf[4];
    TripInit[EM_TRIP_A].MaxValue = 16099; /* 英里最大999.9km 进行复位 */
    TripInit[EM_TRIP_A].IsRestart = 1u;

    //TripInit[EM_TRIP_B].Stamp = 0xFFFFFFFFu;
    //TripInit[EM_TRIP_B].MaxValue = 99999;
    //TripInit[EM_TRIP_B].IsRestart = 1u;
//
    //TripInit[EM_TRIP_C].Stamp = 0xFFFFFFFFu;
    //TripInit[EM_TRIP_C].MaxValue = 99999;
    //TripInit[EM_TRIP_C].IsRestart = 1u;
//
    //TripInit[EM_TRIP_D].Stamp = 0xFFFFFFFFu;
    //TripInit[EM_TRIP_D].MaxValue = 99999;
    //TripInit[EM_TRIP_D].IsRestart = 1u;
    Data_Trip_KL30_Init(DataTripBuf, TripInit, EM_TRIP_MAX, Func.EEPromWrite_Cbk);

    //Data_User_EEPROM_Read(EM_MenuData_Tcs_Val, TempBuf, 1u); 
    eeprom_ReadRecord(EEPROM_BLOCK_08, (uint8_t *)TempBufUser,  1);  
    if (TempBufUser[0u] == 0xFF)
    {     
        MenuData.Tcs_Val = 1;      
        //Data_User_EEPROM_Write(EM_MenuData_Tcs_Val, &MenuData.Tcs_Val, 1u);  
        eeprom_WriteRecord(EEPROM_BLOCK_08, &MenuData.Tcs_Val,  1);
    }

    //Data_User_EEPROM_Read(EM_MenuData_TPMS_LEARN, TempBuf, 1u);  
    eeprom_ReadRecord(EEPROM_BLOCK_09, (uint8_t *)TempBufUser,  2);
    if (TempBufUser[0u] == 0xFF)
    { 
        TPMSLearn[0] =  0;//MenuData.TPMS_Front_Learn;   
        TPMSLearn[1] =  0;//MenuData.TPMS_Rear_Learn;        
        //Data_User_EEPROM_Write(EM_MenuData_TPMS_LEARN, (uint32_t *)TPMSLearn, 1u); 
        eeprom_WriteRecord(EEPROM_BLOCK_09, TPMSLearn, 2); 
    }

    Milleage_InitFlag = 0X5AA53AA3UL;

}

void Data_User_Mileage_WakeupInit(void)
{
    Mileage_Func_t Func = {0};
    Milleage_InitFlag = 0U;

    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_ODO;
    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);
    Milleage_InitFlag = 0X5AA53AA3UL;
}

uint32_t Get_MileageInit_Status(void)
{
    return Milleage_InitFlag;
}

uint32_t Data_User_EEPROM_Read(uint16_t u16BlockID, uint32_t u32Data[], uint16_t u16Len)
{
    uint16_t timeout = 0;
    switch (u16BlockID)
    {
    case EM_MILEAGE_BLOCK:
        odo_readState = eeprom_ReadODO(&g_ReadMileage);
        u32Data[0] = g_ReadMileage.Odo / 100;
        break;

    case EM_ODO_BLOCK:
        timeout = 0;
        odo_readState = eeprom_ReadRecord(EEPROM_BLOCK_01, (uint8_t *)u32Data, u16Len * 4);
        while(odo_readState != WRITE_COMPLETE)
        {
            //eeprom_comm_DelayUs(5000);
            odo_readState = eeprom_ReadRecord(EEPROM_BLOCK_01, (uint8_t *)u32Data, u16Len * 4);
            timeout++;
            if(odo_readState == WRITE_COMPLETE)
            {
                break;
            }
            if(timeout >= 3)
            {
                break;
            }
        }
        break;

    case EM_TRIP_BLOCK:
        timeout = 0;
        odo_readState = eeprom_ReadRecord(EEPROM_BLOCK_03, (uint8_t *)u32Data, u16Len * 4);
        while(odo_readState != WRITE_COMPLETE)
        {
            //eeprom_comm_DelayUs(5000);
            odo_readState = eeprom_ReadRecord(EEPROM_BLOCK_03, (uint8_t *)u32Data, u16Len * 4);
            timeout++;
            if(odo_readState == WRITE_COMPLETE)
            {
                break;
            }
            if(timeout >= 3)
            {
                break;
            }
        }
        break;

    // case EM_Maintenance_BLOCK:
    //     eeprom_ReadRecord(EEPROM_BLOCK_05, (uint8_t *)u32Data, u16Len * 4);
    //     break;

    // case EM_Maintenance_Firstflg:
    //     eeprom_ReadRecord(EEPROM_BLOCK_07, (uint8_t *)u32Data, u16Len * 4);
    //     break;
    // case EM_MenuData_Tcs_Val:
    //     eeprom_ReadRecord(EEPROM_BLOCK_08, (uint8_t *)u32Data, u16Len * 4);
    //     break;
    // case EM_MenuData_TPMS_LEARN:
    //     eeprom_ReadRecord(EEPROM_BLOCK_09, (uint8_t *)u32Data, u16Len * 2);
    //     break;
    

    default:
        break;
    }

    return 0;
}

 void Data_User_EEPROM_Write(Data_EEPROM_Enum_t BlockID, uint32_t u32Data[], uint16_t u16Len)
{
    // uint8_t i = 0u;
    uint8_t timeout = 0;
    switch (BlockID)
    {
    case EM_MILEAGE_BLOCK:
        if (u32Data[0] == 0)
        {
            eeprom_ClearOdoSection();
        }
        else
        {
            g_WriteMileage.Odo = u32Data[0] * 100;
            odo_writeState = WRITE_FAIL;
            odo_writeState = eeprom_WriteODO(&g_WriteMileage, distance_100m, 1);
        }
        break;

    case EM_ODO_BLOCK:
        timeout = 0;
        odoclr_writeState = eeprom_WriteRecord(EEPROM_BLOCK_01, (uint8_t *)u32Data, u16Len * 4);
        while(odoclr_writeState != WRITE_COMPLETE)
        {
            //eeprom_comm_DelayUs(5000);
            odoclr_writeState = eeprom_WriteRecord(EEPROM_BLOCK_01, (uint8_t *)u32Data, u16Len * 4);
            timeout++;
            if(odoclr_writeState == WRITE_COMPLETE)
            {
                break;
            }
            if(timeout >= 3)
            {
                return;
            }
        }
        break;

    case EM_TRIP_BLOCK:
        timeout = 0;
        trip_writeState = eeprom_WriteRecord(EEPROM_BLOCK_03, (uint8_t *)u32Data, u16Len * 4);
        while(trip_writeState != WRITE_COMPLETE)
        {
            //eeprom_comm_DelayUs(5000);
        trip_writeState = eeprom_WriteRecord(EEPROM_BLOCK_03, (uint8_t *)u32Data, u16Len * 4);
        timeout++;
        if(trip_writeState == WRITE_COMPLETE)
        {
                break;
        }
            if(timeout >= 3)
        {
                return;
        }
        }
        break;

    // case EM_Maintenance_BLOCK:
    //     eeprom_WriteRecord(EEPROM_BLOCK_05, (uint8_t *)u32Data, u16Len * 4);
    //     break;

    // case EM_Maintenance_Firstflg:
    //     eeprom_WriteRecord(EEPROM_BLOCK_07, (uint8_t *)u32Data, u16Len * 4);
    //     break;
    // case EM_MenuData_Tcs_Val:
    //     eeprom_WriteRecord(EEPROM_BLOCK_08, (uint8_t *)u32Data, u16Len * 1);
    //     break;
    // case EM_MenuData_TPMS_LEARN:
    //     eeprom_WriteRecord(EEPROM_BLOCK_09, (uint8_t *)u32Data, u16Len * 2);
    //     break;
    default:
        break;
    }
}

void Services_Mileage_Callback(void)
{
    //Data_Mileage_ISR();
    Data_ODO_Processing();
    Data_Trip_Processing();
    Trip_Clear_Km_Service();
}

/**
 * @brief 获取大计里程值
 * @return 根据当前单位输出对应大计里程值
 */
uint32_t Get_ODO_Value(void)
{
    uint32_t ODO = 0;
    if (Get_Dis_KM_Unit() == 0) /* 公制 */
    {
        ODO = Data_ODO_Read();
    }
    else if (Get_Dis_KM_Unit() == 1) /* 英制 */
    {
        ODO = Data_Km_To_Mile(Data_ODO_Read());
    }
    else /* 无效值,按照公里处理,理论上不会执行到这 */
    {
        ODO = Data_ODO_Read();
    }
    if(ODO >= 199999)
    {
        ODO = 199999;
    }
    return ODO;
}

/**
 * @brief 获取小计里程值
 * @return 根据当前单位输出对应小计里程值
 */
uint32_t Get_Trip_Value(void)
{
    uint32_t Trip = 0;
    if (Get_Dis_KM_Unit() == 0) /* 公制 */
    {
        Trip = Data_Read_Trip(EM_TRIP_A);
    }
    else if (Get_Dis_KM_Unit() == 1) /* 英制 */
    {
        Trip = Data_Km_To_Mile(Data_Read_Trip(EM_TRIP_A));
    }
    else /* 无效值,按照公里处理,理论上不会执行到这 */
    {
        Trip = Data_Read_Trip(EM_TRIP_A);
    }
    return Trip;
}

/**
 * @brief 当前单位在KM时,小计里程大于999.9KM,主动触发小计清零
 *
 */
void Trip_Clear_Km_Service(void)
{
    if (Get_Dis_KM_Unit() == 0) /* 公制 */
    {
        if (Data_Read_Trip(EM_TRIP_A) > 9999) /* 当前单位在KM时,里程大于999.9KM进行清零 */
        {
            Data_Clear_Trip_All();
        }
    }
}


/**
 * @brief 触发单位转换时调用,如当前单位英里且里程大于621Mile时,单位转换为公里后需主动写入小计里程为999.9KM;
 * 需要单位转换标志位赋值后进行调用!!!
 * 
 */
void Unit_Convert_Service(void)
{
    if (Get_Dis_KM_Unit() == 0) /* 公制 */
    {
        if (Data_Read_Trip(EM_TRIP_A) > 9999) /* 当前单位在KM时,里程大于999.9KM进行清零 */
        {
            Data_Write_Trip(EM_TRIP_A, 0);
        }
    }   

    if (Get_Dis_Tpms_Unit() == 0) /* bar */
    {
        ;
    }
}