#include <stdint.h>
#include <stdbool.h>  
#include "CANBUS.h"
extern volatile uint16_t tick;
static int8_t CAN_All_Channel_Transmit4HL(CANBUS_t * CAN_Obj, uint8_t ChannelNo, uint8_t Seq, uint32_t *state, uint8_t * CurrntFrmNo, uint16_t * Tick4Timeout, uint32_t *TransmitCANEnterBuffer);                                         
#ifdef USE_CAN1
volatile bool Can1RxSuccess=false;
volatile uint8_t Can1TxSuccess=0;   //we use Success tx :  Bit0 For Tx ChannelA, Bit1 Tx for ChannelB ,Bit2 for Tx ChannelC

//Transmit Channel A for CAN1
extern uint16_t TxCAN_A_RTR_DLC_UseStd_1[]; //For CAN1 channel A transmit:  index is Seq No
//bit15: RTR, bit14: Std CANID , Bit13: Need response, Bit12: Response is long frame response,Bit10: reserved. Bit10-0: DLC (Max 255*7=1785 bytes, so 2048 has some no use, >8 as long frame) 
//if index>3 (Seq4, seq5, ...), we will ignore Bit13, take it as 0 (no need response)
//if transmit is long frame (Bit10-0: DLC>8), we will ignore Bit13, take it as 0 (no need response)
// if bit15: RTR, we will ignore Bit13, take it as 0 (no need response)
extern uint16_t TxCAN_A_Timeout_1[]; //Timeout in ms.  This is timeout for Transmit, which needs response. Index is Seq No , Max index=3 
extern uint32_t TransmitFrameCANID_A_1[]; //CAN ID.   Index is Seq No 

//We changed it to use index of CAN ID
//extern uint32_t TxResponseCANID_A_1[];   //Respnse CAN ID, Index is Seq No. Max Index=3.  Bit31:1----Ext frame. 0--std frame.  
extern uint16_t TxResponseCANID_Index_A_1[]; //Response CAN ID Index,  Bit15-Bit14:  Type of CANID  ---- 00: Std short Frame, 01: Ext short Frame 
// 10: Std long Frame, 11: Ext long Frame.  Bit13-Bit0: truly Response CAN ID index
//This Array's index is Seq No. Max Index=3.
extern uint8_t ResponseDataLen_A_1[]; //Response Data length in byte, Index is Seq No. Max Index=3.  
//When Length>8, respnse is long frame.  But it is possible, it is long frame  when Length <8, for example. Long frame response, but this time, only feedback one frame
//extern uint8_t ResponseData_A_1[][]; //Response Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t * ResponseData_A_1[]; //Response Data , first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t ResponseMaxFrameNo_A_1[]; //Respnse Max frame Number for this time, Index is Seq No. Max Index=3.  

extern volatile uint8_t RxStdDLC_1[]; //CAN1 short Std rx: Bit7 :RTR (1 is RTR, after reading, clear to 0), Bit6-0: DLC (0 to 8)
extern volatile uint8_t RxExtDLC_1[]; //CAN1 short Ext rx: Bit7 :RTR (1 is RTR, after reading, clear to 0), Bit6-0: DLC (0 to 8)


extern uint8_t *TransmitDataArrayA_Seq_1[]; //CAN1 Channel A transmit , Data Array, point to data array. index is Seq No.  This variable is from Simulink



//Transmit Channel B for CAN1
#ifdef USE_CAN1_CHANNELB
extern uint16_t TxCAN_B_RTR_DLC_UseStd_1[]; //For CAN1 channel B transmit:  index is Seq No
//bit15: RTR, bit14: Std CANID , Bit13: Need response, Bit12: long frame response,Bit10: reserved. Bit10-0: DLC (Max 255*7=1785 bytes, so 2048 has some no use, >8 as long frame) 
//if index>3 (Seq4, seq5, ...), we will ignore Bit13, take it as 0 (no need response)
//if transmit is long frame (Bit10-0: DLC>8), we will ignore Bit13, take it as 0 (no need response)
// if bit15: RTR, we will ignore Bit13, take it as 0 (no need response)
extern uint16_t TxCAN_B_Timeout_1[]; //Timeout in ms.  This is timeout for Transmit, which needs response. Index is Seq No , Max index=3 

extern uint32_t TransmitFrameCANID_B_1[]; //CAN ID.   Index is Seq No  
extern uint16_t TxResponseCANID_Index_B_1[]; //Response CAN ID Index,  Bit15-Bit14:  Type of CANID  ---- 00: Std short Frame, 01: Ext short Frame 
// 10: Std long Frame, 11: Ext long Frame.  Bit13-Bit0: truly Response CAN ID index
//This Array's index is Seq No. Max Index=3.

extern uint32_t TxResponseCANID_B_1[]; //Respnse CAN ID, Index is Seq No. Max Index=3.  Bit31:1----Ext frame. 0--std frame.  
extern uint8_t ResponseDataLen_B_1[]; //Respnse Data length in byte, Index is Seq No. Max Index=3.  
//When Length>8, respnse is long frame.  But it is possible, it is long frame  when Length <8, for example. Long frame response, but this time, only feedback one frame
//extern uint8_t ResponseData_B_1[][]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t * ResponseData_B_1[]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t ResponseMaxFrameNo_B_1[]; //Respnse Max frame Number for this time, Index is Seq No. Max Index=3.  
extern uint8_t *TransmitDataArrayB_Seq_1[]; //CAN1 Channel B transmit , Data Array, point to data array. index is Seq No.  This variable is from Simulink
#endif  //end of "#ifdef USE_CAN1_CHANNELB"

//Transmit Channel C for CAN1
#ifdef USE_CAN1_CHANNELC
extern uint16_t TxCAN_C_RTR_DLC_UseStd_1[]; //For CAN1 channel C transmit:  index is Seq No
//bit15: RTR, bit14: Std CANID , Bit13: Need response, Bit12: long frame response,Bit10: reserved. Bit10-0: DLC (Max 255*7=1785 bytes, so 2048 has some no use, >8 as long frame) 
//if index>3 (Seq4, seq5, ...), we will ignore Bit13, take it as 0 (no need response)
//if transmit is long frame (Bit10-0: DLC>8), we will ignore Bit13, take it as 0 (no need response)
// if bit15: RTR, we will ignore Bit13, take it as 0 (no need response)
extern uint16_t TxCAN_C_Timeout_1[]; //Timeout in ms.  This is timeout for Transmit, which needs response. Index is Seq No.  Max index=3  
extern uint32_t TransmitFrameCANID_C_1[]; //CAN ID.   Index is Seq No  
//extern uint32_t TxResponseCANID_C_1[];   //Respnse CAN ID, Index is Seq No. Max Index=3.  Bit31:1----Ext frame. 0--std frame.  
extern uint16_t TxResponseCANID_Index_C_1[]; //Response CAN ID Index,  Bit15-Bit14:  Type of CANID  ---- 00: Std short Frame, 01: Ext short Frame 
// 10: Std long Frame, 11: Ext long Frame.  Bit13-Bit0: truly Response CAN ID index
//This Array's index is Seq No. Max Index=3.
extern uint8_t ResponseDataLen_C_1[]; //Respnse Data length in byte, Index is Seq No. Max Index=3.  
//When Length>8, respnse is long frame.  But it is possible, it is long frame  when Length <8, for example. Long frame response, but this time, only feedback one frame
//extern uint8_t ResponseData_C_1[][]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t * ResponseData_C_1[]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t ResponseMaxFrameNo_C_1[]; //Respnse Max frame Number for this time, Index is Seq No. Max Index=3.  


extern uint8_t *TransmitDataArrayC_Seq_1[]; //CAN1 Channel B transmit , Data Array, point to data array. index is Seq No.  This variable is from Simulink


#endif  //end of "#ifdef USE_CAN1_CHANNELC"

extern volatile uint16_t RxStdCANID_1[]; //Rx Std short frame CANID for CAN1
extern volatile uint32_t RxExtCANID_1[]; //Rx Ext short frame for CAN1
extern volatile uint16_t RxStdCANID_Long_1[]; //Rx Std long frame CANID for CAN1, index is CAN ID index
extern volatile uint32_t RxExtCANID_Long_1[]; //Rx ext long frame CANID for CAN1, index is CAN ID index
extern volatile uint8_t RxStdData_Long_1[][CAN1_RX_MAX_STD_FRAME_QTY4LONG][8]; //CAN1 long Std rx: 1st index  -> CAN ID index, 2nd Index -> Frame No, 3rd index -> Data index,  Array value is Data
extern volatile uint8_t RxExtData_Long_1[][CAN1_RX_MAX_EXT_FRAME_QTY4LONG][8]; //CAN1 long Ext rx: 1st index  -> CAN ID index, 2nd Index -> Frame No, 3rd index -> Data index,  Array value is Data
extern volatile uint8_t RxStdData_1[][8]; //CAN1 short Std rx Data:  1st index  -> No of packet, 2nd index -> Data No
extern volatile uint8_t RxExtData_1[][8]; //CAN1 short Ext rx Data:  1st index  -> No of packet, 2nd index -> Data No
#endif   //end of "#ifdef USE_CAN1"

