SPI-CAN interface using MCP2515 for Jetpack 4.5.1

Hi… I have been struggling ** to interface Jetson Nano with MCP2551 using SPI GPIO for CAN bus connection**. from past few days. I have been following the link provided on previous link. Also, some more link i went thoroughly includes

Topics tagged can-bus

but somehow the information is sparse and not clear for “ latest version ” of Jetpack.

I have been trying to create 1 CAN node on Jetson nano and other node is connected to STM board. However, the communication is not established. So for debug purpose, I started to 2 CAN node on Jetson nano itself and establish a communication in between two nodes.
As for hardware connection, Two MCP2515 are connected with each other using 2 wire CAN_H& CAN_L. SPI connections are connected on SPI1 and SPI2 on 40 pin header. Plus, for interrupt, I have used Pin31(for SPI1) & Pin32(SPI2).

My questions are 1) Is pinmux changes are required if we are using jetpack-io.py file?
2) When using jetpack-io.py, DTB file is generated. how to generate .dtbo file from that? and how to convert it into back .dts file?

I would really appreciate if correct steps can be provided on Jetson nano (b00).

Hi poonam,
Please follow the doc: https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_can.html#wwpID0ELHA

You do not need to update pinmux. Jetson-io tool will do it when you select MCP
DTB will be generated and used when system reboots after selecting MCP. So, configuration should have been done. Still if you want to change some data in dtb, you can decompile using dtc command.
sudo dtc -I dtb <your_dtb.dtb> -o <test.dts>
Edit in test.dts
convert back to dtb: sudo dtc -I dts test.dts -O dtb -o <your_dtb.dtb>

Thanks,
Shubhi

Hi, Actually I referred the steps given on documentation. After just reboot, in extlinux.conf the .dtb file is selected. however, as per document CAN node is not visible in network.

Can you paste what commands have you run with their outputs? also increase dmesg log level.

  1. Fresh write image in new SD card https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write

  2. 5V, GND to both MCP → connected pin 31 & 32 to INT pins of 2 MCP

3. sudo /opt/nvidia/jetson-io/jetson-io.pyConfigure Jetson for compatible hardware → select MCP251x → if asked boot otherwise →

  Configuration saved to file                     |
     |/boot/tegra210-p3448-0000-p3449-0000-b00-mcp251x-can-controller.dtb
  1. sudo /opt/nvidia/jetson-io/jetson-io.py → Configure 40-pin expansion header → save and reboot

  2. ifconfig → to check can0, can1 node,

  3. cat /boot/extlinux/extlinux.conf → to check active dtb file

TIMEOUT 30
DEFAULT MCP251x CAN Controller

MENU TITLE L4T boot options

LABEL primary
MENU LABEL primary kernel
LINUX /boot/Image
INITRD /boot/initrd
APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

When testing a custom kernel, it is recommended that you create a backup of

the original kernel and add a new entry to this file so that the device can

fallback to the original kernel. To do this:

1, Make a backup of the original kernel

sudo cp /boot/Image /boot/Image.backup

2, Copy your custom kernel into /boot/Image

3, Uncomment below menu setting lines for the original kernel

4, Reboot

LABEL backup

MENU LABEL backup kernel

LINUX /boot/Image.backup

INITRD /boot/initrd

APPEND ${cbootargs}

LABEL JetsonIO
MENU LABEL Custom 40-pin Header Config
LINUX /boot/Image
FDT /boot/tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb
INITRD /boot/initrd
APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

LABEL MCP251x CAN Controller
MENU LABEL MCP251x CAN Controller
LINUX /boot/Image
FDT /boot/tegra210-p3448-0000-p3449-0000-b00-mcp251x-can-controller.dtb
INITRD /boot/initrd
APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

