How to implement data sending and receiving of SPI0 and SPI1 on jetson orin nano

I am using a Jetson Orin Nano Developer Kit 8GB. When I try to follow the steps in this link: Jetson/L4T/peripheral/ - eLinux.org to implement SPI1 in slave mode and SPI0 in master mode for data transmission and reception, the SPI0 as the master can send data, but the SPI1 as the slave always receives [0, 0, 0, 0, 0, 0, 0, 0]. I used ChatGPT to generate a Python program to achieve data transmission and reception. The Python program is as follows:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import spidev, time, threading

MASTER_BUS = 0
MASTER_DEVICE = 0
SLAVE_BUS = 1
SLAVE_DEVICE = 0
SPI_SPEED = 25000000
SPI_BITS = 8
SPI_MODE = 0

slave_received = None

def spi_slave():
    global slave_received
    slave = spidev.SpiDev()
    slave.open(SLAVE_BUS, SLAVE_DEVICE)
    slave.max_speed_hz = SPI_SPEED
    slave.bits_per_word = SPI_BITS
    slave.mode = SPI_MODE
    print("Slave device: Waiting for the first stage of transmission...")
    slave_received = slave.readbytes(8)
    print("Data received by the slave device:", slave_received)
    time.sleep(1)
    print("Slave device: Preparing to send data back in the second stage...")
    returned = slave.xfer2(slave_received)
    print("Data received by the slave device in the second stage:", returned)
    slave.close()

def spi_master():
    master = spidev.SpiDev()
    master.open(MASTER_BUS, MASTER_DEVICE)
    master.max_speed_hz = SPI_SPEED
    master.bits_per_word = SPI_BITS
    master.mode = SPI_MODE
    tx_data = [0x55, 0xAA, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44]
    print("Master device: Sending data in the first stage:", tx_data)
    dummy_rx = master.xfer2(tx_data)
    print("Data received by the master device in the first stage (usually meaningless):", dummy_rx)
    time.sleep(2)
    dummy_tx = [0x00] * 8
    print("Master device: Sending dummy data in the second stage:", dummy_tx)
    echo_rx = master.xfer2(dummy_tx)
    print("Data received by the master device in the second stage:", echo_rx)
    master.close()

if __name__ == '__main__':
    slave_thread = threading.Thread(target=spi_slave)
    master_thread = threading.Thread(target=spi_master)
    slave_thread.start()
    time.sleep(0.5)
    master_thread.start()
    slave_thread.join()
    master_thread.join()

the result as below:

jetson@yahboom:~$ python spi_test2_20250317.py
Slave device: Waiting for the first stage of transmission...
Data received by the slave device: [0, 0, 0, 0, 0, 0, 0, 0]
Master device: Sending data in the first stage: [85, 170, 255, 0, 17, 34, 51, 68]
Exception in thread Thread-2 (spi_master):
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/jetson/spi_test2_20250317.py", line 39, in spi_master
    dummy_rx = master.xfer2(tx_data)
OSError: [Errno 22] Invalid argument
Slave device: Preparing to send data back in the second stage...
Data received by the slave device in the second stage: [0, 0, 0, 0, 0, 0, 0, 0]

Can you help me solve this problem? Please provide detailed steps. I’m not very familiar with the operation of Jetson Orin Nano. Thank you very much.

Hi YFH08267,

What’s the Jetpack version in use?

Could you refer to Jetson/L4T/peripheral/ - eLinux.org for the steps to verify slave mode on Orin Nano devkit?

Please use the following spidev_test to verify.
spidev_test (103.4 KB)

Note: You have to run SPI slave before SPI master.

Thanks your answer,KevinFFF
below is my answer :
1“What’s the Jetpack version in use?”
a: my jetpack version is 6.2


2“ Could you refer to Jetson/L4T/peripheral/ - eLinux.org for the steps to verify slave mode on Orin Nano devkit?”
a:Yes, I have successfully configured SPI1 to slave mode by modifying the dtb file

3 ‘‘Please use the following spidev_test to verify.’’
a:yes, using test file you shared, the communication was successful,thank you very much.

then, i have a question that i’ve been wondering about. When i use two SPI interfaces to achieve full duplex communication, the slave device seems to miss data. For example, the master continuously transmits data from 1 to 10 while the slave simultaneously transmits data from 20 to 11, the slave device some time lossing some data, like below:

The python program of the master as:

import spidev
import time

# SPI1 master
spi1 = spidev.SpiDev()
spi1.open(0, 0)           
spi1.max_speed_hz = 15000000  
spi1.bits_per_word = 8
spi1.mode = 1   

data = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00]

for i in range(10):
    current_send = data.copy()
    rx = spi1.xfer2(data)
    print("Received data from SPI3", rx)
    print("Send data to SPI3:", current_send)
    data = [(x + 1) & 0xff for x in current_send]

spi1.close()
print("SPI1 communication completed.")

The python program of slave as:

import spidev
import time

# SPI3 slave
spi3 = spidev.SpiDev()
spi3.open(1, 0)          
spi3.max_speed_hz = 15000000  
spi3.bits_per_word = 8
spi3.mode = 1           

data_send = [0x14, 0x14, 0x14, 0x14, 0x14, 0x14,0x14, 0x14, 0x14, 0x14, 0x14, 0x14,0x14, 0x14, 0x14, 0x14]
count = 0
while count < 10:
    current_send = data_send.copy()
    received_data = spi3.xfer2(data_send)
    print("Received data from SPI1:", received_data)
    print("Send data to SPI1:", current_send)
    data_send = [(x - 1) & 0xff for x in current_send]
    count += 1
    
spi3.close()
print("SPI3 communication completed.")

is there an issue with my program? or could other factors be causing the slave device to loss data? can you help me to improve it, thanks.

