#include "Radar_R3.h"
#include "MFS_UART.h"
#include "EOL_Para.h"
#include "Communication_Over_CAN.h"
#include "Common_Interface.h"

static uint8_t CurIGSt(void);
static uint8_t Radra_Get_Gear_R(void);
void           Recv_New(void);
static void    Radar_Configure(uint8_t Type);
static void    Recv_Byte(void);
void           Rada_Data_Decoding(void);
uint8_t        Rada_Get_R_Distance(void);
uint8_t        Rada_Get_LM_Distance(void);
uint8_t        Rada_Get_RM_Distance(void);
uint8_t        Rada_Get_M_Distance(void);
uint8_t        Rada_Get_L_Distance(void);
static uint8_t PDC_Tepe_buff [ 4U ];

typedef struct
{
    uint8_t  Uart_Rxd;
    uint8_t  Uart_Rx_Cnt;
    uint8_t  Recive_Cnt;
    uint8_t  Indx;
    uint8_t  Step;
    uint8_t  Status;
    uint8_t  CheckSum;
    uint8_t  Eol_Type;
    uint16_t Frame_T;
    uint16_t TimeOut_Cnt;
    uint8_t  Distance_L;
    uint8_t  Distance_M;
    uint8_t  Distance_R;
    uint8_t  Warning;
    union
    {
        uint8_t Buf [ 8U ];
        struct
        {
            uint8_t Head : 8u;

            uint8_t R   : 4u;
            uint8_t R_M : 4u;
            uint8_t L_M : 4u;
            uint8_t L   : 4u;

            uint8_t Reserve_8 : 8u;

            uint8_t R_Mark    : 1u;
            uint8_t R_M_Mark  : 1u;
            uint8_t L_M_Mark  : 1u;
            uint8_t L_Mark    : 1u;
            uint8_t Reserve_4 : 4u;

            uint8_t WarningLevel : 8u;
            uint8_t Tail         : 8u;

        } Distance;
    } RadarData;

} G_Pilot2_0;

G_Pilot2_0 PDC_R3;

