Page 1 of 1

SPI driver - huge delay between transmits Why?

Posted: Tue May 05, 2026 4:22 pm
by NikolaiBaschinski
Hi folks!

I use the ESP SPI master driver for LCD communication (ILI9341). I observe a huge delay between transmits. Transmitting a byte takes 2 us, but the delay is 60us (Debug optimization). Is it possible to make the delay smaller?

Here is my code

Code: Select all

void spi_lcd_init(void)
{
  esp_err_t rv;

  // 1. config the bus
  spi_bus_config_t spi_bus_cfg = {
    .mosi_io_num = GPIO_NUM_7,// DIN (MOSI)
    .miso_io_num = -1,        // not used
    .sclk_io_num = GPIO_NUM_6,// CLK
    .quadwp_io_num = -1,
    .quadhd_io_num = -1,
    .max_transfer_sz = SPI_MAX_TX_BUFFER_SIZE
  };

  rv = spi_bus_initialize(SPI2_HOST, &spi_bus_cfg, SPI_DMA_CH_AUTO);
  if (rv == ESP_OK) {
    ESP_LOGI("", "SPI bus initialization successfully");
  } else {
    ESP_LOGE("", "SPI bus initialization failed with %d", rv);
    while(1);
  }

  // 2. config the device
  spi_device_interface_config_t devcfg = {
    .clock_speed_hz = 4 * 1000 * 1000,
    .mode = 0,
    .spics_io_num = GPIO_NUM_10, // CS Pin
    .queue_size = 1,
    .flags = 0,
    .command_bits = 0,
    .address_bits = 0,
    .dummy_bits = 0
  };

  rv = spi_bus_add_device(SPI2_HOST, &devcfg, &lcd_spi);
  if (rv == ESP_OK) {
    ESP_LOGI("", "SPI added device successfully");
  } else {
    ESP_LOGE("", "SPI adding device failed with %d", rv);
    while(1);
  }
}

Code: Select all

void spi_send(uint8_t byte)
{
    spi_transaction_t t = {
        .length = 8,
        .tx_buffer = &byte,
        .rx_buffer = NULL
    };

    spi_device_transmit(lcd_spi, &t);
}

Re: SPI driver - huge delay between transmits Why?

Posted: Wed May 06, 2026 2:06 am
by Sprite
Transfer larger blocks at a time. There's a fair amount of overhead involved in setting up a SPI transfer, and if you use all that overhead to only send one single byte, your throughput will go down the drain.

Re: SPI driver - huge delay between transmits Why?

Posted: Fri May 08, 2026 3:33 pm
by NikolaiBaschinski
Unfortunately, I have to keep switching back and forth between Data and Command for ILI9341. I can't get it synchronized when I send everything all at once.

In the meantime, I found it in the documentation. ESP makes a big delay between transmissions. :?

Code: Select all

The typical transaction duration for one byte of data is given below.
    Interrupt Transaction via DMA: 34 µs.
    Interrupt Transaction via CPU: 32 µs.
    Polling Transaction via DMA: 17 µs.
    Polling Transaction via CPU: 15 µs.

https://docs.espressif.com/projects/esp ... n-duration

Re: SPI driver - huge delay between transmits Why?

Posted: Sat May 09, 2026 5:23 am
by Sprite
Generally, you send a command (in order to send e.g. display data) and then a large block of data. We actually have a nice example specifically for your display controller: https://github.com/espressif/esp-idf/tr ... master/lcd . That sends the data 16 lines at a time, meaning the overhead of setting up a transaction is a relatively small part of the entire process.

Re: SPI driver - huge delay between transmits Why?

Posted: Fri Jul 31, 2026 10:11 am
by eriksl
My implementation has a SPI "data" buffer that only gets flushed whenever the max SPI transfer size is reached or a command needs to be sent. The IDF driver code probably does something similar. Still the SPI transfer won't ever be so fast you won't see the image building. In my case it takes about 0.2 secs to draw the screen. If you want instant image you need page flipping, which the generic SPI LCD controllers like the ilitech don't have, but e.g. the raio8875 does have, but it's more expensive.