This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28377D: CANA 查询接受帧数据,偶尔会接收错误

Part Number: TMS320F28377D


用can上位机模拟下发给dsp一帧固定的8个字节数据,dsp接收的,偶尔会有接收错误。调用的这个函数(getCANAMessage),查询接受CAN接收的数据,这个数组(ucRXMsgData),接收的数据,偶尔会有高字节的,数据不对。当前,每间隔4ms,调用一次getCANAMessage函数,CAN上位机间隔20ms发送一帧数据。

在线等!

//###########################################################################
//
// FILE:   F2837xD_can.c
//
// TITLE:  F2837xD CAN Support Functions.
//
//###########################################################################
//
// Included Files
//
#include "F28x_Project.h"
#include "F2837xD_device.h"
#include "F2837xD_Examples.h"
#include "Custom_ECan.h"
#include "Variable.h"
#include "Modbus.h"
#include "Commu_Para.h"
/*****************************************************************/
union CanWord_Type CANB_ID,CANA_ID;
Uint8 ucTXMsgData[8], ucRXMsgData[8],ucRX2MsgData[8],ucTX2MsgData[8];
Uint8 ucRX3MsgData[8],ucTX3MsgData[8],ucRX4MsgData[8],ucTX4MsgData[8];
Uint8 ucRX5MsgData[8],ucTX5MsgData[8],ucRX6MsgData[8],ucTX6MsgData[8];
Uint8 ucRX9MsgData[8],ucTX9MsgData[8];
uint32_t ucRXMsg_MSGID_EMS,ucRXMsg_MSGID_STS,ucRXMsg_MSGID_PCSOne,ucRXMsg_MSGID_PCSTwo,ucRXMsg_MSGID_PCS;
Uint32 Test1U32=0,Test2U32=0;
Uint32 Test3U32=0,Test4U32=0;
/*****************************************************************/
static const uint16_t canBitValues[] =
{
    0x1100, // TSEG2 2, TSEG1 2, SJW 1, Divide 5
    0x1200, // TSEG2 2, TSEG1 3, SJW 1, Divide 6
    0x2240, // TSEG2 3, TSEG1 3, SJW 2, Divide 7
    0x2340, // TSEG2 3, TSEG1 4, SJW 2, Divide 8
    0x3340, // TSEG2 4, TSEG1 4, SJW 2, Divide 9
    0x3440, // TSEG2 4, TSEG1 5, SJW 2, Divide 10
    0x3540, // TSEG2 4, TSEG1 6, SJW 2, Divide 11
    0x3640, // TSEG2 4, TSEG1 7, SJW 2, Divide 12
    0x3740  // TSEG2 4, TSEG1 8, SJW 2, Divide 13
};
/*
typedef enum
{
        //! Transmit message object.
        MSG_OBJ_TYPE_TRANSMIT,

        //! Receive message object.
        MSG_OBJ_TYPE_RECEIVE
}
msgObjType;
*/
//
// InitCAN - Initializes the CAN-A controller after reset.
//
void InitCANA(void)
{
	int16_t iMsg;

	//
    // Place CAN controller in init state, regardless of previous state.  This
    // will put controller in idle, and allow the message object RAM to be
    // programmed.
	//
	CanaRegs.CAN_CTL.bit.Init = 1;
	CanaRegs.CAN_CTL.bit.SWR = 1;
	CanaRegs.CAN_CTL.bit.ABO = 1;

	//
    // Wait for busy bit to clear
	//
    while(CanaRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Clear the message value bit in the arbitration register.  This indicates
    // the message is not valid and is a "safe" condition to leave the message
    // object.  The same arb reg is used to program all the message objects.
    //
    CanaRegs.CAN_IF1CMD.bit.DIR = 1;
    CanaRegs.CAN_IF1CMD.bit.Arb = 1;
    CanaRegs.CAN_IF1CMD.bit.Control = 1;
	

    CanaRegs.CAN_IF1ARB.all = 0;
    CanaRegs.CAN_IF1MCTL.all = 0;

    CanaRegs.CAN_IF2CMD.bit.DIR = 1;
    CanaRegs.CAN_IF2CMD.bit.Arb = 1;
    CanaRegs.CAN_IF2CMD.bit.Control = 1;

    CanaRegs.CAN_IF2ARB.all = 0;
    CanaRegs.CAN_IF2MCTL.all = 0;

    //
    // Loop through to program all 32 message objects
    //
    for(iMsg = 1; iMsg <= 32; iMsg+=2)
    {
        //
    	// Wait for busy bit to clear
    	//
        while(CanaRegs.CAN_IF1CMD.bit.Busy)
        {
        }

        //
        // Initiate programming the message object
        //
        CanaRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg;

        //
        // Wait for busy bit to clear
        //
        while(CanaRegs.CAN_IF2CMD.bit.Busy)
        {
        }

        //
        // Initiate programming the message object
        //
        CanaRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1;
    }

    //
    // Acknowledge any pending status interrupts.
    //
    //volatile uint32_t discardRead = CanaRegs.CAN_ES.all;

}
void InitCANB(void)
{
	int16_t iMsg;

	//
    // Place CAN controller in init state, regardless of previous state.  This
    // will put controller in idle, and allow the message object RAM to be
    // programmed.
	//
	CanbRegs.CAN_CTL.bit.Init = 1;
	CanbRegs.CAN_CTL.bit.SWR = 1;
	CanbRegs.CAN_CTL.bit.ABO = 1;
	//
    // Wait for busy bit to clear
	//
    while(CanbRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Clear the message value bit in the arbitration register.  This indicates
    // the message is not valid and is a "safe" condition to leave the message
    // object.  The same arb reg is used to program all the message objects.
    //
    CanbRegs.CAN_IF1CMD.bit.DIR = 1;
    CanbRegs.CAN_IF1CMD.bit.Arb = 1;
    CanbRegs.CAN_IF1CMD.bit.Control = 1;

    CanbRegs.CAN_IF1ARB.all = 0;

    CanbRegs.CAN_IF1MCTL.all = 0;

    CanbRegs.CAN_IF2CMD.bit.DIR = 1;
    CanbRegs.CAN_IF2CMD.bit.Arb = 1;
    CanbRegs.CAN_IF2CMD.bit.Control = 1;

    CanbRegs.CAN_IF2ARB.all = 0;

    CanbRegs.CAN_IF2MCTL.all = 0;

    //
    // Loop through to program all 32 message objects
    //
    for(iMsg = 1; iMsg <= 32; iMsg+=2)
    {
        //
    	// Wait for busy bit to clear
    	//
        while(CanbRegs.CAN_IF1CMD.bit.Busy)
        {
        }

        //
        // Initiate programming the message object
        //
        CanbRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg;

        //
        // Wait for busy bit to clear
        //
        while(CanbRegs.CAN_IF2CMD.bit.Busy)
        {
        }

        //
        // Initiate programming the message object
        //
        CanbRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1;
    }

    //
    // Acknowledge any pending status interrupts.
    //
    //volatile uint32_t discardRead = CanbRegs.CAN_ES.all;

}
//
// setCANBitRate - Set the CAN bit rate based on device clock (Hz)
//                 and desired bit rate (Hz)
//
uint32_t setCANABitRate(uint32_t sourceClock, uint32_t bitRate)
{
    uint32_t desiredRatio;
    uint32_t canBits;
    uint32_t preDivide;
    uint32_t regValue;
    uint16_t canControlValue;

    //
    // Calculate the desired clock rate.
    //
    desiredRatio = sourceClock / bitRate;

    //
    // Make sure that the Desired Ratio is not too large.  This enforces the
    // requirement that the bit rate is larger than requested.
    //
    if((sourceClock / desiredRatio) > bitRate)
    {
        desiredRatio += 1;
    }

    //
    // Check all possible values to find a matching value.
    //
    while(desiredRatio <= CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR)
    {
        //
        // Loop through all possible CAN bit divisors.
        //
        for(canBits = CAN_MAX_BIT_DIVISOR;
            canBits >= CAN_MIN_BIT_DIVISOR;
            canBits--)
        {
            //
            // For a given CAN bit divisor save the pre divisor.
            //
            preDivide = desiredRatio / canBits;

            //
            // If the calculated divisors match the desired clock ratio then
            // return these bit rate and set the CAN bit timing.
            //
            if((preDivide * canBits) == desiredRatio)
            {
                //
                // Start building the bit timing value by adding the bit timing
                // in time quanta.
                //
                regValue = canBitValues[canBits - CAN_MIN_BIT_DIVISOR];

                //
                // To set the bit timing register, the controller must be
                // placed
                // in init mode (if not already), and also configuration change
                // bit enabled.  The state of the register should be saved
                // so it can be restored.
                //
                canControlValue = CanaRegs.CAN_CTL.all;
                CanaRegs.CAN_CTL.bit.Init = 1;
                CanaRegs.CAN_CTL.bit.CCE = 1;

                //
                // Now add in the pre-scalar on the bit rate.
                //
                regValue |= ((preDivide - 1) & CAN_BTR_BRP_M) |
                            (((preDivide - 1) << 10) & CAN_BTR_BRPE_M);

                //
                // Set the clock bits in the and the bits of the
                // pre-scalar.
                //
                CanaRegs.CAN_BTR.all = regValue;

                //
                // Restore the saved CAN Control register.
                //
                CanaRegs.CAN_CTL.all = canControlValue;

                //
                // Return the computed bit rate.
                //
                return(sourceClock / ( preDivide * canBits));
            }
        }

        //
        // Move the divisor up one and look again.  Only in rare cases are
        // more than 2 loops required to find the value.
        //
        desiredRatio++;
    }
    return 0;
}
//
// setCANBitRate - Set the CAN bit rate based on device clock (Hz)
//                 and desired bit rate (Hz)
//
uint32_t setCANBBitRate(uint32_t sourceClock, uint32_t bitRate)
{
    uint32_t desiredRatio;
    uint32_t canBits;
    uint32_t preDivide;
    uint32_t regValue;
    uint16_t canControlValue;

    //
    // Calculate the desired clock rate.
    //
    desiredRatio = sourceClock / bitRate;

    //
    // Make sure that the Desired Ratio is not too large.  This enforces the
    // requirement that the bit rate is larger than requested.
    //
    if((sourceClock / desiredRatio) > bitRate)
    {
        desiredRatio += 1;
    }

    //
    // Check all possible values to find a matching value.
    //
    while(desiredRatio <= CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR)
    {
        //
        // Loop through all possible CAN bit divisors.
        //
        for(canBits = CAN_MAX_BIT_DIVISOR;
            canBits >= CAN_MIN_BIT_DIVISOR;
            canBits--)
        {
            //
            // For a given CAN bit divisor save the pre divisor.
            //
            preDivide = desiredRatio / canBits;

            //
            // If the calculated divisors match the desired clock ratio then
            // return these bit rate and set the CAN bit timing.
            //
            if((preDivide * canBits) == desiredRatio)
            {
                //
                // Start building the bit timing value by adding the bit timing
                // in time quanta.
                //
                regValue = canBitValues[canBits - CAN_MIN_BIT_DIVISOR];

                //
                // To set the bit timing register, the controller must be
                // placed
                // in init mode (if not already), and also configuration change
                // bit enabled.  The state of the register should be saved
                // so it can be restored.
                //
                canControlValue = CanbRegs.CAN_CTL.all;
                CanbRegs.CAN_CTL.bit.Init = 1;
                CanbRegs.CAN_CTL.bit.CCE = 1;

                //
                // Now add in the pre-scalar on the bit rate.
                //
                regValue |= ((preDivide - 1) & CAN_BTR_BRP_M) |
                            (((preDivide - 1) << 10) & CAN_BTR_BRPE_M);

                //
                // Set the clock bits in the and the bits of the
                // pre-scalar.
                //
                CanbRegs.CAN_BTR.all = regValue;

                //
                // Restore the saved CAN Control register.
                //
                CanbRegs.CAN_CTL.all = canControlValue;

                //
                // Return the computed bit rate.
                //
                return(sourceClock / ( preDivide * canBits));
            }
        }

        //
        // Move the divisor up one and look again.  Only in rare cases are
        // more than 2 loops required to find the value.
        //
        desiredRatio++;
    }
    return 0;
}
//
// setupMessageObject - Setup message object as Transmit or Receive
//
void setupCanAMessageObject(uint32_t objID,uint32_t msgIDMsk,uint16_t messageSize,uint32_t msgID, msgObjType msgType)
{
    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
    
    //
    // Wait for busy bit to clear.
    //
    while(CanaRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Clear and Write out the registers to program the message object.
    //
    CAN_IF1CMD_SHADOW.all = 0;    
    CanaRegs.CAN_IF1MSK.all = 0;
    CanaRegs.CAN_IF1ARB.all = 0;
    CanaRegs.CAN_IF1MCTL.all = 0;

    //
    // Set the Control, Mask, and Arb bit so that they get transferred to the
    // Message object.
    //
    CAN_IF1CMD_SHADOW.bit.Control = 1;
    CAN_IF1CMD_SHADOW.bit.Arb = 1;
    CAN_IF1CMD_SHADOW.bit.Mask = 1;
    CAN_IF1CMD_SHADOW.bit.DIR = 1;

    //
    // Set direction to transmit
    //
    if(msgType == MSG_OBJ_TYPE_TRANSMIT)
    {
        CanaRegs.CAN_IF1ARB.bit.Dir = 1;
    }
	/*if(msgType == MSG_OBJ_TYPE_RECEIVE)
    {
        CanaRegs.CAN_IF1ARB.bit.Dir = 0;
    }*/

	//
    // Set Message ID (this example assumes 11 bit ID mask)
    //
	CanaRegs.CAN_IF1MSK.bit.MXtd = 1;
	CanaRegs.CAN_IF1MSK.bit.MDir = 1;
    CanaRegs.CAN_IF1MSK.bit.Msk = msgIDMsk;
    CanaRegs.CAN_IF1MCTL.bit.UMask = 1;
    //
    // Set Message ID (this example assumes 29 bit ID mask)
    //
	CanaRegs.CAN_IF1ARB.bit.Xtd = 1;
    CanaRegs.CAN_IF1ARB.bit.ID = msgID;
    CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;

    //
    // Set the data length since this is set for all transfers.  This is
    // also a single transfer and not a FIFO transfer so set EOB bit.
    //
    CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanaRegs.CAN_IF1MCTL.bit.EoB = 1;

    //
    // Transfer data to message object RAM
    //
    CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
    CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
}
//
// setupMessageObject - Setup message object as Transmit or Receive
//
void setupCanBMessageObject(uint32_t objID,uint32_t msgIDMsk,uint16_t messageSize,uint32_t msgID, msgObjType msgType)
{
    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
    
    //
    // Wait for busy bit to clear.
    //
    while(CanbRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Clear and Write out the registers to program the message object.
    //
    CAN_IF1CMD_SHADOW.all = 0;    
    CanbRegs.CAN_IF1MSK.all = 0;
    CanbRegs.CAN_IF1ARB.all = 0;
    CanbRegs.CAN_IF1MCTL.all = 0;

    //
    // Set the Control, Mask, and Arb bit so that they get transferred to the
    // Message object.
    //
    CAN_IF1CMD_SHADOW.bit.Control = 1;
    CAN_IF1CMD_SHADOW.bit.Arb = 1;
    CAN_IF1CMD_SHADOW.bit.Mask = 1;
    CAN_IF1CMD_SHADOW.bit.DIR = 1;

    //
    // Set direction to transmit
    //
    if(msgType == MSG_OBJ_TYPE_TRANSMIT)
    {
        CanbRegs.CAN_IF1ARB.bit.Dir = 1;
    }
	/*if(msgType == MSG_OBJ_TYPE_RECEIVE)
    {
        CanaRegs.CAN_IF1ARB.bit.Dir = 0;
    }*/

	//
    // Set Message ID (this example assumes 11 bit ID mask)
    //
    CanbRegs.CAN_IF1MSK.bit.MXtd = 1;
    CanbRegs.CAN_IF1MSK.bit.MDir = 1;
    CanbRegs.CAN_IF1MSK.bit.Msk = msgIDMsk;
    CanbRegs.CAN_IF1MCTL.bit.UMask = 1;
    //
    // Set Message ID (this example assumes 11 bit ID mask)
    //
	CanbRegs.CAN_IF1ARB.bit.Xtd = 1;
    CanbRegs.CAN_IF1ARB.bit.ID = msgID;
    CanbRegs.CAN_IF1ARB.bit.MsgVal = 1;

    //
    // Set the data length since this is set for all transfers.  This is
    // also a single transfer and not a FIFO transfer so set EOB bit.
    //
    CanbRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanbRegs.CAN_IF1MCTL.bit.EoB = 1;

    //
    // Transfer data to message object RAM
    //
    CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
    CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
}
//
// setupMessageObject - Transmit data from the specified message object
//
Uint32 CanA_baudrate = 500000;
Uint32 CanB_baudrate = 500000;
void ECan_MObjectInit(void)
{
	uint32_t messageSize;
	union CanWord_Type MessageID;
	CanA_baudrate = (Uint32)Can_BaudRate * 1000;

	setCANABitRate(200000000,CanA_baudrate);

	//
    // Enable the CAN for operation.
    //
    CanaRegs.CAN_CTL.bit.Init = 0;

	//
    // Initialize the message object that will be used for sending CAN
    // messages.
    //
	//PCS To EMS Set
	MessageID.DataInt = CAN_MSG_ID_EMS_Tx;
    //ID_Addr = 0x01;
	//MessageID.bit.SRCADDR = ID_Addr;
	//MessageID.bit.DSTADDRL = EMS_Addr & 0x0f;
	//MessageID.bit.DSTADDRH = (EMS_Addr >>4) & 0x0f;
	messageSize = sizeof(ucTXMsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_TX_MSG_OBJ_EMS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT);
	MessageID.DataInt = CAN_MSG_ID_EMS_Rx;
	//MessageID.bit.SRCADDR = EMS_Addr;
	//MessageID.bit.DSTADDRL = ID_Addr & 0x0f;
	//MessageID.bit.DSTADDRH = (ID_Addr >>4) & 0x0f;
	messageSize = sizeof(ucRXMsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_RX_MSG_OBJ_EMS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE);
	
	//PCS To STS Set 
	MessageID.DataInt = CAN_MSG_ID_STS_Tx;
	messageSize = sizeof(ucTX2MsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_TX_MSG_OBJ_STS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT);
	MessageID.DataInt = CAN_MSG_ID_STS_Rx;
	messageSize = sizeof(ucRX2MsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_RX_MSG_OBJ_STS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE);
	
	//PCS To PCS(During the grid connection process, the slave sends battery current, 
	//and the host receives and calculates the total battery current.)
	MessageID.DataInt = CAN_MSG_ID_PCSDC_Tx;
	MessageID.bit.CNT = Can_BT;         //Battery cluster number
	MessageID.bit.SRCADDR = ID_Addr;    //Slave address
	messageSize = sizeof(ucTX3MsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_TX_MSG_OBJ_PCSOne,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT);
	MessageID.DataInt = CAN_MSG_ID_PCSDC_Rx;
	MessageID.bit.CNT = Can_BT;         //Battery cluster number
	messageSize = sizeof(ucRX3MsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_RX_MSG_OBJ_PCSOne,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE);
	/*
	//PCS To PCS锛圥arallel and offgrid hosts send running status锛夆�斺�擟ANA
	MessageID.DataInt = CAN_MSG_ID_PCSSet_Tx;
	messageSize = sizeof(ucTX4MsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_TX_MSG_OBJ_PCSTwo,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT);
	MessageID.DataInt = CAN_MSG_ID_PCSSet_Rx;
	messageSize = sizeof(ucRX4MsgData);          // Message Size (DLC)
    setupCanAMessageObject(CANA_RX_MSG_OBJ_PCSTwo,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE);
	*/
}
void ECan_RegInit_Internal()
{
    uint32_t messageSize;
    union CanWord_Type MessageID;
    CanB_baudrate = (Uint32)CanB_BaudRate1 * 1000;
    setCANBBitRate(200000000,CanB_baudrate);
    CanbRegs.CAN_CTL.bit.Init = 0;
    //PCS To PCS (Parallel fast communication interface)-CANB
    MessageID.DataInt = CAN_MSG_ID_PCS_Tx;
    messageSize = sizeof(ucTX5MsgData);          // Message Size (DLC)
    setupCanBMessageObject(CANB_TX_MSG_OBJ_PCS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT);
    MessageID.DataInt = CAN_MSG_ID_PCS_Rx;
    messageSize = sizeof(ucRX5MsgData);          // Message Size (DLC)
    setupCanBMessageObject(CANB_RX_MSG_OBJ_PCS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE);

    //PCS To PCS (Parallel fast communication interface)-CANB
    MessageID.DataInt = CAN_MSG_ID_PCS_Tx2;
    MessageID.bit.CNT = Can_BT;
    messageSize = sizeof(ucTX9MsgData);          // Message Size (DLC)
    setupCanBMessageObject(CANB_TX_MSG_OBJ_PCS2,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT);
    MessageID.DataInt = CAN_MSG_ID_PCS_Rx2;
    MessageID.bit.CNT = Can_BT;
    messageSize = sizeof(ucRX9MsgData);          // Message Size (DLC)
    setupCanBMessageObject(CANB_RX_MSG_OBJ_PCS2,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE);
}
//
// sendCANMessage - Transmit data from the specified message object
//
void sendCANAMessage(uint32_t objID,Uint8 *TXMsgData)
{
    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
	union CAN_IF1ARB_REG CAN_IF1ARB_SHADOW;
    
    //
    // Wait for busy bit to clear.
    //
    while(CanaRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Write data to transfer into DATA-A and DATA-B interface registers
    //
	
	CanaRegs.CAN_IF1DATA.bit.Data_0 = *TXMsgData;
	CanaRegs.CAN_IF1DATA.bit.Data_1 = *(TXMsgData + 1);
	CanaRegs.CAN_IF1DATA.bit.Data_2 = *(TXMsgData + 2);
	CanaRegs.CAN_IF1DATA.bit.Data_3 = *(TXMsgData + 3);
	CanaRegs.CAN_IF1DATB.bit.Data_4 = *(TXMsgData + 4);
	CanaRegs.CAN_IF1DATB.bit.Data_5 = *(TXMsgData + 5);
	CanaRegs.CAN_IF1DATB.bit.Data_6 = *(TXMsgData + 6);
	CanaRegs.CAN_IF1DATB.bit.Data_7 = *(TXMsgData + 7);

    //
    // Set Direction to write and set DATA-A/DATA-B to be transfered to
    // message object
    //
    CAN_IF1CMD_SHADOW.all = 0;
    CAN_IF1CMD_SHADOW.bit.DIR = 1;
    CAN_IF1CMD_SHADOW.bit.DATA_A = 1;
    CAN_IF1CMD_SHADOW.bit.DATA_B = 1;
	
	/*CAN_IF1ARB_SHADOW.bit.Dir = 1;
	CAN_IF1ARB_SHADOW.bit.Xtd = 1;
    CAN_IF1ARB_SHADOW.bit.ID = msgID;
    CAN_IF1ARB_SHADOW.bit.MsgVal = 1;
	
	CanaRegs.CAN_IF1ARB.all = CAN_IF1ARB_SHADOW.all;*/
    //
    // Set Tx Request Bit
    //
    CAN_IF1CMD_SHADOW.bit.TXRQST = 1;
    //
    // Transfer the message object to the message object specified by
    // objID.
    //
    CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
    CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
	
	
}
//
// sendCANMessage - Transmit data from the specified message object
//
void sendCANBMessage(uint32_t objID,Uint8 *TXMsgData)
{
    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
    
    //
    // Wait for busy bit to clear.
    //
    while(CanbRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Write data to transfer into DATA-A and DATA-B interface registers
    //
	CanbRegs.CAN_IF1DATA.bit.Data_0 = *TXMsgData;
	CanbRegs.CAN_IF1DATA.bit.Data_1 = *(TXMsgData + 1);
	CanbRegs.CAN_IF1DATA.bit.Data_2 = *(TXMsgData + 2);
	CanbRegs.CAN_IF1DATA.bit.Data_3 = *(TXMsgData + 3);
	CanbRegs.CAN_IF1DATB.bit.Data_4 = *(TXMsgData + 4);
	CanbRegs.CAN_IF1DATB.bit.Data_5 = *(TXMsgData + 5);
	CanbRegs.CAN_IF1DATB.bit.Data_6 = *(TXMsgData + 6);
	CanbRegs.CAN_IF1DATB.bit.Data_7 = *(TXMsgData + 7);

    //
    // Set Direction to write and set DATA-A/DATA-B to be transfered to
    // message object
    //
    CAN_IF1CMD_SHADOW.all = 0;
    CAN_IF1CMD_SHADOW.bit.DIR = 1;
    CAN_IF1CMD_SHADOW.bit.DATA_A = 1;
    CAN_IF1CMD_SHADOW.bit.DATA_B = 1;

    //
    // Set Tx Request Bit
    //
    CAN_IF1CMD_SHADOW.bit.TXRQST = 1;

    //
    // Transfer the message object to the message object specified by
    // objID.
    //
    CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
    CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
}
//
// getCANMessage - Check the message object for new data.
//                 If new data, data written into array and return true.
//                 If no new data, return false.
//
uint16_t getCANAMessage(uint32_t objID,uint32_t *ui32ArbReg,Uint8 *ucRXMsgData)
{
    uint16_t status;
    //
    // Use Shadow variable for IF2CMD. IF2CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF2CMD_REG CAN_IF2CMD_SHADOW;

    //
    // Set the Message Data A, Data B, and control values to be read
    // on request for data from the message object.
    //
    CAN_IF2CMD_SHADOW.all = 0;
    CAN_IF2CMD_SHADOW.bit.Control = 1;
    CAN_IF2CMD_SHADOW.bit.DATA_A = 1;
    CAN_IF2CMD_SHADOW.bit.DATA_B = 1;
	CAN_IF2CMD_SHADOW.bit.Arb = 1;       //Enable reading of arbitration bits

    //
    // Transfer the message object to the message object IF register.
    //
    CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID;
    CanaRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all;

    //
    // Wait for busy bit to clear.
    //
    while(CanaRegs.CAN_IF2CMD.bit.Busy)
    {
    }

	*ui32ArbReg = CanaRegs.CAN_IF2ARB.all;
    //
    // See if there is new data available.
    //
    if(CanaRegs.CAN_IF2MCTL.bit.NewDat == 1)
    {
        //
        // Read out the data from the CAN registers.
        //
        Test1U32=CanaRegs.CAN_IF2DATA.all;
        Test2U32=CanaRegs.CAN_IF2DATB.all;
        *ucRXMsgData = Test1U32 & 0xFF;
        *(ucRXMsgData+1) = (Test1U32 & 0xFF00) >> 8;
        *(ucRXMsgData+2) = (Test1U32 & 0xFF0000) >> 16;
        *(ucRXMsgData+3) = (Test1U32 & 0xFF000000) >> 24;
        *(ucRXMsgData+4) = Test2U32 & 0xFF;
        *(ucRXMsgData+5) = (Test2U32 & 0xFF00) >> 8;
        *(ucRXMsgData+6) = (Test2U32 & 0xFF0000) >> 16;
        *(ucRXMsgData+7) = (Test2U32 & 0xFF000000) >> 24;
        /*
		*ucRXMsgData = CanaRegs.CAN_IF2DATA.bit.Data_0;
		*(ucRXMsgData+1) = CanaRegs.CAN_IF2DATA.bit.Data_1;
		*(ucRXMsgData+2) = CanaRegs.CAN_IF2DATA.bit.Data_2;
		*(ucRXMsgData+3) = CanaRegs.CAN_IF2DATA.bit.Data_3;
		*(ucRXMsgData+4) = CanaRegs.CAN_IF2DATB.bit.Data_4;
		*(ucRXMsgData+5) = CanaRegs.CAN_IF2DATB.bit.Data_5;
		*(ucRXMsgData+6) = CanaRegs.CAN_IF2DATB.bit.Data_6;
		*(ucRXMsgData+7) = CanaRegs.CAN_IF2DATB.bit.Data_7;
		*/
        //
        // Populate Shadow Variable
        //
        //CAN_IF2CMD_SHADOW.all = CanaRegs.CAN_IF2CMD.all;
        CAN_IF2CMD_SHADOW.all = 0;
        CAN_IF2CMD_SHADOW.bit.Control = 1;
        //CAN_IF2CMD_SHADOW.bit.DATA_A = 1;
        //CAN_IF2CMD_SHADOW.bit.DATA_B = 1;
        CAN_IF2CMD_SHADOW.bit.Arb = 1;       //Enable reading of arbitration bits
        //
        // Clear New Data Flag
        //
        CAN_IF2CMD_SHADOW.bit.TxRqst = 1;

        //
        // Transfer the message object to the message object IF register.
        //
        CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID;
        CanaRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all;

        status = true;
        CanaRegs.CAN_IF2MCTL.bit.NewDat = 0;
    }
    else
    {
        status = false;
    }

    return(status);
}
//
// getCANMessage - Check the message object for new data.
//                 If new data, data written into array and return true.
//                 If no new data, return false.
//
uint16_t getCANBMessage(uint32_t objID,uint32_t *ui32ArbReg,Uint8 *ucRXMsgData)
{
    uint16_t status;
    //
    // Use Shadow variable for IF2CMD. IF2CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF2CMD_REG CAN_IF2CMD_SHADOW;

    //
    // Set the Message Data A, Data B, and control values to be read
    // on request for data from the message object.
    //
    CAN_IF2CMD_SHADOW.all = 0;
    CAN_IF2CMD_SHADOW.bit.Control = 1;
    CAN_IF2CMD_SHADOW.bit.DATA_A = 1;
    CAN_IF2CMD_SHADOW.bit.DATA_B = 1;
    CAN_IF2CMD_SHADOW.bit.Arb = 1;
    //
    // Transfer the message object to the message object IF register.
    //
    CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID;
    CanbRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all;

    //
    // Wait for busy bit to clear.
    //
    while(CanbRegs.CAN_IF2CMD.bit.Busy)
    {
    }
	*ui32ArbReg = CanbRegs.CAN_IF2ARB.all;
    //
    // See if there is new data available.
    //
    if(CanbRegs.CAN_IF2MCTL.bit.NewDat == 1)
    {
        //
        // Read out the data from the CAN registers.
        //
        Test3U32=CanbRegs.CAN_IF2DATA.all;
        Test4U32=CanbRegs.CAN_IF2DATB.all;
        *ucRXMsgData = Test3U32 & 0xFF;
        *(ucRXMsgData+1) = (Test3U32 & 0xFF00) >> 8;
        *(ucRXMsgData+2) = (Test3U32 & 0xFF0000) >> 16;
        *(ucRXMsgData+3) = (Test3U32 & 0xFF000000) >> 24;
        *(ucRXMsgData+4) = Test4U32 & 0xFF;
        *(ucRXMsgData+5) = (Test4U32 & 0xFF00) >> 8;
        *(ucRXMsgData+6) = (Test4U32 & 0xFF0000) >> 16;
        *(ucRXMsgData+7) = (Test4U32 & 0xFF000000) >> 24;
        /*
		*ucRXMsgData = CanbRegs.CAN_IF2DATA.bit.Data_0;
		*(ucRXMsgData+1) = CanbRegs.CAN_IF2DATA.bit.Data_1;
		*(ucRXMsgData+2) = CanbRegs.CAN_IF2DATA.bit.Data_2;
		*(ucRXMsgData+3) = CanbRegs.CAN_IF2DATA.bit.Data_3;
		*(ucRXMsgData+4) = CanbRegs.CAN_IF2DATB.bit.Data_4;
		*(ucRXMsgData+5) = CanbRegs.CAN_IF2DATB.bit.Data_5;
		*(ucRXMsgData+6) = CanbRegs.CAN_IF2DATB.bit.Data_6;
		*(ucRXMsgData+7) = CanbRegs.CAN_IF2DATB.bit.Data_7;
        */
        //
        // Populate Shadow Variable
        //
        //CAN_IF2CMD_SHADOW.all = CanbRegs.CAN_IF2CMD.all;
        CAN_IF2CMD_SHADOW.all = 0;
        CAN_IF2CMD_SHADOW.bit.Control = 1;
        //CAN_IF2CMD_SHADOW.bit.DATA_A = 1;
        //CAN_IF2CMD_SHADOW.bit.DATA_B = 1;
        CAN_IF2CMD_SHADOW.bit.Arb = 1;
        //
        // Clear New Data Flag
        //
        CAN_IF2CMD_SHADOW.bit.TxRqst = 1;

        //
        // Transfer the message object to the message object IF register.
        //
        CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID;
        CanbRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all;

        status = true;
        CanbRegs.CAN_IF2MCTL.bit.NewDat = 0;
    }
    else
    {
        status = false;
    }

    return(status);
}
//
// End of file
//