void Radar_R3_Init(void)
{
    PDC_R3.Uart_Rxd             = 0U;
    PDC_R3.Uart_Rx_Cnt          = 0U;
    PDC_R3.Recive_Cnt           = 0U;
    PDC_R3.Indx                 = 0U;
    PDC_R3.CheckSum             = 0U;
    PDC_R3.Step                 = PDC_Standby;
    PDC_R3.Status               = PDC_Data_Error;
    PDC_R3.TimeOut_Cnt          = 0U;
    PDC_R3.Frame_T              = 0U;
    PDC_R3.Distance_L           = 0U;
    PDC_R3.Distance_M           = 0U;
    PDC_R3.Distance_R           = 0U;
    PDC_R3.Warning              = 0U;
    PDC_R3.RadarData.Buf [ 0u ] = 0U;
    PDC_R3.RadarData.Buf [ 1u ] = 0U;
    PDC_R3.RadarData.Buf [ 2u ] = 0U;
    PDC_R3.RadarData.Buf [ 3u ] = 0U;
    PDC_R3.RadarData.Buf [ 4u ] = 0U;
    PDC_R3.RadarData.Buf [ 5u ] = 0U;
    PDC_R3.RadarData.Buf [ 6u ] = 0U;
    PDC_R3.RadarData.Buf [ 7u ] = 0U;
    RADA5V_EN                   = 0U;
}
/*Fill the buffer */
static void Recv_Byte(void)
{
    if ( PDC_R3.Recive_Cnt != PDC_R3.Uart_Rx_Cnt )
    {
        PDC_R3.Recive_Cnt = PDC_R3.Uart_Rx_Cnt;
        PDC_R3.Frame_T    = 0U;
        if ( PDC_R3.Indx < 7U )
        {
            PDC_R3.CheckSum += PDC_R3.Uart_Rxd;
            PDC_R3.RadarData.Buf [ PDC_R3.Indx++ ] = PDC_R3.Uart_Rxd;
        }
        else if ( PDC_R3.Indx == 7u )
        {
            PDC_R3.RadarData.Buf [ PDC_R3.Indx++ ] = PDC_R3.Uart_Rxd;
        }
    }
}
/*DataDecoding*/
void Recv_New(void)
{
    uint8_t Condition_EOL   = 0x07u;    // Val_EOL_F101_Radar();
    uint8_t Condition_Frame = (PDC_R3.Frame_T > 2U) ? 1U : 0U;
    /*PDC_Standby */
    if ( Condition_Frame == 1U )
    {
        PDC_R3.CheckSum = 0u;
        PDC_R3.Indx     = 0u;
        if ( PDC_R3.Uart_Rxd == 0xAAU )
        {
            Recv_Byte( );
            PDC_R3.Step = PDC_Req_Config; /* PDC_Standby ——> PDC_Req_Config*/
        }
        else if ( PDC_R3.Uart_Rxd == 0xBBU )
        {
            Recv_Byte( );
            PDC_R3.Step = PDC_Feed_Back; /* PDC_Req_Config ——>PDC_Feed_Back */
        }
        else if ( PDC_R3.Uart_Rxd == 0xCCU )
        {
            Recv_Byte( );
            PDC_R3.Step = PDC_Work; /* PDC_Feed_Back ——> PDC_Work*/
        }
        else
        {
            Recv_Byte( );
            PDC_R3.Step = PDC_Idle;
        }
        PDC_R3.Status = PDC_Data_Idle;
    }
    else
    {
        if ( PDC_R3.Step == PDC_Req_Config )
        {
            if ( PDC_R3.Indx == 3U )
            {
                /* PDC_Req_Config*/
                if ( (PDC_R3.CheckSum == PDC_R3.Uart_Rxd) && (PDC_R3.RadarData.Buf [ 1U ] == 0x0Au)
                     && (PDC_R3.RadarData.Buf [ 2U ] == 0xAFu) )
                {
                    if ( Condition_EOL == 0x07u ) /*配置类型是后三*/
                    {
                        PDC_R3.Eol_Type = 0x31u;
                        Radar_Configure(PDC_R3.Eol_Type);
                        PDC_R3.Step = PDC_Feed_Back;
                    }
                    else if ( Condition_EOL == 0x06u ) /*配置类型是后四*/
                    {
                        PDC_R3.Eol_Type = 0x41u;
                        Radar_Configure(PDC_R3.Eol_Type);
                        PDC_R3.Step = PDC_Feed_Back;
                    }
                    else
                    {
                        PDC_R3.Step = PDC_Idle; /*未知的配置*/
                    }
                    PDC_R3.TimeOut_Cnt = 0U;
                }
            }
            Recv_Byte( );
            if ( PDC_R3.Indx > 3U )
            {
                PDC_R3.Indx     = 0U;
                PDC_R3.CheckSum = 0U;
            }
        }
        /*PDC_Feed_Back*/
        if ( PDC_R3.Step == PDC_Feed_Back )
        {
            if ( PDC_R3.Indx == 3U )
            {
                if ( (PDC_R3.CheckSum == PDC_R3.Uart_Rxd)
                     && (PDC_R3.RadarData.Buf [ 2U ] == 0xBFu) )
                {
                    PDC_R3.Status      = PDC_Data_OK;  /*数据正确*/
                    PDC_R3.TimeOut_Cnt = 0U;           /*雷达故障数据*/
                    if ( PDC_R3.RadarData.Buf [ 1U ] ) /*雷达故障*/
                    {
                        PDC_R3.Distance_L = (PDC_R3.RadarData.Buf [ 1U ] & 0x08u) ? 3U : 0U;
                        PDC_R3.Distance_M = (PDC_R3.RadarData.Buf [ 1U ] & 0x04u) ? 3U : 0U;
                        PDC_R3.Distance_R = (PDC_R3.RadarData.Buf [ 1U ] & 0x01u) ? 3U : 0U;
                        PDC_R3.Warning    = 5U; /*雷达故障长鸣2s*/
                    }
                    else
                    {
                        PDC_R3.Distance_L = 0U;
                        PDC_R3.Distance_M = 0U;
                        PDC_R3.Distance_R = 0U;
                        PDC_R3.Warning    = 4U; /*长鸣0.5*/
                    }
                }
                else
                {
                    PDC_R3.Status = PDC_Data_Error; /*数据错误*/
                }
            }
            Recv_Byte( );
            if ( PDC_R3.Indx > 3U )
            {
                PDC_R3.Indx     = 0U;
                PDC_R3.CheckSum = 0U;
            }
        }
        /*PDC_Work*/
        if ( PDC_R3.Step == PDC_Work )
        {
            if ( PDC_R3.Indx == 8U )
            {
                if ( (PDC_R3.CheckSum == PDC_R3.RadarData.Buf [ 7U ])
                     && (PDC_R3.RadarData.Buf [ 6U ] == 0xCFu) )
                {
                    PDC_R3.Status      = PDC_Data_OK; /*数据正确*/
                    PDC_R3.Step        = PDC_Work;    /*收到有效数据*/
                    PDC_R3.TimeOut_Cnt = 0U;
                    /**********解析段数**********************/
                    PDC_R3.Distance_L = Rada_Get_L_Distance( );
                    PDC_R3.Distance_M = Rada_Get_M_Distance( );
                    PDC_R3.Distance_R = Rada_Get_R_Distance( );
                    /**********解析声音频率******************/
                    if ( PDC_R3.RadarData.Distance.WarningLevel == 7U )
                    {
                        PDC_R3.Warning = 3U; /*长鸣*/
                    }
                    else
                    {
                        if ( PDC_R3.RadarData.Distance.WarningLevel == 4U )
                        {
                            PDC_R3.Warning = 2U; /*4HZ*/
                        }
                        else
                        {
                            if ( PDC_R3.RadarData.Distance.WarningLevel == 2U )
                            {
                                PDC_R3.Warning = 1U; /*2HZ*/
                            }
                            else
                            {
                                PDC_R3.Warning = 0U; /*不报警*/
                            }
                        }
                    }
                    /*******************END**********************/
                }
                else
                {
                    PDC_R3.Status = PDC_Data_Error; /*数据错误*/
                }
                PDC_R3.Indx     = 0u;
                PDC_R3.CheckSum = 0U;
            }
            Recv_Byte( );
            if ( PDC_R3.Indx > 8U )
            {
                PDC_R3.Indx     = 0U;
                PDC_R3.CheckSum = 0U;
            }
        }
    }
    /*Timeout*/
    if ( PDC_R3.TimeOut_Cnt < 1000U ) /*超时判断 2s*/
    {
        PDC_R3.TimeOut_Cnt++;
    }
    else
    {
        PDC_R3.TimeOut_Cnt++;
        PDC_R3.Status     = PDC_Data_Time_Out;
        PDC_R3.Distance_L = 3U;
        PDC_R3.Distance_M = 3U;
        PDC_R3.Distance_R = 3U;
        PDC_R3.Warning    = 6U; /*数据超时故障报警*/
    }
    /*串口空闲计时器*/
    if ( PDC_R3.Frame_T < 0xFFFFU )
    {
        PDC_R3.Frame_T++;
    }
}

