How to set to spi slave mode

Hello

I want to run spi test by connecting spi1 and spi3 of jetson xavier nx board.
Before connecting spi1-spi3, I connected spi1’s MOSI-MISO (spi3’s MOSI-MISO) and tested with the spidev_test.c example to confirm that tx rx works well for both spi1 and spi3.
(Currently jetson xavier nx board has jetpack4.4 version installed.)
Here I have some questions.

  1. How to set the master mode and slave mode when connecting spi1 and spi3? (Should I update pinmux? or
    https://www.jetsonhacks.com/2020/05/04/spi-on-jetson-using-jetson-io/ like this link on jetson?
  1. https://forums.developer.nvidia.com/t/spi-cant-work-in-slave-mode-on-xavier/128835
    If I set it like this post, does it become slave mode?
    If so, 1) how to configure the device tree and 2) how to add properties?
  1. How to connect spi1-spi3 between the two methods below?
  1. spi1 MISO <-> spi3 MISO / spi1 MOSI <-> spi3 MOSI / spi1 SCK<-> spi3 SCK / spi1 CS0 <-> spi CS0
    2)spi1 MISO <-> spi3 MOSI / spi1 MOSI <-> spi3 MISO / spi1 SCK<-> spi3 SCK / spi1 CS0 <-> spi CS0
  1. How to do rx in spi slave?
    Does an interrupt appear when data comes in?
    Looking at the spi example (spidev_test.c), ioctl(fd, SPI_IOC_MESSAGE(1), &tr) is used to check tx and rx. Is this the only way to check rx?
    If you check rx with ioctl(fd, SPI_IOC_MESSAGE(1), &tr), how do you know if the data has come in?
    Are there any c++ examples of spi slaves?

Thank you.

For 1 and 2.
Configure as below. Add tegra124-spi-slave to the device tree.

  1. Should be 1

  2. open ssh terminal and start the spi slave first with following command
    "./spidev_test -D /dev/spidev0.0 -s 150000 -n100 -g30 -p4 -z
    In another terminal start the spi master with following command
    “./spidev_test -D /dev/spidev3.1 -s 150000 -n100 -g30 -p4 -z”

Thank you for answering.

I tried testing the slave mode as indicated, but I got an’invalid option’ error.
I downloaded the source from this link and tested it.

As you told me, how do I get ./spidev_test -D /dev/spidev0.0 -s 150000 -n100 -g30 -p4 -z to run?

This’s build by my tree. Remove the .txt and change it as executable file.

spidev_test.txt (69.1 KB)

I saw this link and tried to follow it, but I’m not sure.
I proceeded in the following way to modify dts.

1.Run /opt/nvidia/jetson-io/jetson-io.py and activate spi1, spi3
2. sudo dtc -I dts -O dtb -o ~/user-custom.dts /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb
3. Modify user-custom.dts

