#include <stdint.h>
#include <stdbool.h>  
#include "CANBUS.h"

#ifdef USE_CAN1
#include "mcc_generated_files/can1.h"  
#if !defined(__dsPIC33C__)
#include "mcc_generated_files/dma.h"
#endif
#endif
#ifdef USE_CAN2
#include "mcc_generated_files/can2.h"  
#if !defined(__dsPIC33C__)
#include "mcc_generated_files/dma.h"
#endif
#endif

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);
#ifdef USE_CAN1
//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)


#if 0    //we use array point to replace.  And pointer is given in simulink
#ifdef CAN1_TX_CHANNELA_SEQ0_EXIST_DATA
extern uint8_t TransmitDataArrayA0_1[]; //CAN1 Channel A transmit , Seq0 Data Array
#endif
#ifdef CAN1_TX_CHANNELA_SEQ1_EXIST_DATA
extern uint8_t TransmitDataArrayA1_1[]; //CAN1 Channel A transmit , Seq1 Data Array
#endif
#ifdef CAN1_TX_CHANNELA_SEQ2_EXIST_DATA
extern uint8_t TransmitDataArrayA2_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ3_EXIST_DATA
extern uint8_t TransmitDataArrayA3_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ4_EXIST_DATA
extern uint8_t TransmitDataArrayA4_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ5_EXIST_DATA
extern uint8_t TransmitDataArrayA5_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ6_EXIST_DATA
extern uint8_t TransmitDataArrayA6_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ7_EXIST_DATA
extern uint8_t TransmitDataArrayA7_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ8_EXIST_DATA
extern uint8_t TransmitDataArrayA8_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ9_EXIST_DATA
extern uint8_t TransmitDataArrayA9_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ10_EXIST_DATA
extern uint8_t TransmitDataArrayA10_1[];
#endif

#ifdef CAN1_TX_CHANNELA_SEQ11_EXIST_DATA
extern uint8_t TransmitDataArrayA11_1[]; //CAN1 Channel A transmit , Seq11 Data Array
#endif
#ifdef CAN1_TX_CHANNELA_SEQ12_EXIST_DATA
extern uint8_t TransmitDataArrayA12_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ13_EXIST_DATA
extern uint8_t TransmitDataArrayA13_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ14_EXIST_DATA
extern uint8_t TransmitDataArrayA14_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ15_EXIST_DATA
extern uint8_t TransmitDataArrayA15_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ16_EXIST_DATA
extern uint8_t TransmitDataArrayA16_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ17_EXIST_DATA
extern uint8_t TransmitDataArrayA17_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ18_EXIST_DATA
extern uint8_t TransmitDataArrayA18_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ19_EXIST_DATA
extern uint8_t TransmitDataArrayA19_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ20_EXIST_DATA
extern uint8_t TransmitDataArrayA20_1[];
#endif



#ifdef CAN1_TX_CHANNELA_SEQ21_EXIST_DATA
extern uint8_t TransmitDataArrayA21_1[]; //CAN1 Channel A transmit , Seq21 Data Array
#endif
#ifdef CAN1_TX_CHANNELA_SEQ22_EXIST_DATA
extern uint8_t TransmitDataArrayA22_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ23_EXIST_DATA
extern uint8_t TransmitDataArrayA23_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ24_EXIST_DATA
extern uint8_t TransmitDataArrayA24_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ25_EXIST_DATA
extern uint8_t TransmitDataArrayA25_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ26_EXIST_DATA
extern uint8_t TransmitDataArrayA26_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ27_EXIST_DATA
extern uint8_t TransmitDataArrayA27_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ28_EXIST_DATA
extern uint8_t TransmitDataArrayA28_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ29_EXIST_DATA
extern uint8_t TransmitDataArrayA29_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ30_EXIST_DATA
extern uint8_t TransmitDataArrayA30_1[];
#endif
#ifdef CAN1_TX_CHANNELA_SEQ31_EXIST_DATA
extern uint8_t TransmitDataArrayA31_1[];
#endif
#else
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

#endif

//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.  

#if 0   //we use array point to replace.  And pointer is given in simulink
#ifdef CAN1_TX_CHANNELB_SEQ0_EXIST_DATA
extern uint8_t TransmitDataArrayB0_1[]; //CAN1 Channel B transmit , Seq0 Data Array
#endif
#ifdef CAN1_TX_CHANNELB_SEQ1_EXIST_DATA
extern uint8_t TransmitDataArrayB1_1[]; //CAN1 Channel B transmit , Seq1 Data Array
#endif
#ifdef CAN1_TX_CHANNELB_SEQ2_EXIST_DATA
extern uint8_t TransmitDataArrayB2_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ3_EXIST_DATA
extern uint8_t TransmitDataArrayB3_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ4_EXIST_DATA
extern uint8_t TransmitDataArrayB4_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ5_EXIST_DATA
extern uint8_t TransmitDataArrayB5_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ6_EXIST_DATA
extern uint8_t TransmitDataArrayB6_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ7_EXIST_DATA
extern uint8_t TransmitDataArrayB7_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ8_EXIST_DATA
extern uint8_t TransmitDataArrayB8_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ9_EXIST_DATA
extern uint8_t TransmitDataArrayB9_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ10_EXIST_DATA
extern uint8_t TransmitDataArrayB10_1[];
#endif

