/*
此函数为除车速转速函数外其余函数为自定义函数,用于处理表头数据
*/

/*#include "stdint.h"*/
#include "Gauges.h"
#include "GaugesInterface.h"
#include "CD4051.h"
#include "Common_Interface.h"
#include "RTE_ADC.h"
#include "Telltales_user.h"
#include "CAN_Communication_Matrix.h"

#include "CAN_Lib.h"
#include "Flash_synchronizer.h"
#include "Services_Mileage.h"
#include "Data_FuelConsump.h"

//#include "CAN_Signal_Tx.h"

#define        VEH_SPEED_CURVE_NUM         12u
uint16_t RevDispSpeed    = 0u;
uint16_t RevTargetSpeed    = 0u;
uint16_t RevCurrentSpeed    = 0u;

static  uint8_t LED_TEMP_HIGH_FLAG ;
static  uint8_t LED_FUEL_LOW_FLAG ;

typedef struct
{
    uint16_t InputSpeed; /* 外界输入车速或者频率计算车速 */
    uint16_t DispSpeed;  /* 指针显示或者数字显示车速 */
} VehSpeedCurve_t;

/**/
typedef struct
{
    uint16_t         CycleH;
    uint16_t         CycleL;
    uint16_t         Cycle;
    uint16_t         Frequency;
    uint16_t         Duty;
    uint8_t          Edge;
    uint8_t          PulseCnt;
} Frequency_t;

volatile Frequency_t        VehFre;

uint32_t       VehFreLimit;
uint16_t       PPK;



/*

10倍车速
关键点按照放大系数计算出来，其他值根据曲线分段性计算
如果不准就增加数组，调整VEH_SPEED_CURVE_NUM的数值
*/
const VehSpeedCurve_t VehSpeedCurve[ VEH_SPEED_CURVE_NUM ] =
{
    {0u   , 0u},
    {200u , 210u},
    {400u , 420u},
    {600u , 620u},
    {800u , 830u},
    {1000u, 1030u},
    {1200u, 1250u},
    {1400u, 1450u},
    {1600u, 1650u},
    {1800u, 1850u},
    {2000u, 2050u},
    {2250u, 2250u},

};
/*--------------------------------------------------------------------------
* Function Name  : VehSpeedFindSector
* Description    :
* Input          :
* Output         : None
* Return         : INT16U
* onther         : 此函数内容不可更改，如有问题及时反馈
--------------------------------------------------------------------------*/
uint8_t VehSpeedFindSector(uint16_t speed)
{
    uint8_t i = 0u;
    uint8_t Order = 0u;
    uint8_t SectorID = 0u;

    if (VehSpeedCurve[ 0u ].InputSpeed > VehSpeedCurve[ VEH_SPEED_CURVE_NUM - 1u ].InputSpeed)
    {
        Order = 0u;
    }
    else
    {
        Order = 1u;
    }

    for (i = 0u; i < (VEH_SPEED_CURVE_NUM - 1u); i++)
    {
        if (Order == 1u)
        {
            if (speed >= VehSpeedCurve[ i ].InputSpeed)
            {
                SectorID++;
            }
        }
        if (Order == 0u)
        {
            if (speed <= VehSpeedCurve[ i ].InputSpeed)
            {
                SectorID++;
            }
        }
    }
    return SectorID;
}