static void Radar_Configure(uint8_t Type)
{
    PDC_Tepe_buff [ 0U ] = 0xAAu;
    PDC_Tepe_buff [ 1U ] = Type;
    PDC_Tepe_buff [ 2U ] = 0xAFU;
    PDC_Tepe_buff [ 3U ]
        = ( uint8_t )(PDC_Tepe_buff [ 0u ] + PDC_Tepe_buff [ 1U ] + PDC_Tepe_buff [ 2U ]);

    MFS_UART_WaitForSendReady(1U);
    MFS_UART_SendMultiByte(1U, MFS_UART_SendType_Interrupt, PDC_Tepe_buff, 4U);
}

static uint8_t CurIGSt(void)
{
    uint8_t temp;

    if ( Common_Get_IG_Sts_Valid( ) == 1u )
    {
        temp = Common_Get_IG_Sts( );
    }
    else
    {
        temp = 0u;
    }
    return temp;
}
static uint8_t Radra_Get_Gear_R(void)
{
    uint8_t RGear = 0u;

    if ( Get_ID_18FAB027_Sig_VCUGearPositionInd( ) == 0xDFu )
    {
        RGear = 1u;
    }
    else
    {
        RGear = 0u;
    }

    return RGear;
}
void Radar_R3_Receiving_Service(void)
{

    uint8_t Condition_Pow  = 0u;
    uint8_t Condition_Gear = 0u;
    uint8_t Condition_EOL  = 0u;
    Condition_Pow          = CurIGSt( );
    Condition_Gear         = Radra_Get_Gear_R( );
    Condition_EOL          = 0x07u;

    if ( (Condition_Pow) && (Condition_Gear)
         && ((Condition_EOL == 0x07u) || (Condition_EOL == 0x06u)) )
    {
        RADA5V_EN = 0u;
        Recv_New( );
    }
    else
    {
        if ( PDC_R3.Step != PDC_Standby )
        {
            Radar_R3_Init( );
        }
    }
}

