#include "CAN_APP.h"
#include "Telltales_user.h"
#include "Telltales.h"
#include "AirPressure.h"
#include "Services_Mileage.h"
#include "System_Monitor.h"
#include "Analog_Signals.h"
#include "Rscan.h"
#include "CAN_Lib.h"
#include "CAN_Communication_Matrix.h"
#include "RTE_CAN_NM.h"
#include "Telltales_user.h"
#include "Telltales.h"
#include "Common_Interface.h"

static RSCAN0BusoffMonitorStruct RSCAN0Busoff;
uint8_t BUS_OFF_FLAG;
uint8_t BusOffEvent;

#pragma alignvar(8)          //对齐
static uint32_t pTXBuff[CAN_TX_MSG_Block * ID_SEND_TOTAL];
#pragma alignvar(8)
static uint32_t pRXBuff[CAN_RX_MSG_Block * ID_TOTAL_MAX];

void COM_CAN_Init(void)
{
    /*CAN APP BUFFER INIT*/
    Can_TX_BuffInit((uint8_t *)pTXBuff, st_CANSendAttr, ID_SEND_TOTAL, Can_Write);
    Can_RX_BuffInit((uint8_t *)pRXBuff, CAN_MSG_CONST_ARRAY, ID_TOTAL_MAX);
    CAN_RX_SetEnable(0u);
    CAN_TX_SetEnable(CAN_APP_TX_ENABLE);
    /*NM INIT & BSP INIT*/
    RTE_CAN_NM_Init();
}

void COM_RX_Process(void)
{
    CanMSg_XMS_Analysis(5U);
}

void COM_TX_Process(void)
{
    if (SYS_OPR_STAT_IGN_ON)
    {
        Can_Write_Fun(50UL);
    }
    else
    {
        ;
    }
}

void COM_NM_Process(void)
{
    RTE_CAN_NM_Process();
}

/*
request nm
release nm

high voltage
low voltage
2ms
*/

void COM_NM_ACT(void)
{
    if ( SYS_OPR_STAT_RUN_NM )
    {
        if (SYS_OPR_STAT_IGN_ON_NM)
        {
            RTE_CAN_NM_Request(1u);
        }
        else
        {
            RTE_CAN_NM_Release(1u);
        }
    }
    else
    {
        ;
    }
}

uint8_t COM_CAN_BUS(void)
{
    uint8_t Ret = 0u;
    Ret = RTE_CAN_GetBusStatus();
    return Ret;
}

/*
网络管理-0
诊断-1
应用ID-2...
*/

/******Higher******/
void Can_Set_Buff_18F40117(uint8_t CopyData [])
{
    uint8_t  temp = 0;
    uint16_t airp = BatVltFlt_Get_Value();
    
    airp /= 200; 
    //Byte0,低压蓄电池电压,系数0.2,0-36有效值
    CopyData[0] = airp; //28V
    //Byte1
    //.6:左转向灯,硬线信号,高有效
    if (LED_Get_TurnLeft_Status())
    {
        temp |= 0x40;
    }
    //.5:右转向灯,硬线信号,高有效
    if (LED_Get_TurnRight_Status())
    {
        temp |= 0x20;
    }
    //.4:START信号?
    if ((Get_ID_18F101D0_Sig_VCU_VhclSts() == 0u) && (CAN_MSG_Status(ID_VCU_VCUSts1_Msg_Count) == CAN_SIG_RECEIVE))
    {
        temp |= 0x08;
    }
    //.3:ON信号
    if (Get_ID_18F101D0_Sig_VCU_VhclSts() == 1u)
    {
        temp |= 0x10;
    }
    //.2:后舱门?.1:前门,左右车门?.0:中门?,
    if (LED_Get_Status(em_LED_Door))
    {
        temp |= 0x02;
    }
    CopyData[1] = temp;
    //Byte2
    temp = 0;
    //.3:STOP状态?
    if (LED_Get_Status(em_LED_Stop))
    {
        temp |= 0x08;
    }
    //.2:手刹状态,硬线信号,低有效
    if (LED_Get_Status(em_LED_Parking))
    {
        temp |= 0x04;
    }
    //.1:前气压报警
    if (LED_AirPressure_Judgement(0)) //*10bar,Vout=(2.721*0.55MPa+0.5)/5*Vin
    {
        temp |= 0x02;
    }
    //.0:后气压报警
    if (LED_AirPressure_Judgement(1)) //*10bar,Vout=(2.721*0.55MPa+0.5)/5*Vin
    {
        temp |= 0x01;
    }
    CopyData[2] = temp;
    //Byte3 前制动储气筒气压,系数5,单位kPa
    if (AirPressure_Get_Valid(0))
    {
        airp = AirPressure_Get_Value(0); //0.01MPa
        airp *= 10u;         //1kPa
        if (airp > 1000u)
        {
            temp = 0xFEu;
        }
        else
        {
            temp = (uint8_t)(airp / 5);
        }
    }
    else
    {
        temp = 0xFFu;
    }

    CopyData[3] = temp;
    
    //Byte4 后制动储气筒气压,系数5,单位kPa
    if (AirPressure_Get_Valid(1))
    {
        airp = AirPressure_Get_Value(1); //0.01MPa
        airp *= 10u;         //1kPa       
        if (airp > 1000u)
        {
            temp = 0xFEu;
        }
        else
        {
            temp = (uint8_t)(airp / 5);
        }
    }
    else
    {
        temp = 0xFFu;
    }
    
    CopyData[4] = temp;
    
    CopyData[5] = 0u;
    CopyData[6] = 0u;
    CopyData[7] = 0u;
}

