#include "CAN_CH0_CAN_Communication_Matrix.h"
#include "CAN_CH1_CAN_Communication_Matrix.h"
#include "CAN_CH2_CAN_Communication_Matrix.h"
// #include "UDS_ISO14229_Services.h"
#include "COM_CAN.h"
#include "TYW_stdint.h"
#include "RTE_CAN.h"
#include <string.h>
#include "Rscan.h"
///#include "UDS_DTC.h"


#pragma alignvar(8)
static uint32_t pRXBuff[CAN_RX_MSG_Block * CAN_CH0_ID_TOTAL_MAX];
#pragma alignvar(8)
static uint32_t pTXBuff[CAN_TX_MSG_Block * CAN_CH0_ID_SEND_TOTAL];

#pragma alignvar(8)
static uint32_t pCH1RXBuff[CAN_RX_MSG_Block * CAN_CH1_ID_TOTAL_MAX];
#pragma alignvar(8)
static uint32_t pCH1TXBuff[CAN_TX_MSG_Block * CAN_CH1_ID_SEND_TOTAL];

#pragma alignvar(8)
static uint32_t pCH2RXBuff[CAN_RX_MSG_Block * CAN_CH2_ID_TOTAL_MAX];

void COM_CAN_Init(void)
{
    /*CAN APP BUFFER INIT*/

    memset(pRXBuff, 0, sizeof(pRXBuff));
    CAN_CH0_CanMsgOp.CAN_MSG_Analysis = ( st_CANMsgStruct * )pRXBuff;
    CAN_CH0_CanMsgTxOp.CanMsg         = pTXBuff;
    Can_RX_BuffInit(&CAN_CH0_CanMsgOp, CAN_CH0_CAN_MSG_CONST_ARRAY, CAN_CH0_ID_TOTAL_MAX);
    Can_TX_BuffInit(&CAN_CH0_CanMsgTxOp, CAN_CH0_CANSendAttr, CAN_CH0_ID_SEND_TOTAL, Can0_Write0);
    CAN_TX_SetEnable(&CAN_CH0_CanMsgTxOp, CAN_N_TX_Enable);
    CAN_RX_SetEnable(&CAN_CH0_CanMsgOp, CAN_N_RX_Enable);

    memset(pCH2RXBuff, 0, sizeof(pCH2RXBuff));
    CAN_CH2_CanMsgOp.CAN_MSG_Analysis = ( st_CANMsgStruct * )pCH2RXBuff;
    Can_RX_BuffInit(&CAN_CH2_CanMsgOp, CAN_CH2_CAN_MSG_CONST_ARRAY, CAN_CH2_ID_TOTAL_MAX);   
    CAN_RX_SetEnable(&CAN_CH2_CanMsgOp, CAN_N_RX_Enable);

    memset(pCH1RXBuff, 0, sizeof(pCH1RXBuff));
    CAN_CH1_CanMsgOp.CAN_MSG_Analysis = ( st_CANMsgStruct * )pCH1RXBuff;
    CAN_CH1_CanMsgTxOp.CanMsg         = pCH1TXBuff;
    Can_RX_BuffInit(&CAN_CH1_CanMsgOp, CAN_CH1_CAN_MSG_CONST_ARRAY, CAN_CH1_ID_TOTAL_MAX);
    Can_TX_BuffInit(&CAN_CH1_CanMsgTxOp, CAN_CH1_CANSendAttr, CAN_CH1_ID_SEND_TOTAL, Can_CH2_Write);
    CAN_TX_SetEnable(&CAN_CH1_CanMsgTxOp, CAN_N_TX_Enable);
    CAN_RX_SetEnable(&CAN_CH1_CanMsgOp, CAN_N_RX_Enable);
    RTE_CAN_Send_Init();

    /*NM INIT & BSP INIT*/
    Can_Init1( );
}

void COM_RX_Process(void)
{
    CanMSg_XMS_Analysis(&CAN_CH0_CanMsgOp, 5u);
    CanMSg_XMS_Analysis(&CAN_CH1_CanMsgOp, 5u);
    CanMSg_XMS_Analysis(&CAN_CH2_CanMsgOp, 5u);
}

void COM_TX_Process(void)
{
    Can_Write_Fun(&CAN_CH0_CanMsgTxOp,50UL);    
    Can_Write_Fun(&CAN_CH1_CanMsgTxOp,50UL);
    Can_Write_Fun(&CAN_CH2_CanMsgTxOp,50UL);
}



void COM_NM_Process(void)
{
  //  RTE_CAN_NM_Process();
}

uint8_t BusOffEvent;
/**
  *获取busoff状态
  *@return busoff状态 0正常,1异常
  */
uint8_t getBUS_OFF_Status(void)
{
    return BusOffEvent;
}
typedef enum
{
    BUSSOFF_CH_CH0,
    BUSSOFF_CH_CH1,
    BUSSOFF_CH_CH2, 
    BUSSOFF_CH_SUM,
}BUSSSOFF_CH_enum;

static RSCAN0BusoffMonitorStruct     RSCAN0Busoff[BUSSOFF_CH_SUM];

void Can_CH0_BusOffRecover(void);
void Can_CH1_BusOffRecover(void);
void Can_CH2_BusOffRecover(void);
void Can_CH0_BusOff_Fun(void);
void Can_CH1_BusOff_Fun(void);
void Can_CH2_BusOff_Fun(void);