#ifdef CAN1_TX_CHANNELB_SEQ11_EXIST_DATA
extern uint8_t TransmitDataArrayB11_1[]; //CAN1 Channel B transmit , Seq11 Data Array
#endif
#ifdef CAN1_TX_CHANNELB_SEQ12_EXIST_DATA
extern uint8_t TransmitDataArrayB12_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ13_EXIST_DATA
extern uint8_t TransmitDataArrayB13_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ14_EXIST_DATA
extern uint8_t TransmitDataArrayB14_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ15_EXIST_DATA
extern uint8_t TransmitDataArrayB15_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ16_EXIST_DATA
extern uint8_t TransmitDataArrayB16_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ17_EXIST_DATA
extern uint8_t TransmitDataArrayB17_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ18_EXIST_DATA
extern uint8_t TransmitDataArrayB18_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ19_EXIST_DATA
extern uint8_t TransmitDataArrayB19_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ20_EXIST_DATA
extern uint8_t TransmitDataArrayB20_1[];
#endif



#ifdef CAN1_TX_CHANNELB_SEQ21_EXIST_DATA
extern uint8_t TransmitDataArrayB21_1[]; //CAN1 Channel B transmit , Seq21 Data Array
#endif
#ifdef CAN1_TX_CHANNELB_SEQ22_EXIST_DATA
extern uint8_t TransmitDataArrayB22_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ23_EXIST_DATA
extern uint8_t TransmitDataArrayB23_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ24_EXIST_DATA
extern uint8_t TransmitDataArrayB24_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ25_EXIST_DATA
extern uint8_t TransmitDataArrayB25_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ26_EXIST_DATA
extern uint8_t TransmitDataArrayB26_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ27_EXIST_DATA
extern uint8_t TransmitDataArrayB27_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ28_EXIST_DATA
extern uint8_t TransmitDataArrayB28_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ29_EXIST_DATA
extern uint8_t TransmitDataArrayB29_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ30_EXIST_DATA
extern uint8_t TransmitDataArrayB30_1[];
#endif
#ifdef CAN1_TX_CHANNELB_SEQ31_EXIST_DATA
extern uint8_t TransmitDataArrayB31_1[];
#endif
#else
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


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

#if 0   //we use array point to replace.  And pointer is given in simulink
#ifdef CAN1_TX_CHANNELC_SEQ0_EXIST_DATA
extern uint8_t TransmitDataArrayC0_1[]; //CAN1 Channel C transmit , Seq0 Data Array
#endif
#ifdef CAN1_TX_CHANNELC_SEQ1_EXIST_DATA
extern uint8_t TransmitDataArrayC1_1[]; //CAN1 Channel C transmit , Seq1 Data Array
#endif
#ifdef CAN1_TX_CHANNELC_SEQ2_EXIST_DATA
extern uint8_t TransmitDataArrayC2_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ3_EXIST_DATA
extern uint8_t TransmitDataArrayC3_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ4_EXIST_DATA
extern uint8_t TransmitDataArrayC4_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ5_EXIST_DATA
extern uint8_t TransmitDataArrayC5_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ6_EXIST_DATA
extern uint8_t TransmitDataArrayC6_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ7_EXIST_DATA
extern uint8_t TransmitDataArrayC7_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ8_EXIST_DATA
extern uint8_t TransmitDataArrayC8_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ9_EXIST_DATA
extern uint8_t TransmitDataArrayC9_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ10_EXIST_DATA
extern uint8_t TransmitDataArrayC10_1[];
#endif

#ifdef CAN1_TX_CHANNELC_SEQ11_EXIST_DATA
extern uint8_t TransmitDataArrayC11_1[]; //CAN1 Channel C transmit , Seq11 Data Array
#endif
#ifdef CAN1_TX_CHANNELC_SEQ12_EXIST_DATA
extern uint8_t TransmitDataArrayC12_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ13_EXIST_DATA
extern uint8_t TransmitDataArrayC13_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ14_EXIST_DATA
extern uint8_t TransmitDataArrayC14_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ15_EXIST_DATA
extern uint8_t TransmitDataArrayC15_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ16_EXIST_DATA
extern uint8_t TransmitDataArrayC16_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ17_EXIST_DATA
extern uint8_t TransmitDataArrayC17_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ18_EXIST_DATA
extern uint8_t TransmitDataArrayC18_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ19_EXIST_DATA
extern uint8_t TransmitDataArrayC19_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ20_EXIST_DATA
extern uint8_t TransmitDataArrayC20_1[];
#endif



#ifdef CAN1_TX_CHANNELC_SEQ21_EXIST_DATA
extern uint8_t TransmitDataArrayC21_1[]; //CAN1 Channel C transmit , Seq21 Data Array
#endif
#ifdef CAN1_TX_CHANNELC_SEQ22_EXIST_DATA
extern uint8_t TransmitDataArrayC22_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ23_EXIST_DATA
extern uint8_t TransmitDataArrayC23_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ24_EXIST_DATA
extern uint8_t TransmitDataArrayC24_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ25_EXIST_DATA
extern uint8_t TransmitDataArrayC25_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ26_EXIST_DATA
extern uint8_t TransmitDataArrayC26_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ27_EXIST_DATA
extern uint8_t TransmitDataArrayC27_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ28_EXIST_DATA
extern uint8_t TransmitDataArrayC28_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ29_EXIST_DATA
extern uint8_t TransmitDataArrayC29_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ30_EXIST_DATA
extern uint8_t TransmitDataArrayC30_1[];
#endif
#ifdef CAN1_TX_CHANNELC_SEQ31_EXIST_DATA
extern uint8_t TransmitDataArrayC31_1[];
#endif
#else
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