void Can_Set_Buff_18F40217(uint8_t CopyData [])
{
    uint32_t temp32 = Data_ODO_Read();
    //Byte0~Byte3 车辆总里程,系数0.125，单位km
    temp32 = temp32 * 8 / 10;
    CopyData[0] = (uint8_t)temp32;
    CopyData[1] = (uint8_t)(temp32 >> 8);
    CopyData[2] = (uint8_t)(temp32 >> 16);
    CopyData[3] = (uint8_t)(temp32 >> 24);
    
    CopyData[4] = 0u;
    CopyData[5] = 0u;
    CopyData[6] = 0u;
    
    //Byte7 仪表版本,系数0.1
    CopyData[7] = 10; //1.0 
}

void Can_Set_Buff_18FFDC17(uint8_t CopyData [])
{
    CopyData[0] = 0u;
    CopyData[1] = 0u;
    
    if ((Common_GetIgnOnTime() < 3500ul) && (Common_Get_IG_Sts() == 1u))
    {
        CopyData[1] |= 0xCu;
    }
    else
    {
        if (LED_HiBeam_Judgement()) //(LED_Get_Status(em_LED_HiBeam))
        {
            CopyData[1] |= 4u;
        }
    }

    CopyData[2] = 0u;
    CopyData[3] = 0u;
    CopyData[4] = 0u;
    CopyData[5] = 0u;
    CopyData[6] = 0u;
    CopyData[7] = 0u;
}

void Can_Set_Buff_18FFE017(uint8_t CopyData [])
{
    CopyData[0] = 0u;
    CopyData[1] = 0u;
    CopyData[2] = 0u;
    CopyData[3] = 0u;
    CopyData[4] = 0u;
    CopyData[5] = 0u;
    CopyData[6] = 0u;
    
    if ((Common_GetIgnOnTime() < 3500ul) && (Common_Get_IG_Sts() == 1u))
    {
        CopyData[6] |= 0x3u;
    }
    else
    {
        if (LED_SeatBelt_Judgement() == 0u) //(LED_Get_Status(em_LED_SeatBelt) == 0u)
        {
            CopyData[6] |= 1u;
        }
    }
    CopyData[7] = 0u;
}

void Can_Set_Buff_0CFE6CEE(uint8_t CopyData [])
{
    CopyData[0] = 0u;
    CopyData[1] = 0u;
    CopyData[2] = 0u;
    CopyData[3] = 0u;
    CopyData[4] = 0u;
    CopyData[5] = 0u;
    uint32_t u32Result = Get_ID_18F101D0_Sig_VCU_VhclSpd();
            
    if ((u32Result > 0xFAFF) || (CAN_MSG_Status(ID_VCU_VCUSts1_Msg_Count) == CAN_SIG_LOST))
    {
        CopyData[6] = 0xFFu;
        CopyData[7] = 0xFFu;
    }
    else
    {
        CopyData[6] = (uint8_t)(u32Result);
        CopyData[7] = (uint8_t)(u32Result >> 8u); 
    }
}