void Can_CH0_BusOff_Fun(void)
{
    if ((RSCAN0_CH0_Get_Busoff_Status() != 0U))
    {
        //RSCAN0_CH0_Abort(0);
        Can0_Abort_All();
    
        if (RSCAN0Busoff[BUSSOFF_CH_CH0].Status == RSCAN0_BUS_STABLE)
        {
            RSCAN0Busoff[BUSSOFF_CH_CH0].Status = RSCAN0_BUS_OFF_LV1;
        }

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

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

                    RSCAN0Busoff[BUSSOFF_CH_CH0].Status = RSCAN0_BUS_OFF_LV2;
                }
                RSCAN0_CH0_Busoff_Recover( );
            }
        }
        else if (RSCAN0Busoff[BUSSOFF_CH_CH0].Status == RSCAN0_BUS_OFF_LV2)
        {
            RSCAN0Busoff[BUSSOFF_CH_CH0].Timer++;

            if (RSCAN0Busoff[BUSSOFF_CH_CH0].Timer >= (RSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 10U))
            {
                RSCAN0Busoff[BUSSOFF_CH_CH0].Timer = 0U;
                RSCAN0_CH0_Busoff_Recover( );
            }
        }
        else
        {

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

void Can_CH1_BusOff_Fun(void)
{
    if ((RSCAN0_CH1_Get_Busoff_Status() != 0U))
    {
        //RSCAN0_CH1_Abort(0);
        Can1_Abort_All();

        if (RSCAN0Busoff[BUSSOFF_CH_CH1].Status == RSCAN0_BUS_STABLE)
        {
            RSCAN0Busoff[BUSSOFF_CH_CH1].Status = RSCAN0_BUS_OFF_LV1;
        }

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

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

                    RSCAN0Busoff[BUSSOFF_CH_CH1].Status = RSCAN0_BUS_OFF_LV2;
                }
                RSCAN0_CH1_Busoff_Recover( );
            }
        }
        else if (RSCAN0Busoff[BUSSOFF_CH_CH1].Status == RSCAN0_BUS_OFF_LV2)
        {
            RSCAN0Busoff[BUSSOFF_CH_CH1].Timer++;

            if (RSCAN0Busoff[BUSSOFF_CH_CH1].Timer >= (RSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 10U))
            {
                RSCAN0Busoff[BUSSOFF_CH_CH1].Timer = 0U;
                RSCAN0_CH1_Busoff_Recover( );
            }
        }
        else
        {

        }
    }
    else                                          /* 总线正常,没有Bus-off发生/**/
    {
        Can_CH1_BusOffRecover();
    }
}
void Can_CH2_BusOff_Fun(void)
{
    if ((RSCAN0_CH2_Get_Busoff_Status() != 0U))
    {
        RSCAN0_CH2_Abort(0);
        BusOffEvent = 1U;
        if (RSCAN0Busoff[BUSSOFF_CH_CH2].Status == RSCAN0_BUS_STABLE)
        {
            RSCAN0Busoff[BUSSOFF_CH_CH2].Status = RSCAN0_BUS_OFF_LV1;
        }

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

                RSCAN0Busoff[BUSSOFF_CH_CH2].Cnt++;
                if (RSCAN0Busoff[BUSSOFF_CH_CH2].Cnt >= 10U)
                {
                    // BUS_OFF_FLAG = 1U;
                    RSCAN0Busoff[BUSSOFF_CH_CH2].Cnt = 0U;

                    RSCAN0Busoff[BUSSOFF_CH_CH2].Status = RSCAN0_BUS_OFF_LV2;
                }
                RSCAN0_CH2_Busoff_Recover( );
            }
        }
        else if (RSCAN0Busoff[BUSSOFF_CH_CH2].Status == RSCAN0_BUS_OFF_LV2)
        {
            RSCAN0Busoff[BUSSOFF_CH_CH2].Timer++;

            if (RSCAN0Busoff[BUSSOFF_CH_CH2].Timer >= (RSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 10U))
            {
                RSCAN0Busoff[BUSSOFF_CH_CH2].Timer = 0U;
                RSCAN0_CH2_Busoff_Recover( );
            }
        }
        else
        {

        }
    }
    else                                          /* 总线正常,没有Bus-off发生/**/
    {
        Can_CH2_BusOffRecover();
    }
}
void Can_BusOff_Fun(void)
{
    Can_CH0_BusOff_Fun();
    Can_CH1_BusOff_Fun();
    Can_CH2_BusOff_Fun();
}

void Can_BusOffRecover(void)
{   
    Can_CH0_BusOffRecover();
    Can_CH1_BusOffRecover();
    Can_CH2_BusOffRecover();
}

void Can_CH0_BusOffRecover(void)
{
   
    RSCAN0Busoff[BUSSOFF_CH_CH0].Cnt = 0u;
    RSCAN0Busoff[BUSSOFF_CH_CH0].Status = 0u;
    RSCAN0Busoff[BUSSOFF_CH_CH0].Timer = 0u;
}
void Can_CH1_BusOffRecover(void)
{

    RSCAN0Busoff[BUSSOFF_CH_CH1].Cnt = 0u;
    RSCAN0Busoff[BUSSOFF_CH_CH1].Status = 0u;
    RSCAN0Busoff[BUSSOFF_CH_CH1].Timer = 0u;
}
void Can_CH2_BusOffRecover(void)
{
    BusOffEvent = 0u;
    // BUS_OFF_FLAG = 0;
    RSCAN0Busoff[BUSSOFF_CH_CH2].Cnt = 0u;
    RSCAN0Busoff[BUSSOFF_CH_CH2].Status = 0u;
    RSCAN0Busoff[BUSSOFF_CH_CH2].Timer = 0u;
}





