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


