Cannot get can-bus to work on G120 demo board

Hi,

This is my first go with any GHI products. I recently ordered up a FEZ Cobra 2 REV B to demo the G120 SOC setup.

I’m trying to get the CAN bus to work. I’m using a MCP2551 Can Transceiver. I cannot receive or transmit. When I transmit I get a CAN Bus “Bus-Off error”. I’m running the latest firmware.

I can see data on both sides of the transceiver through both a scope and logic analyzer, which leads me to believe its a issue with code or the G120 itself.

I have also tried two different setups with the MCP2551 which I have included the schematics for.

The logicdata can be downloaded from (http://sdrv.ms/1gj7QKk) and the code is below.

Any help would be greatfully appreciated!

[em] Note: I have a 2 known good can analyzers on the same bus, once sending, and one is listen only mode. I can view the data being sent on my separate receiver no problem. (Both are based on the MCP2515 & MCP2551 chipsets.)[/em]

using System;
using System.Threading;
using GHI.Premium.Hardware;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace MFConsoleApplication1
{
    public class Program
    {
        private static CAN.Message[] msgList;

        public static void Main()
        {
            //First lets set date/time
            Utility.SetLocalTime(new DateTime(2013, 09, 15, 08, 55, 00));

            uint bitRate = GetBitRateConfig_120MHZ(Bitrate.BITRATE_500k);

            CAN can = new CAN(CAN.Channel.Channel_2, bitRate);
            

            can.DataReceivedEvent += can_DataReceivedEvent;
            can.ErrorReceivedEvent += can_ErrorReceivedEvent;

            int clock = 1;

            CAN.Message sendMessage = new CAN.Message();

            while (true)
            {
                sendMessage.ArbID = 0x7E5;

                sendMessage.Data[0] = (byte)clock;
                sendMessage.Data[1] = 0x78;
                sendMessage.Data[2] = 0x5F;
                sendMessage.Data[3] = 0xFF;
                sendMessage.Data[4] = 0x3B;
                sendMessage.Data[5] = 0x00;
                sendMessage.Data[6] = 0x00;
                sendMessage.Data[7] = 0x4C;

                if (clock == int.MaxValue - 1)
                    clock = 0;

                clock ++;

                CAN.Message[] messages = new[] {sendMessage};

                int numberMessagesPosted = can.PostMessages(messages, 0, messages.Length);
                var test = can.TransmitErrorCount;

                if(test> 1)
                    Debug.Print(test.ToString());

                Thread.Sleep(500);
            }
        }

        private static void can_ErrorReceivedEvent(CAN sender, CANErrorReceivedEventArgs args)
        {
            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;
            }
        }

        private static void can_DataReceivedEvent(CAN sender, CANDataReceivedEventArgs args)
        {
            Debug.Print(">>> can_DataReceivedEvent <<<");

            // read as many messages as possible
            int count = sender.GetMessages(msgList, 0, msgList.Length);
            for (int i = 0; i < count; i++)
            {
                string m = ("Data: " + msgList[i].Data[0].ToString("X") + " " + msgList[i].Data[1].ToString("X") + " " + msgList[i].Data[2].ToString("X") + " " + msgList[i].Data[3].ToString("X") + " "
                            + msgList[i].Data[3].ToString("X") + " " + msgList[i].Data[4].ToString("X") + " " + msgList[i].Data[5].ToString("X") + " " + msgList[i].Data[6].ToString("X") + " "
                            + msgList[i].Data[7].ToString("X"));
                Debug.Print("MSG: ID = " + msgList[i].ArbID + "DATA: " + m + "  at time = " + msgList[i].TimeStamp);
            }
        }


        public enum Bitrate
        {
            NONE = 0,
            BITRATE_125k = 125000,
            BITRATE_250k = 250000,
            BITRATE_500k = 500000,
            BITRATE_1000k = 1000000,
        }

        /// <summary>
        /// Returns a bitrate for the internal CAN driver
        /// </summary>
        /// <param name="bitrate">Bitrate</param>
        /// <returns>CAN driver bitrate for LPC17XX</returns>
        public static uint GetBitRateConfig_120MHZ(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;
            }

            return (uint) (((t2 - 1) << 20) | ((t1 - 1) << 16) | ((brp - 1) << 0));
        }
    }
}

