I’m working with a custom board designed to use the G120 module. This board provides access to the CAN1 port on the module (circuit attached). I have two of these boards, running identical code, connected together through CAN. I’m using the baud calculation from the Wiki. So both nodes on the bus have termination resistors in place and are using the same baud calculated value. My initialization code is shown below.
public void InitializeCAN()
{
Debug.Print("->Initializing CAN Bus...");
//initialize the can port.
can = new CAN(CAN.Channel.Channel_1, GetBitRateConfig_60MHZ(Bitrate.BITRATE_125k));
// create a message list of 10 incoming messages
rxMsgList = new CAN.Message[10];
for (int i = 0; i < rxMsgList.Length; i++)
rxMsgList[i] = new CAN.Message();
// create a message list of 5 outgoing messages
txMsgList = new CAN.Message[5];
for (int i = 0; i < txMsgList.Length; i++)
txMsgList[i] = new CAN.Message();
canErrors = 0;
canGoodPackets = 0;
// subscribe to events
can.DataReceivedEvent += new CANDataReceivedEventHandler(can_DataReceivedEvent);
can.ErrorReceivedEvent += new CANErrorReceivedEventHandler(can_ErrorReceivedEvent);
// Set the system time. CAN messages will have a time stamp
Utility.SetLocalTime(new DateTime(2011, 2, 14, 0, 0, 0));
//*********************************************************************
}
public uint GetBitRateConfig_60MHZ(Bitrate bitrate)
{
int t1 = 0;
int t2 = 0;
int brp = 0;
switch (bitrate)
{
case Bitrate.BITRATE_125k:
brp = 20;
t1 = 16 - 1;
t2 = 8;
break;
case Bitrate.BITRATE_250k:
brp = 10;
t1 = 16 - 1;
t2 = 8;
break;
case Bitrate.BITRATE_500k:
brp = 5;
t1 = 16 - 1;
t2 = 8;
break;
case Bitrate.BITRATE_1000k:
brp = 5;
t1 = 8 - 1;
t2 = 4;
break;
}
uint returnValue = (uint)(((t2 - 1) << 20) | ((t1 - 1) << 16) | ((brp - 1) << 0));
return returnValue;
}
/// <summary>
/// CAN error receive event handler.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
void can_ErrorReceivedEvent(CAN sender, CANErrorReceivedEventArgs args)
{
canErrors++;
//ledState = true; //force the led on
//Debug.Print(">>> can_ErrorReceivedEvent <<<");
switch (args.Error)
{
case CAN.Error.Overrun:
Debug.Print("Overrun error. Message lost");
break;
case CAN.Error.RXOver:
Debug.Print("RXOver error. Internal buffer is full. Message lost");
break;
case CAN.Error.BusOff:
Debug.Print("BusOff error. Reset CAN controller.");
sender.Reset();
break;
}
}
I have a loop sending out a CAN packet 20 times per sec.
public void SendCANMessageIO()
{
byte inputs_0to7 = 0;
byte inputs_8to15 = 0;
txMsgList[0].ArbID = OUTGOINGCANID_CONTROLLER; //set the packet ID
//build the IO 0-7 byte
if (!Input00.Read()) inputs_0to7 |= 0x01;
if (!Input01.Read()) inputs_0to7 |= 0x02;
if (!Input02.Read()) inputs_0to7 |= 0x04;
if (!Input03.Read()) inputs_0to7 |= 0x08;
if (!Input04.Read()) inputs_0to7 |= 0x010;
if (!Input05.Read()) inputs_0to7 |= 0x020;
if (!Input06.Read()) inputs_0to7 |= 0x040;
if (!Input07.Read()) inputs_0to7 |= 0x080;
txMsgList[0].Data[0] = inputs_0to7;
//build the IO 8-15 byte
if (!Input08.Read()) inputs_8to15 |= 0x01;
if (!Input09.Read()) inputs_8to15 |= 0x02;
if (!Input10.Read()) inputs_8to15 |= 0x04;
if (!Input11.Read()) inputs_8to15 |= 0x08;
if (!Input12.Read()) inputs_8to15 |= 0x010;
if (!Input13.Read()) inputs_8to15 |= 0x020;
if (!Input14.Read()) inputs_8to15 |= 0x040;
if (!Input15.Read()) inputs_8to15 |= 0x080;
txMsgList[0].Data[1] = inputs_8to15;
txMsgList[0].Data[2] = 3;
txMsgList[0].Data[3] = 4;
txMsgList[0].Data[4] = 5;
txMsgList[0].Data[5] = 6;
txMsgList[0].Data[6] = 7;
txMsgList[0].Data[7] = 8;
txMsgList[0].DLC = 8;
txMsgList[0].IsEID = false;
txMsgList[0].IsRTR = false;
int numberOfMessagesPosted = can.PostMessages(txMsgList, 0, 1); //send the message out
}
My problem is that I’m constantly getting “BusOff” errors. I know my cable is good, as I took it from a working system. Any suggestions on where I could be going wrong? I have validated proper voltage on the MCP2551 chip and all the board traces are going to their intended locations.