Hi @jaski.tx,
I’m working on the same issue of @andrecurvello. The problem is that between two consecutive SPI transfers we always have an interval of around 150us with SPI bus idle, even with delay_us set with zero. We need perform thousands of consecutive SPI transfers and an interval of 150us between messages really mean a problem for us.
You can use the following code to reproduce the problem:
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define FILE_DESCRIPTOR "/dev/spidev3.0"
#define VERBOSE 0
enum transfer_sequence {
ADDR_HIGH = 0,
ADDR_LOW,
STATUS,
DATA_HIGH,
DATA_LOW,
TRANSFER_SIZE
};
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
uint16_t tx[TRANSFER_SIZE];
uint16_t rx[TRANSFER_SIZE];
uint32_t data = 0;
uint8_t verbose = VERBOSE;
const char *device = FILE_DESCRIPTOR;
uint32_t mode = 0;
uint8_t bits = 16;
uint32_t speed = 5000000;
uint16_t delay = 0;
uint8_t len_msg = sizeof(__u16)*TRANSFER_SIZE;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)&tx,
.rx_buf = (unsigned long)&rx,
.len = len_msg,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
fd = open(device, O_RDWR);
if (fd < 0)
printf("can't open device");
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
if (ret == -1)
printf("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode);
if (ret == -1)
printf("can't get spi mode");
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
printf("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
printf("can't get bits per word");
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
printf("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
printf("can't get max speed hz");
printf("spi mode: 0x%x\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d MHz)\n", speed, speed/1000000);
tx[ADDR_HIGH] = 0x0000;
tx[ADDR_LOW] = 0x0000;
tx[STATUS] = 0x0000;
tx[DATA_HIGH] = 0x0000;
tx[DATA_LOW] = 0x0000;
while(1) {
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1) {
printf("can't send spi message");
}
if (verbose) {
data = (uint32_t) (0x0000FFFF & rx[DATA_LOW]);
data |= (uint32_t) (0xFFFF0000uL & (rx[DATA_HIGH] << 16));
printf("RX = 0x%08x\n", data);
}
}
close(fd);
return ret;
}
This is the definition of SPI on device tree:
spidev30: spidev3@0 {
compatible = "toradex,evalspi";
reg = <0>;
spi-max-frequency = <50000000>;
fsl,spi-cs-sck-delay = <100>;
fsl,spi-sck-cs-delay = <50>;
status = "okay";
};
The following picture shows samples from SPI bus:
Do you have some sugestion to reduce this time ?
Best regards, Gustavo