Only one of my schematics attached. Here is the second schematic I have tried.

Have you tried a different bitrate? Tried to send from G120 channel1 to channe2? I am guessing it is bit timing issue. And do not forget the termination resistor(s).

Here is a good read as well: Can we use Linux or a Mac for development? – GHI Electronics

Welcome to the community.

Your schematic does not have VSS (GND) connected? This will prevent the device from working correctly.

Is this implied in the PCB software? It’s always good practice to connect it physically on the schematic just to be sure.

If this is OK, one of the biggest issues with CAN is that the sampling point has to be the same for all devices. I have not started CAN on the G120 yet (that’s coming soon) so I am not sure which sampling point the source you listed is using. If for instance this is 75% and your MCP2515 is using 87.5% then they won’t talk. 87.5% is CAN OPEN and/or DEVICENET spec and generally what I see code written for.

Hi Gus, Thanks for Welcoming me to the community.

I did read that document. (Its where i got bit timing code from).

I did try to send CAN traffic between Chl1 and Chl2 just by tying TD to RD, and visa versa between the two channels. (No transceiver) This did not work, and threw the following exception.

>>> can_ErrorReceivedEvent <<< Chl 1
BusOff error. Reset CAN controller.
>>> can_ErrorReceivedEvent <<< Chl 2
BusOff error. Reset CAN controller.

Good catch. It is however tied to Ground. I have attached my updated Drawings to reflect this. There is a termination on the bus.

Sampling point is 75% for all nodes.

-Thanks again everyone for the responses!

I also just tried setting up two MCP2551 transceivers (One for Channel one, the other for channel 2)

When I try to transmit, I still get the following exception.

>>> can_ErrorReceivedEvent <<< Chl 1
BusOff error. Reset CAN controller.

Here is my code as it stands now trying to make the two channels talk to each other.