uint8_t Rada_Get_R_Distance(void)
{
    uint8_t Range = 0u;

    if ( (PDC_R3.RadarData.Distance.R == 0U) || (PDC_R3.RadarData.Distance.R > 0x0Du) )
    {
        Range = 0U;
    }
    else
    {
        if ( (PDC_R3.RadarData.Distance.R > 8u) && (PDC_R3.RadarData.Distance.R <= 0x0Du) )
        {
            Range = 3U;
        }
        else
        {
            if ( (PDC_R3.RadarData.Distance.R > 2u) && (PDC_R3.RadarData.Distance.R <= 0x08u) )
            {
                Range = 2U;
            }
            else
            {
                Range = 1U;
            }
        }
    }

    return Range;
}

uint8_t Rada_Get_LM_Distance(void)
{

    uint8_t Range = 0u;

    if ( (PDC_R3.RadarData.Distance.L_M == 0U) || (PDC_R3.RadarData.Distance.L_M > 0x0Du) )
    {
        Range = 0U;
    }
    else
    {
        if ( (PDC_R3.RadarData.Distance.L_M > 8u) && (PDC_R3.RadarData.Distance.L_M <= 0x0Du) )
        {
            Range = 3U;
        }
        else
        {
            if ( (PDC_R3.RadarData.Distance.L_M > 2u) && (PDC_R3.RadarData.Distance.L_M <= 0x08u) )
            {
                Range = 2U;
            }
            else
            {
                Range = 1U;
            }
        }
    }

    return Range;
}

uint8_t Rada_Get_RM_Distance(void)
{
    uint8_t Range = 0u;

    if ( (PDC_R3.RadarData.Distance.R_M == 0U) || (PDC_R3.RadarData.Distance.R_M > 0x0Du) )
    {
        Range = 0U;
    }
    else
    {
        if ( (PDC_R3.RadarData.Distance.R_M > 8u) && (PDC_R3.RadarData.Distance.R_M <= 0x0Du) )
        {
            Range = 3U;
        }
        else
        {
            if ( (PDC_R3.RadarData.Distance.R_M > 2u) && (PDC_R3.RadarData.Distance.R_M <= 0x08u) )
            {
                Range = 2U;
            }
            else
            {
                Range = 1U;
            }
        }
    }
    return Range;
}

uint8_t Rada_Get_M_Distance(void)
{
    uint8_t LM_Range = 0u;
    uint8_t RM_Range = 0u;

    uint8_t M_Range = 0u;

    if ( PDC_R3.Eol_Type == 0x31u )
    {
        M_Range = Rada_Get_LM_Distance( );
    }
    else
    {
        LM_Range = Rada_Get_LM_Distance( );
        RM_Range = Rada_Get_RM_Distance( );
        if ( LM_Range == RM_Range )
        {
            M_Range = LM_Range;
        }
        else
        {
            if ( (LM_Range == 1U) || (RM_Range == 1U) )
            {
                M_Range = 1U;
            }
            else
            {
                if ( (LM_Range == 2U) || (RM_Range == 2U) )
                {
                    M_Range = 2U;
                }
                else
                {
                    M_Range = 3U;
                }
            }
        }
    }
    return M_Range;
}
uint8_t Rada_Get_L_Distance(void)
{
    uint8_t Range = 0u;

    if ( (PDC_R3.RadarData.Distance.L == 0U) || (PDC_R3.RadarData.Distance.L > 0x0Du) )
    {
        Range = 0U;
    }
    else
    {
        if ( (PDC_R3.RadarData.Distance.L > 8u) && (PDC_R3.RadarData.Distance.L <= 0x0Du) )
        {
            Range = 3U;
        }
        else
        {
            if ( (PDC_R3.RadarData.Distance.L > 2u) && (PDC_R3.RadarData.Distance.L <= 0x08u) )
            {
                Range = 2U;
            }
            else
            {
                Range = 1U;
            }
        }
    }

    return Range;
}
/*探头故障诊断数据*/
uint8_t Rada_Get_Diagnose(void)
{
    return PDC_R3.RadarData.Buf [ 1U ];
}
/*Get one Byte From Uart Register*/
void Uart_Data_Get(uint8_t Value)
{
    PDC_R3.Uart_Rx_Cnt++;
    PDC_R3.Uart_Rxd = Value;
}

/*获取雷达左侧显示数据*/
uint8_t Radra_Get_SEG_L(void)
{
    return PDC_R3.Distance_L;
}
/*获取雷达中间显示数据*/
uint8_t Radra_Get_SEG_M(void)
{
    return PDC_R3.Distance_M;
}
/*获取雷达右侧显示数据*/
uint8_t Radra_Get_SEG_R(void)
{
    return PDC_R3.Distance_R;
}
/*获取雷达报警音数据*/
uint8_t Radra_Get_Warning(void)
{
    return PDC_R3.Warning;
}
