#include "RTE_CAN.h"
#include "RTE_GPIO.h"
#include "CAN_Communication_Matrix.h"
#include "Diag_ID_Def.h"
#include "DoCAN_ISO15765.h"
#include "RSCAN.h"
#include "RSCAN_Table.h"
#include "Check_Ctrl.h"

BusOffMonitorStruct BusOffMonitor;    // BusOff监控结构体
static uint8_t      BusOffCnt = 0u;
//初始化Bus Off监控结构体
void BusOff_Init(void)
{
    //重置相关信息
    BusOffMonitor.Status = BUS_OFF_STATUS_STABLE;
    BusOffMonitor.Timer  = 0;
    BusOffMonitor.Cnt    = 0;
    BusOffCnt            = 0;
}

// OSEK BusOff的判断，只需判断无需进行恢复操作
void BusOff_Service(void)
{
    RSCAN0_CH4_Busoff_Recover( );
    RSCAN0_CH1_Busoff_Recover( );
    RSCAN0_CH2_Busoff_Recover( );
}
/***Middle***/
void Can_Init(void)
{
    CAN_Frame_st_t     stCANFrame;
    RSCAN0_Config_st_t loc_can                      = {0};
    // loc_can.stRSCANCh2.u32RSCANChEn                 = 0U;
    // loc_can.stRSCANCh2.enRSCANChBps                 = RSCAN_Baud_Rate_250K;
    // loc_can.stRSCANCh2.u32RSCANChRuleSize           = CANFD0_CH2_RX_RULE_SIZE;
    // loc_can.stRSCANCh2.pfnRSCANConfirmCallBack      = Can_Confirm;
    // loc_can.stRSCANCh2.pfnRSCANReadMsgCallBack      = Can_Read_Msg;
    // loc_can.stRSCANCh2.pfnRSCANAbortConfirmCallBack = 0;

    loc_can.stRSCANCh4.u32RSCANChEn                 = 1U;
    loc_can.stRSCANCh4.enRSCANChBps                 = RSCAN_Baud_Rate_500K;
    loc_can.stRSCANCh4.u32RSCANChRuleSize           = CANFD0_CH4_RX_RULE_SIZE;
    loc_can.stRSCANCh4.pfnRSCANConfirmCallBack      = Can_Confirm;
    loc_can.stRSCANCh4.pfnRSCANReadMsgCallBack      = Can_Read_Msg;
    loc_can.stRSCANCh4.pfnRSCANAbortConfirmCallBack = 0;

    CAN_RST  = 0;
    RSCAN0_CH_Init(CANFD_RX_RULE_TABLE_LIST, &loc_can);


    
    // stCANFrame.u32CANID=0x666;
    // stCANFrame.u8CANFrameIDE=0;
    // stCANFrame.u8CANLEN=8;
    // stCANFrame.unCANData.u8CANData[0]=1;
    // stCANFrame.unCANData.u8CANData[1]=2;
    // stCANFrame.unCANData.u8CANData[2]=3;
    // stCANFrame.unCANData.u8CANData[3]=4;
    // stCANFrame.unCANData.u8CANData[4]=5;
    // stCANFrame.unCANData.u8CANData[5]=6;
    // stCANFrame.unCANData.u8CANData[6]=7;
    // stCANFrame.unCANData.u8CANData[7]=8;

    //  RSCAN0_CH1_Set_FIFO0_Data(&stCANFrame);
    //  stCANFrame.u32CANID++;
    //  RSCAN0_CH2_Set_FIFO0_Data(&stCANFrame);
    //  stCANFrame.u32CANID++;

    //  RSCAN0_CH4_Set_FIFO0_Data(&stCANFrame);
    //  stCANFrame.u32CANID++;

    //  RSCAN0_CH1_Set_TXBUF_Data(0, &stCANFrame);
    //  stCANFrame.u32CANID++;
    //  RSCAN0_CH1_Set_TXBUF_Data(1, &stCANFrame);
    //  stCANFrame.u32CANID++;
    //  RSCAN0_CH2_Set_TXBUF_Data(0, &stCANFrame);
    //  stCANFrame.u32CANID++;
    //  RSCAN0_CH2_Set_TXBUF_Data(1, &stCANFrame);
    //  stCANFrame.u32CANID++;

    //  RSCAN0_CH4_Set_TXBUF_Data(0, &stCANFrame);
    //  stCANFrame.u32CANID++;
    //  RSCAN0_CH4_Set_TXBUF_Data(1, &stCANFrame);
    //  stCANFrame.u32CANID++;

    //  stCANFrame.u32CANID++;
}

