SPI read random data

Hi,

I’m trying to test spi on the Jetson TX2 and I’m facing a strange issue.

I’m using the nvidia jetson tx2 developer kit and I#M using the SPI interface which is connected to connector J21 (pin 19, 21, 23, 24).

I have followed the guide on following link to enable spi.

https://elinux.org/Jetson/TX2_SPI

Here a code snippet form my device tree:

spi@0 {
    compatible = "spidev";
    reg = <0x0>;
    spi-max-frequency = <0x1312D00>;
    spi-lsbyte-first = <0x0>;
    nvidia,enable-hw-based-cs;
    nvidia,cs-setup-clk-count = <0x1e>;
    nvidia,cs-hold-clk-count = <0x1e>;
    nvidia,rx-clk-tap-delay = <0x1f>;
    nvidia,tx-clk-tap-delay = <0x0>;
};

For the first test I havn’t connected anything to the spi interface.
I wrote a small application which sends a read command first and then reads in some data.
Because of the reason i haven’t connected anything to the spi interface (and there is a pulldown on the MISO pin) I am expecting to read 0, but it seems that I’m getting some random numbers (0xe541 0xbacb 0xbaa5 …).

I would be very grateful anybody could help me with my problem.

This is the application i used for testing spi.

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

int main(int argc, char **argv)
{
	uint16_t data = 0;
	uint16_t readCommand = 0x2;
	struct spi_ioc_transfer mesg[2] = { {0}, };
	char *device = "/dev/spidev3.0";
	int ret;
	int fd;

	// Read command
	mesg[0].tx_buf = (uint64_t)&readCommand;
	mesg[0].rx_buf = (uint64_t)NULL;
	mesg[0].len = 2; 
	mesg[0].delay_usecs = 0;
	mesg[0].speed_hz = 100000;
	mesg[0].bits_per_word = 16;


	// Dummy
	mesg[1].tx_buf = (uint64_t)NULL;
	mesg[1].rx_buf = (uint64_t)&data;
	mesg[1].len = 2;
	mesg[1].delay_usecs = 0;
	mesg[1].speed_hz = 100000;
	mesg[1].bits_per_word = 16;

	/* open device */
	fd = open(device, O_RDWR);
	if (fd < 0) {
		printf("Could not open file %s (%s)\n", device, strerror(errno));
		return -1;
	}

	/* send */
	ret = ioctl(fd, SPI_IOC_MESSAGE(2), mesg);
	if (ret < 0) {
		printf("Could not read from file %s (%s)\n", device, strerror(errno));
		return -1;
	}

	/* close device */
	ret = close(fd);
	if (ret < 0) {
		printf("Could not close file %s (%s)\n", device, strerror(errno));
		return -1;
	}

	printf("Read reg: %x \n", data);
	
	return 0;
}

Hi
Please follow below link to use the loopback for test on TX2.

https://elinux.org/Jetson/TX1_SPI

Thank you, the spidev_test.c example helped me to find a working solution.

It seems to be that sending several massages within one ioctl command is not working.

This code isn’t working.

// Read command
mesg[0].tx_buf = (uint64_t)&readCommand;
mesg[0].rx_buf = (uint64_t)NULL;
mesg[0].len = 2; 
mesg[0].delay_usecs = 0;
mesg[0].speed_hz = 100000;
mesg[0].bits_per_word = 16;


// Dummy
mesg[1].tx_buf = (uint64_t)NULL;
mesg[1].rx_buf = (uint64_t)&data;
mesg[1].len = 2;
mesg[1].delay_usecs = 0;
mesg[1].speed_hz = 100000;
mesg[1].bits_per_word = 16;

ret = ioctl(fd, SPI_IOC_MESSAGE(2), mesg);

Splitting the ioctl command into two calls has solved my issue.

This code works fine.

mesg.tx_buf = (uint64_t)&readCommand;
mesg.rx_buf = (uint64_t)NULL;
mesg.len = 2; 
mesg.delay_usecs = 0;
mesg.speed_hz = 100000;
mesg.bits_per_word = 16;

ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);

mesg.tx_buf = (uint64_t)NULL;
mesg.rx_buf = (uint64_t)&data;

ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);