spi@3210000 {
compatible = “nvidia,tegra186-spi”;
reg = <0x0 0x3210000 0x0 0x10000>;
interrupts = <0x0 0x24 0x4>;
#address-cells = <0x1>;
#size-cells = <0x0>;
iommus = <0x2 0x20>;
dma-coherent;
dmas = <0x19 0xf 0x19 0xf>;
dma-names = “rx”, “tx”;
spi-max-frequency = <0x3dfd240>;
nvidia,clk-parents = “pll_p”, “clk_m”;
clocks = <0x4 0x87 0x4 0x66 0x4 0xe>;
clock-names = “spi”, “pll_p”, “clk_m”;
resets = <0x5 0x5b>;
reset-names = “spi”;
status = “okay”;
linux,phandle = <0xf2>;
phandle = <0xf2>;
spi@0 {
compatible = “spidev”;
reg = <0x0>;
spi-max-frequency = <0x2faf080>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
spi@1 {
compatible = “spidev”;
reg = <0x1>;
spi-max-frequency = <0x2faf080>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
};
spi@3230000 {
compatible = “nvidia,tegra186-spi-slave”;
reg = <0x0 0x3230000 0x0 0x10000>;
interrupts = <0x0 0x26 0x4>;
#address-cells = <0x1>;
#size-cells = <0x0>;
iommus = <0x2 0x20>;
dma-coherent;
dmas = <0x19 0x11 0x19 0x11>;
dma-names = “rx”, “tx”;
spi-max-frequency = <0x3dfd240>;
nvidia,clk-parents = “pll_p”, “clk_m”;
clocks = <0x4 0x89 0x4 0x66 0x4 0xe>;
clock-names = “spi”, “pll_p”, “clk_m”;
resets = <0x5 0x5d>;
reset-names = “spi”;
status = “okay”;
linux,phandle = <0xf4>;
phandle = <0xf4>;
spi@0 {
compatible = “spidev”;
reg = <0x0>;
spi-max-frequency = <0x2faf080>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
spi@1 {
compatible = “spidev”;
reg = <0x1>;
spi-max-frequency = <0x2faf080>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
};

  1. sudo dtc -I dts -O dtb -o /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb ~/user-custom.dts
  2. reboot

By modifying dts in this way, spi1(master, spidev0.0), spi3(slave, spidev2.0) were connected and executed as follows.

./spidev_test -D /dev/spidev2.0 -s 150000 -n10000 -g30 -p4 -z

./spidev_test -D /dev/spidev0.0 -s 150000 -n10000 -g30 -p4 -z

(The photo shows’./spidev_test -D /dev/spidev0.0 -s 150000 -n10000 -g30 -p4 -z -r’, but When I used ‘./spidev_test -D /dev/spidev0.0 -s 150000 -n10000- g30 -p4 -z’ , the result was the same.)

The result is shown in the photo.


When I ran it in slave mode, a transfer error occurred and the master was test failed.

What did I do wrong?

Have devmem2 to read those REG to confirm the setting.


Are jetson xaiver nx the same as the register value in this post?
Should I change the register values of spi1 and spi3 the same?

Jetson NX is the same chip with Xavier

I still get the error though.
Instead of flashing by modifying pinmux, I used devmem2 to temporarily change the register value.

when checking dmesg, the following error appears.

[ 280.340212] spi-tegra124-slave 3230000.spi: Tx is not supported in mode 0
[ 280.340215] spi-tegra124-slave 3230000.spi: spi can not start transfer, err -22
[ 280.340301] spi_master spi2: failed to transfer one message from queue

Below is suggest.

Have connected -> SPI1_MOSI<-->SPI3_MISO, SPI1_CLK<-->SPI3_CLK, SP1_CS0 <--> SPI3_CS0  and SPI1_CS1->SPI3_CS1.

SPI1 has to be configured as Master and SPI3 has to be configured as slave in the dt and pinmux settings have to be updated. 
SPI1 DT:    
spi@3210000 {
        status = "okay";
        compatible = "nvidia,tegra186-spi";
        spi@0 {
            compatible = "spidev";
            reg = <0>;
            spi-max-frequency = <65000000>;
            controller-data {
                nvidia,enable-hw-based-cs;
            };
        };
    };

SPI3 DT
    spi@3230000 {
        status = "okay";
        compatible = "nvidia,tegra186-spi-slave";
        spi@0 {
            compatible = "spidev";
            reg = <0>;
            spi-max-frequency = <65000000>;
            controller-data {
                nvidia,enable-hw-based-cs;
            };
        };
     };

PINMUX settings are listed below for SPI1 and SP13 for loopback. (Note: SPI1 and SP3 have an internal loopback connection for Xavier)

SPI_1 pinmux settings:
PADCTL_UART_SPI1_MISO_0  (0x0243d020) =  0x440;
PADCTL_UART_SPI1_MOSI_0 (0x0243d058) =  0x440;
PADCTL_UART_SPI1_SCK_0 (0x0243d040) =  0x440;
PADCTL_UART_SPI1_CS0_0 (0x0243d010) =  0x448;
PADCTL_UART_SPI1_CS1_0 (0x0243d050) =  0x448;

SPI_3 pinmux settings:
PADCTL_UART_SPI3_MISO_0  (0x0243d008) =  0x440;
PADCTL_UART_SPI3_MOSI_0 (0x0243d060) =  0x440;
PADCTL_UART_SPI3_SCK_0 (0x0243d048) =  0x444;
PADCTL_UART_SPI3_CS0_0 (0x0243d018) =  0x448;
PADCTL_UART_SPI3_CS1_0 (0x0243d028) =  0x448;

There are a few things I’d like to ask in your answer.

  1. Do you connect SPI1_MOSI<–>SPI3_MISO?
    Why connect MOSI and MISO?
    SPI1_MISO<–> Why doesn’t SPI3_MOSI connect?

  2. Do I need to update the pinmux setting by changing from dt to slave means I have to flash again?
    Can’t I do it in the following way?

(1) Activate spi1, spi3 in /opt/nvidia/jetson-io/jetson-io.py
(2) dtb decompile
—> sudo dtc -I dtb -O dts -o ~/ user-custom.dts / boot / tegra194-p3668-all- p3509-0000-user-custom.dtb
(3) Open the ~/ user-custom.dts file and change spi3(spi@3230000) to slave
(compatible = “nvidia, tegra186-spi” -> compatible = “nvidia, tegra186-spi-slave”)
(4) dts compilation
—> sudo dtc -I dts -O dtb -o /boot/tegra194-p3668-all- p3509-0000-user-custom.dtb ~/user-custom.dts
(5) reboot jetson
(6) Change reg value using devmem2 (temporary)
(7) Connection: SPI1_MOSI<–>SPI3_MISO, SPI1_CLK<–>SPI3_CLK, SP1_CS0 <–> SPI3_CS0 and SPI1_CS1<–>SPI3_CS1
(8) test

  1. Where is the dt file? (Where should I change the spi3 slave?)

  2. Where do I change the reg? Do I change it in my cfg (galen.cfg)?

  3. Is the pinmux update method correct?

&&pinmux update method&&
(1) Jetson_Xavier_NX_Pinmux_Configuration_Template_v1.06 Set pinmux with .xlsm and create DT
(tegra19x-jetson_xavier_nx_module-gpio-default.dtsi, tegra19x-jetson_xavier_nx_module-padvoltage-default.dtsi, tegra19x-jetson_xavier_nx_module-pinmux.dtsi)
(2) Install Linux_for_Tegra with SDK Manager on Linux host PC
(3) Go to /Linux_for_Tegra/kernel/pinmux/t19x
(4) Import the dtsi( tegra19x-jetson_xavier_nx_module-gpio-default.dtsi, tegra19x-jetson_xavier_nx_module-padvoltage-default.dtsi, tegra19x-jetson_xavier_nx_module-pinmux.dtsi) file to the Linux host PC and create a cfg file.
----> python pinmux-dts2cfg.py --pinmux addr_info.txt gpio_addr_info.txt por_val.txt tegra19x-jetson_xavier_nx_module-pinmux.dtsi tegra19x-jetson_xavier_nx_module-gpio-default.dtsi 1.0>galen.cfg <------------
(5) Change galen.cfg to /Linux_for_Tegra/bootloader/t186ref/BCT/tegra19x-mb1-pinmux-p3668-a01
(6) Flash with sdk manager (or sudo ./flash.sh jetson-xavier-nx-devkit mmcblk0p1

  1. Can you give me the source file of spi_test.txt that you gave me?
    I want to know how to slave (functions used, interrupts, etc.)
  1. Should be SPI1_MOSI<- ->SPI3_MOSI, SPI1_MISO<- ->SPI3_MISO, SPI1_CLK<–>SPI3_CLK, SP1_CS0 <–> SPI3_CS0 and SPI1_CS1->SPI3_CS1.

  2. You can try devmem2 to write those pinmux setting.

  3. You can still update the dtb like as you do before. How to set to spi slave mode

  4. change the cfg file …/Linux_for_Tegra/bootloader/t186ref/BCT/ and check with devmem2 would be good.

  5. Correct.

  6. It’s public source. https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c

When testing by connecting spi1(master)-spi3(slave), should I connect both SP1_CS0 <–> SPI3_CS0 and SPI1_CS1->SPI3_CS1?
Do you connect only one of cs0 or cs1?


Here you are told to run the command
./spidev_test -D /dev/spidev0.0 -s 150000 -n100 -g30 -p4 -z,
but the source code you gave me does not have the -g, -p, -z, -n options.

Also, how do I test master(spi1) -slave(spi3) with this code?
I need to run the slave first and then the master, but when I run the slave (/dev/spidev2.0) I get an error.

can’t send spi message: Invalid argument
Aborted (core dumped)
<<<<< dmesg >>>>>>
spi-tegra124-slave 3230000.spi: Tx is not supported in mode 0
spi-tegra124-slave 3230000.spi: spi can not start transfer, err -22
spi_master spi2: failed to transfer one message from queue

Before make it working I would suggest to connect both of the cs0 and cs1.
Run the master first may be make a script like

./spidev_test -D /dev/spidev0.0 -s 150000 -n100 -g30 -p4 -z
sleep 1
./spidev_test -D /dev/spidev0.1 -s 150000 -n100 -g30 -p4 -z

I want to test by connecting spi1(master)-spi3(slave)!
Master doesn’t want to know
An error occurs when executing the slave mode program.
I modified dt and reg value as you tell me to do, but when I run the program an error occurs.

can’t send spi message: Invalid argument
Aborted (core dumped)
<<<<< dmesg >>>>>>
spi-tegra124-slave 3230000.spi: Tx is not supported in mode 0
spi-tegra124-slave 3230000.spi: spi can not start transfer, err -22
spi_master spi2: failed to transfer one message from queue

Please tell me how to run the program in slave mode.

Have a try below command.

./spidev_test -D /dev/spidev0.0 -s 150000 -n100 -g30 -p4 -z & ./spidev_test -D /dev/spidev2.1 -s 150000 -n100 -g30 -p4 -z

https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c
This source code is ./spidev_test -D /dev/spidev0.0 -s 150000 -n100 -g30 -p4 -z & Can you run ./spidev_test -D /dev/spidev2.1 -s 150000 -n100 -g30 -p4 -z command?

Why do you need the source?
This binary should be modify by internal developer for some case. I think the public source should be OK for the test.

If you look at the error that occurs when you run the program, it seems that there is a problem with tx in slave mode.
So I want to see the source code.

can’t send spi message: Invalid argument
Aborted (core dumped)
<<<<< dmesg >>>>>>
spi-tegra124-slave 3230000.spi: Tx is not supported in mode 0
spi-tegra124-slave 3230000.spi: spi can not start transfer, err -22
spi_master spi2: failed to transfer one message from queue

https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c
Was this source code program tested in slave mode?

I did what you said
1. Modify dt to slave(/boot/tegra194-p3668-all-p3509-0000-user-custom.dtb)


2. Change reg value

3. Connection: SPI1 MOSI (pin 19) <-> SPI3 MOSI (pin 37), SPI1 MISO (pin 21) <-> SPI3 MISO (pin 22), SPI1 SCK (pin 23) <-> SPI3 SCK (pin 13), SPI1 CS0 (pin 24) <-> SPI3 CS0 (pin 18), SPI1 CS1 (pin 26) <-> SPI3 CS1 (pin 16)

But why do I still get the error in slave mode?

And I have another question.
In the source code, ioctl(fd, SPI_IOC_MESSAGE(1), &tr) sends and receives data to tx,rx included in the tr structure.
Do you use ioctl(fd, SPI_IOC_MESSAGE(1), &tr) to send and receive data even in slave mode?

Why!!! Can’t I!!!
What else do I need to fix?
Or do I need to create a new driver for the slave?
Should I create a new test program?

Will have a check with developer to verify the loopback mode on NX.