SPI CAN with L4T 32.4.4 on Jetson NANO eMMC

Hi,

I’m trying to enable SPI CAN on NANO, and have followed some topics related, but things just don’t work out.

Use Pin 110, 108, 104, 106 (SPI1_CS0, SPI1_MISO, SPI1_MOSI, SPI1_SCK) and an interrupt pin 130 to MCP2515.

I altered some files as below:

 .../tegra210-porg-gpio-p3448-0002-b00.dtsi         |  6 +----
 .../tegra210-porg-pinmux-p3448-0002-b00.dtsi       |  8 +++----
 .../kernel-dts/tegra210-porg-p3448-common.dtsi     | 28 ++++++++++++++++++----
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0002-b00.dtsi b/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0002-b00.dtsi
index ac8bda8..650b165 100644
--- a/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0002-b00.dtsi
+++ b/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0002-b00.dtsi
@@ -27,10 +27,6 @@
 		gpio_default: default {
 			gpio-input = <
 				TEGRA_GPIO(BB, 0)
-				TEGRA_GPIO(B, 4)
-				TEGRA_GPIO(B, 5)
-				TEGRA_GPIO(B, 6)
-				TEGRA_GPIO(B, 7)
 				TEGRA_GPIO(DD, 0)
 				TEGRA_GPIO(E, 6)
 				TEGRA_GPIO(S, 5)
@@ -58,6 +54,7 @@
 				TEGRA_GPIO(H, 2)
 				TEGRA_GPIO(H, 5)
 				TEGRA_GPIO(H, 6)
+				TEGRA_GPIO(I, 0)
 				TEGRA_GPIO(CC, 4)
 				>;
 			gpio-output-low = <
@@ -67,7 +64,6 @@
 				TEGRA_GPIO(H, 3)
 				TEGRA_GPIO(H, 4)
 				TEGRA_GPIO(H, 7)
-				TEGRA_GPIO(I, 0)
 				TEGRA_GPIO(I, 2)
 				>;
 			gpio-output-high = <
diff --git a/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-pinmux-p3448-0002-b00.dtsi b/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-pinmux-p3448-0002-b00.dtsi
index 60e5bb4..109a069 100644
--- a/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-pinmux-p3448-0002-b00.dtsi
+++ b/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-pinmux-p3448-0002-b00.dtsi
@@ -505,7 +505,7 @@
 
 			spi2_mosi_pb4 {
 				nvidia,pins = "spi2_mosi_pb4";
-				nvidia,function = "rsvd2";
+				nvidia,function = "spi2";
 				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -513,7 +513,7 @@
 
 			spi2_miso_pb5 {
 				nvidia,pins = "spi2_miso_pb5";
-				nvidia,function = "rsvd2";
+				nvidia,function = "spi2";
 				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -521,7 +521,7 @@
 
 			spi2_sck_pb6 {
 				nvidia,pins = "spi2_sck_pb6";
-				nvidia,function = "rsvd2";
+				nvidia,function = "spi2";
 				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
@@ -529,7 +529,7 @@
 
 			spi2_cs0_pb7 {
 				nvidia,pins = "spi2_cs0_pb7";
-				nvidia,function = "rsvd2";
+				nvidia,function = "spi2";
 				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
diff --git a/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi b/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi
index 57cb90c..dcb2ac9 100644
--- a/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi
+++ b/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi
@@ -205,8 +205,17 @@
 		};
 	};
 
+	can_clock: can_clock{
+		phandle = <0x12c>;
+		linux,phandle = <0x12c>;
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <8000000>;
+		clock-accuracy = <100>;
+	};
+
 	spi@7000d400 { /* SPI 1 to 40 pin header */
-		status = "okay";
+		status = "disabled";
 		spi@0 {
 			compatible = "spidev";
 			reg = <0x0>;
@@ -229,13 +238,24 @@
 
 	spi@7000d600 { /* SPI 2 to 40 pin header */
 		status = "okay";
+		num-cs = <1>;
+		cs-gpios = <&gpio TEGRA_GPIO(B, 7) GPIO_ACTIVE_LOW>;
 		spi@0 {
-			compatible = "spidev";
+			status = "okay";
+			compatible = "microchip,mcp2515";
 			reg = <0x0>;
-			spi-max-frequency = <33000000>;
+			clocks = <&can_clock>;
+			interrupt-parent = <&gpio>;
+			interrupts = <TEGRA_GPIO(I, 0) 0x01>;
+			vdd-supply = <&battery_reg>;
+			xceiver-supply = <&battery_reg>;
+			spi-max-frequency = <10000000>;
 			controller-data {
 				nvidia,enable-hw-based-cs;
-				nvidia,rx-clk-tap-delay = <6>;
+				nvidia,cs-setup-clk-count = <0x1e>;
+				nvidia,cs-hold-clk-count = <0x1e>;
+				nvidia,rx-clk-tap-delay = <0x1f>;
+				nvidia,tx-clk-tap-delay = <0x0>;
 			};
 		};
 		spi@1 {
-- 
2.7.4

0001-modify-for-SPI-CAN.patch (4.3 KB)

Then update pinmux as Pinmux Changes as follow:

6.Rebuild the device tree image:
    $ cd <src_path>/kernel/kernel-4.9/
    $ make ARCH=arm64 tegra_defconfig
    $ make ARCH=arm64 dtbs
7.Copy the updated device tree image to the L4T release tree:
    $ cp arch/arm64/boot/dts/tegra210-p3448-0002-p3449-0000-b00.dtb <path-to-L4T-release>/kernel/dtb/

And flash,

sudo ./flash.sh -r -k DTB jetson-nano-emmc mmcblk0p1
sudo ./flash.sh -r -k RP1 jetson-nano-emmc mmcblk0p1

Now check on target.

~$ sudo cat /sys/kernel/debug/pinctrl/pinctrl-handles | grep spi2
    type: MUX_GROUP controller 700008d4.pinmux group: spi2_mosi_pb4 (37) function: spi2 (55)
    type: CONFIGS_GROUP controller 700008d4.pinmux group spi2_mosi_pb4 (37)config pull=1
    type: MUX_GROUP controller 700008d4.pinmux group: spi2_miso_pb5 (38) function: spi2 (55)
    type: CONFIGS_GROUP controller 700008d4.pinmux group spi2_miso_pb5 (38)config pull=1
    type: MUX_GROUP controller 700008d4.pinmux group: spi2_sck_pb6 (39) function: spi2 (55)
    type: CONFIGS_GROUP controller 700008d4.pinmux group spi2_sck_pb6 (39)config pull=1
    type: MUX_GROUP controller 700008d4.pinmux group: spi2_cs0_pb7 (40) function: spi2 (55)
    type: CONFIGS_GROUP controller 700008d4.pinmux group spi2_cs0_pb7 (40)config pull=1
    type: MUX_GROUP controller 700008d4.pinmux group: spi2_cs1_pdd0 (41) function: rsvd1 (42)
    type: CONFIGS_GROUP controller 700008d4.pinmux group spi2_cs1_pdd0 (41)config pull=1

~$ sudo grep "Name:\|I:\| B:" /sys/kernel/debug/tegra_gpio
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
 B: 0:1 80 80 80 80 00 00 000000
 I: 2:0 07 07 03 00 00 00 000000

But get the result:

~$ dmesg | grep spi
[    0.448818] iommu: Adding device 7000d600.spi to group 7
[    3.689779] mcp251x spi1.0: Cannot initialize MCP2515. Wrong wiring?
[    3.698816] mcp251x spi1.0: Probe failed, err=19

Have followed threads below, but SPI CAN never worked.

Any help is appreciated.
Thanks,

hello imbrandon,

since Nano using device tree for board configuration,
please just update device tree (DTB) partition, you may exclude your step which updating RP1 partition.

could you please disassembler your device tree blob (*.dtb file) into text file for examination.
for example, $ dtc -I dtb -O dts -o output.txt tegra210-p3448-0002-p3449-0000-b00.dtb

Hi Jerry,

Thank you for your reply.
Disassembled device tree as follow: output.txt (324.2 KB)
The original dtb: tegra210-p3448-0002-p3449-0000-b00.dtb (236.1 KB)
Thank again.

hello imbrandon,

could you please also refer to Topic 111323 for the patch to address SPI bug.

Hi Jerry,

I had patched the drivers/spi/spi-tegra114.c as below
static int tegra_spi_transfer_one_message(struct spi_master *master,
struct spi_message *msg)
.
.
complete_xfer:
#if 1
cmd1 = tspi->command1_reg;
#else
if (prefer_last_used_cs)
cmd1 = tspi->command1_reg;
else
cmd1 = tspi->def_command1_reg;
#endif
if (ret < 0 || skip) {
if (cstate && cstate->cs_gpio_valid)
gpio_set_value(spi->cs_gpio, gval);
tegra_spi_writel(tspi, cmd1, SPI_COMMAND1);
tegra_spi_transfer_delay(xfer->delay_usecs);
goto exit;
} else if (list_is_last(&xfer->transfer_list,
.
.
.
But I still get the error message,
[ 1.024106] tegradc tegradc.0: Bootloader disp_param detected. Detected mode: 1920x1080 (on 0x0mm) pclk=148350781
[ 1.024946] of_fixed_clk: probe of can_clock failed with error -17
[ 1.027408] tegradc tegradc.0: probed
Andw
[ 4.538082] mcp251x spi1.0: setup 8 bpw, ~cpol, ~cpha, 65000000Hz
[ 4.538125] mcp251x spi1.0: setup mode 0, 8 bits/w, 65000000 Hz max → 0
[ 4.550742] spi-tegra114 7000d600.spi: Setting clk_src pll_p
[ 4.550805] spi-tegra114 7000d600.spi: The def 0x43d08000 and written 0x43e01807
[ 4.555876] spi-tegra114 7000d600.spi: The def 0x43d08000 and written 0x43e01807
[ 4.555944] mcp251x spi1.0: Cannot initialize MCP2515. Wrong wiring?
[ 4.581421] mcp251x spi1.0: Probe failed, err=19

Thanks.

hello jason_yang,

you may also check into the probing function to understand which paragraph cause MCP2515 initialization failed.

Hi Jerry,

I think it should be the pinmux setting issue, since we can’t see the SPI signal on oscilloscope.

Thanks.

There is no update from you for a period, assuming this is not an issue any more.
Hence we are closing this topic. If need further support, please open a new one.
Thanks

Could you try the SPI loopback test to check it.

And not sure why your GPIO PB7 still enable.

Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
B: 0:1 80 80 80 80 00 00 000000