#define GLOBALS_TP_DIAGNO

#include "Link_Layer.h"
#include "TP_Layer.h"
#include "UDS_def.h"
#include "UDS_CFG.H"
#include "app_Service.h"
#include "app_ServiceProc.h"
#include <string.h>
#include "RTE_CAN.h"

volatile _N_USData N_US_R_MultiData;
volatile _N_USData N_US_S_MultiData; //仪表外发的数据信息-multi
volatile _N_RSPData N_RSPData;       //仪表外发的数据信息
volatile _N_US_Data_FF N_US_R_Data_FF;
volatile _N_US_Data_FF N_US_S_Data_FF;
volatile _N_USSFData N_USSFData[2];
volatile uint16_t N_RecLen;
volatile uint8_t g_bReturn;

/*-------------------------------------------------------------------------
* Function Name  : TP_Buffer_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_Buffer_handle(void)
{
    if (LinkDataBuf[0].TransferStatus == full)
    {
        (void)memcpy((uint8_t *)&LinkData, (uint8_t *)&LinkDataBuf[0], sizeof(_LinkData));
        LinkDataBuf[0].TransferStatus = empoty;
    }
    else if (LinkDataBuf[1].TransferStatus == full)
    {
        (void)memcpy((uint8_t *)&LinkData, (uint8_t *)&LinkDataBuf[1], sizeof(_LinkData));
        LinkDataBuf[1].TransferStatus = empoty;
    }

    TP_AbnormalInResSF_handle();
    TP_AbnormalInReqFF_handle();
    TP_UnknownlPDU_handle();
    TP_AbnormalInResCF_handle();
    TP_AbnormalInReqFC_handle();
    TP_AbnormalInResFC_handle();
    TP_TooShortDLC_handle((_LinkData *)&LinkData);
}
/*-------------------------------------------------------------------------
* Function Name  : TP_TooShortDLC_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_TooShortDLC_handle(_LinkData *LK_Data)
{
    uint16_t len;
    uint8_t CtrlMask;

    CtrlMask = LK_Data->Data[0] & 0xf0;
    len = LK_Data->Data[0] & 0x0F;

    if (CtrlMask == SingleFrame)
    {
        if (LK_Data->DLC <= len)
        {
            LK_Data->TransferStatus = empoty;
        }
    }
    if (CtrlMask == FirstFrame)
    {
        if (LK_Data->DLC != 8)
        {
            LK_Data->TransferStatus = empoty;
        }
    }
    if (CtrlMask == FlowControlFrame)
    {
        if (LK_Data->DLC < 3)
        {
            LK_Data->TransferStatus = empoty;
            N_US_R_MultiData.ind.N_Result = N_WRONG_SN_9;
        }
    }
    if (CtrlMask == ConsecutiveFrame)
    {
        if ((N_US_R_MultiData.ind.Length / 7) == len)
        {
            len = len - 1;
            if ((len * 7 + 5 + LK_Data->DLC) < N_US_R_MultiData.ind.Length)
            {
                LK_Data->TransferStatus = empoty;
                N_US_R_MultiData.ind.N_Result = N_WRONG_SN_9;
            }
        }
        else
        {
            if (LK_Data->DLC < 7)
            {
                LK_Data->TransferStatus = empoty;
                N_US_R_MultiData.ind.N_Result = N_WRONG_SN_9;
            }
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_UnknownlPDU_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_AbnormalInResSF_handle(void)
{
    uint8_t CtrlMask;
    if ((N_US_S_MultiData.ind.N_Result == N_OK_2) && (N_US_S_Data_FF.ind.N_PCI) && (LinkData.TransferStatus == full))
    {
        CtrlMask = LinkData.Data[0] & 0x30;
        if (CtrlMask == FirstFrame)
        {
            LinkData.TransferStatus = empoty;
        }
        if (CtrlMask == ConsecutiveFrame)
        {
            LinkData.TransferStatus = empoty;
        }
        if (CtrlMask == SingleFrame)
        {
            LinkData.TransferStatus = empoty;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_UnknownlPDU_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_UnknownlPDU_handle(void)
{
    uint8_t CtrlMask;
    CtrlMask = LinkData.Data[0] & 0xC0;

    if (N_US_S_MultiData.ind.N_Result == N_OK_2)
    {
        if (CtrlMask)
        {
            LinkData.TransferStatus = empoty;
        }
    }
    if ((N_US_R_MultiData.ind.N_Result == WAIT) || (N_US_R_MultiData.ind.N_Result == CTS))
    {
        if ((CtrlMask) && (LinkData.TransferStatus == full))
        {
            LinkData.TransferStatus = empoty;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_AbnormalInReqFF_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_AbnormalInReqFF_handle(void)
{
    uint8_t CtrlMask;

    CtrlMask = LinkData.Data[0] & 0xf0;

    if ((CtrlMask == FirstFrame) && (LinkData.TransferStatus == full))
    {
        if (N_US_R_MultiData.ind.N_Result == CTS)
        {
            N_US_R_MultiData.ind.N_Result = STATE0;
            N_US_R_Data_FF.ind.pos = 0;
            N_US_R_Data_FF.ind.N_PCI = 0;
            N_US_R_Data_FF.ind.N_RecSN_L = 0;
        }

    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_AbnormalInResCF_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_AbnormalInResCF_handle(void)
{
    if (N_US_S_MultiData.ind.N_Result == N_OK_2)
    {
        if (((LinkData.Data[0] & 0xf0) == ConsecutiveFrame) && (LinkData.TransferStatus == full))
        {
            LinkData.TransferStatus = empoty;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_AbnormalInReqFC_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_AbnormalInReqFC_handle(void)
{
    if (N_US_R_MultiData.ind.N_Result == CTS)
    {
        if (((LinkData.Data[0] & 0xf0) == FlowControlFrame) && (LinkData.TransferStatus == full))
        {
            LinkData.TransferStatus = empoty;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_AbnormalInResFC_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_AbnormalInResFC_handle(void)
{
    if (N_US_S_Data_FF.ind.N_PCI == ConsecutiveFrame)
    {
        if ((LinkData.TransferStatus == full) && ((LinkData.Data[0] & 0x30) == FlowControlFrame))
        {
            LinkData.TransferStatus = empoty;
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : TP_NormalRecFC_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_NormalRecFC_handle(void)
{
    uint8_t CtrlMask;
    uint8_t FC_State;

    CtrlMask = LinkData.Data[0] & 0xF0;

    if (N_US_S_Data_FF.ind.N_PCI == FC_WAIT)
    {

        if (CtrlMask == FlowControlFrame)
        {


            FC_State = LinkData.Data[0] & 0x0f;
            if (FC_State == 1)
            {
                N_US_S_Data_FF.ind.N_PCI = FC_WAIT;
                TP_SetBsTimer(N_Bs, (_DiagClock *)&DiagClock);
            }
            if (FC_State == 2)
            {
                N_US_S_MultiData.ind.N_Result = OVFLW;
            }
            if ((FC_State >= 3) && (FC_State <= 0x0F))
            {
                N_US_S_MultiData.ind.N_Result = N_INVALID_FS_8;
            }
            if (FC_State == 0)
            {
                N_US_S_MultiData.ind.N_Result = N_OK_2;

                N_US_S_Data_FF.ind.N_PCI = ConsecutiveFrame;

                N_US_S_Data_FF.ind.N_FC_Num = 0;
                N_US_S_Data_FF.ind.N_BS = LinkData.Data[1];
                N_US_S_Data_FF.ind.N_BS_CNT = 0;

                if ((LinkData.Data[2] <= 0x7F))
                {
                    DiagnoCtl.N_STmin_0 = LinkData.Data[2] + 1;
                }
                if ((LinkData.Data[2] >= 0xF1) && (LinkData.Data[2] <= 0xF9))
                {
                    DiagnoCtl.N_STmin_0 = 1;
                }
                if ((LinkData.Data[2] >= 0xFA) && (LinkData.Data[2] <= 0xFF))
                {
                    DiagnoCtl.N_STmin_0 = 128;
                }
                DiagClock.TT_BsEnable = 0;
                TP_SetSTminTimer(DiagnoCtl.N_STmin_0, (_DiagClock *)&DiagClock);
            }
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : TP_NormalSendFC_Fun
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_NormalSendFC_Fun(void)
{
    if (N_US_R_MultiData.ind.N_Result == WAIT)
    {
        N_RSPData.ind.N_Result = N_OK_2;
        N_RSPData.ind.len = 3;
        N_RSPData.ind.MsgData[1] = DiagnoCtl.N_REV_MAX_BS;
        if (N_US_R_MultiData.ind.Length <= MaxBuff)
        {
            N_RSPData.ind.MsgData[0] = 0x30;
            N_RSPData.ind.MsgData[2] = 0x0A;
            N_US_R_MultiData.ind.N_Result = CTS;
            TP_SetCrTimer(N_Cr, (_DiagClock *)&DiagClock);
        }
        else
        {
            N_RSPData.ind.MsgData[0] = 0x32;
            N_RSPData.ind.MsgData[2] = 0x32;
            N_US_R_MultiData.ind.N_Result = STATE0;
        }
    }
    if (N_US_R_MultiData.ind.N_Result == CTS)
    {
        if (TP_CrTimerOver((_DiagClock *)&DiagClock))
        {
            N_US_R_MultiData.ind.N_Result = N_TIMEOUT_Bs_6;
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : TP_ReciveSF_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_ReciveSF_handle(void)
{
    uint16_t len;
    if ((LinkData.Data[0] & 0xf0) == SingleFrame)
    {
        len = LinkData.Data[0] & 0x0f;
        if ((len > 0) && (len <= 7))
        {
            if ((Exct_USData.ind.N_Result == N_OK_2) || (N_USSFData[0].ind.N_Result == N_OK_2))
            {
                N_USSFData[1].ind.Length = len;

                N_USSFData[1].ind.N_TAtype = LinkData.Identifier;
                N_USSFData[1].ind.N_PCI = SingleFrame;
                N_USSFData[1].ind.N_Result = N_OK_2;
                (void)App_CopyRam((uint8_t *) & (N_USSFData[1].ind.MsgData[0]), (uint8_t *)&LinkData.Data[1], 7);
            }
            else
            {
                N_USSFData[0].ind.Length = len;

                N_USSFData[0].ind.N_TAtype = LinkData.Identifier;
                N_USSFData[0].ind.N_PCI = SingleFrame;
                N_USSFData[0].ind.N_Result = N_OK_2;

                (void)App_CopyRam((uint8_t *) & (N_USSFData[0].ind.MsgData[0]), (uint8_t *)&LinkData.Data[1], 7);
            }
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_ReciveMultiF_handle
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_ReciveMultiF_handle(void)
{
    uint16_t wPos = 0;
    uint16_t SN = 0;
    uint8_t len = 0;

    if (((LinkData.Data[0] & 0xf0) == FirstFrame) && (N_US_R_MultiData.ind.N_Result == STATE0))
    {
        N_US_R_MultiData.ind.Length = LinkData.Data[0] & 0x0F;
        N_US_R_MultiData.ind.Length <<= 8;
        N_US_R_MultiData.ind.Length |= LinkData.Data[1];

        if (N_US_R_MultiData.ind.Length >= 8)
        {
            N_US_R_MultiData.ind.N_TAtype = LinkData.Identifier;

            N_US_R_Data_FF.ind.N_PCI = FirstFrame;
            N_US_R_Data_FF.ind.N_RecSN_L = 0x0001; //

            (void)App_CopyRam((uint8_t *)&N_US_R_MultiData.ind.MsgData[0], (uint8_t *)&LinkData.Data[2], 6);

            N_US_R_MultiData.ind.N_Result = WAIT;

            N_US_R_Data_FF.ind.N_SID = LinkData.Data[2];
        }
        else
        {
            N_US_R_Data_FF.ind.N_PCI = 0;
        }
        N_RecLen = 0;
    }
    if ((LinkData.Data[0] & 0xf0) == ConsecutiveFrame)
    {
        N_US_R_Data_FF.ind.N_PCI = ConsecutiveFrame;
    }
    if ((N_US_R_Data_FF.ind.N_PCI == ConsecutiveFrame) && (N_US_R_MultiData.ind.N_Result == CTS))
    {
        TP_SetCrTimer(N_Cr, (_DiagClock *)&DiagClock);

        N_US_R_Data_FF.ind.N_PCI = 0;

        SN = LinkData.Data[0] & 0x0F;

        wPos = (1 << SN);

        if (N_US_R_Data_FF.ind.N_RecSN_L & wPos)
        {
            N_US_R_MultiData.ind.N_Result = N_WRONG_SN_9;
        }
        else
        {
            N_US_R_Data_FF.ind.N_RecSN_L |= wPos;
        }

        if (N_US_R_MultiData.ind.Length <= 111)
        {
            N_RecLen = TP_CalMsgLen(N_US_R_Data_FF.ind.N_RecSN_L, 0);

            if (SN == 0)
            {
                N_US_R_MultiData.ind.N_Result = N_WRONG_SN_9;
            }
        }
        else
        {
            if (N_RecLen == 0)
            {
                len = TP_CalMsgLen(N_US_R_Data_FF.ind.N_RecSN_L, 0);
            }
            else
            {
                len = TP_CalMsgLen(N_US_R_Data_FF.ind.N_RecSN_L, 1);
            }
            if (N_US_R_Data_FF.ind.N_RecSN_L == 0xFFFF)
            {
                N_RecLen += len;
                len = 0;
                N_US_R_Data_FF.ind.N_RecSN_L = 0;
            }
        }

        if (SN > 0)
        {
            SN -= 1;
        }

        (void)App_CopyRam((uint8_t *)&N_US_R_MultiData.ind.MsgData[(N_RecLen + len) - 7], (uint8_t *)&LinkData.Data[1], 7);

        if ((N_RecLen + len) >= N_US_R_MultiData.ind.Length)
        {
            N_US_R_MultiData.ind.N_Result = N_OK_2;
            DiagClock.TT_CrEnable = 0;
            N_US_R_Data_FF.ind.N_RecSN_L = 0;
            N_RecLen = 0;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_TransmitPDU                              仪表诊断外发
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_TransmitPDU(void)
{
    g_txCanMsg.id = ID_ResAddr;

    _CAN_Msg canMag;

    if (N_US_S_MultiData.ind.N_Result == N_OK_2) //no use
    {
        if (N_US_S_Data_FF.ind.N_PCI == 0)
        {
            g_txCanMsg.msg[0] = (uint8_t)N_US_S_MultiData.ind.Length;
            (void)App_CopyRam((uint8_t *)&g_txCanMsg.msg[1], (uint8_t *)&N_US_S_MultiData.ind.MsgData[0], 7);

            LK_FillMsg((uint8_t *)&g_txCanMsg.msg[0], N_FILL, N_US_S_MultiData.ind.Length + 1);

            //g_bReturn = bsp_CANSendFrame(g_txCanMsg.id, txResNum, (uint8_t *)&g_txCanMsg.msg[0], 8);

            canMag.MsgID  = g_txCanMsg.id;
            canMag.MsgDLC = 8u;
            canMag.MsgPro = 0u;
            canMag.MsgStd = 0u;
            canMag.MsgRTR = 0u;

            canMag.Msg[0u] = g_txCanMsg.msg[0u];
            canMag.Msg[1u] = g_txCanMsg.msg[1u];
            canMag.Msg[2u] = g_txCanMsg.msg[2u];
            canMag.Msg[3u] = g_txCanMsg.msg[3u];
            canMag.Msg[4u] = g_txCanMsg.msg[4u];
            canMag.Msg[5u] = g_txCanMsg.msg[5u];
            canMag.Msg[6u] = g_txCanMsg.msg[6u];
            canMag.Msg[7u] = g_txCanMsg.msg[7u];

            g_bReturn = Can_Write(&canMag);

            N_US_S_MultiData.ind.N_Result = STATE0;
        }
        else
        {
            if (N_US_S_Data_FF.ind.N_PCI == FirstFrame)
            {
                N_US_S_Data_FF.ind.N_PCI = FC_WAIT;

                g_txCanMsg.msg[0] = FirstFrame | (N_US_S_Data_FF.ind.Length >> 8);
                g_txCanMsg.msg[1] = (uint8_t)N_US_S_Data_FF.ind.Length;

                (void)App_CopyRam((uint8_t *)&g_txCanMsg.msg[2], (uint8_t *)&N_US_S_MultiData.ind.MsgData[0], 6);

                //g_bReturn = bsp_CANSendFrame(g_txCanMsg.id, txResNum, (uint8_t *)&g_txCanMsg.msg[0], 8);

                canMag.MsgID  = g_txCanMsg.id;
                canMag.MsgDLC = 8u;
                canMag.MsgPro = 0u;
                canMag.MsgStd = 0u;
                canMag.MsgRTR = 0u;

                canMag.Msg[0u] = g_txCanMsg.msg[0u];
                canMag.Msg[1u] = g_txCanMsg.msg[1u];
                canMag.Msg[2u] = g_txCanMsg.msg[2u];
                canMag.Msg[3u] = g_txCanMsg.msg[3u];
                canMag.Msg[4u] = g_txCanMsg.msg[4u];
                canMag.Msg[5u] = g_txCanMsg.msg[5u];
                canMag.Msg[6u] = g_txCanMsg.msg[6u];
                canMag.Msg[7u] = g_txCanMsg.msg[7u];

                g_bReturn = Can_Write(&canMag);

                N_US_S_Data_FF.ind.N_SendSN = 0;
                N_US_S_Data_FF.ind.pos = 6;
                TP_SetBsTimer(N_Bs, (_DiagClock *)&DiagClock);
            }
            if (TP_STminTimerOver((_DiagClock *)&DiagClock))
            {
                if (N_US_S_Data_FF.ind.N_PCI == ConsecutiveFrame)
                {
                    (void)App_CopyRam((uint8_t *)&g_txCanMsg.msg[1], (uint8_t *)&N_US_S_MultiData.ind.MsgData[N_US_S_Data_FF.ind.pos], 7);

                    N_US_S_Data_FF.ind.N_SendSN++;
                    N_US_S_Data_FF.ind.N_FC_Num++;

                    if (N_US_S_Data_FF.ind.N_BS)
                    {
                        N_US_S_Data_FF.ind.N_BS_CNT++;
                        if (N_US_S_Data_FF.ind.N_BS_CNT >= N_US_S_Data_FF.ind.N_BS)
                        {
                            N_US_S_Data_FF.ind.N_PCI = FC_WAIT;
                            TP_SetBsTimer(N_Bs, (_DiagClock *)&DiagClock);
                        }
                    }
                    if (N_US_S_Data_FF.ind.N_SendSN > 0x0F)
                    {
                        N_US_S_Data_FF.ind.N_SendSN = 0;
                    }
                    N_US_S_Data_FF.ind.pos += 7;
                    if (N_US_S_Data_FF.ind.pos >= N_US_S_Data_FF.ind.Length)
                    {
                        N_US_S_Data_FF.ind.N_PCI = 0;
                        N_US_S_MultiData.ind.N_Result = STATE0;
                        if (((N_US_S_Data_FF.ind.Length - 6) % 7) != 0)
                        {
                            LK_FillMsg((uint8_t *)&g_txCanMsg.msg[0], N_FILL, ((N_US_S_Data_FF.ind.Length - 6) % 7) + 1);
                        }
                    }
                    else
                    {
                        if (N_US_S_Data_FF.ind.N_BS)
                        {
                            if (N_US_S_Data_FF.ind.N_FC_Num == N_US_S_Data_FF.ind.N_BS)
                            {
                                N_US_S_Data_FF.ind.N_PCI = FC_WAIT;
                                TP_SetBsTimer(N_Bs, (_DiagClock *)&DiagClock);
                            }
                        }
                    }

                    g_txCanMsg.msg[0] = ConsecutiveFrame | N_US_S_Data_FF.ind.N_SendSN;

                    //g_bReturn = bsp_CANSendFrame(g_txCanMsg.id, txResNum, (uint8_t *)&g_txCanMsg.msg[0], 8);

                    canMag.MsgID  = g_txCanMsg.id;
                    canMag.MsgDLC = 8u;
                    canMag.MsgPro = 0u;
                    canMag.MsgStd = 0u;
                    canMag.MsgRTR = 0u;

                    canMag.Msg[0u] = g_txCanMsg.msg[0u];
                    canMag.Msg[1u] = g_txCanMsg.msg[1u];
                    canMag.Msg[2u] = g_txCanMsg.msg[2u];
                    canMag.Msg[3u] = g_txCanMsg.msg[3u];
                    canMag.Msg[4u] = g_txCanMsg.msg[4u];
                    canMag.Msg[5u] = g_txCanMsg.msg[5u];
                    canMag.Msg[6u] = g_txCanMsg.msg[6u];
                    canMag.Msg[7u] = g_txCanMsg.msg[7u];

                    g_bReturn = Can_Write(&canMag);

                    TP_SetSTminTimer(DiagnoCtl.N_STmin_0, (_DiagClock *)&DiagClock);
                }
            }
        }
    }

    //-- 返回正确格式 --//
    if (N_RSPData.ind.N_Result == N_OK_2)
    {
        N_RSPData.ind.N_Result = STATE0; //1

        (void)App_CopyRam((uint8_t *)&g_txCanMsg.msg[0], (uint8_t *)&N_RSPData.ind.MsgData[0], 8);

        LK_FillMsg((uint8_t *)&g_txCanMsg.msg[0], N_FILL, N_RSPData.ind.len);

        //g_bReturn = bsp_CANSendFrame(g_txCanMsg.id, txResNum, (uint8_t *)&g_txCanMsg.msg[0], 8);

        canMag.MsgID  = g_txCanMsg.id;
        canMag.MsgDLC = 8u;
        canMag.MsgPro = 0u;
        canMag.MsgStd = 0u;
        canMag.MsgRTR = 0u;

        canMag.Msg[0u] = g_txCanMsg.msg[0u];
        canMag.Msg[1u] = g_txCanMsg.msg[1u];
        canMag.Msg[2u] = g_txCanMsg.msg[2u];
        canMag.Msg[3u] = g_txCanMsg.msg[3u];
        canMag.Msg[4u] = g_txCanMsg.msg[4u];
        canMag.Msg[5u] = g_txCanMsg.msg[5u];
        canMag.Msg[6u] = g_txCanMsg.msg[6u];
        canMag.Msg[7u] = g_txCanMsg.msg[7u];

        g_bReturn = Can_Write(&canMag);
    }

    TP_TransmitNegatePDU((_ErrorFrame *)&Error); //返回错误内容
}
/*-------------------------------------------------------------------------
* Function Name  : TP_TransmitNegatePDU                        服务否定响应
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_TransmitNegatePDU(_ErrorFrame *Err)
{
    _CAN_Msg canMag;

    if (Err->FrameErr)
    {
        if (N_US_R_Data_FF.ind.N_SID == Err->RespSerId)
        {
            N_US_R_Data_FF.ind.Length = 0;
            N_US_R_Data_FF.ind.N_SID = 0;
        }
        if (Err->N_TAtype == ID_PhyAddr) //物理寻址--回复错误
        {
            g_txCanMsg.id = ID_ResAddr;
            g_txCanMsg.msg[0] = 3;
            g_txCanMsg.msg[1] = NegativeId;     //7F
            g_txCanMsg.msg[2] = Err->RespSerId; //服务ID-27
            g_txCanMsg.msg[3] = Err->FrameErr;  //0x35
            g_txCanMsg.msg[4] = N_FILL;         //0x55
            g_txCanMsg.msg[5] = N_FILL;         //0x55
            g_txCanMsg.msg[6] = N_FILL;         //0x55
            g_txCanMsg.msg[7] = N_FILL;         //0x55
            g_txCanMsg.dlc = 8;

            //g_bReturn = bsp_CANSendFrame(g_txCanMsg.id, txResNum, (uint8_t *)&g_txCanMsg.msg[0], 8);

            canMag.MsgID  = g_txCanMsg.id;
            canMag.MsgDLC = 8u;
            canMag.MsgPro = 0u;
            canMag.MsgStd = 0u;
            canMag.MsgRTR = 0u;

            canMag.Msg[0u] = g_txCanMsg.msg[0u];
            canMag.Msg[1u] = g_txCanMsg.msg[1u];
            canMag.Msg[2u] = g_txCanMsg.msg[2u];
            canMag.Msg[3u] = g_txCanMsg.msg[3u];
            canMag.Msg[4u] = g_txCanMsg.msg[4u];
            canMag.Msg[5u] = g_txCanMsg.msg[5u];
            canMag.Msg[6u] = g_txCanMsg.msg[6u];
            canMag.Msg[7u] = g_txCanMsg.msg[7u];

            g_bReturn = Can_Write(&canMag);
        }
        if ((Err->FrameErr != ServiceNotSupported) &&
                (Err->FrameErr != SubFunctionNotSupported) &&
                (Err->FrameErr != RequestOutOfRange))
        {
            g_txCanMsg.id = ID_ResAddr;
            g_txCanMsg.msg[0] = 3;
            g_txCanMsg.msg[1] = NegativeId;
            g_txCanMsg.msg[2] = Err->RespSerId;
            g_txCanMsg.msg[3] = Err->FrameErr;
            g_txCanMsg.msg[4] = N_FILL;
            g_txCanMsg.msg[5] = N_FILL;
            g_txCanMsg.msg[6] = N_FILL;
            g_txCanMsg.msg[7] = N_FILL;
            g_txCanMsg.dlc = 8;

            //g_bReturn = bsp_CANSendFrame(g_txCanMsg.id, txResNum, (uint8_t *)&g_txCanMsg.msg[0], 8);

            canMag.MsgID  = g_txCanMsg.id;
            canMag.MsgDLC = 8u;
            canMag.MsgPro = 0u;
            canMag.MsgStd = 0u;
            canMag.MsgRTR = 0u;

            canMag.Msg[0u] = g_txCanMsg.msg[0u];
            canMag.Msg[1u] = g_txCanMsg.msg[1u];
            canMag.Msg[2u] = g_txCanMsg.msg[2u];
            canMag.Msg[3u] = g_txCanMsg.msg[3u];
            canMag.Msg[4u] = g_txCanMsg.msg[4u];
            canMag.Msg[5u] = g_txCanMsg.msg[5u];
            canMag.Msg[6u] = g_txCanMsg.msg[6u];
            canMag.Msg[7u] = g_txCanMsg.msg[7u];

            g_bReturn = Can_Write(&canMag);
        }
        Err->FrameErr = 0;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : TP_CalMsgLen
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t TP_CalMsgLen(uint16_t BIT_DATA, uint8_t SnLoop)
{
    uint16_t wTemp;
    uint8_t len;
    uint8_t i;
    len = 0;
    wTemp = BIT_DATA;
    for (i = 0; i <= 15; i++)
    {
        if (wTemp & 0x0001)
        {
            len += 7;
        }
        wTemp = wTemp >> 1;
    }
    if (SnLoop == 0)
    {
        len -= 1;
    }

    return len;
}

/*-------------------------------------------------------------------------
* Function Name  : TP_SetCrTimer
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_SetCrTimer(uint32_t Second, _DiagClock *T)
{
    T->TT_CrEnable = 1;
    T->OverCrTime = Second;
    T->CrTime = 0;
}

/*-------------------------------------------------------------------------
* Function Name  : Api_TTimerOver2
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t TP_CrTimerOver(_DiagClock *T)
{
    if ((T->CrTime >= T->OverCrTime) && (T->TT_CrEnable))
    {
        T->TT_CrEnable = 0;
        T->CrTime = 0;
        return 1;
    }
    else
    {
        return 0;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_SetSTminTimer
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_SetSTminTimer(uint32_t Second, _DiagClock *T)
{
    T->TT_STminEnable = 1;
    T->OverSTminTime = Second;
    T->STminTime = 0;
}
/*-------------------------------------------------------------------------
* Function Name  : TP_STminTimerOver
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t TP_STminTimerOver(_DiagClock *T)
{
    if ((T->STminTime >= T->OverSTminTime) && (T->TT_STminEnable))
    {
        T->TT_STminEnable = 0;
        T->STminTime = 0;
        return 1;
    }
    else
    {
        return 0;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : TP_SetBsTimer
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void TP_SetBsTimer(uint32_t Second, _DiagClock *T)
{
    T->TT_BsEnable = 1;
    T->OverBsTime = Second;
    T->BsTime = 0;
}
/*-------------------------------------------------------------------------
* Function Name  : TP_BsTimerOver
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t TP_BsTimerOver(_DiagClock *T)
{
    if ((T->BsTime >= T->OverBsTime) && (T->TT_BsEnable))
    {
        T->TT_BsEnable = 0;
        T->BsTime = 0;
        return 1;
    }
    else
    {
        return 0;
    }
}