#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

//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)

#if 0   //we use array point to replace.  And pointer is given in simulink
#ifdef CAN2_TX_CHANNELA_SEQ0_EXIST_DATA
extern uint8_t TransmitDataArrayA0_2[]; //CAN2 Channel A transmit , Seq0 Data Array
#endif
#ifdef CAN2_TX_CHANNELA_SEQ1_EXIST_DATA
extern uint8_t TransmitDataArrayA1_2[]; //CAN2 Channel A transmit , Seq1 Data Array
#endif
#ifdef CAN2_TX_CHANNELA_SEQ2_EXIST_DATA
extern uint8_t TransmitDataArrayA2_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ3_EXIST_DATA
extern uint8_t TransmitDataArrayA3_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ4_EXIST_DATA
extern uint8_t TransmitDataArrayA4_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ5_EXIST_DATA
extern uint8_t TransmitDataArrayA5_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ6_EXIST_DATA
extern uint8_t TransmitDataArrayA6_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ7_EXIST_DATA
extern uint8_t TransmitDataArrayA7_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ8_EXIST_DATA
extern uint8_t TransmitDataArrayA8_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ9_EXIST_DATA
extern uint8_t TransmitDataArrayA9_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ10_EXIST_DATA
extern uint8_t TransmitDataArrayA10_2[];
#endif

#ifdef CAN2_TX_CHANNELA_SEQ11_EXIST_DATA
extern uint8_t TransmitDataArrayA11_2[]; //CAN2 Channel A transmit , Seq11 Data Array
#endif
#ifdef CAN2_TX_CHANNELA_SEQ12_EXIST_DATA
extern uint8_t TransmitDataArrayA12_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ13_EXIST_DATA
extern uint8_t TransmitDataArrayA13_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ14_EXIST_DATA
extern uint8_t TransmitDataArrayA14_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ15_EXIST_DATA
extern uint8_t TransmitDataArrayA15_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ16_EXIST_DATA
extern uint8_t TransmitDataArrayA16_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ17_EXIST_DATA
extern uint8_t TransmitDataArrayA17_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ18_EXIST_DATA
extern uint8_t TransmitDataArrayA18_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ19_EXIST_DATA
extern uint8_t TransmitDataArrayA19_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ20_EXIST_DATA
extern uint8_t TransmitDataArrayA20_2[];
#endif



#ifdef CAN2_TX_CHANNELA_SEQ21_EXIST_DATA
extern uint8_t TransmitDataArrayA21_2[]; //CAN2 Channel A transmit , Seq21 Data Array
#endif
#ifdef CAN2_TX_CHANNELA_SEQ22_EXIST_DATA
extern uint8_t TransmitDataArrayA22_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ23_EXIST_DATA
extern uint8_t TransmitDataArrayA23_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ24_EXIST_DATA
extern uint8_t TransmitDataArrayA24_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ25_EXIST_DATA
extern uint8_t TransmitDataArrayA25_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ26_EXIST_DATA
extern uint8_t TransmitDataArrayA26_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ27_EXIST_DATA
extern uint8_t TransmitDataArrayA27_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ28_EXIST_DATA
extern uint8_t TransmitDataArrayA28_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ29_EXIST_DATA
extern uint8_t TransmitDataArrayA29_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ30_EXIST_DATA
extern uint8_t TransmitDataArrayA30_2[];
#endif
#ifdef CAN2_TX_CHANNELA_SEQ31_EXIST_DATA
extern uint8_t TransmitDataArrayA31_2[];
#endif
#else
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
#endif

//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. 

#if 0   //we use array point to replace.  And pointer is given in simulink
#ifdef CAN2_TX_CHANNELB_SEQ0_EXIST_DATA
extern uint8_t TransmitDataArrayB0_2[]; //CAN2 Channel B transmit , Seq0 Data Array
#endif
#ifdef CAN2_TX_CHANNELB_SEQ1_EXIST_DATA
extern uint8_t TransmitDataArrayB1_2[]; //CAN2 Channel B transmit , Seq1 Data Array
#endif
#ifdef CAN2_TX_CHANNELB_SEQ2_EXIST_DATA
extern uint8_t TransmitDataArrayB2_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ3_EXIST_DATA
extern uint8_t TransmitDataArrayB3_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ4_EXIST_DATA
extern uint8_t TransmitDataArrayB4_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ5_EXIST_DATA
extern uint8_t TransmitDataArrayB5_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ6_EXIST_DATA
extern uint8_t TransmitDataArrayB6_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ7_EXIST_DATA
extern uint8_t TransmitDataArrayB7_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ8_EXIST_DATA
extern uint8_t TransmitDataArrayB8_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ9_EXIST_DATA
extern uint8_t TransmitDataArrayB9_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ10_EXIST_DATA
extern uint8_t TransmitDataArrayB10_2[];
#endif

#ifdef CAN2_TX_CHANNELB_SEQ11_EXIST_DATA
extern uint8_t TransmitDataArrayB11_2[]; //CAN2 Channel B transmit , Seq11 Data Array
#endif
#ifdef CAN2_TX_CHANNELB_SEQ12_EXIST_DATA
extern uint8_t TransmitDataArrayB12_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ13_EXIST_DATA
extern uint8_t TransmitDataArrayB13_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ14_EXIST_DATA
extern uint8_t TransmitDataArrayB14_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ15_EXIST_DATA
extern uint8_t TransmitDataArrayB15_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ16_EXIST_DATA
extern uint8_t TransmitDataArrayB16_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ17_EXIST_DATA
extern uint8_t TransmitDataArrayB17_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ18_EXIST_DATA
extern uint8_t TransmitDataArrayB18_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ19_EXIST_DATA
extern uint8_t TransmitDataArrayB19_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ20_EXIST_DATA
extern uint8_t TransmitDataArrayB20_2[];
#endif