I have one more question, when the main folder for dtb file should be from*/boot/dtb/*, the file above shows the current active file in /boot/ folder. Does that means do i have to change it into /boot/dtb/ folder?

1.Connect the MCP device’s INT pin to the Jetson Nano carrier board’s 40‑pin expansion header. -OK

There are two SPI controllers with pin-outs on the 40‑pin expansion header.

•To use SPI1, connect INT to the 40‑pin expansion header’s pin 31. - OK connected one MCP2515 INT (connected with 5V-GND)

•To use SPI2, connect INT to the 40‑pin expansion header’s pin 32. - OK connected second MCP2515 INT (connected with 5V-GND)

2.Start the Jetson-IO tool on the Jetson device.

3.Go to the hardware section of the Jetson‑IO interface and select the MCP device. - OK

4.Reboot the Jetson device when Jetson‑IO prompts you to do so. - OK

Until is okay but how much time I try running these commands can node just not show up. My hardware connection i have tried multiple times. They seems all correct. anyway only INT Pins and power supply signal is connected so not a chance of any confusion. Still i cross checked multiple times

5.After the Jetson device reboots, check the network connections. If the device has connected correctly to the network it shows two CAN nodes, CAN0 and CAN1. Watch for nodes that should not be present as well as nodes that are missing.

Hi… Any updates?

If the device has connected correctly to the network it shows two CAN nodes, CAN0 and CAN1. Watch for nodes that should not be present as well as nodes that are missing.

can you please elaborate this? or any other steps missing which should be take care?

what are other prerequisite in software i.e. particular driver file should be present at particular folder! or maybe some commands should run in particular sequence? Please update.

Hello poonam,

you said anyway only INT Pins and power supply signal is connected
SPI connections are not there?

@shgarg
Thank you for your response. As per step 1,Connect the MCP device’s INT pin to the Jetson Nano carrier board’s 40‑pin expansion header, I have connected only INT, 5V and GND of MCP to the jetson nano.

and then ran command sudo /opt/nvidia/jetson-io/jetson-io.py

Hi,
You need to connect SPI connections also. Sorry, if it is confusing from doc, we will update.
But without SPI connections, it will not work.

OK… I will connect all pins at once and then run the JetsonIO Tool → and Hardware=MCP select. Then will update you.

I did revised the above steps with all the pins connected on the jetson nano. SPI pins are visible on the Jetson IO tool. Interrupt pin are 31 and 32 for two MCPs.

This is also one doubt which seems confusing. Our main .dtb file runs from the ‘/boot/dtb’ then why our generated file is stored in ‘/boot/’ folder instead of ‘/boot/dtb/’? Do we need to change the place of our new generated file to /boot/dtb?
if yes, how the changes will reflect in our boot sequence of new_location_of_dtb?

On my DTS file i am able to see one can0 nod, which seems confusing to me. As it should be one of SPI node instead of separate can0 node. It would be helpful if you can explain if it is okay or not!

spi@7000d400 {
		compatible = "nvidia,tegra210-spi";
		clocks = <0x26 0x29 0x26 0xf3 0x26 0xe9>;
		resets = <0x26 0x29>;
		clock-names = "spi", "pll_p", "clk_m";
		nvidia,clk-parents = "pll_p", "clk_m";
		status = "okay";
		#address-cells = <0x1>;
		interrupts = <0x0 0x3b 0x4>;
		#size-cells = <0x0>;
		dma-names = "rx", "tx";
		nvidia,always-hw-cs;
		phandle = <0x110>;
		reg = <0x0 0x7000d400 0x0 0x200>;
		iommus = <0x30 0xe>;
		pinctrl-0 = <0x13a>;
		dmas = <0x51 0xf 0x51 0xf>;
		reset-names = "spi";
		linux,phandle = <0x110>;
		pinctrl-names = "default";

		prod-settings {
			#prod-cells = <0x3>;

			prod_c_flash {
				prod = <0x4 0x3f 0x7>;
				status = "disabled";
			};

			prod {
				prod = <0x4 0xfff 0x0>;
			};

			prod_c_loop {
				prod = <0x4 0xfff 0x44b>;
				status = "disabled";
			};
		};

		spi@1 {
			compatible = "spidev";
			status = "okay";
			reg = <0x1>;
			spi-max-frequency = <0x1f78a40>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x7>;
			};
		};

		can@0 {
			compatible = "microchip,mcp2515";
			clocks = <0x13b>;
			status = "okay";
			interrupt-parent = <0x5b>;
			interrupts = <0xd 0x8>;
			phandle = <0x13c>;
			reg = <0x0>;
			spi-max-frequency = <0x989680>;

			controller-data {
				nvidia,tx-clk-tap-delay = <0x0>;
				nvidia,enable-hw-based-cs;
				nvidia,cs-hold-clk-count = <0x1e>;
				nvidia,cs-setup-clk-count = <0x1e>;
				nvidia,rx-clk-tap-delay = <0x1f>;
			};
		};

		spi@0 {
			compatible = "spidev";
			reg = <0x0>;
			spi-max-frequency = <0x1f78a40>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x7>;
			};
		};
	};

Edit : This might be some reference

header-40pin-spi0-pinmux {
		phandle = <0x13a>;

		pin19 {
			nvidia,enable-input = <0x1>;
			nvidia,pins = "spi1_mosi_pc0";
			nvidia,tristate = <0x0>;
			nvidia,function = "spi1";
			nvidia,pull = <0x1>;
		};

		pin23 {
			nvidia,enable-input = <0x1>;
			nvidia,pins = "spi1_sck_pc2";
			nvidia,tristate = <0x0>;
			nvidia,function = "spi1";
			nvidia,pull = <0x1>;
		};

		pin21 {
			nvidia,enable-input = <0x1>;
			nvidia,pins = "spi1_miso_pc1";
			nvidia,tristate = <0x0>;
			nvidia,function = "spi1";
			nvidia,pull = <0x1>;
		};

		pin24 {
			nvidia,enable-input = <0x1>;
			nvidia,pins = "spi1_cs0_pc3";
			nvidia,tristate = <0x0>;
			nvidia,function = "spi1";
			nvidia,pull = <0x2>;
		};

		pin22 {
			nvidia,enable-input = <0x1>;
			nvidia,pins = "spi2_miso_pb5";
			nvidia,tristate = <0x0>;
			nvidia,function = "rsvd2";
			nvidia,pull = <0x2>;
		};
	};

Hi poonam,
Please do not update any dtb manually. We have made it easy for you using jetson-io tool.
In tool, you have 2 options, configure for compatible hardware and 40-pin header
Choose compatible hardware, select MCP and reboot. If connections are made properly, you will see CAN nodes in ifconfig.
Jetson IO tool applies all the dtb settings for the hardware chosen on top of main dtb and gives us new dtb which you can see in extlinux.conf
Main dtb file should also be in /boot and new dtb should also be in /boot.
Please reset all your dtb settings, for that, delete dtb which is created by Jetson IO tool from /boot/ folder and use tool again to recreate. Kindly follow the procedure from the doc mentioned before.
Let me know if you find any issues.

Thanks,
Shubhi

Hi,
Thanks for your reply.
Our MCP module is using 8MHz crystal and we used jetson b01 module. In this particular configuration, we have selected jetson IO tool and selected MCP from compatible hardware. And rebooted with the new dtb generated by IO tool.

After new changes are made,

  • on checking ifconfig can node is not visible

  • also cat /proc/interrupts | grep mcp not any interrupt pin is generated on mcp

  • on checking dmesg | grep mcp , getting following error
    image

  • hardware connections are made as follow,
    mcp 1 :
    pin 19 - mosi
    pin 21 - miso
    pin 23 - sck
    pin 24 - cs0
    pin 31 - INT

mcp 2 :
pin 37 - mosi
pin 22 - miso
pin 13 - sck
pin 18 - cs0
pin 32 - INT

mcp 1 and mcp 2 are connected CAN_H – CAN_H, and CAN_L – CAN_L.

Please suggest if any changes are required. Eagerly awaiting for your reply.

Thanks

This means mcp251x kernel driver version is not matching with the kernel image flashed.
May I know how have you flashed device? Also, you have compiled mcp driver on your own?

We have only used Jetson IO tool with selected mcp and booted the system with new hardware changes.

And we have not edited/changed any MCP driver files, How should we flash the device?

Please refer to NVIDIA Jetson Linux Developer Guide : Flashing and Booting the Target Device | NVIDIA Docs