/*-------------------------------------------------------------------------
* Function Name  : VehSpeedAmplification
* Description    : 车速显示放大
* Input          : CAN或者频率计算车速
* Output         : 经过放大的车速
* Return         : None
* onther         : 此函数内容不可更改，如有问题及时反馈
--------------------------------------------------------------------------*/
uint16_t VehSpeedAmplification(uint16_t Speed)
{
    uint8_t  i            = 0u;
    uint8_t  SectorID     = 0u;
    uint32_t PerCentum    = 0u;
    uint8_t  ASCF         = 0u;
    uint32_t wTemp        = 0u;
    uint32_t DispSpeed    = 0u;
    uint8_t  validflag    = 1u;

    SectorID = VehSpeedFindSector(Speed);

    if (SectorID > (VEH_SPEED_CURVE_NUM - 1u))
    {
        validflag = 0u;
    }

    if (VEH_SPEED_CURVE_NUM < 2u)
    {
        validflag = 0u;
    }

    if (validflag == 1u)
    {
        if (VehSpeedCurve[ 1u ].InputSpeed > VehSpeedCurve[ 0u ].InputSpeed)
        {
            ASCF = 1u;
        }
        if (VehSpeedCurve[ 1u ].InputSpeed < VehSpeedCurve[ 0u ].InputSpeed)
        {
            ASCF = 2u;
        }

        if (ASCF == 1u)
        {
            for (i = 0u; i < (VEH_SPEED_CURVE_NUM - 2u); i++)
            {
                if ((VehSpeedCurve[ i ].InputSpeed > VehSpeedCurve[ i + 1u ].InputSpeed) || \
                        (VehSpeedCurve[ i ].DispSpeed > VehSpeedCurve[ i + 1u ].DispSpeed))
                {
                    validflag = 0u;
                    break;
                }
            }

            if (validflag == 1u)
            {
                wTemp = ((uint32_t)Speed - (uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed));
                PerCentum = wTemp * 1000u;

                PerCentum = PerCentum / ((uint32_t)(VehSpeedCurve[ SectorID ].InputSpeed) - (uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed));
            }
        }

        if (ASCF == 2u)
        {
            for (i = 0u; i < (VEH_SPEED_CURVE_NUM - 2u); i++)
            {
                if ((VehSpeedCurve[ i ].InputSpeed < VehSpeedCurve[ i + 1u ].InputSpeed) || \
                        (VehSpeedCurve[ i ].DispSpeed < VehSpeedCurve[ i + 1u ].DispSpeed))
                {
                    validflag = 0u;
                    break;
                }
            }

            if (validflag == 1u)
            {
                wTemp = (uint32_t)VehSpeedCurve[ SectorID - 1u ].InputSpeed - Speed;
                PerCentum = wTemp * 1000u;

                PerCentum = PerCentum / ((uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed) - (uint32_t)(VehSpeedCurve[ SectorID ].InputSpeed));
            }
        }

        if (validflag == 1u)
        {
            wTemp = (uint32_t)(VehSpeedCurve[ SectorID ].DispSpeed) - (uint32_t)(VehSpeedCurve[ SectorID - 1u ].DispSpeed);
            wTemp = wTemp * PerCentum;

            wTemp += 500u; /* 四舍五入 */

            DispSpeed = wTemp / 1000u + (uint32_t)(VehSpeedCurve[ SectorID - 1u ].DispSpeed);
        }
    }
    return (uint16_t)(DispSpeed);
}
/**@brief Rev Speed Manage function处理怠速抖动问题
* @author TYW
* @param[in] 输入转速
* @param[Out] 经过处理的转速
* @since 1.0.0.0
*/
uint8_t RevJumpFlag = 0u;
uint16_t RevSpeedManage(uint16_t Speed)
{
    RevTargetSpeed = Speed;
    if (RevCurrentSpeed >= (RevTargetSpeed + 50u))
    {
        RevCurrentSpeed -= 50u;
    }
    else
    {
        if ((RevCurrentSpeed + 50u) <= RevTargetSpeed)
        {

            RevCurrentSpeed += 50u;
        }
        else
        {
            ;
        }
    }
    if ((RevTargetSpeed < 500u) || (RevTargetSpeed > 900u))
    {
        RevCurrentSpeed = RevTargetSpeed;
        RevDispSpeed = RevCurrentSpeed;
        RevJumpFlag = 0u;
    }
    else
    {
        if (RevJumpFlag == 0u)
        {
            RevJumpFlag = 1u;
            RevCurrentSpeed = RevTargetSpeed;
            RevDispSpeed = RevCurrentSpeed;
        }
        else
        {
            ;
        }
        if (RevCurrentSpeed % 100u == 0u)
        {
            RevDispSpeed = RevCurrentSpeed;
        }
        else
        {
            ;
        }
    }

    return RevDispSpeed;

}
/**以下为用户自定义函数**/



void Fre_SwapShort(volatile uint32_t *pData1, volatile uint32_t *pData2);
void Fre_SortShort(volatile uint32_t SortData[], uint8_t len);
//uint16_t Cal_Veh_Frequency(void);


typedef enum
{
    FuelFastMode = 0u,
    FuelMidMode,
    FuelSlowMode,
    FuelSpeedTotal,
} _FuelSpeedNum;
uint8_t  VehSpeedFindSector(uint16_t speed);
uint16_t VehSpeedAmplification(uint16_t Speed);
/*-------------------------------------------------------------------------
* Function Name  : App_Swap
* Description    : 交换
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_Swap(uint16_t *pData1, uint16_t *pData2)
{
    uint16_t psw;
    if ((*pData1) > (*pData2))
    {
        psw = (*pData2);
        (*pData2) = (*pData1);
        (*pData1) = psw;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_SortNByte
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_SortNByte(uint16_t *SortData, uint8_t len)
{
    uint8_t n = 0, m;
    for (; n < len - 1; n++)
    {
        for (m = n + 1; m < len; m++)
        {
            App_Swap((SortData + n), (SortData + m));
        }
    }
}
/**@brief Rev Speed Manage function处理怠速抖动问题
* @author TYW
* @param[in] 输入转速
* @param[Out] 经过处理的转速
* @since 1.0.0.0
*/
void Veh_Fre_Init(uint32_t PPK)
{
    VehFre.Cycle = 0u;
    VehFre.Frequency = 0u;
    VehFre.PulseCnt = 0u;
    //VehFreLimit = (3600000000u / (220u * PPK)) / 4u / 50u;
    VehFreLimit = (3600000000u / (250u * PPK)) / 4u / 50u;
}

