How to configure and use CAN bus

This page explains how to enable the CAN bus on ODROID-N2/C4 via HW SPI interface.
Detail instruction to exchange data with a MCP2515 Bus Monitor board is also documented.
can_bus

The following products are required to configure the hardware:

ODROID-N2/C4, Tinkering Kit, MCP2515 CAN module

ODROID-N2 ODROID-C4
C Tinkering Kit mcp2515

Reference circuit

Connect CAN module and ODROID-N2/C4 using tinkering kit

[NOTE 1] D1 Diode
The diode serially connected is NOT needed if mcp2515 CAN Module is loaded/initialized without issue.
In the case of ODROID-C4 5V power supply from pin2 or pin4 is designed 5.207V.
Depends on the board slightly has supplied about 5.3V or something above while it's booting.
That behavior has made the driver probe failed of the CAN module. If you were having trouble with it under ODROID-C4, consider placing a common diode serially has a forward voltage of 0.7V or less.
(In the examination, 30mA current supply to the CAN module from ODROID-C4 pin 2 or pin 4 therefore a forward voltage was about 0.3V at the diode 1N5819.)
Sometimes, even using a long dupont cable is could be a solution.

☞ Download Fritzing parts mcp2515_canwthinkeringb.fzz

  • Operation confirmed with ODROID-N2 ubuntu minimal image on 4.9.236-104 kernel on now 20th November 2020.
  • Operation confirmed with ODROID-C4 ubuntu minimal image on 4.9.236-51 kernel on now 20th November 2020.
  • The can-bus example uses the same cs-pin as spidev, so both must not be enabled at the same time.
  • If spidev is enabled, the can-bus may not work properly.
  • The can-bus example uses device tree overlays and SPI host interface. Assigned cs-pin on the spidev module is 0(zero) and can_dev used by mcp251x is 1(one).
root@odroid:~# apt update && apt full-upgrade

Apply Device tree overlay

Add the text “can0”-can(zero)- on the Device Tree Overlay section in your file located at /media/boot/config.ini.

    .
    .
    88
    89  ; Device Tree Overlay
    90  overlay_resize=16384
    91  overlay_profile=
    92  overlays="spi0 i2c0 i2c1 uart0 can0"
    93
    .
    .

Then reboot to apply the changes. You can check if the modules loaded.

root@odroid:~# dmesg | grep spi
[    5.034462] meson-spicc ffd13000.spi: registered master spi0
[    5.034626] spi spi0.1: setup mode 0, 8 bits/w, 10000000 Hz max --> 0
[    5.034745] meson-spicc ffd13000.spi: registered child spi0.1
[    5.034768] spi spi0.0: setup mode 0, 8 bits/w, 100000000 Hz max --> 0
[    5.034863] meson-spicc ffd13000.spi: registered child spi0.0
[    9.297674] mcp251x spi0.1: setup mode 0, 8 bits/w, 10000000 Hz max --> 0
[    9.352688] mcp251x spi0.1 can0: MCP2515 successfully initialized.
root@odroid:~# lsmod | grep spi
spidev                 20480  0
spi_meson_spicc        20480  0
root@odroid:~# lsmod | grep mcp251x
mcp251x                24576  0
can_dev                24576  1 mcp251x
root@odroid:~#
Verify the CAN host driver is registered correctly
root@odroid:~# ls /sys/class/net/
can0  eth0  lo
root@odroid:~# ifconfig can0
can0: flags=128<NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
root@odroid:~# 
Power on CAN hardware

Set the bitrate before all operations Example: Set the bitrate of the can0 interface to 125kbps:

root@odroid:~# ip link set can0 type can bitrate 125000 triple-sampling on
root@odroid:~# ifconfig can0 up
root@odroid:~# ifconfig
can0: flags=193<UP,RUNNING,NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.8  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::e160:7710:5360:f82a  prefixlen 64  scopeid 0x20<link>
        ether 02:00:00:0d:1d:01  txqueuelen 1000  (Ethernet)
        RX packets 24  bytes 6066 (6.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 54  bytes 6420 (6.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 22  
 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 129  bytes 10117 (10.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 129  bytes 10117 (10.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
root@odroid:~#
Installing SocketCAN utils

can-utils package is a collection of CAN drivers and networking tools for Linux. It allows interfacing with CAN bus devices in a similar fashion as other network devices.

sudo apt install can-utils
Loopback test on a single CAN port

loopback mode on can0

ifconfig can0 down
ip link set can0 type can bitrate 125000 loopback on
ifconfig can0 up
ip -details link show can0
root@odroid:~# ifconfig can0 down
root@odroid:~# ip link set can0 type can bitrate 125000 loopback on
root@odroid:~# ifconfig can0 up
root@odroid:~# ip -details link show can0
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 10
    link/can  promiscuity 0 
    can <LOOPBACK,TRIPLE-SAMPLING> state ERROR-ACTIVE restart-ms 0 
          bitrate 125000 sample-point 0.850 
          tq 400 prop-seg 8 phase-seg1 8 phase-seg2 3 sjw 1
          mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
          clock 5000000numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
root@odroid:~# 

The following command shows the received message from the CAN bus

candump can0

On second terminal, The following command sends 3 bytes on the bus (0x11, 0x22, 0x33) with the identifier 500.

cansend can0 500#11.22.33

Connect CANL, CANH pins of two ODROID-N2/C4 boards

The picture below works at the old version of kernel not using device tree overlay with the CS pin using pin number 24(CE0).
If you are using the latest version of the kernel 4.9.236-51 (27th Nov. 2020 now) with kernel device tree overlay, the CS pin should be connected at pin number 26(#118) like above reference_circuit.

CAN-bus link

Power-up both boards Type the following into the shell of both boards for configuration the CAN bus device:

ip link set can0 type can bitrate 125000 triple-sampling on
ifconfig can0 up

Type the following to the shell of board 1 (which is used for testing receiving over can0 device):

candump can0

Type the following to the shell of board 2 (which is used for testing sending data packets over can0 device):

cansend can0 500#11.22.33

At this point, board 1 will receive the data packet sent from board 2:

root@odroid:~# candump can0
  can0  500   [3]  11 22 33
  can0  500   [3]  11 22 33
2020/03/19 18:13 · luke.go