Hi,
I try to write a SPI protocol driver (kernel space) using Linux 3.10.70 kernel. The SPI transfer works so far, but serveral transfers to read or write registers on the slave chips have long delays. Looking at the SPI signals I see that the CS signal is much too long, and here are also small waits between the transfered bytes.
I use 8MHz SPI clock speed.
The registers are all 8bit and one transaction consists of 4 bytes:
Write:
<addr write ctrl> <register addr> <data write ctrl> <data>
Read:
<addr write ctrl> <register addr> <data read ctrl> <data>
Example data read:
Complete transaction (same read):
You see that the chip select is much longer activ as needed, about 4us before SPI clock starts and about 40 us after the transaction did end.
My code for read is simple:
static u8 read_xhfc_spi(struct xhfc_spi *xs, u8 reg)
{
int ret;
xs->txd[0] = XSPI_ADDR | XSPI_WR | xs->dev_n;
xs->txd[1] = reg;
xs->txd[2] = XSPI_DATA | XSPI_RD;
xs->spi_xfer.tx_buf = xs->txd;
xs->spi_xfer.rx_buf = xs->rxd;
xs->spi_xfer.len = 4;
ret = spi_sync(xs->pdev, &xs->spi_msg);
if (ret) {
dev_err(&xs->pdev->dev, "error %d on spi_sync() for read 0x%02x\n", ret, reg);
xs->rxd[3] = 0;
}
return xs->rxd[3];
}
The xs->spi_msg is setuped as follows and reused every time:
spi->bits_per_word = 8; | |
/* initialise pre-made spi transfer messages */ | |
spi_message_init(&xs->spi_msg); | |
spi_message_add_tail(&xs->spi_xfer, &xs->spi_msg); |
Do you have an idea, why this happens and how to change the behavior, or what I doing wrong ?
Thanks
Karsten
Hi,
the issue with the long chip select is fixed, it was a misconfiguration of the chipselect pin.
We are using PAD_KEY_ROW1 for it. It was configured as GPIO and the GPIO was given to the SPI master driver as
chip select. This caused the long activation of the signal (Still unknown why - do you haven an idea ?).
I reconfigured the PAD to act as ECSPI1_SS0 and now the SPI transfer itself looks much better:
But the performance of multiple short transactions seems to be still very poor. I see 45 - 65 us delay between 2 transaction which are
2 register reads with only 2 if test for bits in the first read result between. Also writes have the same delay between single transactions.
Is this performance normal for the ECSPI inside the linux kernel ?
Hi,
I wonder if you can share the code to take a look at it?
If you are performing the something like :
/*Send first message*/
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
/*Send Second message*/
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
For each message to transfer, I think it makes sense the delay between messages.
I assume the kernel performs other tasks between the messages and therefore it takes more time get back and send the other frames.
/Alejandro