#ifdef USE_CAN2
volatile bool Can2RxSuccess=false;
volatile uint32_t Can2TxSuccess=0;   //we use Success tx :  Bit0 For Tx ChannelA, Bit1 Tx for ChannelB ,Bit2 for Tx ChannelC
//Transmit Channel A for CAN2
extern uint16_t TxCAN_A_RTR_DLC_UseStd_2[]; //For CAN2 channel A transmit:  index is Seq No
//bit15: RTR, bit14: Std CANID , Bit13: Need response, Bit12: long frame response,Bit10: reserved. Bit10-0: DLC (Max 255*7=1785 bytes, so 2048 has some no use, >8 as long frame) 
//if index>3 (Seq4, seq5, ...), we will ignore Bit13, take it as 0 (no need response)
//if transmit is long frame (Bit10-0: DLC>8), we will ignore Bit13, take it as 0 (no need response)
// if bit15: RTR, we will ignore Bit13, take it as 0 (no need response)
extern uint16_t TxCAN_A_Timeout_2[]; //Timeout in ms.  This is timeout for Transmit, which needs response. Index is Seq No  ,Max  Index=3
extern uint32_t TransmitFrameCANID_A_2[]; //CAN ID.   Index is Seq No  
//extern uint32_t TxResponseCANID_A_2[];   //Respnse CAN ID, Index is Seq No. Max Index=3.  Bit31:1----Ext frame. 0--std frame. 
extern uint16_t TxResponseCANID_Index_A_2[]; //Response CAN ID Index,  Bit15-Bit14:  Type of CANID  ---- 00: Std short Frame, 01: Ext short Frame 
// 10: Std long Frame, 11: Ext long Frame.  Bit13-Bit0: truly Response CAN ID index
//This Array's index is Seq No. Max Index=3.
extern uint8_t ResponseDataLen_A_2[]; //Respnse Data length in byte, Index is Seq No. Max Index=3.  
//When Length>8, respnse is long frame.  But it is possible, it is long frame  when Length <8, for example. Long frame response, but this time, only feedback one frame
//extern uint8_t ResponseData_A_2[][]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t * ResponseData_A_2[]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t ResponseMaxFrameNo_A_2[]; //Respnse Max frame Number for this time, Index is Seq No. Max Index=3.  

extern volatile uint8_t RxStdDLC_2[]; //CAN2 short Std rx: Bit7 :RTR (1 is RTR, after reading, clear to 0), Bit6-0: DLC (0 to 8)
extern volatile uint8_t RxExtDLC_2[]; //CAN2 short Ext rx: Bit7 :RTR (1 is RTR, after reading, clear to 0), Bit6-0: DLC (0 to 8)


extern uint8_t *TransmitDataArrayA_Seq_2[]; //CAN2 Channel A transmit , Data Array, point to data array. index is Seq No.  This variable is from Simulink


//Transmit Channel B for CAN2
#ifdef USE_CAN2_CHANNELB
extern uint16_t TxCAN_B_RTR_DLC_UseStd_2[]; //For CAN2 channel B transmit:  index is Seq No
//bit15: RTR, bit14: Std CANID , Bit13: Need response, Bit12: long frame response,Bit10: reserved. Bit10-0: DLC (Max 255*7=1785 bytes, so 2048 has some no use, >8 as long frame) 
//if index>3 (Seq4, seq5, ...), we will ignore Bit13, take it as 0 (no need response)
//if transmit is long frame (Bit10-0: DLC>8), we will ignore Bit13, take it as 0 (no need response)
// if bit15: RTR, we will ignore Bit13, take it as 0 (no need response)
extern uint16_t TxCAN_B_Timeout_2[]; //Timeout in ms.  This is timeout for Transmit, which needs response. Index is Seq No  ,Max  Index=3
extern uint32_t TransmitFrameCANID_B_2[]; //CAN ID.   Index is Seq No  
//extern uint32_t TxResponseCANID_B_2[];   //Respnse CAN ID, Index is Seq No. Max Index=3.  Bit31:1----Ext frame. 0--std frame.  
extern uint16_t TxResponseCANID_Index_B_2[]; //Response CAN ID Index,  Bit15-Bit14:  Type of CANID  ---- 00: Std short Frame, 01: Ext short Frame 
// 10: Std long Frame, 11: Ext long Frame.  Bit13-Bit0: truly Response CAN ID index
//This Array's index is Seq No. Max Index=3.
extern uint8_t ResponseDataLen_B_2[]; //Respnse Data length in byte, Index is Seq No. Max Index=3.  
//When Length>8, respnse is long frame.  But it is possible, it is long frame  when Length <8, for example. Long frame response, but this time, only feedback one frame
//extern uint8_t ResponseData_B_2[][]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t * ResponseData_B_2[]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t ResponseMaxFrameNo_B_2[]; //Respnse Max frame Number for this time, Index is Seq No. Max Index=3. 


extern uint8_t *TransmitDataArrayB_Seq_2[]; //CAN2 Channel B transmit , Data Array, point to data array. index is Seq No.  This variable is from Simulink

#endif  //end of "#ifdef USE_CAN2_CHANNELB"


//Transmit Channel C for CAN2
#ifdef USE_CAN2_CHANNELC
extern uint16_t TxCAN_C_RTR_DLC_UseStd_2[]; //For CAN2 channel C transmit:  index is Seq No
//bit15: RTR, bit14: Std CANID , Bit13: Need response, Bit12: long frame response,Bit10: reserved. Bit10-0: DLC (Max 255*7=1785 bytes, so 2048 has some no use, >8 as long frame) 
//if index>3 (Seq4, seq5, ...), we will ignore Bit13, take it as 0 (no need response)
//if transmit is long frame (Bit10-0: DLC>8), we will ignore Bit13, take it as 0 (no need response)
// if bit15: RTR, we will ignore Bit13, take it as 0 (no need response)
extern uint16_t TxCAN_C_Timeout_2[]; //Timeout in ms.  This is timeout for Transmit, which needs response. Index is Seq No  ,Max  Index=3
extern uint32_t TransmitFrameCANID_C_2[]; //CAN ID.   Index is Seq No  
//extern uint32_t TxResponseCANID_C_2[];   //Respnse CAN ID, Index is Seq No. Max Index=3.  Bit31:1----Ext frame. 0--std frame.  
extern uint16_t TxResponseCANID_Index_C_2[]; //Response CAN ID Index,  Bit15-Bit14:  Type of CANID  ---- 00: Std short Frame, 01: Ext short Frame 
// 10: Std long Frame, 11: Ext long Frame.  Bit13-Bit0: truly Response CAN ID index
//This Array's index is Seq No. Max Index=3.
extern uint8_t ResponseDataLen_C_2[]; //Respnse Data length in byte, Index is Seq No. Max Index=3.  
//When Length>8, respnse is long frame.  But it is possible, it is long frame  when Length <8, for example. Long frame response, but this time, only feedback one frame
//extern uint8_t ResponseData_C_2[][]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t * ResponseData_C_2[]; //Respnse Data length in byte, first Index is Seq No. Max Index=3. 2nd index is byte no.
extern uint8_t ResponseMaxFrameNo_C_2[]; //Respnse Max frame Number for this time, Index is Seq No. Max Index=3. 

extern uint8_t *TransmitDataArrayC_Seq_2[]; //CAN2 Channel C transmit , Data Array, point to data array. index is Seq No.  This variable is from Simulink


#endif  //end of "#ifdef USE_CAN2_CHANNELC"
extern volatile uint16_t RxStdCANID_2[]; //Rx Std short frame CANID for CAN2
extern volatile uint32_t RxExtCANID_2[]; //Rx Ext short frame for CAN2
extern volatile uint16_t RxStdCANID_Long_2[]; //Rx Std long frame CANID for CAN2, index is CAN ID index
extern volatile uint32_t RxExtCANID_Long_2[]; //Rx ext long frame CANID for CAN2, index is CAN ID index
extern volatile uint8_t RxStdData_Long_2[][CAN2_RX_MAX_STD_FRAME_QTY4LONG][8]; //CAN2 long Std rx: 1st index  -> CAN ID index, 2nd Index -> Frame No, 3rd index -> Data index,  Array value is Data
extern volatile uint8_t RxExtData_Long_2[][CAN2_RX_MAX_EXT_FRAME_QTY4LONG][8]; //CAN2 long Ext rx: 1st index  -> CAN ID index, 2nd Index -> Frame No, 3rd index -> Data index,  Array value is Data
extern volatile uint8_t RxStdData_2[][8]; //CAN2 short Std rx Data:  1st index  -> No of packet, 2nd index -> Data No
extern volatile uint8_t RxExtData_2[][8]; //CAN2 short Ext rx Data:  1st index  -> No of packet, 2nd index -> Data No
#endif   //end of "#ifdef USE_CAN2"



