Jetson agx orin JetPack_5.1.2 use SPI2

Hi,
My Jetson agx orin is currently using JetPack_5.1.2,
When I was using spi2, there was a problem, spi2 communication failed, and the output data waveform could not be measured with the oscilloscope.

Let me explain how I do it:
1.Check whether the pinmux file is normal,

2.Check my “tegra234 - soc - spi.dtsi”, its path is “/ source/Linux_for_Tegra/source/public/hardware/nvidia/soc/t23x/kernel-dts/tegra234 - soc /”

3.Load driver
sudo devmem2 0x0c302048 word 0x00000400
sudo devmem2 0x0c302050 word 0x00000450
sudo devmem2 0x0c302048 word 0x00000400
sudo devmem2 0x0c302028 word 0x00000400

sudo modprobe spide
4.run code

#define SPI_DEVICE_PATH "/dev/spidev2.0"
#define SPI_SPEED_HZ 1000000 // 500kHz
void handleError(const char *msg)
{
  perror(msg);
  exit(EXIT_FAILURE);
}
void spiTest()
{
  int spiDev = open(SPI_DEVICE_PATH, O_RDWR);
  if (spiDev < 0)
  {
    handleError("Unable to open the SPI device");
  }

  uint8_t mode = SPI_MODE_0;
  if (ioctl(spiDev, SPI_IOC_WR_MODE, &mode) < 0)
  {
    handleError("Unable to set the SPI mode");
  }

  uint32_t speed = SPI_SPEED_HZ;
  if (ioctl(spiDev, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
  {
    handleError("Unable to set the SPI rate");
  }
  struct spi_ioc_transfer spi;
  std::memset(&spi, 0, sizeof(spi));

  uint8_t txData[] = {0xAA, 0xBB}; 
  uint8_t rxData[sizeof(txData)];  
  spi.tx_buf = reinterpret_cast<unsigned long>(&txData); 
  spi.rx_buf = reinterpret_cast<unsigned long>(&rxData);
  spi.len = sizeof(txData);                              
  spi.delay_usecs = 0;                                   
  spi.speed_hz = speed;                                  
  spi.bits_per_word = 8;                                 

  while (true)
  {
    /* code */
    if (ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi) < 0)
    {
      handleError("SPI transfer failure");
    }
    printf("********Test SPIDEV2.0****** \n");
    printf("Tx Data: 0x%02X 0x%02X\n", txData[0], txData[1]);
    printf("Rx Data: 0x%02X 0x%02X\n", rxData[0], rxData[1]);

    usleep(1000 * 1000 * 1);
  }

  printf("Rx Data: 0x%02X 0x%02X\n", rxData[0], rxData[1]);

  close(spiDev);
}

When I used the SPI loopback test, it also didn’t work properly…

Hi,

When I load the driver, I can look up my SPI bus in /dev/…
image
image

Hi Andyyyyy,

Are you using the devkit or custom board for AGX Orin?

Do you have any modification in device tree for SPI?

Could your SPI1 work? (spidev0.0 and spidev0.1)

Hi,

I did not make any changes to the device tree of SPI, I used my custom version. I spent a day to verify whether there was any problem with my hardware circuit, and the result was that it had nothing to do with the hardware circuit.

SPI1 (spidev0.0 and spidev0.1) I haven’t verified it yet, but I will verify it in the next hour.

/*
 * Copyright (c) 2015-2021, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/ {
	aliases {
		spi0 = &spi0;
		spi1 = &spi1;
		spi2 = &spi2;
		spi6 = &qspi0;
		spi7 = &qspi1;
	};

	spi0: spi@3210000 {
		compatible = "nvidia,tegra186-spi";
		reg = <0x0 0x03210000 0x0 0x10000>;
		interrupts = <0 36 0x04>;
		#address-cells = <1>;
		#size-cells = <0>;
		iommus = <&smmu_niso0 TEGRA_SID_NISO0_GPCDMA_0>;
		dma-coherent;
		dmas = <&gpcdma 15>, <&gpcdma 15>;
		dma-names = "rx", "tx";
		spi-max-frequency = <65000000>;
		nvidia,clk-parents = "pll_p", "clk_m";
		clocks = <&bpmp_clks TEGRA234_CLK_SPI1>,
			<&bpmp_clks TEGRA234_CLK_PLLP_OUT0>,
			<&bpmp_clks TEGRA234_CLK_CLK_M>;
		clock-names = "spi", "pll_p", "clk_m";
		resets = <&bpmp_resets TEGRA234_RESET_SPI1>;
		reset-names = "spi";
		status = "disabled";
	};

	spi1: spi@c260000 {
		compatible = "nvidia,tegra186-spi";
		reg = <0x0 0x0c260000 0x0 0x10000>;
		interrupts = <0 37 0x04>;
		#address-cells = <1>;
		#size-cells = <0>;
		iommus = <&smmu_niso0 TEGRA_SID_NISO0_GPCDMA_0>;
		dma-coherent;
		dmas = <&gpcdma 16>, <&gpcdma 16>;
		dma-names = "rx", "tx";
		spi-max-frequency = <65000000>;
		nvidia,clk-parents = "pll_p", "osc";
		clocks = <&bpmp_clks TEGRA234_CLK_SPI2>,
			<&bpmp_clks TEGRA234_CLK_PLLAON>,
			<&bpmp_clks TEGRA234_CLK_OSC>;
		clock-names = "spi", "pll_p", "osc";
		resets = <&bpmp_resets TEGRA234_RESET_SPI2>;
		reset-names = "spi";
		status = "disabled";
	};

	spi2: spi@3230000 {
		compatible = "nvidia,tegra186-spi";
		reg = <0x0 0x03230000 0x0 0x10000>;
		interrupts = <0 38 0x04>;
		#address-cells = <1>;
		#size-cells = <0>;
		iommus = <&smmu_niso0 TEGRA_SID_NISO0_GPCDMA_0>;
		dma-coherent;
		dmas = <&gpcdma 17>, <&gpcdma 17>;
		dma-names = "rx", "tx";
		spi-max-frequency = <65000000>;
		nvidia,clk-parents = "pll_p", "clk_m";
		clocks = <&bpmp_clks TEGRA234_CLK_SPI3>,
			<&bpmp_clks TEGRA234_CLK_PLLP_OUT0>,
			<&bpmp_clks TEGRA234_CLK_CLK_M>;
		clock-names = "spi", "pll_p", "clk_m";
		resets = <&bpmp_resets TEGRA234_RESET_SPI3>;
		reset-names = "spi";
		status = "disabled";
	};

	qspi0: spi@3270000 {
		compatible = "nvidia,tegra23x-qspi";
		reg = <0x0 0x3270000 0x0 0x10000>;
		interrupts = < 0 35 0x04 >;
		#address-cells = <1>;
		#size-cells = <0>;
		iommus = <&smmu_niso1 TEGRA_SID_NISO1_QSPI0>;
		dma-coherent;
		dma-names = "rx", "tx";
		spi-max-frequency = <204000000>;
		nvidia,clk-parents = "pllc", "pll_p";
		clocks = <&bpmp_clks TEGRA234_CLK_QSPI0_2X_PM>,
			 <&bpmp_clks TEGRA234_CLK_QSPI0_PM>,
			 <&bpmp_clks TEGRA234_CLK_PLLC>,
			 <&bpmp_clks TEGRA234_CLK_PLLP_OUT0>;
		clock-names = "qspi", "qspi_out", "pllc", "pll_p";
		resets = <&bpmp_resets TEGRA234_RESET_QSPI0>;
		reset-names = "qspi";
		status = "disabled";

	};

	qspi1: spi@3300000 {
		compatible = "nvidia,tegra23x-qspi";
		reg = <0x0 0x3300000 0x0 0x10000>;
		interrupts = < 0 39 0x04 >;
		#address-cells = <1>;
		#size-cells = <0>;
		iommus = <&smmu_niso1 TEGRA_SID_NISO1_QSPI1>;
		dma-coherent;
		dma-names = "rx", "tx";
		spi-max-frequency = <204000000>;
		nvidia,clk-parents = "pllc", "pll_p";
		clocks = <&bpmp_clks TEGRA234_CLK_QSPI1_2X_PM>,
			 <&bpmp_clks TEGRA234_CLK_QSPI1_PM>,
			 <&bpmp_clks TEGRA234_CLK_PLLC>,
			 <&bpmp_clks TEGRA234_CLK_PLLP_OUT0>;
		clock-names = "qspi", "qspi_out", "pllc", "pll_p";
		resets = <&bpmp_resets TEGRA234_RESET_QSPI1>;
		reset-names = "qspi";
		status = "disabled";
	};
};

What do you mean about “custom version”?
Are you using the devkit or custom board for AGX Orin?

To enable SPI (no matter SPI1 or SPI2), you have to configure pinmux first, and disable the GPIO usage for those pins then loading the spi driver.
The overall steps could be found in the following thread, but that is for the Jetson Nano devkit.
Jetson Nano SPI Bus Not Working - #10 by KevinFFF

Hi KevinFFF,

I mean, I use a custom board, not devkit…

Hi

SPI1 is not used in my custom board, so I cannot test the function of SPI1.

Hi KevinFFF,

I now know that the SPI2 used in pinmux has a node index of -1 in the device tree, and it maps to spidev1.0 in the operating system, not spidev2.0. But I can’t find the /dev/spidev1.0 device node.

Hi @Andyyyyy ,

Have you tried the Jetson-IO utility?

Give it a try.

Embedded SW Engineer at RidgeRun Contact us: support@ridgerun.com Developers wiki: https://developer.ridgerun.com/ Website: www.ridgerun.com

Hi https://forums.developer.nvidia.com/u/OscarPorras,
I’ve tried loading spidev using the Jetson-IO utily tool.
But I’m not sure if “spi1(19,21,23,24,26)” corresponds to the pins of my custom board.

The pins used in my custom board are as follows, and I have provided a partial schematic. I configured it both in Pinmux and in the device tree.



I don’t think I should use the Jetson-IO utily tool to configure my SPI.

Sincere regards.
Andy,

Yes, please just use pinmux spreadsheet to configure the pinmux register for the custom carrier board.

Could you share the result of the following command on your board?

$ sudo busybox devmem 0x0c302048 //PADCTL_AO_SPI2_SCK_0
$ sudo busybox devmem 0x0c302050 //PADCTL_AO_SPI2_MISO_0
$ sudo busybox devmem 0x0c302028 //PADCTL_AO_SPI2_MOSI_0
$ sudo busybox devmem 0x0c302038 //PADCTL_AO_SPI2_CS0_0

Have you verified the SPI loopback test (please short MISO/MOSI first) on your board successfully?

$ sudo modprobe spidev
$ wget https://raw.githubusercontent.com/torvalds/linux/v4.9/tools/spi/spidev_test.c
$ gcc -o spidev_test spidev_test.c
$ sudo ./spidev_test -D /dev/spidev2.0 -v -p "HelloWorld123456789abcdef"

Hi https://forums.developer.nvidia.com/u/KevinFFF,

I have successfully shorted MISO/MOSI and tested data loopback.
The running result is shown in the figure below, TX has data, and RX has no data.

I don’t think I should use /dev/spidev2.0. I don’t think I should use /dev/spidev1.0.

Because in Pinmux E61:SPI2_CLK、D62:SPI_MISO、F60:SPI2_MOSI、D60:SPI2_CS0_N,
The node mapped to the device tree should be “spi1: spi@c260000”
image

Sincere regards,

Andy.

Which one do you think that you should use?

Could you share the result of ls -l /dev/spidev* on your board?

Please also share 4 pinmux registers’ value I asked for.

I’m really sorry that my words have caused a misunderstanding.

I should have used /dev/spidev1.0 instead.

This is the value of my 4 pinmux register, maybe you can help me check if the register corresponds to /dev/spidev1.0 (spi@c260000).

root@tegra-ubuntu:/home/nvidia# sudo busybox devmem 0x0c302048
0x00001448
root@tegra-ubuntu:/home/nvidia# sudo busybox devmem 0x0c302050
0x00000458
root@tegra-ubuntu:/home/nvidia# sudo busybox devmem 0x0c302048
0x00001448
root@tegra-ubuntu:/home/nvidia# sudo busybox devmem 0x0c302028
0x00000008
root@tegra-ubuntu:/home/nvidia#

The result of pinmux register seem as expected for SPI.

Could you share the result of ls -l /dev/spidev* on your board?

and try using the following command for the loopback test.

$ sudo ./spidev_test -D /dev/spidev1.0 -v -p "HelloWorld123456789abcdef"

I’m sorry I’m late recovering,At present, I have problems and need to continue to discuss.

“ls -l /dev/spidev*”
image

“./spidev_test -D /dev/spidev1.0 -v -p “HelloWorld123456789abcdef””

Hi https://forums.developer.nvidia.com/u/KevinFFF.
How do I load “/dev/spidev1.0”?

That’s why I suggest you using /dev/spidev2.0.

It seems there’s no /dev/spidev1.0 in your case.

Do you have the devkit could reproduce the same issue?