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, ¶m);
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,¤t_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,¤t_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?