using System;
using System.Threading;
using GHI.Premium.Hardware;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace MFConsoleApplication1
{
    public class Program
    {
        private static CAN.Message[] msgList;

        public static void Main()
        {
            //First lets set date/time
            Utility.SetLocalTime(new DateTime(2013, 09, 15, 08, 55, 00));

            uint bitRate = GetBitRateConfig_120MHZ(Bitrate.BITRATE_500k);

            CAN can = new CAN(CAN.Channel.Channel_1, bitRate);

            CAN canTwo = new CAN(CAN.Channel.Channel_2, bitRate);

            can.DataReceivedEvent += can_DataReceivedEvent;
            can.ErrorReceivedEvent += can_ErrorReceivedEvent;

            canTwo.DataReceivedEvent += canTwo_DataReceivedEvent;
            canTwo.ErrorReceivedEvent += canTwo_ErrorReceivedEvent;

            int clock = 1;

            CAN.Message sendMessage = new CAN.Message();

            
            sendMessage.ArbID = 0x7E5;

            sendMessage.Data[0] = (byte)clock;
            sendMessage.Data[1] = 0x78;
            sendMessage.Data[2] = 0x5F;
            sendMessage.Data[3] = 0xFF;
            sendMessage.Data[4] = 0x3B;
            sendMessage.Data[5] = 0x00;
            sendMessage.Data[6] = 0x00;
            sendMessage.Data[7] = 0x4C;

            if (clock == int.MaxValue - 1)
                clock = 0;

            clock ++;

            CAN.Message[] messages = new[] {sendMessage};

            int numberMessagesPosted = can.PostMessages(messages, 0, messages.Length);
            var test = can.TransmitErrorCount;

            if(test> 1)
                Debug.Print(test.ToString());

            Thread.Sleep(500);
            
        }

        static void canTwo_ErrorReceivedEvent(CAN sender, CANErrorReceivedEventArgs args)
        {
            Debug.Print(">>> can_ErrorReceivedEvent <<< Chl 2");

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

        static void canTwo_DataReceivedEvent(CAN sender, CANDataReceivedEventArgs args)
        {
            Debug.Print(">>> can_DataReceivedEvent <<< Chl 2");

            // read as many messages as possible
            int count = sender.GetMessages(msgList, 0, msgList.Length);
            for (int i = 0; i < count; i++)
            {
                string m = ("Data: " + msgList[i].Data[0].ToString("X") + " " + msgList[i].Data[1].ToString("X") + " " + msgList[i].Data[2].ToString("X") + " " + msgList[i].Data[3].ToString("X") + " "
                            + msgList[i].Data[3].ToString("X") + " " + msgList[i].Data[4].ToString("X") + " " + msgList[i].Data[5].ToString("X") + " " + msgList[i].Data[6].ToString("X") + " "
                            + msgList[i].Data[7].ToString("X"));
                Debug.Print("MSG: ID = " + msgList[i].ArbID + "DATA: " + m + "  at time = " + msgList[i].TimeStamp);
            }
        }

        private static void can_ErrorReceivedEvent(CAN sender, CANErrorReceivedEventArgs args)
        {
            Debug.Print(">>> can_ErrorReceivedEvent <<< Chl 1");

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

        private static void can_DataReceivedEvent(CAN sender, CANDataReceivedEventArgs args)
        {
            Debug.Print(">>> can_DataReceivedEvent <<< Chl 1");

            // read as many messages as possible
            int count = sender.GetMessages(msgList, 0, msgList.Length);
            for (int i = 0; i < count; i++)
            {
                string m = ("Data: " + msgList[i].Data[0].ToString("X") + " " + msgList[i].Data[1].ToString("X") + " " + msgList[i].Data[2].ToString("X") + " " + msgList[i].Data[3].ToString("X") + " "
                            + msgList[i].Data[3].ToString("X") + " " + msgList[i].Data[4].ToString("X") + " " + msgList[i].Data[5].ToString("X") + " " + msgList[i].Data[6].ToString("X") + " "
                            + msgList[i].Data[7].ToString("X"));
                Debug.Print("MSG: ID = " + msgList[i].ArbID + "DATA: " + m + "  at time = " + msgList[i].TimeStamp);
            }
        }


        public enum Bitrate
        {
            NONE = 0,
            BITRATE_125k = 125000,
            BITRATE_250k = 250000,
            BITRATE_500k = 500000,
            BITRATE_1000k = 1000000,
        }

        /// <summary>
        /// Returns a bitrate for the internal CAN driver
        /// </summary>
        /// <param name="bitrate">Bitrate</param>
        /// <returns>CAN driver bitrate for LPC17XX</returns>
        public static uint GetBitRateConfig_120MHZ(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;
        }

        return (uint) (((t2 - 1) << 20) | ((t1 - 1) << 16) | ((brp - 1) << 0));
    }
}

}

It was the MCP 2551 Transciver.

Switched out to a SN65HVD230D for 3.3 logic. I can at least send messages now.

Thanks!
-Matt

@ zeroaviation -
hello, I am doing almost the same thing as you did. G120 with CAN DW to send and receive messages.

I defined the G120 pins corresponding to its sockets pins to ensure it fits the C type socket by programming in C#, do I need to solder them physically?

What’s the usage of schematic?

Please answer my stupid question. thank you

@ andre.m -
Sorry, I am really new for this…

@ andre.m -
sorry, one more stupid question.
I just need to wire the related G120HDR pins with socket pins directly? Because, I saw zeroaviation posted some schematics, which I don’t understand…
Do I need to design a schematic or something?
Electronics is so difficult!!!

@ andre.m -
Thank youmechanical guy walks hard with tears on the road of electronics~so sad

It’s ok, we are here to help make that a bit easier, but my first suggestion is if you want to have less electronics requirement then the HDR boards are not the best, use a more full-featured device like the Spider since it has as many connections as you’re likely to need to connect modules to directly, with no manipulation.

@ Brett -
Thank you for your advice. You are right, but I am doing my thesis, and my professor let me do with G120HDR. I can’t choose.

@ Brett -
I used the program that zeroaviation posted here, but I can’t send and receive messages(by using CAN analyzer). I am using two CAN_DW modules, do I need to make any modification in the program?
in my out put window it is said:

Using mainboard GHI Electronics G120HDR version 2.0
Number of messages posted: 1
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0
Number of messages posted: 0 

I don’t know why~~~~

OK, so there’s a good chance that your problem is your wiring.

What equipment do you have access to - logic analysers or oscilloscopes? I am guessing that as you’re at Uni it’s likely you’d have that stuff somewhere. It’s probably worth finding out if the connections you have are expected to work - so you could start here by posting some photos of the way you have connections and describe why you connected what you did.

@ Brett -
My final goal is to build a gateway to get information from CAN bus and send to OBD2 devices. Of course, I need to make a conversion of information due to different protocols.
By now, I even can not send and receive one byte. I am testing to use socket 6 of G120 to send and receive messages. Any suggestions for me?
there are
no postdone event raised
no DataReceivedEvent raised
no ErrorReceivedEvent raised

@ Brett -
I try another codes, but still no use.

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;
using GHI.Premium.Hardware;



using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;




namespace GadgeteerApp2
{
    public partial class can_test
    {

        private static CAN.Message[] msgList ;
        void ProgramStarted()
        {
            can_dw2.InitializeCAN(15, 8, 20);
            

            //events            
            can_dw2.DataReceived += new CAN_DW.DataReceivedEventHandler(can_dw2_DataRecieved);
            can_dw2.ErrorReceived += new CAN_DW.ErrorReceivedEventHandler(can_dw2_ErrorRecieved);
            can_dw2.PostDone += new CAN_DW.PostMessagesDoneEventHandler(can_dw2_PostDone);

            // Create a new message list to fill out and send.
            can_dw2.msgList = new CAN.Message[15];

            // Loop through the messages and fill them out.
            for (int i = 0; i < can_dw2.msgList.Length; i++)
            {
                can_dw2.msgList[i] = new CAN.Message();
             
                can_dw2.msgList[i].ArbID = (uint)5;
                can_dw2.msgList[i].Data[0] = 0x16;
                can_dw2.msgList[i].DLC = 1;
                can_dw2.msgList[i].IsEID = false;
                can_dw2.msgList[i].IsRTR = false;
            }

            int numberOfMsgSent = 0;

            //Send all of the messages
            while (true)
            {
                // Post as many messages as possible.
                can_dw2.PostMessages(0, can_dw2.msgList.Length - numberOfMsgSent);
                

                // Record how many were sent.
                numberOfMsgSent += can_dw2.NumMessagesSent;

                // If we have sent all of the messgaes, break out of the loop.
                if (numberOfMsgSent == can_dw2.msgList.Length)
                    break;

                // Sleep to allow the messages time to transmit.
                Debug.Print("programing");
                System.Threading.Thread.Sleep(1000);
            }
        }


        void can_dw2_PostDone(int numPosted)
        {
            Debug.Print(numPosted.ToString() + " messages were posted");
        }


        void can_dw2_ErrorRecieved(CAN sender, CANErrorReceivedEventArgs args)
        {
            Debug.Print("CAN error received: " + args.Error.ToString());
        }


        void can_dw2_DataRecieved(CAN sender, CANDataReceivedEventArgs args)
        {
            Debug.Print(">>> can_DataReceivedEvent <<<");

            CAN.Message[] incMsg = new CAN.Message[25];

            for (int i = 0; i < incMsg.Length; i++)
            {
                incMsg[i] = new CAN.Message();
            }

            int numMessages = sender.GetMessages(incMsg, 0, incMsg.Length);

            // Process messages here
        }
    }
}

Now, I just want to send some message from G120 to Can analyzer, it is not possible. I controlled Pin 0.5 and it is possible to get some random data in Can analyzer Window on PC.

public class Program
    {
        public static void Main()
        {
            OutputPort port = new OutputPort(GHI.Hardware.G120.Pin.P0_5, false);
            while (true)
            {
                port.Write(!port.Read());
                Debug.Print("Pin P0.5: " + port.Read());
                Thread.Sleep(5);   
            }

            InputPort port1 = new InputPort(GHI.Hardware.G120.Pin.P0_4, true, Port.ResistorMode.Disabled);
            while (true)
            {
                Debug.Print("Pin P0.4" + port1.Read());
                Thread.Sleep(100);
            }
        }

but when I want to send some message from PC(Can analyzer to G120), there is no change of Pin0.4. I don’t know why!

I really need help!!!

Looking at the schematic for the G120HDR and the CAN_DW module, there is no connection for CAN on socket 6 of the G120HDR. Only CAN1_TD is present on this socket and it is not on the correct pin. There is no CAN1_RD connection at all.

As for the user connection, socket 4, I can’t see if you have wired up the CAN2_TD and CAN2_RD lines to this socket? This socket will work, but you need to connect it from the main headers. You only need 2 connections from CAN2_TD and CAN2_RD

This would explain why you are not seeing any sending on CAN2.

Try wiring up Socket 4 for CAN2 and you should at least see this on your analyser.

@ Dave McLaughlin -
Thank you, I am sorry, i did not post the detail picture of it. I have soldered the related socket pins with G120 CUP pins, and socket is in type C. The following codes and pictures show that.
and I modify the drive program of G120 the define the pins as follow:

 #region Socket 4

            socket = GT.Socket.SocketInterfaces.CreateNumberedSocket(4);
            socket.SupportedTypes = new[] {'C'};
            socket.CpuPins[3] = Pin.GPIO_NONE;
            socket.CpuPins[4] = Pin.P0_1;
            socket.CpuPins[5] = Pin.P0_0;
            socket.CpuPins[6] = Pin.GPIO_NONE;
            socket.CpuPins[7] = Pin.GPIO_NONE;
            socket.CpuPins[8] = Pin.GPIO_NONE;
            socket.CpuPins[9] = Pin.GPIO_NONE;

            //// A
            //GT.Socket.SocketInterfaces.SetAnalogInputFactors(socket, 3.3, 0, 12);
            //socket.AnalogInput3 = Cpu.AnalogChannel.ANALOG_2;
            //socket.AnalogInput4 = Cpu.AnalogChannel.ANALOG_1;
            //socket.AnalogInput5 = Cpu.AnalogChannel.ANALOG_0;

            //// I
            //// N/A

            //// T
            //// N/A

            //// X
            //socket.NativeI2CWriteRead = nativeI2C;

            GT.Socket.SocketInterfaces.RegisterSocket(socket);

            #endregion Socket 4

            #region Socket 5

            socket = GT.Socket.SocketInterfaces.CreateNumberedSocket(5);
            socket.SupportedTypes = new[] {'D'};
            socket.CpuPins[3] = Pin.GPIO_NONE;
            socket.CpuPins[4] = (Cpu.Pin) 14; // USB_A_N
            socket.CpuPins[5] = (Cpu.Pin) 31; // USB_A_P        
            socket.CpuPins[6] = Pin.GPIO_NONE;
            socket.CpuPins[7] = Pin.GPIO_NONE;
            socket.CpuPins[8] = Pin.GPIO_NONE;
            socket.CpuPins[9] = Pin.GPIO_NONE;

            //// U
            //socket.SerialPortName = "COM1";

            //// X
            //socket.NativeI2CWriteRead = nativeI2C;

            GT.Socket.SocketInterfaces.RegisterSocket(socket);

            #endregion Socket 5

            #region Socket 6

            socket = GT.Socket.SocketInterfaces.CreateNumberedSocket(6);
            socket.SupportedTypes = new[] {'C'};
            socket.CpuPins[3] = Pin.GPIO_NONE;
            socket.CpuPins[4] = Pin.P0_5;
            socket.CpuPins[5] = Pin.P0_4;
            socket.CpuPins[6] = Pin.GPIO_NONE;
            socket.CpuPins[7] = Pin.GPIO_NONE;
            socket.CpuPins[8] = Pin.GPIO_NONE;
            socket.CpuPins[9] = Pin.GPIO_NONE;

            // S
            socket.SPIModule = SPI.SPI_module.SPI2;

            // X
            socket.NativeI2CWriteRead = nativeI2C;

            GT.Socket.SocketInterfaces.RegisterSocket(socket);

            #endregion Socket 6

            #endregion Socket Setup

@ a31415926

Sorry to go a little off topic. What size are the standoffs you’re using on the CAN DW boards?