iMX8 SPI maximal burst size

Hello,

While sending 100 Bytes through SPI, a relatively big latency emerges after bursting 512bits (64Bytes) of data, then the SPI driver continue sending the rest bytes (36Bytes) as shown in picture:

How can increase the burst size (or how can i remove this latency)?

Oscilloscope:

SPI C code:

 #define SPI_CLK_SPEED 20 * 1000000
     #define SPI_BITS 8
     #define SPI_DELAY 0
     static const char *device = "/dev/spidev0.0";
     struct spi_ioc_transfer tr;
     int fd_spi;
     
     uint8_t default_tx[100] ;
     uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, };
     
     void transfer(int fd,struct spi_ioc_transfer* tr, uint8_t const *tx, uint8_t const *rx, size_t len)
     {
         int ret;
         tr->tx_buf = (unsigned long)tx;
         tr->rx_buf = (unsigned long)rx;
         tr->len = len;
     
     
         ret = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
         if (ret < 1)
         {
             pabort("can't send spi message");
             exit(1);
         }
     
     }
     
     int SPI_init( const char  *dev,struct spi_ioc_transfer *tr,uint32_t mode,uint8_t bits,uint32_t speed,uint16_t delay)
     {
         int spiFD,ret;
     
         tr->delay_usecs = delay;
         tr->speed_hz = speed;
         tr->bits_per_word = bits;
     
     
         if (mode & SPI_TX_QUAD)
             tr->tx_nbits = 4;
         else if (mode & SPI_TX_DUAL)
             tr->tx_nbits = 2;
         if (mode & SPI_RX_QUAD)
             tr->rx_nbits = 4;
         else if (mode & SPI_RX_DUAL)
             tr->rx_nbits = 2;
         if (!(mode & SPI_LOOP)) {
             if (mode & (SPI_TX_QUAD | SPI_TX_DUAL))
                 tr->rx_buf = 0;
             else if (mode & (SPI_RX_QUAD | SPI_RX_DUAL))
                 tr->tx_buf = 0;
         }
     
         spiFD = open(dev, O_RDWR);
         if (spiFD < 0)
             pabort("can't open device");
     
     
          // spi mode
         ret = ioctl(spiFD, SPI_IOC_WR_MODE32, &mode);
         if (ret == -1)
             pabort("can't set spi mode");
     
         ret = ioctl(spiFD, SPI_IOC_RD_MODE32, &mode);
         if (ret == -1)
             pabort("can't get spi mode");
     
     
          //bits per word
         ret = ioctl(spiFD, SPI_IOC_WR_BITS_PER_WORD, &bits);
         if (ret == -1)
             pabort("can't set bits per word");
     
         ret = ioctl(spiFD, SPI_IOC_RD_BITS_PER_WORD, &bits);
         if (ret == -1)
             pabort("can't get bits per word");
     
     
          // max speed hz
         ret = ioctl(spiFD, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
         if (ret == -1)
             pabort("can't set max speed hz");
     
         ret = ioctl(spiFD, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
         if (ret == -1)
             pabort("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 KHz)\n", speed, speed/1000);
         return (spiFD);
     
     }
     
     int main()
     {
          fd_spi = SPI_init(device,&tr,SPI_MODE,SPI_BITS,SPI_CLK_SPEED,SPI_DELAY);
          fd_spi01 = 
          while(1)
          {
                usleep(200);
                transfer(fd_spi,&tr, default_tx, default_rx, 100);
          }
     }

HI @majd.m

Thanks for writing to the Toradex Community!

How can increase the burst size (or how can i remove this latency)?

What exactly is your Application? What is your use-cse?

Best regards,
Jaski

Hello @jaski.tx,

Thanks for your respond. I use the SPI for a userspace driver in which about 100 bytes at a time is sent using spi. I noticed this delay in the communication and wonderd whether I need to change something to remove it.

Best regards, Majd

Hi @majd.m

I was able to reproduce your issue. Actually with higher clock frequency the delay between bursts of 64 Bytes becomes bigger and with lower clock frequency smaller. You can continuously send data, if the SPI Clock frequency is 6MHz or lower.

You can reduce/remove the delay between two bursts of 64 bytes by enabling the DMA in the device-tree as following:

--- a/arch/arm64/boot/dts/freescale/fsl-imx8qm-apalis.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qm-apalis.dtsi
@@ -1116,7 +1116,7 @@
        pinctrl-0 = <&pinctrl_lpspi0>;
        #address-cells = <1>;
        #size-cells = <0>;
-       dma-names = "no","no";
+       dma-names = "tx","rx";
 
        spidev0: spi@0 {
            compatible = "toradex,evalspi";

However, there is a side effect that the chip select goes up after sending every 1Byte. Depending on your Application, this might be an Issue. You can also try to use a regular GPIO controlled by user Application instead of using the Chipselect by Hardware.

As another Alternative you can also use M4 for the Spi Communication and synchronize the data between the ARM CPU and M4 using Rpmsg driver.

Best regards,
Jaski