#ifdef CAN2_TX_CHANNELB_SEQ21_EXIST_DATA
extern uint8_t TransmitDataArrayB21_2[]; //CAN2 Channel B transmit , Seq21 Data Array
#endif
#ifdef CAN2_TX_CHANNELB_SEQ22_EXIST_DATA
extern uint8_t TransmitDataArrayB22_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ23_EXIST_DATA
extern uint8_t TransmitDataArrayB23_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ24_EXIST_DATA
extern uint8_t TransmitDataArrayB24_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ25_EXIST_DATA
extern uint8_t TransmitDataArrayB25_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ26_EXIST_DATA
extern uint8_t TransmitDataArrayB26_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ27_EXIST_DATA
extern uint8_t TransmitDataArrayB27_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ28_EXIST_DATA
extern uint8_t TransmitDataArrayB28_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ29_EXIST_DATA
extern uint8_t TransmitDataArrayB29_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ30_EXIST_DATA
extern uint8_t TransmitDataArrayB30_2[];
#endif
#ifdef CAN2_TX_CHANNELB_SEQ31_EXIST_DATA
extern uint8_t TransmitDataArrayB31_2[];
#endif
#else
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

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

#if 0   //we use array point to replace.  And pointer is given in simulink
#ifdef CAN2_TX_CHANNELC_SEQ0_EXIST_DATA
extern uint8_t TransmitDataArrayC0_2[]; //CAN2 Channel C transmit , Seq0 Data Array
#endif
#ifdef CAN2_TX_CHANNELC_SEQ1_EXIST_DATA
extern uint8_t TransmitDataArrayC1_2[]; //CAN2 Channel C transmit , Seq1 Data Array
#endif
#ifdef CAN2_TX_CHANNELC_SEQ2_EXIST_DATA
extern uint8_t TransmitDataArrayC2_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ3_EXIST_DATA
extern uint8_t TransmitDataArrayC3_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ4_EXIST_DATA
extern uint8_t TransmitDataArrayC4_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ5_EXIST_DATA
extern uint8_t TransmitDataArrayC5_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ6_EXIST_DATA
extern uint8_t TransmitDataArrayC6_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ7_EXIST_DATA
extern uint8_t TransmitDataArrayC7_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ8_EXIST_DATA
extern uint8_t TransmitDataArrayC8_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ9_EXIST_DATA
extern uint8_t TransmitDataArrayC9_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ10_EXIST_DATA
extern uint8_t TransmitDataArrayC10_2[];
#endif

#ifdef CAN2_TX_CHANNELC_SEQ11_EXIST_DATA
extern uint8_t TransmitDataArrayC11_2[]; //CAN2 Channel C transmit , Seq11 Data Array
#endif
#ifdef CAN2_TX_CHANNELC_SEQ12_EXIST_DATA
extern uint8_t TransmitDataArrayC12_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ13_EXIST_DATA
extern uint8_t TransmitDataArrayC13_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ14_EXIST_DATA
extern uint8_t TransmitDataArrayC14_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ15_EXIST_DATA
extern uint8_t TransmitDataArrayC15_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ16_EXIST_DATA
extern uint8_t TransmitDataArrayC16_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ17_EXIST_DATA
extern uint8_t TransmitDataArrayC17_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ18_EXIST_DATA
extern uint8_t TransmitDataArrayC18_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ19_EXIST_DATA
extern uint8_t TransmitDataArrayC19_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ20_EXIST_DATA
extern uint8_t TransmitDataArrayC20_2[];
#endif



#ifdef CAN2_TX_CHANNELC_SEQ21_EXIST_DATA
extern uint8_t TransmitDataArrayC21_2[]; //CAN2 Channel C transmit , Seq21 Data Array
#endif
#ifdef CAN2_TX_CHANNELC_SEQ22_EXIST_DATA
extern uint8_t TransmitDataArrayC22_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ23_EXIST_DATA
extern uint8_t TransmitDataArrayC23_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ24_EXIST_DATA
extern uint8_t TransmitDataArrayC24_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ25_EXIST_DATA
extern uint8_t TransmitDataArrayC25_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ26_EXIST_DATA
extern uint8_t TransmitDataArrayC26_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ27_EXIST_DATA
extern uint8_t TransmitDataArrayC27_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ28_EXIST_DATA
extern uint8_t TransmitDataArrayC28_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ29_EXIST_DATA
extern uint8_t TransmitDataArrayC29_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ30_EXIST_DATA
extern uint8_t TransmitDataArrayC30_2[];
#endif
#ifdef CAN2_TX_CHANNELC_SEQ31_EXIST_DATA
extern uint8_t TransmitDataArrayC31_2[];
#endif
#else
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

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


#if 0