uint8_t CrcCheckSum(uint8_t data[], uint8_t len)
{
    uint8_t crc = 0xffu;
    uint8_t CRC_POLY = 0x2fu;
    uint8_t crcxor = 0xffu;
    uint8_t bit_index = 0u;
    uint8_t byte_index = 0u;
    uint8_t temp = 0u;

    for (byte_index = 0u; byte_index < len; ++byte_index )
    {
        crc ^= data[byte_index];
        for (bit_index = 0u; bit_index < 8u; ++bit_index)
        {
            if ((crc & 0x80u) != 0u)
            {
                temp = crc << 1u;
                crc = temp ^ CRC_POLY;
            }
            else
            {
                crc = (crc << 1u);
            }
        }
    }
    crc = crc ^ crcxor;
    return crc;
}

void CAN_QuickTimer_Init ( void )
{
    uint8_t i = 0u;
    for ( i = 0u; i < ID_SEND_TOTAL; i++)
    {
        //CanMsg[i].u32Timer = st_CANSendAttr[i].u32MsgCycleOffset;
        //CanMsg[i].u32MsgCycle = st_CANSendAttr[i].u32MsgCycle;
        //CanMsg[i].u32SendCnt = st_CANSendAttr[i].u32InitSendCnt;
    }
}

void Can_BusOff_Fun(void)
{
    if (Get_CH0_BusOffStatus() != 0u)
    { 
        CANFD_SetTX_Abort();
        BusOffEvent = 1U;
        CAN_QuickTimer_Init();
        if(RSCAN0Busoff.ReportDTCCnt < 100u)
        {
            RSCAN0Busoff.ReportDTCCnt++;
        }
        else
        {
            BUS_OFF_FLAG = 1U;
        }
        
        if (RSCAN0Busoff.Status == RSCAN0_BUS_STABLE)
        {
            RSCAN0Busoff.Status = RSCAN0_BUS_OFF_LV1;
        }

        if (RSCAN0Busoff.Status == RSCAN0_BUS_OFF_LV1)
        {
            RSCAN0Busoff.Timer++;
            
            if (RSCAN0Busoff.Timer >= RSCAN0_BUS_OFF_LV1_RECOVERY_TIME / 10U)
            {
                RSCAN0Busoff.Timer = 0U;

                RSCAN0Busoff.Cnt++;
                if (RSCAN0Busoff.Cnt >= 10U)
                {
                    
                    RSCAN0Busoff.Cnt = 0U;

                    RSCAN0Busoff.Status = RSCAN0_BUS_OFF_LV2;
                }
                CAN_BUSOFF_Recover();
            }
        }
        else if (RSCAN0Busoff.Status == RSCAN0_BUS_OFF_LV2)
        {
            RSCAN0Busoff.Timer++;

            if (RSCAN0Busoff.Timer >= RSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 10U)
            {
                RSCAN0Busoff.Timer = 0U;
                CAN_BUSOFF_Recover();

            }
        }
        else
        {

        }
    }
    else                                          /* 总线正常,没有Bus-off发生/**/
    {
        
    }
}

void Can_BusOffRecover(void)
{
    BusOffEvent = 0u;
    RSCAN0Busoff.Cnt = 0u;
    RSCAN0Busoff.ReportDTCCnt = 0u;
    RSCAN0Busoff.Status = 0u;
    RSCAN0Busoff.Timer = 0u;
}

/**
  *获取busoff状态
  *@return busoff状态 0正常,1异常
  */
uint8_t getBUS_OFF_Status(void)
{
    return BusOffEvent;
}

/**
  *获取busoff标志
  *@return busoff状态 0正常,1异常
  */
uint8_t getBUS_OFF_FLAG(void)
{
    uint8_t FLAG = BUS_OFF_FLAG;
    if (!getBUS_OFF_Status())
    {
        BUS_OFF_FLAG = 0u;
    }
    return FLAG;
}