void PollTXOK(CANBUS_t * pCANxObj) 
{
    uint32_t txRequest;
    uint16_t i;
    if ( pCANxObj->CAN_Peripheral_No==1)
    {
        #if defined(USE_CAN1) && !defined(USE_CANFD1)  
           //DCAN           
            txRequest = HWREG(CANBUS1Base + CAN_O_TXRQST);            
            for (i=0;i<3;i++) {
                if ((txRequest & (1U << i)) == 0) {
                    // Message Object 1 has completed transmission
                    Can1TxSuccess |= (1U << i);
                }
            }
        #elif defined(USE_CAN1) && defined(USE_CANFD1) 
            //MCAN
            Can1TxSuccess=~MCAN_getTxBufReqPend(CANBUS1Base);

        #endif
    }
    else {
        #if defined(USE_CAN2) && !defined(USE_CANFD2)     
           //DCAN       
            txRequest = HWREG(CANBUS2Base + CAN_O_TXRQST);            
            for (i=0;i<3;i++) {
                if ((txRequest & (1U << i)) == 0) {
                    // Message Object 1 has completed transmission
                    Can2TxSuccess |= (1U << i);
                }
            }
        #elif defined(USE_CAN2) && defined(USE_CANFD2)  
             //MCAN   
             Can2TxSuccess=~MCAN_getTxBufReqPend(CANBUS2Base);
        #endif
    }
}

//Wrap CAN_Rx_Function


#ifdef USE_CAN1
extern CANBUS_t CAN_myObj1; //for CAN1

/**
 * Put all CAN1  Rx data into our high level buffers
 */
void CAN1_fill_Rx_Data() {
    uint16_t MyCANData[8];
    uint32_t msgID;
    uint32_t i;
    if (CAN_myObj1.RxCANReceived)  {
        CAN_myObj1.RxCANReceived=false;
    #ifndef USE_CANFD1
        //DCAN        
        uint32_t DCAN_RxMailBox1_shot;
        CAN_MsgFrameType frameType;
        // Disable interrupt line 0 to protect shared variable
        CAN_disableInterrupt(CANBUS1Base, CAN_INT_IE0);
        DCAN_RxMailBox1_shot=DCAN_RxMailBox1;
        DCAN_RxMailBox1=0;
        // Re-enable interrupt line 0
        CAN_enableInterrupt(CANBUS1Base, CAN_INT_IE0);
        bool isRTR = 0;
        uint8_t dlc;
        MyCANData[0]=0XFFFF;
        MyCANData[1]=0XFFFF;
        MyCANData[2]=0XFFFF;
        MyCANData[3]=0XFFFF;
        MyCANData[4]=0XFFFF;
        MyCANData[5]=0XFFFF;
        MyCANData[6]=0XFFFF;
        MyCANData[7]=0XFFFF; 
        for (i=3;i<32; i++)  {            
            if (DCAN_RxMailBox1_shot & (1U<<i)) {                                                
                if (CAN_readMessageWithID(CANBUS1Base,
                                  i+1,
                                  &frameType,
                                  &msgID,
                                  MyCANData))   {
                    dlc=0;
                    if (MyCANData[0]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[1]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[2]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[3]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[4]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[5]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[6]!=0xffff) dlc++; else goto done_dlc;
                    if (MyCANData[7]!=0xffff) dlc++;
                    done_dlc:
                    if (frameType==CAN_MSG_FRAME_STD)   {
                        putCAN1RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) msgID, /*bool RTR*/isRTR, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/MyCANData);
                    }   
                    else {
                        putCAN1RxExtCAN2Buffer(/*uint32_t CANID*/msgID, /*bool RTR*/isRTR, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/MyCANData);
                    }
                    MyCANData[0]=0XFFFF;
                    MyCANData[1]=0XFFFF;
                    MyCANData[2]=0XFFFF;
                    MyCANData[3]=0XFFFF;
                    MyCANData[4]=0XFFFF;
                    MyCANData[5]=0XFFFF;
                    MyCANData[6]=0XFFFF;
                    MyCANData[7]=0XFFFF;           

                }           
                
            }
        }
    
    #else
        //MCAN
        MCAN_RxBufElement rxMsg;        
        uint32_t intrStatus;
        do {
            MCAN_readMsgRam(CANBUS1Base, MCAN_MEM_TYPE_FIFO, 0, MCAN_RX_FIFO_NUM_0, &rxMsg);
            uint8_t dlc =rxMsg.dlc;
            if (dlc>8) dlc=8;
            if (0==rxMsg.xtd) {
                //standard frame 
                putCAN1RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) (rxMsg.id>>18), /*bool RTR*/rxMsg.rtr, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/rxMsg.data);

            }
            else {
                //extended frame
                putCAN1RxExtCAN2Buffer(/*uint32_t CANID*/ (rxMsg.id&0x1FFFFFFF), /*bool RTR*/rxMsg.rtr, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/rxMsg.data);
            }
            intrStatus = MCAN_getIntrStatus(CANBUS1Base);
        }  while(  (MCAN_INTR_SRC_RX_FIFO0_NEW_MSG & intrStatus) == MCAN_INTR_SRC_RX_FIFO0_NEW_MSG);  

    #endif    
    }  

}


#endif

/**
 * CAN1 Channel A transmit in Seq No, and it can get response data
 * @param Seq
 * @return 
 * 0: Success
 * 1: continue
 * negative: fail
 */
int8_t CAN1_A_Channel_Transmit4HL(uint8_t Seq) {
#ifndef USE_CAN1
    return 0;
#else
    static uint32_t state = 0;
    static uint32_t TransmitCANEnterBuffer=0;
    static uint8_t CurrntFrmNo[MAX_SEQQTY4A_1]; //for long frame transmit
    static uint16_t Tick4Timeout[4]; //long frame response tick for timeout, Max Seq No=3    
    //NO NEED tick for Sync because we clear Sync arrived flag in high level when all Channel transmit sone.
    //static uint16_t SyncArrivedTick;  //Syn arrived tick.  After you get sync, you can transmit if Sync Enable. Sync over 10ms, if no transmit, then Sync expires
    return CAN_All_Channel_Transmit4HL(/*uCANBUS_t * CAN_Obj*/ &CAN_myObj1, /*uint8_t ChannelNo*/0, Seq,
            /*uint32_t *state*/&state, /*uint8_t * CurrntFrmNo*/CurrntFrmNo, /*uint16_t * Tick4Timeout*/Tick4Timeout, /* uint32_t *TransmitCANEnterBuffer*/&TransmitCANEnterBuffer );

#endif


}



/**
 * CAN1 Channel B transmit in Seq No
 * @param Seq
 * @return 
 * 0: Success
 * 1: continue
 * negative: fail
 */
int8_t CAN1_B_Channel_Transmit4HL(uint8_t Seq) {
#ifndef USE_CAN1
    return 0;
#else
#ifndef USE_CAN1_CHANNELB
    return 0;
#else
    static uint32_t state = 0;
    static uint32_t TransmitCANEnterBuffer=0;
    static uint8_t CurrntFrmNo[MAX_SEQQTY4B_1]; //for long frame transmit
    static uint16_t Tick4Timeout[4]; //long frame response tick for timeout, Max Seq No=3    
    //NO NEED tick for Sync because we clear Sync arrived flag in high level when all Channel transmit sone.
    //static uint16_t SyncArrivedTick;  //Syn arrived tick.  After you get sync, you can transmit if Sync Enable. Sync over 10ms, if no transmit, then Sync expires
     return CAN_All_Channel_Transmit4HL(/*uCANBUS_t * CAN_Obj*/ &CAN_myObj1, /*uint8_t ChannelNo*/1, Seq,
            /*uint32_t *state*/&state, /*uint8_t * CurrntFrmNo*/CurrntFrmNo, /*uint16_t * Tick4Timeout*/Tick4Timeout, &TransmitCANEnterBuffer);
#endif

#endif
}

/**
 * CAN1 Channel C transmit in Seq No
 * @param Seq
 * @return 
 * 0: Success
 * 1: continue
 * negative: fail
 */
int8_t CAN1_C_Channel_Transmit4HL(uint8_t Seq) {
#ifndef USE_CAN1
    return 0;
#else   
#ifndef USE_CAN1_CHANNELC
    return 0;
#else
    static uint32_t state = 0;
    static uint32_t TransmitCANEnterBuffer=0;
    static uint8_t CurrntFrmNo[MAX_SEQQTY4C_1]; //for long frame transmit
    static uint16_t Tick4Timeout[4]; //long frame response tick for timeout, Max Seq No=3    
    //NO NEED tick for Sync because we clear Sync arrived flag in high level when all Channel transmit sone.
    //static uint16_t SyncArrivedTick;  //Syn arrived tick.  After you get sync, you can transmit if Sync Enable. Sync over 10ms, if no transmit, then Sync expires
    return CAN_All_Channel_Transmit4HL(/*uCANBUS_t * CAN_Obj*/ &CAN_myObj1, /*uint8_t ChannelNo*/2, Seq,
            /*uint32_t *state*/&state, /*uint8_t * CurrntFrmNo*/CurrntFrmNo, /*uint16_t * Tick4Timeout*/Tick4Timeout,&TransmitCANEnterBuffer);
#endif
#endif
}