void LowLayer_init(CANBUS_t * pCANxObj) {

    if (1 == pCANxObj->CAN_Peripheral_No) {
#ifdef USE_CAN1
        //For PIC, Copy from void CAN1_Initialize(void) and modify Mask regs, but changed dead loop "while"
        //Simulink add for init CAN1 -- start
        // Disable interrupts before the Initialization
        IEC2bits.C1IE = 0;
        C1INTE = 0;

        // set the CAN1_initialize module to the options selected in the User Interface

        /* put the module in configuration mode */
        C1CTRL1bits.REQOP = CAN_CONFIGURATION_MODE;
        //modify to detect fail
        uint16_t tick4config;
        tick4config = tick;
        //while (C1CTRL1bits.OPMODE != CAN_CONFIGURATION_MODE);
        while (C1CTRL1bits.OPMODE != CAN_CONFIGURATION_MODE) {
            ClrWdt();
            if (tick - tick4config > 800U) {
                pCANxObj->CANInitConfigFail = 1;
                return;
            }
        }

        /* Set up the baud rate*/
        C1CFG1 = 0x03; //BRP TQ = (2 x 4)/FCAN; SJW 1 x TQ; 
        C1CFG2 = 0x3BE; //WAKFIL disabled; SEG2PHTS Freely programmable; SEG2PH 4 x TQ; SEG1PH 8 x TQ; PRSEG 7 x TQ; SAM Once at the sample point; 
        C1FCTRL = 0xC003; //FSA Transmit/Receive Buffer TRB3; DMABS 32; 
        C1FEN1 = 0x07; //FLTEN8 disabled; FLTEN7 disabled; FLTEN9 disabled; FLTEN0 enabled; FLTEN2 enabled; FLTEN10 disabled; FLTEN1 enabled; FLTEN11 disabled; FLTEN4 disabled; FLTEN3 disabled; FLTEN6 disabled; FLTEN5 disabled; FLTEN12 disabled; FLTEN13 disabled; FLTEN14 disabled; FLTEN15 disabled; 
        C1CTRL1 = 0x00; //CANCKS FOSC/2; CSIDL disabled; ABAT disabled; REQOP Sets Normal Operation Mode; WIN Uses buffer window; CANCAP disabled; 

        /* Filter configuration */
        /* enable window to access the filter configuration registers */
        /* use filter window*/
        C1CTRL1bits.WIN = 1;

        /* select acceptance masks for filters */
        C1FMSKSEL1bits.F0MSK = 0x0; //Select Mask 0 for Filter 0
        C1FMSKSEL1bits.F1MSK = 0x0; //Select Mask 0 for Filter 1
        C1FMSKSEL1bits.F2MSK = 0x0; //Select Mask 0 for Filter 2

        /* Configure the masks */
        //for CANbus----start
#if 0        
        C1RXM0SIDbits.SID = 0x7ff;
        C1RXM1SIDbits.SID = 0x0;
        C1RXM2SIDbits.SID = 0x0;

        C1RXM0SIDbits.EID = 0x3;
        C1RXM1SIDbits.EID = 0x0;
        C1RXM2SIDbits.EID = 0x0;

        C1RXM0EID = 0xFFFF;
        C1RXM1EID = 0x00;
        C1RXM2EID = 0x00;

        C1RXM0SIDbits.MIDE = 0x0;
        C1RXM1SIDbits.MIDE = 0x0;
        C1RXM2SIDbits.MIDE = 0x0;
#else
        if (pCANxObj->MASK0IsSTD) {
            C1RXM0SIDbits.SID = (pCANxObj->Mask0) & 0x7ff;
            C1RXM0SIDbits.EID = 0;
            C1RXM0EID = 0;
        } else {
            C1RXM0SIDbits.SID = ((pCANxObj->Mask0) >> 18) & 0x7ff;
            C1RXM0SIDbits.EID = ((pCANxObj->Mask0) >> 16) & 0x3;
            C1RXM0EID = (pCANxObj->Mask0) & 0xffff;
            ;
        }

        if (pCANxObj->MASK1IsSTD) {
            C1RXM1SIDbits.SID = (pCANxObj->Mask1) & 0x7ff;
            C1RXM1SIDbits.EID = 0;
            C1RXM1EID = 0;
        } else {
            C1RXM1SIDbits.SID = ((pCANxObj->Mask1) >> 18) & 0x7ff;
            C1RXM1SIDbits.EID = ((pCANxObj->Mask1) >> 16) & 0x3;
            C1RXM1EID = (pCANxObj->Mask1) & 0xffff;
            ;
        }

        if (pCANxObj->MASK2IsSTD) {
            C1RXM2SIDbits.SID = (pCANxObj->Mask2) & 0x7ff;
            C1RXM2SIDbits.EID = 0;
            C1RXM2EID = 0;
        } else {
            C1RXM2SIDbits.SID = ((pCANxObj->Mask2) >> 18) & 0x7ff;
            C1RXM2SIDbits.EID = ((pCANxObj->Mask2) >> 16) & 0x3;
            C1RXM2EID = (pCANxObj->Mask2) & 0xffff;
            ;
        }

        C1RXM0SIDbits.MIDE = 0x1; //We care EIDE in filter
        C1RXM1SIDbits.MIDE = 0x1;
        C1RXM2SIDbits.MIDE = 0x1;
#endif 
        //for CANbus----end


        /* Configure the filters */
        C1RXF0SIDbits.SID = 0x123;
        C1RXF1SIDbits.SID = 0x0;
        C1RXF2SIDbits.SID = 0x321;

        C1RXF0SIDbits.EID = 0x0;
        C1RXF1SIDbits.EID = 0x0;
        C1RXF2SIDbits.EID = 0x0;

        C1RXF0EID = 0x00;
        C1RXF1EID = 0x23;
        C1RXF2EID = 0x00;

        C1RXF0SIDbits.EXIDE = 0x0;
        C1RXF1SIDbits.EXIDE = 0x0;
        C1RXF2SIDbits.EXIDE = 0x0;

        /* FIFO Mode */
        C1BUFPNT1bits.F0BP = 0xf; //Filter 0 uses FIFO
        C1BUFPNT1bits.F1BP = 0xf; //Filter 1 uses FIFO
        C1BUFPNT1bits.F2BP = 0xf; //Filter 2 uses FIFO

        /* clear window bit to access CAN1 control registers */
        C1CTRL1bits.WIN = 0;

        /*configure CAN1 Transmit/Receive buffer settings*/
        C1TR01CONbits.TXEN0 = 0x1; // Buffer 0 is a Transmit Buffer 
        C1TR01CONbits.TXEN1 = 0x1; // Buffer 1 is a Transmit Buffer 
        C1TR23CONbits.TXEN2 = 0x1; // Buffer 2 is a Transmit Buffer 
        C1TR23CONbits.TXEN3 = 0x0; // Buffer 3 is a Receive Buffer 
        C1TR45CONbits.TXEN4 = 0x0; // Buffer 4 is a Receive Buffer 
        C1TR45CONbits.TXEN5 = 0x0; // Buffer 5 is a Receive Buffer 
        C1TR67CONbits.TXEN6 = 0x0; // Buffer 6 is a Receive Buffer 
        C1TR67CONbits.TXEN7 = 0x0; // Buffer 7 is a Receive Buffer 

        C1TR01CONbits.TX0PRI = 0x0; // Message Buffer 0 Priority Level
        C1TR01CONbits.TX1PRI = 0x0; // Message Buffer 1 Priority Level
        C1TR23CONbits.TX2PRI = 0x0; // Message Buffer 2 Priority Level
        C1TR23CONbits.TX3PRI = 0x0; // Message Buffer 3 Priority Level
        C1TR45CONbits.TX4PRI = 0x0; // Message Buffer 4 Priority Level
        C1TR45CONbits.TX5PRI = 0x0; // Message Buffer 5 Priority Level
        C1TR67CONbits.TX6PRI = 0x0; // Message Buffer 6 Priority Level
        C1TR67CONbits.TX7PRI = 0x0; // Message Buffer 7 Priority Level

        /* clear the buffer and overflow flags */
        C1RXFUL1 = 0x0000;
        C1RXFUL2 = 0x0000;
        C1RXOVF1 = 0x0000;
        C1RXOVF2 = 0x0000;

        /* configure the device to interrupt on the receive buffer full flag */
        /* clear the buffer full flags */
        C1INTFbits.RBIF = 0;

        /* put the module in normal mode */
        C1CTRL1bits.REQOP = CAN_NORMAL_OPERATION_MODE;
        //modify to detect fail       
        tick4config = tick;
        // while (C1CTRL1bits.OPMODE != CAN_NORMAL_OPERATION_MODE);
        while (C1CTRL1bits.OPMODE != CAN_NORMAL_OPERATION_MODE) {
            ClrWdt();
            if (tick - tick4config > 800U) {
                pCANxObj->CANInitConfigFail = 1;
                return;
            }
        }
        pCANxObj->CANInitConfigFail = 0; //Success to config

        /* Initialize Interrupt Handler*/
        CAN1_SetBusErrorHandler(&CAN1_DefaultBusErrorHandler);
        CAN1_SetTxErrorPassiveHandler(&CAN1_DefaultTxErrorPassiveHandler);
        CAN1_SetRxErrorPassiveHandler(&CAN1_DefaultRxErrorPassiveHandler);
        CAN1_SetBusWakeUpActivityInterruptHandler(&CAN1_DefaultBusWakeUpActivityHandler);
        CAN1_SetRxBufferInterruptHandler(&CAN1_DefaultReceiveBufferHandler);
        CAN1_SetRxBufferOverFlowInterruptHandler(&CAN1_DefaultRxBufferOverFlowHandler);

        /* Enable CAN1 Interrupt */
        IEC2bits.C1IE = 1;

        /* Enable Receive interrupt */
        C1INTEbits.RBIE = 1;

        /* Enable Error interrupt*/
        C1INTEbits.ERRIE = 1;

        /* Enable Receive buffer Overflow interrupt */
        C1INTEbits.RBOVIE = 1;

        /* Enable TxReq IEC bit */
        IEC4bits.C1TXIE = 1;

        /* Enable RxReady IEC bit */
        IEC2bits.C1RXIE = 1;
        //Simulink add for init CAN1 -- end
#endif
    }
    if (2 == pCANxObj->CAN_Peripheral_No) {
#ifdef USE_CAN2
        //For PIC, Copy from void CAN2_Initialize(void) and modify Mask regs
        //Simulink add for init CAN2 -- start

        //Simulink add for init CAN2 -- end
#endif
    }
}
#endif

