Jetson Nano (Developer Kit) SPI Hell

Hi,

So I’ve read all I could read.
Went through the instructions on https://github.com/rt-net/JetsonNano_DT_SPI
The script executed successfully from a host running Ubuntu. After the flashing was over and the Jetson restarted I got ‘spidev’ when I did ‘lsmod’.
I was also able to see spidev0.0 and spidev1.0 under /dev.

At this point I took the kernel test code spidev.c compiled it and executed '/spidev_test -D /dev/spidev0.0 -v
Placed a probe on PIN 23 (CLK) and …

Nothing :)
Absolutely nothing at all.
NVIDIA, letting developers an easy access to peripherals (SPI, I2C. UART act’) is mandatory, in my opinion, for the success of this line of products.

Eitan.

If you’re running JetPack 4.3, Linux For Tegra 32.3.1, use the new jetson-io tool to enable spidev.

https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3231/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fhw_setup_jetson_io.html%23

If running an older version, try the following…

https://devtalk.nvidia.com/default/topic/1062646/jetson-nano/updated-instructions-for-spi-on-nano-developmentkit-with-l4t-32-2-1/1

The instructions change during that thread so read all the way through.

Since I have a clean image that I’ve DL today I’ve tested the python tool.
As expected I got the error, I’ve typed the magical line :

sudo find /opt/nvidia/jetson-io/ -mindepth 1 -maxdepth 1 -type d -exec touch {}/init.py ;

And tested again the python script (sudo /opt/nvidia/jetson-io/jetson-io.py ).
I was able to see something that blinks momentarily and then it was gone.
No error message, no nothing.

Any clue ?

You also need to make sure the existing DTBs are both in the /boot and /boot/dtb directories.

You can see the error by running

jetson-io.py | less

This removes the screen formatting so you can see the error at the bottom of the output.

Thanks,

And how shall I get those files?
Ans yes, I known It’s probably buried deep in one of the gazillion readme files in the SDK.

They’re already in /boot. You just need to create a /boot/dtb directory and copy them down.

Thanks !!

SPI (master) works, the simple spidev.c tester works and I can see the clocks from an external logic.
Now, I’m trying to make the Jetson nano work in a slave mode, so it could read and analyze a fast stream of data being sent to it from an external sensor,

So the next question would be, did this python script enabled SPI slave on SPI 0 & 1?
If so, could you point me to a simple SPI slave source that I could use as a reference, My focus is more on analyzing the data in the Jetson core rather the communication method which seem to take most of my time.

Thanks for the help!
Eitan.

There currently isn’t a device tree model for using the tegra210 in slave mode. There’s a driver that supports it though so I can try and create one. Give me a day or so.

That would be awesome,
Thank you very much!

I think I’ve got a devicetree overlay that’ll put a controller in slave mode. I’m testing and packaging now. Do you have some software that uses the slave mode that I could test with?

Well, this is exactly what I have to create.

The master in this case sends messages of 256 / 512 bytes, where the slave (Jetson) never sends anything, it’s a simple SPI listener, not sure if the CS is being used at all.
Each ‘message’ has start byte of 0xa5 and the last 2 bytes are crc16.
Once I have SPI slave mode running all I’ll crate some sort of a Q that stores those messages and another thread that takes those messages and do all the math.

Hi,
Any chance there’s something new with that slave overlay?

Sorry. I got carried away with the install procedure and wound up writing a whole python library to create overlays. :) I’ll have a zip file for you to test with later this afternoon (GMT-7).

OK, here you go…

# unzip DTBOverlayCreator.zip
# cd DTBOverlayCreator
# make
# make install
# reboot

I’m still working on the documentation but running SPI_Custom.py will create a dts file that enables /dev/spidev0.0 in master mode and /dev/spidev1.0 in slave mode. The Makefile runs that python script and compiles the result into a new dtb file.

Give it a shot and see how it works.
DTBOverlayCreator.zip (25 KB)

Thanks!