#ifdef USE_CAN2
extern CANBUS_t CAN_myObj2; //for CAN2
/**
 * Put all CAN2  Rx data into our high level buffers
 */
void CAN2_fill_Rx_Data() {   
    uint16_t MyCANData[8];
    uint32_t msgID;
    uint32_t i;
    if (CAN_myObj2.RxCANReceived)  {
        CAN_myObj2.RxCANReceived=false;
    #ifndef USE_CANFD2
        //DCAN        
        uint32_t DCAN_RxMailBox2_shot;
        CAN_MsgFrameType frameType;
        // Disable interrupt line 0 to protect shared variable
        CAN_disableInterrupt(CANBUS2Base, CAN_INT_IE0);
        DCAN_RxMailBox2_shot=DCAN_RxMailBox2;
        DCAN_RxMailBox2=0;
        // Re-enable interrupt line 0
        CAN_enableInterrupt(CANBUS2Base, CAN_INT_IE0);
        bool isRTR = 0;
        uint8_t dlc;
        MyCANData[0]=0XFFFF;
        MyCANData[1]=0XFFFF;
        MyCANData[2]=0XFFFF;
        MyCANData[3]=0XFFFF;
        MyCANData[4]=0XFFFF;
        MyCANData[5]=0XFFFF;
        MyCANData[6]=0XFFFF;
        MyCANData[7]=0XFFFF; 
        for (i=3;i<32; i++)  {            
            if (DCAN_RxMailBox2_shot & (1U<<i)) {
                //Message Object i+1 received data 
                dlc=0;
                if (MyCANData[0]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[1]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[2]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[3]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[4]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[5]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[6]!=0xffff) dlc++; else goto done_dlc;
                if (MyCANData[7]!=0xffff) dlc++;
                done_dlc:    
                if (CAN_readMessageWithID(CANBUS2Base,
                                  i+1,
                                  &frameType,
                                  &msgID,
                                  MyCANData))   {
                    if (frameType==CAN_MSG_FRAME_STD)   {
                        putCAN2RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) msgID, /*bool RTR*/isRTR, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/MyCANData);
                    }   
                    else {
                        putCAN2RxExtCAN2Buffer(/*uint32_t CANID*/msgID, /*bool RTR*/isRTR, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/MyCANData);
                    }          

                }           
                MyCANData[0]=0XFFFF;
                MyCANData[1]=0XFFFF;
                MyCANData[2]=0XFFFF;
                MyCANData[3]=0XFFFF;
                MyCANData[4]=0XFFFF;
                MyCANData[5]=0XFFFF;
                MyCANData[6]=0XFFFF;
                MyCANData[7]=0XFFFF; 
            }
        }
    
    #else
        //MCAN
        MCAN_RxBufElement rxMsg;       
        uint32_t intrStatus;
        do {
                MCAN_readMsgRam(CANBUS2Base, MCAN_MEM_TYPE_FIFO, 0,MCAN_RX_FIFO_NUM_0, &rxMsg);
                uint8_t dlc =rxMsg.dlc;
                if (dlc>8) dlc=8;
                if (0==rxMsg.xtd) {
                    //standard frame 
                    putCAN2RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) (rxMsg.id>>18), /*bool RTR*/rxMsg.rtr, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/rxMsg.data);

                }
                else {
                    //extended frame
                    putCAN2RxExtCAN2Buffer(/*uint32_t CANID*/ (rxMsg.id&0x1FFFFFFF), /*bool RTR*/rxMsg.rtr, /*uint8_t DLC*/dlc, /*uint8_t * pCAN_Data*/rxMsg.data);
                }
                intrStatus = MCAN_getIntrStatus(CANBUS2Base);
        }  while(  (MCAN_INTR_SRC_RX_FIFO0_NEW_MSG & intrStatus) == MCAN_INTR_SRC_RX_FIFO0_NEW_MSG);
        
    #endif    
    }  


}





#endif

/**
 * CAN2 Channel A transmit in Seq No
 * @param Seq
 * @return 
 * 0: Success
 * 1: continue
 * negative: fail
 */
int8_t CAN2_A_Channel_Transmit4HL(uint8_t Seq) {
#ifndef USE_CAN2
    return 0;
#else
#ifndef USE_CAN2_CHANNELA
    return 0;
#else
    static uint32_t state = 0;
    static uint32_t TransmitCANEnterBuffer=0;
    static uint8_t CurrntFrmNo[MAX_SEQQTY4A_2]; //for long frame transmit
    static uint16_t Tick4Timeout[4]; //long frame response tick for timeout, Max Seq No=3    
    //NO NEED tick for Sync because we clear Sync arrived flag in high level when all Channel transmit sone.
    //static uint16_t SyncArrivedTick;  //Syn arrived tick.  After you get sync, you can transmit if Sync Enable. Sync over 10ms, if no transmit, then Sync expires
    return CAN_All_Channel_Transmit4HL(/*uCANBUS_t * CAN_Obj*/ &CAN_myObj2, /*uint8_t ChannelNo*/0, Seq,
            /*uint32_t *state*/&state, /*uint8_t * CurrntFrmNo*/CurrntFrmNo, /*uint16_t * Tick4Timeout*/Tick4Timeout,&TransmitCANEnterBuffer);
#endif
#endif
}

/**
 * CAN2 Channel B transmit in Seq No
 * @param Seq
 * @return 
 * 0: Success
 * 1: continue
 * negative: fail
 */
int8_t CAN2_B_Channel_Transmit4HL(uint8_t Seq) {
#ifndef USE_CAN2
    return 0;
#else
#ifndef USE_CAN2_CHANNELB
    return 0;
#else
    static uint32_t state = 0;
    static uint32_t TransmitCANEnterBuffer=0;
    static uint8_t CurrntFrmNo[MAX_SEQQTY4B_2]; //for long frame transmit
    static uint16_t Tick4Timeout[4]; //long frame response tick for timeout, Max Seq No=3    
    //NO NEED tick for Sync because we clear Sync arrived flag in high level when all Channel transmit sone.
    //static uint16_t SyncArrivedTick;  //Syn arrived tick.  After you get sync, you can transmit if Sync Enable. Sync over 10ms, if no transmit, then Sync expires
    return CAN_All_Channel_Transmit4HL(/*uCANBUS_t * CAN_Obj*/ &CAN_myObj2, /*uint8_t ChannelNo*/1, Seq,
            /*uint32_t *state*/&state, /*uint8_t * CurrntFrmNo*/CurrntFrmNo, /*uint16_t * Tick4Timeout*/Tick4Timeout,&TransmitCANEnterBuffer);
#endif
#endif
}

/**
 * CAN2 Channel C transmit in Seq No
 * @param Seq
 * @return 
 * 0: Success
 * 1: continue
 * negative: fail
 */
int8_t CAN2_C_Channel_Transmit4HL(uint8_t Seq) {
#ifndef USE_CAN2
    return 0;
#else    
#ifndef USE_CAN2_CHANNELC
    return 0;
#else
    static uint32_t state = 0;
    static uint32_t TransmitCANEnterBuffer=0;
    static uint8_t CurrntFrmNo[MAX_SEQQTY4C_2]; //for long frame transmit
    static uint16_t Tick4Timeout[4]; //long frame response tick for timeout, Max Seq No=3    
    //NO NEED tick for Sync because we clear Sync arrived flag in high level when all Channel transmit sone.
    //static uint16_t SyncArrivedTick;  //Syn arrived tick.  After you get sync, you can transmit if Sync Enable. Sync over 10ms, if no transmit, then Sync expires
    return CAN_All_Channel_Transmit4HL(/*uCANBUS_t * CAN_Obj*/ &CAN_myObj2, /*uint8_t ChannelNo*/2, Seq,
            /*uint32_t *state*/&state, /*uint8_t * CurrntFrmNo*/CurrntFrmNo, /*uint16_t * Tick4Timeout*/Tick4Timeout,&TransmitCANEnterBuffer);
#endif
#endif
}