#ifdef USE_CAN1
extern CANBUS_t CAN_myObj1; //for CAN1
#if !defined(__dsPIC33C__)
void CAN1_CallbackMessageReceived(void) {
    CAN_myObj1.RxCANReceived = 1;
}
#endif

/**
 * Put all CAN1  Rx data into our high level buffers
 */
void CAN1_fill_Rx_Data() {
    CAN_MSG_OBJ tempCAN;
    uint8_t MyCANData[8];
    tempCAN.data = MyCANData;
    #if !defined(__dsPIC33C__)
    while (CAN1_Receive(&tempCAN)) {
        if (tempCAN.field.idType == CAN_FRAME_STD) {
            //Std handle
            //tempCAN.msgId is in "Std
            putCAN1RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
        } else {
            //Ext handle
            putCAN1RxExtCAN2Buffer(/*uint32_t CANID*/tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
        }

    }
    #else
    while (CAN1_ReceivedMessageCountGet() > 0) {
        while (CAN1_Receive(&tempCAN)) {
            if (tempCAN.field.idType == CAN_FRAME_STD) {
                //Std handle
                //tempCAN.msgId is in "Std
                putCAN1RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
            } else {
                //Ext handle
                putCAN1RxExtCAN2Buffer(/*uint32_t CANID*/tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
            }

        }
        CAN1_Tasks();
    }
    #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 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);

#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 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);
#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 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);
#endif
#endif
}

#ifdef USE_CAN2
extern CANBUS_t CAN_myObj2; //for CAN2
#if !defined(__dsPIC33C__)
void CAN2_CallbackMessageReceived(void) {
    CAN_myObj2.RxCANReceived = 1;
}
#endif

/**
 * Put all CAN2 Rx data into our high level buffers
 */
void CAN2_fill_Rx_Data() {
    CAN_MSG_OBJ tempCAN;
    uint8_t MyCANData[8];
    tempCAN.data = MyCANData;
    //if (CAN1_Receive(&tempCAN) )
    #if !defined(__dsPIC33C__)
    while (CAN2_Receive(&tempCAN)) {
        if (tempCAN.field.idType == CAN_FRAME_STD) {
            //Std handle
            //tempCAN.msgId is in "Std
            putCAN2RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
        } else {
            //Ext handle
            putCAN2RxExtCAN2Buffer(/*uint32_t CANID*/tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
        }

    }
    #else
    while (CAN2_ReceivedMessageCountGet() > 0) {
        while (CAN2_Receive(&tempCAN)) {
            if (tempCAN.field.idType == CAN_FRAME_STD) {
                //Std handle
                //tempCAN.msgId is in "Std
                putCAN2RxStdCAN2Buffer(/*uint16_t CANID*/(uint16_t) tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
            } else {
                //Ext handle
                putCAN2RxExtCAN2Buffer(/*uint32_t CANID*/tempCAN.msgId, /*bool RTR*/tempCAN.field.frameType, /*uint8_t DLC*/tempCAN.field.dlc, /*uint8_t * pCAN_Data*/tempCAN.data);
            }

        }
        CAN2_Tasks();
    }
    #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 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);
#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 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);
#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 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);
#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) {
    CAN_MSG_OBJ msg;
    uint16_t TxDATALen;
    CAN_TX_MSG_REQUEST_STATUS TxResult;
    bool Stage4Seq;
    bool BusOFF_F_Return;
    uint16_t TimeOutSettings;
    uint8_t * ResponseData;
    uint8_t ResponseDataLen;
    uint16_t TxResponseCANID_Index;
    uint16_t TxCAN_RTR_DLC_UseStd;
    #if !defined(__dsPIC33C__)
    CAN_TX_PRIOIRTY TxPriority;
    #else
    CAN1_TX_FIFO_CHANNELS TxPriority;
    #endif
    uint32_t TransmitFrameCANID;
    uint8_t * TransmitDataArray_Seq;
    
    volatile uint8_t * pRxdDLC;
    volatile uint8_t ( * pRxData )[8];
    
    volatile uint16_t * RxStdCANID;
    volatile uint32_t * RxExtCANID;
    #if !defined(__dsPIC33C__)
    CAN_TX_MSG_REQUEST_STATUS(*CAN_Transmit)(CAN_TX_PRIOIRTY priority, CAN_MSG_OBJ * sendCanMsg);
    #else
    CAN_TX_MSG_REQUEST_STATUS(*CAN_Transmit)(CAN1_TX_FIFO_CHANNELS priority, CAN_MSG_OBJ * sendCanMsg);
    #endif
    if (1 == CAN_Obj->CAN_Peripheral_No) {
#ifndef USE_CAN1
        return 0;
#else
        CAN_Transmit = CAN1_Transmit;
        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];
                #if !defined(__dsPIC33C__)
                TxPriority = CAN_PRIORITY_HIGH;
                #else
                TxPriority = 0;  //Actually it is CAN1_TXQ or CAN2_TXQ
                #endif
                TransmitDataArray_Seq = TransmitDataArrayA_Seq_1[Seq];
                TransmitFrameCANID = TransmitFrameCANID_A_1[Seq];
                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];
                #if !defined(__dsPIC33C__)
                TxPriority = CAN_PRIORITY_MEDIUM;
                #else
                TxPriority = 0;  //Actually it is CAN1_TXQ or CAN2_TXQ
                #endif
                TransmitDataArray_Seq = TransmitDataArrayB_Seq_1[Seq];
                TransmitFrameCANID = TransmitFrameCANID_B_1[Seq];
                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];
                #if !defined(__dsPIC33C__)
                TxPriority = CAN_PRIORITY_LOW;
                #else
                TxPriority = 0;  //Actually it is CAN1_TXQ or CAN2_TXQ
                #endif
                TransmitDataArray_Seq = TransmitDataArrayC_Seq_1[Seq];
                TransmitFrameCANID = TransmitFrameCANID_C_1[Seq];
#endif   

        }
#endif
    } else if (2 == CAN_Obj->CAN_Peripheral_No) {
#ifndef USE_CAN2
        return 0;
#else
        CAN_Transmit = CAN2_Transmit;
        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];
                #if !defined(__dsPIC33C__)
                TxPriority = CAN_PRIORITY_HIGH;
                #else
                TxPriority = 0;  //Actually it is CAN1_TXQ or CAN2_TXQ
                #endif
                TransmitDataArray_Seq = TransmitDataArrayA_Seq_2[Seq];
                TransmitFrameCANID = TransmitFrameCANID_A_2[Seq];
                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];
                #if !defined(__dsPIC33C__)
                TxPriority = CAN_PRIORITY_MEDIUM;
                #else
                TxPriority = 0;  //Actually it is CAN1_TXQ or CAN2_TXQ
                #endif
                TransmitDataArray_Seq = TransmitDataArrayB_Seq_2[Seq];
                TransmitFrameCANID = TransmitFrameCANID_B_2[Seq];
                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];
                #if !defined(__dsPIC33C__)
                TxPriority = CAN_PRIORITY_LOW;
                #else
                TxPriority = 0;  //Actually it is CAN1_TXQ or CAN2_TXQ
                #endif
                TransmitDataArray_Seq = TransmitDataArrayC_Seq_2[Seq];
                TransmitFrameCANID = TransmitFrameCANID_C_2[Seq];
