Jetson Orin Nano MCP2515 CAN bitrate problem (Jetson Linux 36.3)

Kernel version : jetson-linux 36.3
Platform : Jetson Orin Nano Devkit (SD card)

Hello!
I am trying to make use of MCP2515 to enable additional CAN bus.
I followed the example on Jetson/L4T/peripheral/ - eLinux.org, which was referred on multiple forum posts. Thanks to that tutorial, I have managed to enable can1 and can2 on my Jetson Orin Nano(SD card).

$ sudo ip link set can0 up type can bitrate 1000000
$ sudo ip link set can1 up type can bitrate 1000000
$ sudo ip link set can2 up type can bitrate 1000000

$ cansend can0 0FF#01.01.01.01.01.01.01.01
$ cansend can1 0FF#01.01.01.01.01.01.01.01
$ cansend can2 0FF#01.01.01.01.01.01.01.01

However, when I compared the CAN msg on an oscilloscope, there is a bitrate difference between the native CAN bus(can0) and the MCP2515 driven CAN bus(can1, can2).
The difference is shown as below. channel 1(yellow) is can1, channel 2(green) is can0.

fig.1 can1 and can0 sending the same message mentioned above (1Mbps)

fig.2 zoomed in picture of can1 and can0. both showing the length of 1 bit (1Mbps)

can0 reads fine. The length of 1 bit is 1μs, which is the right value since all CAN bus is set to 1Mbps. However, it seems the bitrate on MCP2515 CAN bus is about 3 times slower than the settings, showing 3μs per bit.

I tried 100kbps, 500kbps, 1Mbps and it all bitrates had the same results.

I hardly doubt that this problem stems from the MCP2515’s hardware, since I ran test with the same MCP2515 modules on Arduino Mega and Arduino Due. Both cases used the mcp_can library by coryjfowler, a C++ Arduino library.
I even modified the mcp_can library using JETGPIO by Rubberazer to test MCP2515 on Jetson Orin Nano, and in that test, it still had no problems with the CAN msg bitrate.

I also tried altering the SPI max speed tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi from 2Mbps(based on the eLinux tutorial) to 10Mbps, to match the MCP2515’s max SPI communication speed. But this did not change a thing.

Since, this is my first time modifying and using a Jetson Orin Nano, any help or comments would be very thankful.

Hi SpiralCrab,

Do you mean that there’s similar issue when you are using MCP2515 module with Arduino?

Please share the steps how did you setup CAN interface for both internal can0 (mttcan) and external can1(MCP2515 module).
And the result of following commands from your board.

$ sudo ip -d -s link show can0
$ sudo ip -d -s link show can1
1 Like

Hello KevinFFF,

thanks for the fast reply!

I never had the same problem when using the MCP2515 module with the Arduino.

The steps I took to setup can0 was simple :

### loading the mods for can
$ modprobe can
$ modprobe can_raw
$ modprobe mttcan

### setting up can0 with a bitrate of 1Mbps
$ sudo ip link set can0 up type can bitrate 1000000
### sending a can message(8 byte) through can0 for testing purpose
$ cansend can0 0FF#01.01.01.01.01.01.01.01

For can1 and can2, I followed the Jetson/L4T/peripheral/ - eLinux.org, and here is a brief summary :

  1. changed settings on tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi according to the website
  2. changed settings on defconfig according to the website
  3. build and flashed a custom kernel that contains the modified dtsi, defconfig on my Jetson Orin Nano
  4. enabled SPI using jetson-io.py and reboot
  5. Connect the MCP2515 module on SPI0
  6. setup can1 just like can0
### loading the mods for can
$ modprobe can
$ modprobe can_raw
$ modprobe mttcan
$ modprobe mcp251x

### setting up can 1 with a bitrate of 1Mbps
$ sudo ip link set can1 up type can bitrate 1000000

### sending a message for testing purpose
$ cansend can1 0FF#01.01.01.01.01.01.01.01

The results for the commands that you showed me are shown below:

$ sudo ip -d -s link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can  promiscuity 0 minmtu 0 maxmtu 0 
    can state ERROR-PASSIVE (berr-counter tx 128 rx 0) restart-ms 0 
	  bitrate 1000000 sample-point 0.740 
	  tq 20 prop-seg 18 phase-seg1 18 phase-seg2 13 sjw 1
	  mttcan: tseg1 2..255 tseg2 0..127 sjw 1..127 brp 1..511 brp-inc 1
	  mttcan: dtseg1 1..31 dtseg2 0..15 dsjw 1..15 dbrp 1..15 dbrp-inc 1
	  clock 50000000 
	  re-started bus-errors arbit-lost error-warn error-pass bus-off
	  0          0          0          1          1          0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 parentbus platform parentdev c310000.mttcan 
    RX:  bytes packets errors dropped  missed   mcast           
            16       2      0       0       0       0 
    TX:  bytes packets errors dropped carrier collsns           
             0       0      0       0       0       0 
$ sudo ip -d -s link show can1
5: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can  promiscuity 0 minmtu 0 maxmtu 0 
    can state ERROR-PASSIVE restart-ms 0 
	  bitrate 961538 sample-point 0.692 
	  tq 80 prop-seg 4 phase-seg1 4 phase-seg2 4 sjw 1
	  mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
	  clock 12500000 
	  re-started bus-errors arbit-lost error-warn error-pass bus-off
	  0          0          0          1          1          0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 parentbus spi parentdev spi0.0 
    RX:  bytes packets errors dropped  missed   mcast           
             0       0      0       0       0       0 
    TX:  bytes packets errors dropped carrier collsns           
             0       0      0       0       0       0 

Thanks for your help, I can see that the clock speed is different(mttcan with 50000000, mcp251x with 12500000). But I’m not sure which clock is this referring to. The can_clock in tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi was set just as the eLinux verification page:

can_clock: can_clock{
        compatible = "fixed-clock";
        #clock-cells = <0>;
        clock-frequency = <25000000>;
        clock-accuracy = <100>;

yes, the bitrate, sample-point and clock rate should be similar for both side to confirm they are sending/receiving with same rate.

Please modify the following line to check if it could help.

can_clock: can_clock{
        compatible = "fixed-clock";
        #clock-cells = <0>;
-        clock-frequency = <25000000>;
+        clock-frequency = <100000000>;
        clock-accuracy = <100>;
1 Like

Sorry for the late reply,

I tried your suggestion and it got me an error code of -34 from mcp251x while booting.
It seems the can clock frequency is capped in between 100000 - 25000000 according to a post : mcp251x: Probe failed (spi0.0), with Error -34 · Issue #3610 · raspberrypi/linux · GitHub

However, thanks to your suggestion, I did figure out that I should type in the oscillator frequency on the MCP2515 module. I tested both 16 MHz and 8 MHz, and 8 MHz worked, which is the same frequency with the oscillator on my MCP2515 module.

Somehow the can bitrate is capped to 500kbps when I use 8 MHz for the can clock frequency. It seems the mcp251x.c only supports up to 500kbps when the can clock is 8 MHz. Kind of strange considering when mcp_can library for Arduino supports 1Mbps at can clock frequency of 8 MHz. I’ll just change the oscillator on the MCP2515 module from 8 MHz to 16 MHz later.

Anyway, Thank you for helping me out!

And Happy Holidays!