int8_t CAN_All_Channel_Transmit4HL(CANBUS_t * CAN_Obj, uint8_t ChannelNo, uint8_t Seq, uint32_t *state, uint8_t * CurrntFrmNo, uint16_t * Tick4Timeout, uint32_t *TransmitCANEnterBuffer) {
    //struct CAN_MSG_OBJ msg;    
	uint32_t pMyCANhandle;
    bool Stage4Seq;
    bool TransmitEnterBuffer4Seq;
    bool BusOFF_F_Return;
    uint16_t TimeOutSettings;
    uint8_t * ResponseData;
    uint8_t ResponseDataLen;
    uint16_t TxResponseCANID_Index;
    uint16_t TxCAN_RTR_DLC_UseStd;

    uint32_t TransmitFrameCANID;
    uint8_t * TransmitDataArray_Seq;
    volatile uint8_t * pRxdDLC;
    volatile uint8_t(* pRxData)[8];

    volatile uint16_t * RxStdCANID;
    volatile uint32_t * RxExtCANID;
    volatile uint8_t * successTx;

    //volatile uint32_t *mailbox4classic;  //this is for returned transmitted mailbox
    bool is_MCAN=false; 
    uint32_t txBufferNo_Or_MsgObjID;
    #if (defined(USE_CANFD1) && defined(USE_CAN1)) || (defined(USE_CANFD2) && defined(USE_CAN2))
        #define EXIST_MCAN
        MCAN_TxBufElement txMsg;       
    #endif  
    #if (!defined(USE_CANFD1) && defined(USE_CAN1)) || (!defined(USE_CANFD2) && defined(USE_CAN2))
        #define EXIST_DCAN        
    #endif     
    if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifndef USE_CAN1
        return 0;
#else
        successTx=&Can1TxSuccess;
        switch (ChannelNo) {
            case 0:
                //A channel
                TimeOutSettings = TxCAN_A_Timeout_1[Seq];
                ResponseData = ResponseData_A_1[Seq];
                ResponseDataLen = ResponseDataLen_A_1[Seq];
                TxResponseCANID_Index = TxResponseCANID_Index_A_1[Seq];
                TxCAN_RTR_DLC_UseStd = TxCAN_A_RTR_DLC_UseStd_1[Seq];

                TransmitDataArray_Seq = TransmitDataArrayA_Seq_1[Seq];
                TransmitFrameCANID = TransmitFrameCANID_A_1[Seq];               
                
                #ifdef USE_CANFD1
                txBufferNo_Or_MsgObjID=0;
                #else
                txBufferNo_Or_MsgObjID=1;
                #endif

                break;
#ifdef USE_CAN1_CHANNELB
            case 1:
                //B channel
                TimeOutSettings = TxCAN_B_Timeout_1[Seq];
                ResponseData = ResponseData_B_1[Seq];
                ResponseDataLen = ResponseDataLen_B_1[Seq];
                TxResponseCANID_Index = TxResponseCANID_Index_B_1[Seq];
                TxCAN_RTR_DLC_UseStd = TxCAN_B_RTR_DLC_UseStd_1[Seq];

                TransmitDataArray_Seq = TransmitDataArrayB_Seq_1[Seq];
                TransmitFrameCANID = TransmitFrameCANID_B_1[Seq];
                
                #ifdef USE_CANFD1
                txBufferNo_Or_MsgObjID=1;
                #else
                txBufferNo_Or_MsgObjID=2;
                #endif

                break;
#endif
#ifdef USE_CAN1_CHANNELC
            case 2:
                //C Channel
                TimeOutSettings = TxCAN_C_Timeout_1[Seq];
                ResponseData = ResponseData_C_1[Seq];
                ResponseDataLen = ResponseDataLen_C_1[Seq];
                TxResponseCANID_Index = TxResponseCANID_Index_C_1[Seq];
                TxCAN_RTR_DLC_UseStd = TxCAN_C_RTR_DLC_UseStd_1[Seq];

                TransmitDataArray_Seq = TransmitDataArrayC_Seq_1[Seq];
                TransmitFrameCANID = TransmitFrameCANID_C_1[Seq];
                
                #ifdef USE_CANFD1
                txBufferNo_Or_MsgObjID=2;
                #else
                txBufferNo_Or_MsgObjID=3;
                #endif
#endif

        }
#endif
    } else if (2 == CAN_Obj->CAN_Peripheral_No) {
#ifndef USE_CAN2
        return 0;
#else
        successTx=&Can2TxSuccess;
        switch (ChannelNo) {
            case 0:
                //A channel
                TimeOutSettings = TxCAN_A_Timeout_2[Seq];
                ResponseData = ResponseData_A_2[Seq];
                ResponseDataLen = ResponseDataLen_A_2[Seq];
                TxResponseCANID_Index = TxResponseCANID_Index_A_2[Seq];
                TxCAN_RTR_DLC_UseStd = TxCAN_A_RTR_DLC_UseStd_2[Seq];

                TransmitDataArray_Seq = TransmitDataArrayA_Seq_2[Seq];
                TransmitFrameCANID = TransmitFrameCANID_A_2[Seq];
                
                #ifdef USE_CANFD2
                txBufferNo_Or_MsgObjID=0;
                #else
                txBufferNo_Or_MsgObjID=1;
                #endif

                break;
#ifdef USE_CAN2_CHANNELB
            case 1:
                //B channel
                TimeOutSettings = TxCAN_B_Timeout_2[Seq];
                ResponseData = ResponseData_B_2[Seq];
                ResponseDataLen = ResponseDataLen_B_2[Seq];
                TxResponseCANID_Index = TxResponseCANID_Index_B_2[Seq];
                TxCAN_RTR_DLC_UseStd = TxCAN_B_RTR_DLC_UseStd_2[Seq];

                TransmitDataArray_Seq = TransmitDataArrayB_Seq_2[Seq];
                TransmitFrameCANID = TransmitFrameCANID_B_2[Seq];
                

                #ifdef USE_CANFD2
                txBufferNo_Or_MsgObjID=1;
                #else
                txBufferNo_Or_MsgObjID=2;
                #endif
                
                break;
#endif
#ifdef USE_CAN2_CHANNELC
            case 2:
                //C Channel
                TimeOutSettings = TxCAN_C_Timeout_2[Seq];
                ResponseData = ResponseData_C_2[Seq];
                ResponseDataLen = ResponseDataLen_C_2[Seq];
                TxResponseCANID_Index = TxResponseCANID_Index_C_2[Seq];
                TxCAN_RTR_DLC_UseStd = TxCAN_C_RTR_DLC_UseStd_2[Seq];

                TransmitDataArray_Seq = TransmitDataArrayC_Seq_2[Seq];
                TransmitFrameCANID = TransmitFrameCANID_C_2[Seq];
                
                #ifdef USE_CANFD2
                txBufferNo_Or_MsgObjID=2;
                #else
                txBufferNo_Or_MsgObjID=3;
                #endif
#endif

        }

#endif
    }

    Stage4Seq = (*state >> Seq) &0x1;
    TransmitEnterBuffer4Seq=(*TransmitCANEnterBuffer >> Seq) &0x1;
    if (1 == CAN_Obj->CAN_Peripheral_No) {
         #ifdef USE_CAN1
            #ifndef USE_CANFD1
            //CAN CLASSIC
            uint32_t status;
            status = CAN_getStatus(CANBUS1Base);
    	    if (status & CAN_STATUS_BUS_OFF) {
    	        // Bus-Off state is active
    	    	BusOFF_F_Return=true;
    	    }
            else BusOFF_F_Return=false;
            #else
            //CANFD
            is_MCAN=true;
            MCAN_ProtocolStatus protStatus;
            MCAN_getProtocolStatus(CANBUS1Base,  &protStatus);
            if (protStatus.busOffStatus)
            {
                // Bus-Off state detected
            	BusOFF_F_Return=true;
            }
            else BusOFF_F_Return=false;
            #endif 
            pMyCANhandle=CANBUS1Base;          
        #else
            BusOFF_F_Return=true;
        #endif
    } else {
        #ifdef USE_CAN2
            #ifndef USE_CANFD2
            //CAN CLASSIC
            uint32_t status;
            status = CAN_getStatus(CANBUS2Base);
            if (status & CAN_STATUS_BUS_OFF) {
    	        // Bus-Off state is active
                BusOFF_F_Return=true;
            }
            else BusOFF_F_Return=false;
            #else
            //CANFD
            is_MCAN=true;
            MCAN_ProtocolStatus protStatus;
            MCAN_getProtocolStatus(CANBUS2Base,  &protStatus);
            if (protStatus.busOffStatus) {
                // Bus-Off state detected
    	        BusOFF_F_Return=true;
            }
            else BusOFF_F_Return=false;
            #endif   
            pMyCANhandle=CANBUS2Base;          
        #else
            BusOFF_F_Return=true;
        #endif
    }
    //if (CAN1_IsBusOff() == false) {
    if (BusOFF_F_Return == false) {
        if (0 == Stage4Seq) {
            //Transmit stage
            if (CAN_Obj->EnableSyn) {
                //Enable Sync
                //if sync does not arrive, we return "continue next time"
                if (0 == (CAN_Obj->SyncCANID & 0x80000000)) return 1;
            }
            #ifdef EXIST_DCAN
            CAN_MsgFrameType FRAMEType_DCAN;
            uint32_t FRAME_ID_DCAN;             
            #endif
            if (is_MCAN)  {
                #ifdef EXIST_MCAN
                if (TxCAN_RTR_DLC_UseStd & 0x4000)
                {
                    txMsg.xtd=0;  //11 Bits ID
                    txMsg.id=(TransmitFrameCANID<<18); 
                }
            	else
                {
                    txMsg.xtd=1;  //29 bits ID
                    txMsg.id=TransmitFrameCANID; 
                }
            	  
                txMsg.rtr=1;    
                txMsg.dlc=0;
                if (1 == CAN_Obj->CAN_Peripheral_No) {
                    #ifndef MCAN1USE_BRS
                    txMsg.brs=0;
                    #else
                    txMsg.brs=1;
                    #endif
                    #ifndef MCAN1USE_FD_MODE
                    txMsg.fdf=0; //classic
                    #else
                    txMsg.fdf=1; //fdCAN
                    #endif
                } else {
                    #ifndef MCAN2USE_BRS
                    txMsg.brs=0;
                    #else
                    txMsg.brs=1;
                    #endif
                    #ifndef MCAN2USE_FD_MODE
                    txMsg.fdf=0; //classic
                    #else
                    txMsg.fdf=1; //fdCAN
                    #endif
                }
                txMsg.efc=0; //don't store event                      
                #endif
            }
            else {
                #ifdef EXIST_DCAN
                FRAME_ID_DCAN=TransmitFrameCANID;
                if (TxCAN_RTR_DLC_UseStd & 0x4000)  {
            	    FRAMEType_DCAN=CAN_MSG_FRAME_STD;                    
                }
                else
            	    FRAMEType_DCAN=CAN_MSG_FRAME_EXT;
                #endif
            }                                         
            if (TxCAN_RTR_DLC_UseStd & 0x8000) {
                //RTR transmit
                if (!TransmitEnterBuffer4Seq) {
                    //Didn't send tx to buffer
                    if (is_MCAN)  {
                        //MCAN
                        #ifdef EXIST_MCAN      
                        txMsg.data[0]=0;                  
                        MCAN_writeMsgRam(pMyCANhandle, MCAN_MEM_TYPE_BUF, txBufferNo_Or_MsgObjID,
                        &txMsg);
                        MCAN_txBufAddReq(pMyCANhandle, txBufferNo_Or_MsgObjID);
                        #endif

                    }
                    else {
                        //DCAN
                        #ifdef EXIST_DCAN
                        CAN_setupMessageObject(pMyCANhandle, txBufferNo_Or_MsgObjID, FRAME_ID_DCAN,
                        FRAMEType_DCAN, CAN_MSG_OBJ_TYPE_TX_REMOTE, 0,
                        /*CAN_MSG_OBJ_TX_INT_ENABLE*/0, 0);  
                        CAN_sendMessage(pMyCANhandle, txBufferNo_Or_MsgObjID, 0,
                        TransmitDataArray_Seq);
                        #endif

                    }
                    *TransmitCANEnterBuffer |= (1U << Seq);
                	Tick4Timeout[ChannelNo]=tick;
                    return 1;  //continue
                }
                else {
                    //already send tx to buffer, so judge for sent out
                    if (*successTx & (1U<<ChannelNo)) {
                        //Success sent out
                        *TransmitCANEnterBuffer &= ~(1U << Seq);
                        return 0;  //Success
                    }
                    else
                    {
                        if (tick-Tick4Timeout[ChannelNo]>=500) {
                            //timeout for 500ms
                            *TransmitCANEnterBuffer &= ~(1U << Seq);
                            if (is_MCAN)  {
                                //MCAN
                                #ifdef EXIST_MCAN
                                MCAN_txBufCancellationReq(pMyCANhandle,txBufferNo_Or_MsgObjID);
                                #endif
                            }
                            else {
                               //DCAN
                               #ifdef EXIST_DCAN
                               //Abort
                               HWREG(pMyCANhandle + CAN_O_IF1CMD) = CAN_IF1CMD_CONTROL;
                               HWREG(pMyCANhandle + CAN_O_IF1NO) = txBufferNo_Or_MsgObjID;
                               // Wait for busy bit to clear
                               while (HWREG(pMyCANhandle + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) SysCtl_serviceWatchdog();
                               // Clear TXRQST bit to abort transmission
                               HWREG(pMyCANhandle + CAN_O_IF1MCTL) &= ~CAN_IF1MCTL_TXRQST;
                               #endif

                            }                            
                            return -1;

                        }
                    }

                }

            } else {
                //Data frame           	
                if ((Seq <= 3) && ((TxCAN_RTR_DLC_UseStd & 0x7FF)<= 8) && (TxCAN_RTR_DLC_UseStd & 0x2000)) { //Bit13: need response and Bit10-0: length
                    //Need response
                    if (!TransmitEnterBuffer4Seq) {
                        //Tx didn't send to Budffer
                        if (is_MCAN)  {
                            //MCAN
                            #ifdef EXIST_MCAN        
                            txMsg.rtr=0;      //data frame
                            txMsg.dlc=TxCAN_RTR_DLC_UseStd & 0x7FF;         
                            txMsg.data[0]=TransmitDataArray_Seq[0];    
                            txMsg.data[1]=TransmitDataArray_Seq[1];  
                            txMsg.data[2]=TransmitDataArray_Seq[2]; 
                            txMsg.data[3]=TransmitDataArray_Seq[3]; 
                            txMsg.data[4]=TransmitDataArray_Seq[4];    
                            txMsg.data[5]=TransmitDataArray_Seq[5];  
                            txMsg.data[6]=TransmitDataArray_Seq[6]; 
                            txMsg.data[7]=TransmitDataArray_Seq[7]; 
                            MCAN_writeMsgRam(pMyCANhandle, MCAN_MEM_TYPE_BUF, txBufferNo_Or_MsgObjID,
                            &txMsg);
                            MCAN_txBufAddReq(pMyCANhandle, txBufferNo_Or_MsgObjID);
                            #endif
                        }
                        else {
                            //DCAN
                            #ifdef EXIST_DCAN                            
                            CAN_setupMessageObject(pMyCANhandle, txBufferNo_Or_MsgObjID, FRAME_ID_DCAN,
                            FRAMEType_DCAN, CAN_MSG_OBJ_TYPE_TX, 0,
                           /*CAN_MSG_OBJ_TX_INT_ENABLE*/0, TxCAN_RTR_DLC_UseStd & 0x7FF);
                            CAN_sendMessage(pMyCANhandle, txBufferNo_Or_MsgObjID, TxCAN_RTR_DLC_UseStd & 0x7FF,
                            TransmitDataArray_Seq);
                            #endif

                        }
                        *TransmitCANEnterBuffer |= (1U << Seq);
                        Tick4Timeout[ChannelNo]=tick;
                        return 1;  //continue                    	
                    }
                    else {
                        //already send tx to buffer, so judge for sent out
                        if (*successTx & (1U<<ChannelNo)) {
                            //Success sent out
                            *TransmitCANEnterBuffer &= ~(1U << Seq);

                            *state = *state | (1 << Seq);
                            //set bit14 of Rx CANID to 1 for std frame response , or set bit30 of Rx canid to 1 for ext frame response
                            if (0x0000 == (TxResponseCANID_Index & 0xc000)) {
                                //short std frame response
                                if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                                    RxStdCANID = RxStdCANID_1;
#endif
                                } else {
#ifdef USE_CAN2
                                    RxStdCANID = RxStdCANID_2;
#endif
                                }
                                //RxStdCANID_1[TxResponseCANID_Index & 0x3FFF] |= 0x4000;
                                RxStdCANID[TxResponseCANID_Index & 0x3FFF] |= 0x4000;

                            } else if (0x4000 == (TxResponseCANID_Index & 0xc000)) {
                                //short ext frame response
                                if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                                    RxExtCANID = RxExtCANID_1;
#endif
                                } else {
#ifdef USE_CAN2
                                    RxExtCANID = RxExtCANID_2;
#endif
                                }
                                //RxExtCANID_1[TxResponseCANID_Index & 0x3FFF] |= 0x40000000;
                                RxExtCANID[TxResponseCANID_Index & 0x3FFF] |= 0x40000000;

                            } else if (0x8000 == (TxResponseCANID_Index & 0xc000)) {
                                //long std frame response
                                if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                                    RxStdCANID = RxStdCANID_Long_1;
#endif
                                } else {
#ifdef USE_CAN2
                                    RxStdCANID = RxStdCANID_Long_2;
#endif
                                }
                                //RxStdCANID_Long_1[TxResponseCANID_Index & 0x3FFF] |= 0x4000;
                                RxStdCANID[TxResponseCANID_Index & 0x3FFF] |= 0x4000;
                            } else if (0xC000 == (TxResponseCANID_Index & 0xc000)) {
                                //long ext frame response
                                if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                                    RxExtCANID = RxExtCANID_Long_1;
#endif
                                } else {
#ifdef USE_CAN2
                                    RxExtCANID = RxExtCANID_Long_2;
#endif
                                }
                                //RxExtCANID_Long_1[TxResponseCANID_Index & 0x3FFF] |= 0x40000000;
                                RxExtCANID[TxResponseCANID_Index & 0x3FFF] |= 0x40000000;
                            }
                            Tick4Timeout[Seq] = tick;
                            return 1; //Continue


                        }
                        else
                        {
                            if (tick-Tick4Timeout[ChannelNo]>=500) {
                                //timeout for 500ms
                                *TransmitCANEnterBuffer &= ~(1U << Seq);
                                if (is_MCAN)  {
                                    //MCAN
                                    #ifdef EXIST_MCAN
                                    MCAN_txBufCancellationReq(pMyCANhandle,txBufferNo_Or_MsgObjID);
                                    #endif
                                }
                                else {
                                    //DCAN
                                    #ifdef EXIST_DCAN
                                    //Abort
                                    HWREG(pMyCANhandle + CAN_O_IF1CMD) = CAN_IF1CMD_CONTROL;
                                    HWREG(pMyCANhandle + CAN_O_IF1NO) = txBufferNo_Or_MsgObjID;
                                    // Wait for busy bit to clear
                                    while (HWREG(pMyCANhandle + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) SysCtl_serviceWatchdog();
                                    // Clear TXRQST bit to abort transmission
                                    HWREG(pMyCANhandle + CAN_O_IF1MCTL) &= ~CAN_IF1MCTL_TXRQST;
                                    #endif
                                }                   
                                return -1;
                            }
                        }

                    }


                } else {
                    //No need response
                    if ((TxCAN_RTR_DLC_UseStd & 0x7FF) <= 8) {
                        //short frame
                        if (!TransmitEnterBuffer4Seq) {
                            //Tx didn't send to Budffe
                        	if (is_MCAN)  {
                                //MCAN
                                #ifdef EXIST_MCAN        
                                txMsg.rtr=0;      //data frame
                                txMsg.dlc=TxCAN_RTR_DLC_UseStd & 0x7FF;   
                                txMsg.data[0]=TransmitDataArray_Seq[0];   
                                txMsg.data[1]=TransmitDataArray_Seq[1];    
                                txMsg.data[2]=TransmitDataArray_Seq[2];  
                                txMsg.data[3]=TransmitDataArray_Seq[3];
                                txMsg.data[4]=TransmitDataArray_Seq[4];   
                                txMsg.data[5]=TransmitDataArray_Seq[5];    
                                txMsg.data[6]=TransmitDataArray_Seq[6];  
                                txMsg.data[7]=TransmitDataArray_Seq[7];
                                MCAN_writeMsgRam(pMyCANhandle, MCAN_MEM_TYPE_BUF, txBufferNo_Or_MsgObjID,
                                &txMsg);
                                MCAN_txBufAddReq(pMyCANhandle, txBufferNo_Or_MsgObjID);
                                #endif
                            }
                            else {
                                //DCAN
                                #ifdef EXIST_DCAN                            
                                CAN_setupMessageObject(pMyCANhandle, txBufferNo_Or_MsgObjID, FRAME_ID_DCAN,
                                FRAMEType_DCAN, CAN_MSG_OBJ_TYPE_TX, 0,
                                /*CAN_MSG_OBJ_TX_INT_ENABLE*/0, TxCAN_RTR_DLC_UseStd & 0x7FF);
                                CAN_sendMessage(pMyCANhandle, txBufferNo_Or_MsgObjID, TxCAN_RTR_DLC_UseStd & 0x7FF,
                                TransmitDataArray_Seq);
                                #endif
                            }
                            *TransmitCANEnterBuffer |= (1U << Seq);
                            Tick4Timeout[ChannelNo]=tick;
                            return 1;  //continue
                        }
                        else {
                            //already send tx to buffer, so judge for sent out
                            if (*successTx & (1U<<ChannelNo)) {
                                //Success sent out
                                *TransmitCANEnterBuffer &= ~(1U << Seq);
                                return 0;  //success
                            }
                            else {
                               //judge time out because not done
                               if (tick-Tick4Timeout[ChannelNo]>=500) {
                                    //timeout for 500ms
                                    *TransmitCANEnterBuffer &= ~(1U << Seq);
                                    if (is_MCAN)  {
                                        //MCAN
                                        #ifdef EXIST_MCAN
                                        MCAN_txBufCancellationReq(pMyCANhandle,txBufferNo_Or_MsgObjID);
                                        #endif
                                    }
                                    else {
                                        //DCAN
                                        #ifdef EXIST_DCAN
                                        //Abort
                                        HWREG(pMyCANhandle + CAN_O_IF1CMD) = CAN_IF1CMD_CONTROL;
                                        HWREG(pMyCANhandle + CAN_O_IF1NO) = txBufferNo_Or_MsgObjID;
                                        // Wait for busy bit to clear
                                        while (HWREG(pMyCANhandle + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) SysCtl_serviceWatchdog();
                                        // Clear TXRQST bit to abort transmission
                                        HWREG(pMyCANhandle + CAN_O_IF1MCTL) &= ~CAN_IF1MCTL_TXRQST;
                                        #endif
                                    }                                                 
                                    return -1;
                                }
                            }

                        }

                    } else {
                        //long frame
                        uint8_t HasTransmittedByteQty;
                        uint8_t pData[8];
                        uint8_t dataDLCNew;
                        uint8_t i;
                        if (0 == CAN_Obj->FrameNoIs0_based) {
                            //1-based frame No
                            if (0 == CurrntFrmNo[Seq]) CurrntFrmNo[Seq] = 1;
                            HasTransmittedByteQty = (CurrntFrmNo[Seq] - 1)*7;
                        } else {
                            //0 based frame No
                            HasTransmittedByteQty = CurrntFrmNo[Seq]*7;
                        }

                        pData[0] = CurrntFrmNo[Seq];                        
                        if ((TxCAN_RTR_DLC_UseStd & 0x7FF) - HasTransmittedByteQty >= 7) {
                            //msg.field.dlc = 8;
                            dataDLCNew=8;
                            for (i = 1; i < 8; i++) {
                                pData[i] = *(TransmitDataArray_Seq + HasTransmittedByteQty + i - 1);
                            }

                        } else if ((TxCAN_RTR_DLC_UseStd & 0x7FF) - HasTransmittedByteQty > 0) {
                            //msg.field.dlc = TxDATALen - HasTransmittedByteQty + 1;
                            dataDLCNew=(TxCAN_RTR_DLC_UseStd & 0x7FF) - HasTransmittedByteQty + 1;
                            for (i = 0; i < (TxCAN_RTR_DLC_UseStd & 0x7FF) - HasTransmittedByteQty; i++) {
                                pData[i + 1] = *(TransmitDataArray_Seq + HasTransmittedByteQty + i);
                            }
                        } else {
                            //==-, no need to transmit
                            *TransmitCANEnterBuffer &= ~(1U << Seq);
                            CurrntFrmNo[Seq] = 0;
                            return 0; //success done all frames Tx
                        }

                        if (!TransmitEnterBuffer4Seq) {
                            //Tx didn't send to Budffer                            
                            if (is_MCAN)  {
                                //MCAN
                                #ifdef EXIST_MCAN  
                                txMsg.data[0] = pData[0]; 
                                txMsg.data[1] = pData[1]; 
                                txMsg.data[2] = pData[2]; 
                                txMsg.data[3] = pData[3];  
                                txMsg.data[4] = pData[4]; 
                                txMsg.data[5] = pData[5]; 
                                txMsg.data[6] = pData[6]; 
                                txMsg.data[7] = pData[7]; 
                                txMsg.rtr=0;      //data frame
                                txMsg.dlc=dataDLCNew;            
                                MCAN_writeMsgRam(pMyCANhandle, MCAN_MEM_TYPE_BUF, txBufferNo_Or_MsgObjID,
                                &txMsg);
                                MCAN_txBufAddReq(pMyCANhandle, txBufferNo_Or_MsgObjID);
                                #endif
                            }
                            else {
                                //DCAN
                                #ifdef EXIST_DCAN                            
                                CAN_setupMessageObject(pMyCANhandle, txBufferNo_Or_MsgObjID, FRAME_ID_DCAN,
                                FRAMEType_DCAN, CAN_MSG_OBJ_TYPE_TX, 0,
                                /*CAN_MSG_OBJ_TX_INT_ENABLE*/0, dataDLCNew);
                                CAN_sendMessage(pMyCANhandle, txBufferNo_Or_MsgObjID,dataDLCNew,
                                pData);
                                #endif
                            }
                            *TransmitCANEnterBuffer |= (1U << Seq);
                            Tick4Timeout[ChannelNo]=tick;
                            return 1; //continue to next frame in next time                                 
                        }
                        else {
                            //already send tx to buffer, so judge for sent out
                            if (*successTx & (1U<<ChannelNo)) {
                                //Success sent out
                                *TransmitCANEnterBuffer &= ~(1U << Seq);
                                if ((TxCAN_RTR_DLC_UseStd & 0x7FF) == HasTransmittedByteQty + dataDLCNew - 1) { //Judgement ahead of time in case 255+1=0 case
                                    CurrntFrmNo[Seq] = 0;
                                    return 0; //success done all frames Tx
                                }
                                CurrntFrmNo[Seq]++;
                                return 1; //continue to next frame in next time

                            }
                            else {
                               //judge time out because not done
                               if (tick-Tick4Timeout[ChannelNo]>=500) {
                                    //timeout for 500ms
                                    *TransmitCANEnterBuffer &= ~(1U << Seq);
                                    CurrntFrmNo[Seq] = 0; //init it
                                    if (is_MCAN)  {
                                        //MCAN
                                        #ifdef EXIST_MCAN
                                        MCAN_txBufCancellationReq(pMyCANhandle,txBufferNo_Or_MsgObjID);
                                        #endif
                                    }
                                    else {
                                        //DCAN
                                        #ifdef EXIST_DCAN
                                        //Abort
                                        HWREG(pMyCANhandle + CAN_O_IF1CMD) = CAN_IF1CMD_CONTROL;
                                        HWREG(pMyCANhandle + CAN_O_IF1NO) = txBufferNo_Or_MsgObjID;
                                        // Wait for busy bit to clear
                                        while (HWREG(pMyCANhandle + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) SysCtl_serviceWatchdog();
                                        // Clear TXRQST bit to abort transmission
                                        HWREG(pMyCANhandle + CAN_O_IF1MCTL) &= ~CAN_IF1MCTL_TXRQST;
                                        #endif
                                    }                                            
                                    return -1;
                                }
                            }
                        }





                    }
                }

            }


        } else {
            //response stage
            //wait for response stage:  This is situation we need response frame
            if (TxCAN_RTR_DLC_UseStd & 0x1000) { //bit12 : long frame response
                //need long frame response
                if (0x8000 == (TxResponseCANID_Index & 0xc000)) {
                    //Standard 11 bit CAN ID long frame
                    //2025 May 06 add for uninitialze pointer----start
                    if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1

                        RxStdCANID = RxStdCANID_Long_1;
#endif

                    } else {
#ifdef USE_CAN2

                        RxStdCANID = RxStdCANID_Long_2;
#endif
                    }
                    //2025 May 06 add for uninitialze pointer----end
                    //if (!(RxStdCANID_Long_1[TxResponseCANID_Index & 0x3FFF] & 0x4000)) {
                    if (!(RxStdCANID[TxResponseCANID_Index & 0x3FFF] & 0x4000)) {
                        //Response coming
                        //get data from long frame
                        //ResponseDataLen=TxCAN_RTR_DLC_UseStd & 0x3ff;
                        int16_t i;
                        uint8_t j;
                        if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                            for (i = 0; i < ResponseDataLen; i++) {
                                j = i / 7;
                                ResponseData[i] = RxStdData_Long_1[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                                //ResponseData[i] = RxData_Long[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                            }
#endif
                        } else {
#ifdef USE_CAN2
                            for (i = 0; i < ResponseDataLen; i++) {
                                j = i / 7;
                                ResponseData[i] = RxStdData_Long_2[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                                //ResponseData[i] = RxData_Long[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                            }
#endif

                        }
                        *state = *state & ~(1UL << Seq);
                        return 0; //success
                    } else {
                        //check time out
                        if (tick - Tick4Timeout[Seq] > TimeOutSettings) {
                            //Time out
                            *state = *state & ~(1UL << Seq);
                            return -1; //fail
                        } else return 1; //continue
                    }

                } else if (0xC000 == (TxResponseCANID_Index & 0xc000)) {
                    //Ext 29 bit CAN ID long frame
                    //2025 May 06 add for uninitialze pointer----start
                    if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                        RxExtCANID = RxExtCANID_Long_1;
#endif

                    } else {
#ifdef USE_CAN2
                        RxExtCANID = RxExtCANID_Long_2;
#endif
                    }
                    //2025 May 06 add for uninitialze pointer----end
                    //if (!(RxExtCANID_Long_1[TxResponseCANID_Index & 0x3FFF] & 0x40000000)) {
                    if (!(RxExtCANID[TxResponseCANID_Index & 0x3FFF] & 0x40000000)) {
                        //Response coming
                        //get data from long frame
                        //ResponseDataLen=TxCAN_RTR_DLC_UseStd & 0x3ff;
                        int16_t i;
                        uint8_t j;
                        if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                            for (i = 0; i < ResponseDataLen; i++) {
                                j = i / 7;
                                ResponseData[i] = RxExtData_Long_1[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                                //ResponseData[i] = RxData_Long[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                            }
#endif
                        } else {
#ifdef USE_CAN2
                            for (i = 0; i < ResponseDataLen; i++) {
                                j = i / 7;
                                ResponseData[i] = RxExtData_Long_2[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                                //ResponseData[i] = RxData_Long[TxResponseCANID_Index & 0x3FFF][j][(i % 7) + 1];
                            }
#endif
                        }
                        *state = *state & ~(1UL << Seq);
                        return 0; //success
                    } else {
                        //check time out
                        if (tick - Tick4Timeout[Seq] > TimeOutSettings) {
                            //Time out
                            *state = *state & ~(1UL << Seq);
                            return -1; //fail
                        } else return 1; //continue
                    }
                }

            } else {
                //need short frame response
                if (0x0000 == (TxResponseCANID_Index & 0xc000)) {
                    //short std frame response
                    if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                        pRxdDLC = RxStdDLC_1;
                        pRxData = RxStdData_1;
                        RxStdCANID = RxStdCANID_1;
#endif

                    } else {
#ifdef USE_CAN2
                        pRxdDLC = RxStdDLC_2;
                        pRxData = RxStdData_2;
                        RxStdCANID = RxStdCANID_2;
#endif
                    }

                    //if (!(RxStdCANID_1[TxResponseCANID_Index & 0x3FFF] & 0x4000)) {
                    if (!(RxStdCANID[TxResponseCANID_Index & 0x3FFF] & 0x4000)) {
                        //Response coming
                        //get data
                        //if (ResponseDataLen <= (0x7f & RxStdDLC_1[TxResponseCANID_Index & 0x3FFF])) {
                        if (ResponseDataLen <= (0x7f & pRxdDLC[TxResponseCANID_Index & 0x3FFF])) {
                            int8_t i;
                            for (i = 0; i < ResponseDataLen; i++) {
                                //*(ResponseData + i) = RxStdData_1[TxResponseCANID_Index & 0x3FFF][i];
                                *(ResponseData + i) = pRxData[TxResponseCANID_Index & 0x3FFF][i];
                            }
                            *state = *state & ~(1UL << Seq);
                            return 0; //success
                        }
                    } else {
                        //check time out
                        if (tick - Tick4Timeout[Seq] > TimeOutSettings) {
                            //Time out
                            *state = *state & ~(1UL << Seq);
                            return -1; //fail
                        } else return 1; //continue
                    }


                } else if (0x4000 == (TxResponseCANID_Index & 0xc000)) {
                    //short ext frame response
                    if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifdef USE_CAN1
                        pRxdDLC = RxExtDLC_1;
                        pRxData = RxExtData_1;
                        RxExtCANID = RxExtCANID_1;
#endif

                    } else {
#ifdef USE_CAN2
                        pRxdDLC = RxExtDLC_2;
                        pRxData = RxExtData_2;
                        RxExtCANID = RxExtCANID_2;
#endif
                    }

                    //if (!(RxExtCANID_1[TxResponseCANID_Index & 0x3FFF] & 0x40000000)) {
                    if (!(RxExtCANID[TxResponseCANID_Index & 0x3FFF] & 0x40000000)) {
                        //REspons coming
                        //get data
                        //if (ResponseDataLen <= (0x7f & RxExtDLC_1[TxResponseCANID_Index & 0x3FFF])) {
                        if (ResponseDataLen <= (0x7f & pRxdDLC[TxResponseCANID_Index & 0x3FFF])) {
                            if (ResponseDataLen > 8) ResponseDataLen = 8;
                            int8_t i;
                            for (i = 0; i < ResponseDataLen; i++) {
                                //*(ResponseData + i) = RxExtData_1[TxResponseCANID_Index & 0x3FFF][i];
                                *(ResponseData + i) = pRxData[TxResponseCANID_Index & 0x3FFF][i];
                            }
                            *state = *state & ~(1UL << Seq);
                            return 0; //success
                        }
                    } else {
                        //check time out
                        if (tick - Tick4Timeout[Seq] > TimeOutSettings) {
                            //Time out
                            *state = *state & ~(1UL << Seq);
                            return -1; //fail
                        } else return 1; //continue
                    }
                }
            }


        }

    } else {
        //Bus off
        CurrntFrmNo[Seq] = 0; //init it
        return -1;
    }
    return 0; //continue



}