/*-------------------------------------------------------------------------
* Function Name  : Fre_SwapShort
* Description    : 数据交换
* Input          : None
* Output         : None
* Return         : None
* onther         : qitiancun 2018-9-10
--------------------------------------------------------------------------*/
void Fre_SwapShort(volatile uint32_t *pData1, volatile uint32_t *pData2)
{
    uint32_t psw;
    if ((*pData1) > (*pData2))
    {
        psw = (*pData2);
        (*pData2) = (*pData1);
        (*pData1) = psw;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : Fre_SortShort
* Description    :排序
* Input          : None
* Output         : None
* Return         : None
* onther         : qitiancun 2018-9-10
--------------------------------------------------------------------------*/
void Fre_SortShort(volatile uint32_t SortData[], uint8_t len)
{
    uint8_t n = 0u, m;
    for (; n < len - 1u; n++)
    {
        for (m = n + 1u; m < len; m++)
        {
            Fre_SwapShort(&SortData[n], &SortData[m]);
        }
    }
}
/**@brief Cal Veh  Cyc function计算车速周期
* @author TYW
* @param[in] IO输入
* @since 1.0.0.0
*/
uint32_t VehFreDropTimes;
void Cal_Veh_Cycle(uint8_t VehInput)
{
    if (VehInput)
    {
        if (VehFre.Edge == 1u)
        {
            VehFre.Edge = 0u;
            if ((VehFre.CycleH > VehFreLimit) && (VehFre.CycleL > VehFreLimit))
            {
                VehFreDropTimes = 4000u;

                if (VehFre.Frequency >= 65u)
                {
                    if (VehFre.PulseCnt < 8u)
                    {
                        VehFre.PulseCnt ++;
                        VehFre.Cycle += (VehFre.CycleH + VehFre.CycleL);
                    }
                }
                else
                {
                    if (VehFre.PulseCnt < 4u)
                    {
                        VehFre.PulseCnt ++;
                        VehFre.Cycle += (VehFre.CycleH + VehFre.CycleL);
                    }
                }
            }
            VehFre.CycleH = 0;
            VehFre.CycleL = 0;
        }
        VehFre.CycleH++;
    }
    else
    {
        VehFre.Edge = 1u;
        VehFre.CycleL ++;
    }
    if (VehFreDropTimes > 0u)
    {
        VehFreDropTimes--;
    }
    else
    {
        ;
    }
}

/**@brief Cal Veh  Fre function计算车速频率
* @author TYW
* @param[in] IO输入
* @param[out] 返回频率
* @since 1.0.0.0
*/

uint16_t Cal_Veh_Frequency(void)
{
    if ((VehFre.Frequency >= 65u) && (VehFre.PulseCnt >= 8u))
    {
        VehFre.Cycle >>= 3u;

        VehFre.Frequency = (uint16_t)(20000 / VehFre.Cycle);
        VehFre.Cycle = 0u;
        VehFre.PulseCnt = 0u;
    }
    else if ((VehFre.Frequency < 65u) && (VehFre.PulseCnt >= 4u))
    {
        VehFre.Cycle >>= 2u;

        VehFre.Frequency = (uint16_t)(20000 / VehFre.Cycle);
        VehFre.Cycle = 0u;
        VehFre.PulseCnt = 0u;
    }

    if ((VehFreDropTimes == 0u) || ((VehFre.Frequency > 0u) && (VehFre.Frequency < 3u)))
    {
        VehFre.Frequency = 0u;
        VehFre.Cycle = 0u;
        VehFre.PulseCnt = 0u;
    }
    else
    {
        ;
    }
    return VehFre.Frequency;
}
/**@brief Cal Veh  Val function计算车速
* @author TYW
* @param[in]
* @param[out] 返回10倍车速
* @since 1.0.0.0
*/

//uint16_t Cal_Veh_Val(void)
//{
//
//}

uint8_t    FuelDropTimes = 0;
uint8_t    FuelInvalTimes = 0;
uint8_t    FuelInvalTFlag = 0;
uint16_t   percent = 0u;
static const uint16_t  FuelMoveTimes[FuelSpeedTotal] = {5,  2200,   11250};
void Data_Fuel_Processing_Service(void)
{

}
uint8_t getData_Fuel_InvalFlag(void)
{
    return FuelInvalTFlag;
}
void Data_ESpeed_LED_Processing_Service(void)
{
}
/***************************************
数据处理服务函数
***************************************/
void Data_Group_Processing_Service(void)
{

}
void Data_VehicleSpeed_Fre_CaptureSimulata(void)
{
}


void TRIP_FuelConsump(void)
{
    uint32_t trip = 0u;

    trip = Data_Read_Trip(EM_TRIP_A);
    if (trip > 99999u)
    {
        Data_Clear_Trip(EM_TRIP_A);
    }
    else
    {
        ;
    }
    trip = Data_Read_Trip(EM_TRIP_B);
    if (trip > 99999u)
    {
        Rest_FuelCounsumpTrip_Data();
    }
    else
    {
        ;
    }
    trip = Data_Read_Trip(EM_TRIP_C);
    if (trip > 99999u)
    {
        Rest_FuelCounsumpThisTime_Data();
    }
    else
    {
        ;
    }


}

uint8_t Common_Get_TempHigh_Type(void)
{
    return LED_TEMP_HIGH_FLAG ;
}

uint8_t Common_Get_FuelLow_Type(void)
{
    return LED_FUEL_LOW_FLAG ;
}
