multiple transaction ECSPI1 transfers on iMX6 very slow

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

multiple transaction ECSPI1 transfers on iMX6 very slow

979 Views
pingus
Contributor I

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:

spitrans1.png

Complete transaction (same read):

spitrans2.png

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

Labels (3)
0 Kudos
2 Replies

575 Views
pingus
Contributor I

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:

spitrans3.png

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.

spitrans4.png

Is this performance normal for the ECSPI inside the linux kernel ?

0 Kudos

575 Views
alejandrolozan1
NXP Employee
NXP Employee

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

0 Kudos