void CanRx_Buf_Clear(void)
{
    memset(pRXBuff, 0u, sizeof(pRXBuff));
    Can_RX_BuffInit((uint8_t *)pRXBuff, CAN_MSG_CONST_ARRAY, ID_TOTAL_MAX);
    CAN_RX_SetEnable(0u);
}

void Data64_DataU8(uint8_t *dataU8, uint64_t temp64)
{
    for (uint8_t i=0u; i<8u; i++)
    {
        dataU8[i] = (uint8_t)(temp64);
        temp64 >>= 8u; 
    }
}

void memcopy(uint16_t *dest, uint16_t *source, uint8_t len)
{
    for (uint8_t i=0u; i<len; i++)
    {
        dest[i] = source[i];
    }
}

volatile uint8_t  ABS_DTC_Data[60u][8u];
volatile uint32_t ABS_DTC[100u];
volatile uint8_t  ABS_DTC_Cnt;
volatile uint8_t  ABS_DTC_End;

void ABS_Error_Code_Process(void)
{
    if (CAN_MSG_Status(ID_DM1_Msg_Count) == CAN_SIG_RECEIVE)
    {
        ABS_DTC_End = 1u;
        ABS_DTC_Cnt = 1u;
        ABS_DTC[0u] = (uint32_t)CAN_MSG_Read(ID_DM1_Msg_Count, 4u) << 16u | (uint32_t)CAN_MSG_Read(ID_DM1_Msg_Count, 3u) << 8u | (uint32_t)CAN_MSG_Read(ID_DM1_Msg_Count, 2u);
    }
    else if (CAN_MSG_Status(ID_DM1_1_Msg_Count) == CAN_SIG_RECEIVE)
    {
        ABS_DTC_End = 1u;
        ABS_DTC_Cnt = 1u;
        ABS_DTC[0u] = (uint32_t)CAN_MSG_Read(ID_DM1_1_Msg_Count, 4u) << 16u | (uint32_t)CAN_MSG_Read(ID_DM1_1_Msg_Count, 3u) << 8u | (uint32_t)CAN_MSG_Read(ID_DM1_1_Msg_Count, 2u);
    }
    else
    {
        if ((CAN_MSG_Status(ID_TP_CM_BAM0_Msg_Count) == CAN_SIG_RECEIVE) && (CAN_MSG_Status(ID_TP_DT0_Msg_Count) == CAN_SIG_RECEIVE))
        {
            uint8_t  dataU8[8u], count, i, j;
            uint16_t bytes;

            Data64_DataU8(dataU8, Get_ID_18ECFF0B_Sig_ABS_DTC());
            if ((dataU8[0u] == 0x20u) && (dataU8[5u] == 0xCAu) && (dataU8[6u] == 0xFEu) && (dataU8[7u] == 0x00u))
            {
                count = dataU8[3u] - 1u;
                bytes = (((uint16_t)dataU8[2u] << 8u) & 0xFF00u) | dataU8[1u];
                ABS_DTC_Cnt = (bytes - 2u) / 4u;
                Data64_DataU8(dataU8, Get_ID_18EBFF0B_Sig_ABS_DTC());
                j = dataU8[0u] - 1u;
                if (j < 57u)
                {
                    for (uint8_t i=0u; i<8u; i++)
                    {
                        ABS_DTC_Data[j][i] = dataU8[i];
                    }
                }
                else
                {
                    j = 56u;
                }
                
                if (j == count)
                {
                    ABS_DTC_End = 1u;
                    
                    for (i=0u; i<ABS_DTC_Cnt; i++)
                    {
                        switch (i % 7u)
                        {
                            case 0u: 
                                j = i / 7u * 4u;
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][6u] << 24u | (uint32_t)ABS_DTC_Data[j][5u] << 16u | (uint32_t)ABS_DTC_Data[j][4u] << 8u | (uint32_t)ABS_DTC_Data[j][3u];
                                break;
                            case 1u: 
                                j = i / 7u * 4u + 1u;
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][3u] << 24u | (uint32_t)ABS_DTC_Data[j][2u] << 16u | (uint32_t)ABS_DTC_Data[j][1u] << 8u | (uint32_t)ABS_DTC_Data[j - 1u][7u];
                                break;
                            case 2u:
                                j = i / 7u * 4u + 1u; 
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][7u] << 24u | (uint32_t)ABS_DTC_Data[j][6u] << 16u | (uint32_t)ABS_DTC_Data[j][5u] << 8u | (uint32_t)ABS_DTC_Data[j][4u];
                                break;
                            case 3u: 
                                j = i / 7u * 4u + 2u; 
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][4u] << 24u | (uint32_t)ABS_DTC_Data[j][3u] << 16u | (uint32_t)ABS_DTC_Data[j][2u] << 8u | (uint32_t)ABS_DTC_Data[j][1u];
                                break;
                            case 4u: 
                                j = i / 7u * 4u + 2u;
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j + 1u][1u] << 24u | (uint32_t)ABS_DTC_Data[j][7u] << 16u | (uint32_t)ABS_DTC_Data[j][6u] << 8u | (uint32_t)ABS_DTC_Data[j][5u];
                                break;
                            case 5u: 
                                j = i / 7u * 4u + 3u;
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][5u] << 24u | (uint32_t)ABS_DTC_Data[j][4u] << 16u | (uint32_t)ABS_DTC_Data[j][3u] << 8u | (uint32_t)ABS_DTC_Data[j][2u];
                                break;
                            case 6u: 
                                j = i / 7u * 4u + 3u;
                                ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j + 1u][2u] << 24u | (uint32_t)ABS_DTC_Data[j + 1u][1u] << 16u | (uint32_t)ABS_DTC_Data[j][7u] << 8u | (uint32_t)ABS_DTC_Data[j][6u];
                            default:
                                break;
                        }
                    }    
                  #if 0  
                    ABS_DTC[ 0u] = (uint32_t)ABS_DTC_Data[ 0u][6u] << 24u | (uint32_t)ABS_DTC_Data[ 0u][5u] << 16u | (uint32_t)ABS_DTC_Data[ 0u][4u] << 8u | (uint32_t)ABS_DTC_Data[ 0u][3u];
                    ABS_DTC[ 1u] = (uint32_t)ABS_DTC_Data[ 1u][3u] << 24u | (uint32_t)ABS_DTC_Data[ 1u][2u] << 16u | (uint32_t)ABS_DTC_Data[ 1u][1u] << 8u | (uint32_t)ABS_DTC_Data[ 0u][7u];
                    ABS_DTC[ 2u] = (uint32_t)ABS_DTC_Data[ 1u][7u] << 24u | (uint32_t)ABS_DTC_Data[ 1u][6u] << 16u | (uint32_t)ABS_DTC_Data[ 1u][5u] << 8u | (uint32_t)ABS_DTC_Data[ 1u][4u];
                    ABS_DTC[ 3u] = (uint32_t)ABS_DTC_Data[ 2u][4u] << 24u | (uint32_t)ABS_DTC_Data[ 2u][3u] << 16u | (uint32_t)ABS_DTC_Data[ 2u][2u] << 8u | (uint32_t)ABS_DTC_Data[ 2u][1u];
                    ABS_DTC[ 4u] = (uint32_t)ABS_DTC_Data[ 3u][1u] << 24u | (uint32_t)ABS_DTC_Data[ 2u][7u] << 16u | (uint32_t)ABS_DTC_Data[ 2u][6u] << 8u | (uint32_t)ABS_DTC_Data[ 2u][5u];
                    ABS_DTC[ 5u] = (uint32_t)ABS_DTC_Data[ 3u][5u] << 24u | (uint32_t)ABS_DTC_Data[ 3u][4u] << 16u | (uint32_t)ABS_DTC_Data[ 3u][3u] << 8u | (uint32_t)ABS_DTC_Data[ 3u][2u];
                    ABS_DTC[ 6u] = (uint32_t)ABS_DTC_Data[ 4u][2u] << 24u | (uint32_t)ABS_DTC_Data[ 4u][1u] << 16u | (uint32_t)ABS_DTC_Data[ 3u][7u] << 8u | (uint32_t)ABS_DTC_Data[ 3u][6u];
                    
                    ABS_DTC[ 7u] = (uint32_t)ABS_DTC_Data[ 4u][6u] << 24u | (uint32_t)ABS_DTC_Data[ 4u][5u] << 16u | (uint32_t)ABS_DTC_Data[ 4u][4u] << 8u | (uint32_t)ABS_DTC_Data[ 4u][3u];
                    ABS_DTC[ 8u] = (uint32_t)ABS_DTC_Data[ 5u][3u] << 24u | (uint32_t)ABS_DTC_Data[ 5u][2u] << 16u | (uint32_t)ABS_DTC_Data[ 5u][1u] << 8u | (uint32_t)ABS_DTC_Data[ 4u][7u];
                    ABS_DTC[ 9u] = (uint32_t)ABS_DTC_Data[ 5u][7u] << 24u | (uint32_t)ABS_DTC_Data[ 5u][6u] << 16u | (uint32_t)ABS_DTC_Data[ 5u][5u] << 8u | (uint32_t)ABS_DTC_Data[ 5u][4u];
                    ABS_DTC[10u] = (uint32_t)ABS_DTC_Data[ 6u][4u] << 24u | (uint32_t)ABS_DTC_Data[ 6u][3u] << 16u | (uint32_t)ABS_DTC_Data[ 6u][2u] << 8u | (uint32_t)ABS_DTC_Data[ 6u][1u];
                    ABS_DTC[11u] = (uint32_t)ABS_DTC_Data[ 7u][1u] << 24u | (uint32_t)ABS_DTC_Data[ 6u][7u] << 16u | (uint32_t)ABS_DTC_Data[ 6u][6u] << 8u | (uint32_t)ABS_DTC_Data[ 6u][5u];
                    ABS_DTC[12u] = (uint32_t)ABS_DTC_Data[ 7u][5u] << 24u | (uint32_t)ABS_DTC_Data[ 7u][4u] << 16u | (uint32_t)ABS_DTC_Data[ 7u][3u] << 8u | (uint32_t)ABS_DTC_Data[ 7u][2u];
                    ABS_DTC[13u] = (uint32_t)ABS_DTC_Data[ 8u][2u] << 24u | (uint32_t)ABS_DTC_Data[ 8u][1u] << 16u | (uint32_t)ABS_DTC_Data[ 7u][7u] << 8u | (uint32_t)ABS_DTC_Data[ 7u][6u];
                    
                    ABS_DTC[14u] = (uint32_t)ABS_DTC_Data[ 8u][6u] << 24u | (uint32_t)ABS_DTC_Data[ 8u][5u] << 16u | (uint32_t)ABS_DTC_Data[ 8u][4u] << 8u | (uint32_t)ABS_DTC_Data[ 8u][3u];
                    ABS_DTC[15u] = (uint32_t)ABS_DTC_Data[ 9u][3u] << 24u | (uint32_t)ABS_DTC_Data[ 9u][2u] << 16u | (uint32_t)ABS_DTC_Data[ 9u][1u] << 8u | (uint32_t)ABS_DTC_Data[ 8u][7u];
                    ABS_DTC[16u] = (uint32_t)ABS_DTC_Data[ 9u][7u] << 24u | (uint32_t)ABS_DTC_Data[ 9u][6u] << 16u | (uint32_t)ABS_DTC_Data[ 9u][5u] << 8u | (uint32_t)ABS_DTC_Data[ 9u][4u];
                    ABS_DTC[17u] = (uint32_t)ABS_DTC_Data[10u][4u] << 24u | (uint32_t)ABS_DTC_Data[10u][3u] << 16u | (uint32_t)ABS_DTC_Data[10u][2u] << 8u | (uint32_t)ABS_DTC_Data[10u][1u];
                    ABS_DTC[18u] = (uint32_t)ABS_DTC_Data[11u][1u] << 24u | (uint32_t)ABS_DTC_Data[10u][7u] << 16u | (uint32_t)ABS_DTC_Data[10u][6u] << 8u | (uint32_t)ABS_DTC_Data[10u][5u];
                    ABS_DTC[19u] = (uint32_t)ABS_DTC_Data[11u][5u] << 24u | (uint32_t)ABS_DTC_Data[11u][4u] << 16u | (uint32_t)ABS_DTC_Data[11u][3u] << 8u | (uint32_t)ABS_DTC_Data[11u][2u];
                    ABS_DTC[20u] = (uint32_t)ABS_DTC_Data[12u][2u] << 24u | (uint32_t)ABS_DTC_Data[12u][1u] << 16u | (uint32_t)ABS_DTC_Data[11u][7u] << 8u | (uint32_t)ABS_DTC_Data[11u][6u];
                  #endif
                }
            }
            else
            {
                if ((CAN_MSG_Status(ID_TP_CM_BAM_Msg_Count) == CAN_SIG_RECEIVE) && (CAN_MSG_Status(ID_TP_DT_Msg_Count) == CAN_SIG_RECEIVE))
                {
                    uint8_t  dataU8[8u], count, i, j;
                    uint16_t bytes;

                    Data64_DataU8(dataU8, Get_ID_1CECFF0B_Sig_ABS_DTC());
                    if ((dataU8[0u] == 0x20u) && (dataU8[5u] == 0xCAu) && (dataU8[6u] == 0xFEu) && (dataU8[7u] == 0x00u))
                    {
                        count = dataU8[3u] - 1u;
                        bytes = (((uint16_t)dataU8[2u] << 8u) & 0xFF00u) | dataU8[1u];
                        ABS_DTC_Cnt = (bytes - 2u) / 4u;
                        Data64_DataU8(dataU8, Get_ID_1CEBFF0B_Sig_ABS_DTC());
                        j = dataU8[0u] - 1u;
                        if (j < 57u)
                        {
                            for (uint8_t i=0u; i<8u; i++)
                            {
                                ABS_DTC_Data[j][i] = dataU8[i];
                            }
                        }
                        else
                        {
                            j = 56u;
                        }
                        
                        if (j == count)
                        {
                            ABS_DTC_End = 1u;
                            
                            for (i=0u; i<ABS_DTC_Cnt; i++)
                            {
                                switch (i % 7u)
                                {
                                    case 0u: 
                                        j = i / 7u * 4u;
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][6u] << 24u | (uint32_t)ABS_DTC_Data[j][5u] << 16u | (uint32_t)ABS_DTC_Data[j][4u] << 8u | (uint32_t)ABS_DTC_Data[j][3u];
                                        break;
                                    case 1u: 
                                        j = i / 7u * 4u + 1u;
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][3u] << 24u | (uint32_t)ABS_DTC_Data[j][2u] << 16u | (uint32_t)ABS_DTC_Data[j][1u] << 8u | (uint32_t)ABS_DTC_Data[j - 1u][7u];
                                        break;
                                    case 2u:
                                        j = i / 7u * 4u + 1u; 
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][7u] << 24u | (uint32_t)ABS_DTC_Data[j][6u] << 16u | (uint32_t)ABS_DTC_Data[j][5u] << 8u | (uint32_t)ABS_DTC_Data[j][4u];
                                        break;
                                    case 3u: 
                                        j = i / 7u * 4u + 2u; 
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][4u] << 24u | (uint32_t)ABS_DTC_Data[j][3u] << 16u | (uint32_t)ABS_DTC_Data[j][2u] << 8u | (uint32_t)ABS_DTC_Data[j][1u];
                                        break;
                                    case 4u: 
                                        j = i / 7u * 4u + 2u;
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j + 1u][1u] << 24u | (uint32_t)ABS_DTC_Data[j][7u] << 16u | (uint32_t)ABS_DTC_Data[j][6u] << 8u | (uint32_t)ABS_DTC_Data[j][5u];
                                        break;
                                    case 5u: 
                                        j = i / 7u * 4u + 3u;
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][5u] << 24u | (uint32_t)ABS_DTC_Data[j][4u] << 16u | (uint32_t)ABS_DTC_Data[j][3u] << 8u | (uint32_t)ABS_DTC_Data[j][2u];
                                        break;
                                    case 6u: 
                                        j = i / 7u * 4u + 3u;
                                        ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j + 1u][2u] << 24u | (uint32_t)ABS_DTC_Data[j + 1u][1u] << 16u | (uint32_t)ABS_DTC_Data[j][7u] << 8u | (uint32_t)ABS_DTC_Data[j][6u];
                                    default:
                                        break;
                                }
                            }    
                        }
                    }
                    else
                    {
                        ABS_DTC_End = 0u;
                        ABS_DTC_Cnt = 0u;
                    }
                }
                else
                {
                    ABS_DTC_End = 0u;
                    ABS_DTC_Cnt = 0u;
                }
            }
        }
        else
        {
            if ((CAN_MSG_Status(ID_TP_CM_BAM_Msg_Count) == CAN_SIG_RECEIVE) && (CAN_MSG_Status(ID_TP_DT_Msg_Count) == CAN_SIG_RECEIVE))
            {
                uint8_t  dataU8[8u], count, i, j;
                uint16_t bytes;

                Data64_DataU8(dataU8, Get_ID_1CECFF0B_Sig_ABS_DTC());
                if ((dataU8[0u] == 0x20u) && (dataU8[5u] == 0xCAu) && (dataU8[6u] == 0xFEu) && (dataU8[7u] == 0x00u))
                {
                    count = dataU8[3u] - 1u;
                    bytes = (((uint16_t)dataU8[2u] << 8u) & 0xFF00u) | dataU8[1u];
                    ABS_DTC_Cnt = (bytes - 2u) / 4u;
                    Data64_DataU8(dataU8, Get_ID_1CEBFF0B_Sig_ABS_DTC());
                    j = dataU8[0u] - 1u;
                    if (j < 57u)
                    {
                        for (uint8_t i=0u; i<8u; i++)
                        {
                            ABS_DTC_Data[j][i] = dataU8[i];
                        }
                    }
                    else
                    {
                        j = 56u;
                    }
                    
                    if (j == count)
                    {
                        ABS_DTC_End = 1u;
                        
                        for (i=0u; i<ABS_DTC_Cnt; i++)
                        {
                            switch (i % 7u)
                            {
                                case 0u: 
                                    j = i / 7u * 4u;
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][6u] << 24u | (uint32_t)ABS_DTC_Data[j][5u] << 16u | (uint32_t)ABS_DTC_Data[j][4u] << 8u | (uint32_t)ABS_DTC_Data[j][3u];
                                    break;
                                case 1u: 
                                    j = i / 7u * 4u + 1u;
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][3u] << 24u | (uint32_t)ABS_DTC_Data[j][2u] << 16u | (uint32_t)ABS_DTC_Data[j][1u] << 8u | (uint32_t)ABS_DTC_Data[j - 1u][7u];
                                    break;
                                case 2u:
                                    j = i / 7u * 4u + 1u; 
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][7u] << 24u | (uint32_t)ABS_DTC_Data[j][6u] << 16u | (uint32_t)ABS_DTC_Data[j][5u] << 8u | (uint32_t)ABS_DTC_Data[j][4u];
                                    break;
                                case 3u: 
                                    j = i / 7u * 4u + 2u; 
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][4u] << 24u | (uint32_t)ABS_DTC_Data[j][3u] << 16u | (uint32_t)ABS_DTC_Data[j][2u] << 8u | (uint32_t)ABS_DTC_Data[j][1u];
                                    break;
                                case 4u: 
                                    j = i / 7u * 4u + 2u;
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j + 1u][1u] << 24u | (uint32_t)ABS_DTC_Data[j][7u] << 16u | (uint32_t)ABS_DTC_Data[j][6u] << 8u | (uint32_t)ABS_DTC_Data[j][5u];
                                    break;
                                case 5u: 
                                    j = i / 7u * 4u + 3u;
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j][5u] << 24u | (uint32_t)ABS_DTC_Data[j][4u] << 16u | (uint32_t)ABS_DTC_Data[j][3u] << 8u | (uint32_t)ABS_DTC_Data[j][2u];
                                    break;
                                case 6u: 
                                    j = i / 7u * 4u + 3u;
                                    ABS_DTC[i] = (uint32_t)ABS_DTC_Data[j + 1u][2u] << 24u | (uint32_t)ABS_DTC_Data[j + 1u][1u] << 16u | (uint32_t)ABS_DTC_Data[j][7u] << 8u | (uint32_t)ABS_DTC_Data[j][6u];
                                default:
                                    break;
                            }
                        }    
                    }
                }
                else
                {
                    ABS_DTC_End = 0u;
                    ABS_DTC_Cnt = 0u;
                }
            }
            else
            {
                ABS_DTC_End = 0u;
                ABS_DTC_Cnt = 0u;
            }
        }
    }
}