Additional question: What are the differences in transmission speed between SPI modes 0, 1, 2, and 3? If the device is in slave mode, do different SPI modes impose different limitations?

Sorry that we don’t debug the custom application direclty.
Could you just use that spidev_test tool and transfer the similar bytes to check if there’s similar data drop issue?
Or you can get a scope or logic analyzer to check from signal.

I think the the transmission is not relating to SPI mode.
Please just confirm that you used the identical SPI mode for both master and slave.

Hi @KevinFFF,

I’m working with a new Jetson Orin Nano running JetPack 6.2. I successfully performed the SPI loopback test following https://forums.developer.nvidia.com/t/nvidia-orin-nano-spi-loopback-test-not-receiving-data/310660/5?u=yfh08267 and it worked perfectly.

However, when I tried to configure SPI3 for slave mode using this reference https://elinux.org/Jetson/L4T/peripheral/#Slave_Mode , I encountered an issue. I modified the device tree as follows:

spi@3230000 {
compatible = “nvidia,tegra210-spi-slave\0nvidia,tegra114-spi-slave”;

But when I executed the test command using the spidev_test file you provided, an unexpected behavior occurred. I first ran the slave test code, but the test terminated prematurely before executing the master code, with the following results:

sudo chmod +x spidev_test
jetson@yahboom:~$ sudo ./spidev_test -D /dev/spidev1.0 -s8000000 -g8 -b8 -H -f pattern.txt -n1 -zzz -r
Disabling transmit
using device: /dev/spidev1.0
setting spi mode for read,write
setting spi bpw
setting max speed for rd/wr
spi mode: 1
bits per word: 8 bytes per word: 1
max speed: 8000000 Hz (8000 KHz)
no. runs: 1
Using seed:0x67f23745
loop count = 0
transfer: Return actual transfer length: 8
receive bytes [8]
0000: 00 00 00 00 00 00 00 00
Not enough data in file, repeat data from file…
transfer: received packet size:8 len:8 stat:0
/dev/spidev1.0: TEST PASSED
====== Transfer stats ====
Receive:
total: 8B (0KiB 0MiB)
total: 1P
good: 8B (0KiB 0MiB)
good: 1P
ioerr: 0P
dataerr: 0P
Rate:
good: -1B/s (0KB/s)
good: -1P/s
packet drop: -1/10000

Total time: 0.001370s
Subsequently, when executing the master test code, the process entered an infinite execution state requiring manual termination via Ctrl+C. The observed output was as follows:
jetson@yahboom:~$ sudo ./spidev_test -D /dev/spidev0.0 -s8000000 -g8 -b8 -H -f pattern.txt -n1 -zzz -t
Disabling receive
using device: /dev/spidev0.0
setting spi mode for read,write
setting spi bpw
setting max speed for rd/wr
spi mode: 1
bits per word: 8 bytes per word: 1
max speed: 8000000 Hz (8000 KHz)
no. runs: 1
Using seed:0x67f239a5
loop count = 0
Using user defined pattern from pattern.txt file …
transfer bytes [8]
0000: 55 55 55 55 55 55 55 55
^Ctransfer ioctl error: -1
/dev/spidev0.0: TEST FAILED !!! (status:-1)
====== Transfer stats ====
Transmit:
total: 18446744073709551615B (18014398509481983KiB 17592186044415MiB)
total: 1P
ioerr: 8B (0KiB 0MiB)
ioerr: 1P
Rate:
wire total: 1468422420B/s (1434006KB/s)
total: 1468414556B/s (1433998KB/s)
wire total: 0P/s
total: 0P/s

Total time: 514.867342s

The kernel logs related to the SPI (Serial Peripheral Interface) bus are as follows:

jetson@yahboom:~$ sudo dmesg | grep spi
[sudo] password for jetson:
[ 10.180883] spi-tegra124-slave 3230000.spi: Adding to iommu group 1
[ 10.181555] spi-tegra124-slave 3230000.spi: Dynamic bus number will be registered
[ 10.191504] spi-tegra114 3210000.spi: Adding to iommu group 1
[ 852.447288] spi-tegra124-slave 3230000.spi: waiting for controller was interrupted
[ 852.447360] spi_master spi0: failed to transfer one message from queue
[ 925.437426] spi-tegra124-slave 3230000.spi: waiting for controller was interrupted
[ 925.437487] spi_master spi0: failed to transfer one message from queue
[ 1913.819371] spi-tegra124-slave 3230000.spi: waiting for controller was interrupted
[ 1913.819409] spi_master spi0: failed to transfer one message from queue

can you help me?

It seems your SPI slave registered earlier than SPI master so that you have to run SPI slave with /dev/spidev0.0 first and run SPI master with /dev/spidev1.0 later.

Hi Kevin,

Thank you for your reminder! I’ve adjusted the SPI settings as discussed:

  • ​**spidev0.0** is now configured as ​Master.
  • ​**spidev1.0** is set to ​Slave.

[sudo] password for jetson:
[ 10.032516] spi-tegra114 3210000.spi: Adding to iommu group 1
[ 10.033781] spi-tegra124-slave 3230000.spi: Adding to iommu group 1
[ 10.033819] spi-tegra124-slave 3230000.spi: Dynamic bus number will be registered

But when I checked the SPI signals with an oscilloscope:

The oscilloscope shows an ​abnormal SCK signal (blue). Could you help confirm whether this is caused by:

  1. Hardware damage (e.g., broken SPI controller or circuit), or
  2. System/driver issues (e.g., misconfiguration or incomplete debugging)?

Have you confirmed that you measure the correct line for SCK?
If it does not work as expected, how could you get expected data line(MOSI)?

Have you configured the pinmux before use?

Could you share the block diagram of your connection between SPI master and slave?