#endif   

        }

#endif
    }

    Stage4Seq = (*state >> Seq) &0x1;
    if (1 == CAN_Obj->CAN_Peripheral_No) {
        #ifdef USE_CAN1
            BusOFF_F_Return=CAN1_IsBusOff();
        #else
            BusOFF_F_Return=true;
        #endif
    }
    else
    {
        #ifdef USE_CAN2
            BusOFF_F_Return=CAN2_IsBusOff(); 
        #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;
            }
            if (TxCAN_RTR_DLC_UseStd & 0x4000)
                msg.field.idType = CAN_FRAME_STD;
            else
                msg.field.idType = CAN_FRAME_EXT;
            msg.msgId = TransmitFrameCANID;
            #if defined(__dsPIC33C__)
            msg.field.formatType = CAN_2_0_FORMAT;
            msg.field.brs = CAN_NON_BRS_MODE;
            #endif
            if (TxCAN_RTR_DLC_UseStd & 0x8000) {
                //RTR transmit                
                msg.field.frameType = CAN_FRAME_RTR;
                TxResult = CAN_Transmit(TxPriority, &msg);
                if (CAN_TX_MSG_REQUEST_SUCCESS == TxResult) {
                    return 0;
                } else return -1;

            } else {
                //Data frame
                msg.field.frameType = CAN_FRAME_DATA; //Very important because msg is in stack. Value is random
                TxDATALen = TxCAN_RTR_DLC_UseStd & 0x7FF; //Bit10-0: length
                if ((Seq <= 3) && (TxDATALen <= 8) && (TxCAN_RTR_DLC_UseStd & 0x2000)) { //Bit13: need response
                    //Need response                    
                    msg.field.dlc = TxDATALen;
                    msg.data = TransmitDataArray_Seq;
                    TxResult = CAN_Transmit(TxPriority, &msg);
                    if (CAN_TX_MSG_REQUEST_SUCCESS == TxResult) {
                        *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 {
                        return -1; //fail
                    }


                } else {
                    //No need response
                    if (TxDATALen <= 8) {
                        //short frame
                        msg.field.dlc = TxDATALen;
                        msg.data = TransmitDataArray_Seq;
                        TxResult = CAN_Transmit(TxPriority, &msg);
                        if (CAN_TX_MSG_REQUEST_SUCCESS == TxResult) {
                            return 0;
                        } else return -1;
                    } else {
                        //long frame
                        uint8_t HasTransmittedByteQty;
                        uint8_t pData[8];
                        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 (TxDATALen - HasTransmittedByteQty >= 7) {
                            msg.field.dlc = 8;
                            for (i = 1; i < 8; i++) {
                                pData[i] = *(TransmitDataArray_Seq + HasTransmittedByteQty + i - 1);
                            }

                        } else if (TxDATALen - HasTransmittedByteQty > 0) {
                            msg.field.dlc = TxDATALen - HasTransmittedByteQty + 1;
                            for (i = 0; i < TxDATALen - HasTransmittedByteQty; i++) {
                                pData[i + 1] = *(TransmitDataArray_Seq + HasTransmittedByteQty + i);
                            }
                        } else {
                            //==-, no need to transmit
                            CurrntFrmNo[Seq] = 0;
                            return 0; //success done all frames Tx
                        }
                        msg.data = pData;
                        TxResult = CAN_Transmit(TxPriority, &msg);
                        if (CAN_TX_MSG_REQUEST_SUCCESS == TxResult) {
                            if (TxDATALen == HasTransmittedByteQty + msg.field.dlc - 1) { //Judgemeny 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 {
                            CurrntFrmNo[Seq] = 0; //init it
                            return -1; //fail
                        }



                    }
                }

            }


        } 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;
    }




}