Cannot transmit CAN message on Jetson Nano with MCP2515

Hi,

I have interfaced an MCP2515 (with an 8 MHz crystal) to the Jetson Nano. I am able to receive CAN messages correctly as long as I do not transmit anything from the Jetson Nano.

However, when I try to transmit a CAN frame from the Jetson Nano, the MCP2515 does not send the message onto the CAN bus and Jetson Nano also does not receive any messages afterward. In Vector CANoe, I do not see any CAN errors at any time. This suggests that the MCP2515 is failing to transmit rather than encountering a bus-level error.

I also connected a logic analyser to the INT pin of MCP2515 and observed that, after attempting to transmit, the INT pin stays low permanently. I think it may because for some reason Jetson Nano isn’t reading the received message from the MCP2515 and clearing the interrupt. So the INT pin stays low. This doesn’t happen if don’t send any message after setting up CAN on Jetson Nano. When its low, I think the mcp251x driver reads the data and clears the interrupt and thus INT pin goes high after a few milliseconds.

I tested this on jetpack 4.6.1 and 4.6.2 and in both I am facing the same issue.. Any higher jetson pack, SPI doesn’t seems to work. The bootloader update is causing the SPI to don’t work. As I can’t use SDK manager to install the OS, I followed this quickstart guide to flash the OS.

I have attached the DTS files, dmesg logs, and screenshots for reference.
While setting up CAN on the Jetson Nano, I also noticed another issue — right after bringing up the CAN interface, the Jetson Nano receives a random CAN frame with ID 0x00, even though no node on the bus is transmitting such a message. This frame appears only once after receiving the very first CAN message.

dmesg.log (68.5 KB)

output.dts.txt (321.4 KB)

Hi Abhijith45,

Are you using the devkit or custom board for Jetson Nano?

I don’t see CAN related error in the dmesg you shared.

Could you share the result of the following command on your board when you hit CAN transmission issue?

$ sudo ip -d -s link show can0

Please also share the block diagram of your connection for the current test.
Are you connecting 2 MCP2515 together for the transaction?

I am currently using Jetson Nano Devkit and connected 2 MCP2515. I am getting the same issue even if only one MCP2515 is connected.

SPI 1 Pin connections
24 - CS
19 - SI
21 - SO
23 - SCK

SPI 2 Pin connections
13 - SCK
37 - SI
22 - SO
18 - CS

After setting up can0 and can1 using the below commend:
sudo ip link set up can0 type can bitrate 500000
sudo ip link set up can1 type can bitrate 500000

4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
0 0 0 0 0 0
TX: bytes packets errors dropped carrier collsns
0 0 0 0 0 0

5: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
0 0 0 0 0 0
TX: bytes packets errors dropped carrier collsns
0 0 0 0 0 0

After receiving the a couple of can messages to both can interfaces

4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
16 9 0 0 0 0
TX: bytes packets errors dropped carrier collsns
18446744073709551615 1 0 0 0 0

5: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
14 8 0 0 0 0
TX: bytes packets errors dropped carrier collsns
18446744073709551615 1 0 0 0 0

After trying to send a couple of messages from both can interfaces

4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
16 9 0 0 0 0
TX: bytes packets errors dropped carrier collsns
18446744073709551615 1 0 0 0 0

5: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
24 13 0 0 0 0
TX: bytes packets errors dropped carrier collsns
18446744073709551615 1 0 0 0 0

I don’t see the unexpected state of CAN or the error/dropped packaet in the result you shared.

Which pin you used for 2 MCP2515 module respectively?
Have you configured those pinmux before use?

I have connected the INT pins of both MCP2515 to pin 31 and 32. Then I connected a logic analyzer to pins of one of the MCP2515 just to see if any messages are been transferred. It is then I noticed that the INT pin stays low all as soon it receives a CAN message after I try to send a CAN message.

I configured the device tree using the jetson-io.py tool. After launching the tool, I selected the MCP2515 CAN controller from the compatible hardware list, applied the changes, and rebooted the system.

Next, I copied the newly generated DTB file from the /boot directory and decompiled it to a DTS file. I updated the oscillator clock frequency from 16 MHz to 8 MHz, then recompiled it into a DTB with a new filename. I placed this updated DTB file back into the /boot directory, modified the extlinux.conf entry to point to the new DTB filename, and rebooted.

Do you mean that you use the following 2 pins as interrupt for 2 MCP2515 module?
image
If so, have you configured their pinmux from pinmux spreadsheet before use?

Is the behavior the same for both interrupts? Or just PIN32 hit this issue?

The INT pin of the MCP2515 connected to SPI0 pins is connected to the 31 pin in the 40pin header and other MCP2515 INT pin is connected to the 32 pin the 40 pin header.

Yes. I’ve attached the screenshot of the logic analyser results. The first low-to-high transition occurs when I send a CAN message to one of the MCP2515 modules individually. After that, I tried sending a single CAN message from both MCP2515 modules one at a time, and then again sending a CAN message to each module one at a time. From the screenshot, you can see that after a trying to send a CAN message and then a message is received, the INT pins on both MCP2515 modules remain low.

They are pulled down by unknown reason in your case. I guess if it may be caused from internal Pull-down.

It seems you configured interrupt with IRQ_TYPE_EDGE_RISING(0x1).
Could you try using IRQ_TYPE_LEVEL_LOW(0x8) instead?

		spi@0 {
-			interrupts = <0xc8 0x1>;
+			interrupts = <0xc8 0x8>;
			interrupt-parent = <0x5b>;
			clocks = <0x131>;
			nvidia,rx-clk-tap-delay = <0x7>;
			nvidia,enable-hw-based-cs;
			compatible = "microchip,mcp2515";
			..

I updated the DTS to use IRQ_TYPE_LEVEL_LOW, but that change alone didn’t resolve the issue. However, after disabling spi@1 (spidev configuration), I was able to successfully transmit and receive CAN messages. I also disabled SPI1 during this test. Since I only need one mcp2515, I haven’t check if by disabled the spi@1 of SPI1 would also make the second MCP2515 work. I’ve also kept the interrupt trigger configured as IRQ_TYPE_LEVEL_LOW.