void Can_DeInit(void)
{
}

uint8_t Can_Write(_CAN_Msg *Msg)
{
    CAN_Frame_st_t m_msg;
    uint32_t       i;
    uint32_t       idx;
    m_msg.u32CANID      = Msg->MsgID;
    m_msg.u8CANLEN      = Msg->MsgDLC;
    m_msg.u8CANFrameIDE = 0;
    m_msg.u8CANFrameType = 0;
    for ( i = 0; i < m_msg.u8CANLEN; i++ )
    {
        m_msg.unCANData.u8CANData [ i ] = Msg->Msg [ i ];
    }
    if(CAN_Msg_Tx_Enable == 0)
    {
        return 0;
    }
    RSCAN0_CH4_Set_TXBUF_Data(Msg->MsgPro, &m_msg);

    return 0;
}

uint8_t Can_Write_FIFO(_CAN_Msg *Msg)
{
    CAN_Frame_st_t m_msg;
    uint32_t       i;
    uint32_t       idx;
    m_msg.u32CANID      = Msg->MsgID;
    m_msg.u8CANLEN      = Msg->MsgDLC;
    m_msg.u8CANFrameIDE = 0;
    m_msg.u8CANFrameType = 0;
    for ( i = 0; i < m_msg.u8CANLEN; i++ )
    {
        m_msg.unCANData.u8CANData [ i ] = Msg->Msg [ i ];
    }
    if(CAN_Msg_Tx_Enable == 0)
    {
        return 0;
    }
    RSCAN0_CH4_Set_FIFO0_Data(&m_msg);

    return 0;
}

void Can_Sleep_Fun(void)
{
}

void Can_SleepController_Fun(void)
{
}

void Can_Wakeup_Fun(void)
{
}

void Can_Uds_Abort(void)
{
}

void Can_Abort_All(void)
{
}

/*****Lower*******/
/**
 * @brief 从CAN通道读取消息
 *
 * 该函数用于从指定的CAN通道读取消息，并根据消息ID进行相应的处理。
 *
 * @param m_id 消息ID
 * @param m_dlc 数据长度码（DLC）
 * @param m_Msg 消息数据数组
 */
void Can_Read_Msg(uint32_t m_id, uint8_t m_dlc, uint8_t m_Msg [])
{
    Co_Can_Buff_Set(&CAN_CH4_CanMsgOp, Co_Can_ConvertSubID_CAN_CH4(m_id),m_dlc, m_Msg);
    //UDS_ReceivedMsg(m_id, m_dlc); 
    if ( (m_id == DIAG_ID_Rx_FUN) || (m_id == DIAG_ID_Rx_PHY) )
    {
        DoCAN_L_Data_Indication(m_id, m_dlc, m_Msg);
    }
}

void Can_Confirm(uint32_t Identifier, uint8_t TransferStatus)
{
    uint32_t MSG_ID;
    MSG_ID = 0ul;
    switch ( Identifier )
    {
        case RSCAN_CHANNEL_BUF_1:
            MSG_ID = DIAG_ID_Tx;
            DoCAN_L_Data_Confirm(MSG_ID, TransferStatus);

            break;

        default:
            break;
    }

    if ( TransferStatus == 0x00 )
    {
        DoCAN_L_Data_Confirm(Identifier, 1);
    }
    else
    {
    }
}
