SPI1 transfer time varies greatly in different versions (r3274, r3531)

SPI1 of agx xavier devkit transfer time varies greatly in different versions (r3274, r3531). I have established the same testing environment. The data length is 128byte. The SPI frequency is 12Mbps. In r3274, the transfer time is 210us ~ 260us (jitter is low), while it is 320us ~ 7000us (jitter is high) in r3531. I recorded the SPI transfer time every 10ms:
spi_transfer_time_r3274.txt (64 KB)
spi_transfer_time_r3531.txt (84 KB)

The device tree configuration for SPI1 is the same.

	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 = <0x24 0xf 0x24 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 = <0x4 0x5b>;
		reset-names = "spi";
		status = "okay";
		phandle = <0x30d>;

		prod-settings {

			prod_c_cs0 {
				prod = <0x4 0xfff 0x11>;
			};
		};

		spi@0 {
			compatible = "tegra-spidev";
			reg = <0x0>;
			spi-max-frequency = <0x1f78a40>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x11>;
				nvidia,cs-setup-clk-count = <0xa>;
				nvidia,cs-hold-clk-count = <0xa>;
			};
		};

......

	};

The test code is the same.

static int transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
	int ret;
	int out_fd;

        struct spi_ioc_transfer tr = {0,};
	tr.tx_buf = (unsigned long)tx;
	tr.rx_buf = (unsigned long)rx;
	tr.len = len;
	tr.speed_hz = trans.speed_hz;
	tr.bits_per_word = trans.bits_per_word;
	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 1)
		printf("can't send spi message");
        return ret; 
}

int UserSpiDataExchange(uint8_t *pTxBuf, uint8_t *pRxBuf, uint32_t u32PackSize)
{
        transfer(xf_handle, pTxBuf, pRxBuf, u32PackSize);
	return 1;
}

int UserSys_Init(uint32_t u32SpiFreq)
{
        int ret;
        uint32_t mode;
        struct sched_param param = {.sched_priority = 99};
	if(xf_handle < 0 && u32SpiFreq != 0){
		xf_handle = open( DEVNAME, O_RDONLY);
		if(xf_handle < 0){
                        printf("Init error: %d\n", xf_handle);
			return -EIO;
                }
                mode = SPI_MODE_0;
                trans.speed_hz = u32SpiFreq;
                trans.bits_per_word = 8;
	        ret = ioctl(xf_handle, SPI_IOC_WR_MODE32, &mode);
	        if (ret == -1)
		        printf("can't set spi mode");

	        /*
	         * bits per word
	         */
	        ret = ioctl(xf_handle, SPI_IOC_WR_BITS_PER_WORD, &trans.bits_per_word);
	        if (ret == -1)
		        printf("can't set bits per word");

	        /*
	         * max speed hz
	         */
	        ret = ioctl(xf_handle, SPI_IOC_WR_MAX_SPEED_HZ, &trans.speed_hz);
	        if (ret == -1)
		        printf("can't set max speed hz");
   
	}
        pthread_setschedparam( pthread_self(), SCHED_FIFO, &param);
        return 0;
}

#define TEST_SPI_DATA_SIZE		128
#define TEST_SPI_FREQ			12000000
uint8_t RxPDOData[TEST_SPI_DATA_SIZE];
uint8_t TxPDOData[TEST_SPI_DATA_SIZE];
int main (int argc,char ** argv)
{
	FILE *fp = NULL;
	char data_char[20] = "\0";
	struct timespec current_time;
	int64_t current_time_ns, pre_current_time_ns;
    fp = fopen("spi_transfer_time.txt","w+");
    UserSys_Init(TEST_SPI_FREQ);
	while (1)
	{
		clock_gettime(CLOCK_MONOTONIC,&current_time);
		current_time_ns = TIMESPEC2NS(current_time);
		pre_current_time_ns = current_time_ns;
		UserSpiDataExchange(TxPDOData,RxPDOData,TEST_SPI_DATA_SIZE);
		clock_gettime(CLOCK_MONOTONIC,&current_time);
		current_time_ns = TIMESPEC2NS(current_time);
		sprintf(data_char,"%d%c",(current_time_ns - pre_current_time_ns),'\n');
		fprintf(fp,"%s",data_char);
		usleep(10000);
	}
}

In r3531, can SPI1 transfer time be reduced to as same as r3274?

Hi Xu_Xu,

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

It seems the similar issue as following topic.
Orin NX SPI delay between transfers - Jetson & Embedded Systems / Jetson Orin NX - NVIDIA Developer Forums
You could try to port the driver from K4.9 to K5.10 to check the performance.

I use the devkit board for AGX Xavier.
The current state is that the SPI transfer jitter of r3531 (K5.10) is greater. However, r3274 (K4.9) is lower (better performance).

Do you want me to follow the method you mentioned? That is to copy the spi-tegra114.c file from 4.9 into 5.10. If we use this method, do we still need to recompile the Linux kernel?

Please try to replace the SPI driver in K5.10(R35.3.1) with the spi-tegra114.c from K4.9(R32.7.4).
Yes, you would need to rebuild the kernel image and flash the board to apply the change.

Also turn on polling-mode with nvidia,polling-mode it works a lot better

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

Hi @Xu_Xu ,

Do you still have issue with the time gap between SPI packet on K5.10?