#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"

#define RSCAN0_BUS_OFF_LV1_RECOVERY_TIME 100U  /* Bus-off ???100ms */
#define RSCAN0_BUS_OFF_LV2_RECOVERY_TIME 1000U /* Bus-off???1000ms */

void RSCAN0_CH4_Abort_All(void)
{
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_0);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_1);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_2);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_3);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_4);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_5);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_6);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_7);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_8);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_9);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_10);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_11);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_12);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_13);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_14);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_15);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_16);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_17);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_18);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_19);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_20);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_21);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_22);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_23);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_24);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_25);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_26);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_27);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_28);
    RSCAN0_CH4_Abort(RSCAN_CHANNEL_BUF_29);
}


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;
// }
uint8_t UDS_DtcBusoffCnt;
static uint8_t BusOffCnt = 0u;
// OSEK BusOff的判断，只需判断无需进行恢复操作
//初始化Bus Off监控结构体
void BusOff_Init(void)
{
    //重置相关信息
    BusOffMonitor.Status = BUS_OFF_STATUS_STABLE;
    BusOffMonitor.Timer = 0;
    BusOffMonitor.Cnt = 0;
    BusOffCnt = 0;

    UDS_DtcBusoffCnt = 0u;
    // end
}

void Can_BusOffRecover(void)
{
    BusOffMonitor.Cnt = 0u;
    BusOffMonitor.Status = 0u;
    BusOffMonitor.Timer = 0u;

    UDS_DtcBusoffCnt = 0u;
}

uint8_t GetBusOffState(void)
{
	uint8_t rscan_st;
	rscan_st = RSCAN0_CH4_Get_Busoff_Status();

	return rscan_st;
}

void CanBusoffRecover(void)
{
    RSCAN0_CH4_Busoff_Recover();
}
// OSEK BusOff的判断，只需判断无需进行恢复操作
void BusOff_Service(void)
{
    if (GetBusOffState() != 0u)
    {
        RSCAN0_CH4_Abort_All();
        BusOffMonitor.RecoverCnt = 0u;

        if (BusOffMonitor.Status == BUS_OFF_STATUS_STABLE)
        {
            BusOffMonitor.Status = BUS_OFF_STATUS_LV1;
        }

        if (BusOffMonitor.Status == BUS_OFF_STATUS_LV1)
        {
            BusOffMonitor.Timer++;
            if (BusOffMonitor.Timer >= RSCAN0_BUS_OFF_LV1_RECOVERY_TIME / 10U)
            {
                BusOffMonitor.Timer = 0U;
                Can_QuickTimer_Init();
                CanBusoffRecover();

                if(UDS_DtcBusoffCnt <= 100u)
                {
                    UDS_DtcBusoffCnt ++;
                }

                BusOffMonitor.Cnt++;
                if (BusOffMonitor.Cnt >= 10U)
                {
                    BusOffMonitor.Cnt = 0U;
                    BusOffMonitor.Status = BUS_OFF_STATUS_LV2;
                }
            }
        }
        else if (BusOffMonitor.Status == BUS_OFF_STATUS_LV2)
        {
            BusOffMonitor.Timer++;
            if (BusOffMonitor.Timer >= RSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 10U)
            {
                BusOffMonitor.Timer = 0U;
                Can_QuickTimer_Init();
                CanBusoffRecover();

                if(UDS_DtcBusoffCnt <= 100u)
                {
                    UDS_DtcBusoffCnt ++;
                }
            }
        }
    }
    else
    {
        if(BusOffMonitor.RecoverCnt < 2u)
        {
            BusOffMonitor.RecoverCnt ++;
        }
        else
        {
            BusOffMonitor.Cnt = 0u;
            BusOffMonitor.Status = 0u;
            BusOffMonitor.Timer = 0u;
            UDS_DtcBusoffCnt = 0u;
        }
    }
}
/***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
    {
    }
}

void Can_QuickTimer_Init(void)
{
	uint32_t i = 0u;

    for ( i = 0u; i < CAN_CH4_ID_SEND_TOTAL; i++ )
    {
        // Can_Msg_TX_FastInitCycle(&CAN_CH4_CanMsgTxOp, i, CAN_CH4_CANSendAttr [ i ].u32MsgCycleOffset);
    }
}