OK,so I have my sensor hooked to SPI1 (hope I got it right)
SPI1_CLK : PIN 13
SPI1_MISO : PIN 22
SPI1 CS0 : PIN 18
SPI1 MOSI : None, we are the slave and we never talk.

I have executed your script and rebooted.
So, since the overlay enables SPI on spidev I could actually read data from the master in user space ?
( I can see only spi=master under /sys/class)

If so could you point me to a sample that does this?
Could find anything regarding Linux, SPI -Slave, SPIDev.

Thanks
Eitan.

the spi device will still show as a “master” device even though it’s operating in slave mode.

This should read 1 byte from /dev/spidev1.0 and print it. Set the block_size, mode, bits, and speed as appropriate.

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

int main() {
	int block_size = 1;
	uint32_t mode = 0;
	uint8_t bits = 8;
	uint32_t speed = 1000000;
	uint8_t rx[block_size];
	int ret;
	int fd;


	fd = open("/dev/spidev1.0", O_RDONLY);

	// Example mode. Just use the modes you need if any.
	// mode = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST | SPI_LSB_FIRST | SPI_NO_CS;
	ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

	ret = read(fd, rx, block_size);
	
	printf("0x%2x\n", rx[0]);

	return 0;

}

Hello,

First, I can’t thank you enough for all the help !
So I have the following :

I’ve attached a different board to the Jetosn’s SPI-1 (only Clk, MOSI & CS). This board is a
master that sends 0xa5 and 0x5a continuously at 500Khz, I have a logic that observing the data being sent between that board and the Jetson, everything looks fine, CS goes low, master is sending data during the 8 clocks it’s generating.

I’ve used SPI1 (37: MOSI, 13 CLK, 18: CS).
I’ve used you reference code, and made an infinite loop that read and print a received byte.
In another terminal I have ‘dmesg -w’
Immediately after I turn the master device on I get :

[ 8283.765308] spi_master spi1: CMD[03f01027]: Sl M0 CS0 [HHHH] MSB MSb Rx Pa 8b TRANS[00ff0000]:BSY I:255 B:0
FIFO[00c00004]:RxF:1 TxE:64 Err RxSTA TxSTA[E]DMA[00000000]: RxTr:0 TxTr:0 B:0
[ 8283.784388] spi_master spi1: failed to transfer one message from queue
[ 8283.792313] spi_master spi1: failed to transfer one message from queue
[ 8283.800204] spi_master spi1: failed to transfer one message from queue
[ 8283.807625] spi_master spi1: failed to transfer one message from queue … endlessly

(Doesn’t look good but it means that the Jetson knows that data is being transmitted, when I turn the master device off, those error messages stops).

My process gets many errors (read returns a negative value) and once in a while it reads a byte (but not 0xa5 or 0xa5).

Any clue?
Eitan.

Forgot to ad:
I’ve tested this at a very low speed (1 bytes every ~2 seconds at ~100Khz).
The full (repeating) error sounds like a DMA issue :

[12712.352737] spi_master spi1: rx-dma-err [status:80c00004]
[12712.358568] spi_master spi1: CMD[03f01027]: Sl M0 CS0 [HHHH] MSB MSb Rx Pa 8b TRANS[00ff0001]:BSY I:255 B:1
FIFO[00c00004]:RxF:1 TxE:64 Err[] RxSTA[] TxSTA[E]DMA[00110000]: RxTr:2 TxTr:2 B:4095
[12712.378533] spi_master spi1: failed to transfer one message from queue

Thanks,
Eitan.

Well, that’s progress. :)

Try adding SPI_CPHA to the mode.

Something is defiantly working now :)
And I think I know what’s causing the ‘failed to transfer one message from queue’ errors
My device is sending data at 12Mhz with about 30μ between each byte.
if I place ~5ms gap between the bytes everything works, once the gap is less I get tons of errors.

Is there anything I could do ?
The real sensor is sending data at fast rate and I can’t change it’s behavior.