ESP-IDF problem in SPI latency

Moondrop
Posts: 5
Joined: Tue Aug 31, 2021 6:27 pm

ESP-IDF problem in SPI latency

Postby Moondrop » Wed Dec 21, 2022 12:39 pm

Hi All.
I am trying to port some code from Arduino to ESP-IDF, and I am encounetring a strange behaviour regarding to SPI timings.

My arduino code is:

Code: Select all

SPIClass spiV = SPIClass(VSPI);
spiV.begin(-1, -1, -1, -1);
spiV.beginTransaction(SPISettings(40000000, MSBFIRST, SPI_MODE3));
bufIdx = 0;
intToRead = 0;
while (intToRead < 6) { 
          digitalWrite(CHIP_SELECT, LOW);
          psdRamBuffer[bufIdx++] = spiV.transfer16(0x00);
          digitalWrite(CHIP_SELECT, HIGH);
          intToRead++;
}

digitalWrite(CHIP_SELECT, LOW);
spiV.transfer16(0x00);
digitalWrite(CHIP_SELECT, HIGH);

digitalWrite(CHIP_SELECT, LOW);
spiV.transfer16(0x00);
digitalWrite(CHIP_SELECT, HIGH);
spiV.endTransaction();
In the code above the full spi read (16bits * 8times) takes 30us. When I ported this code to ESP-IDF environment the same read (16bits * 8 times) takes 3 times longer (around 80us in average). My ESP-IDF code:

Code: Select all

    spi_device_handle_t spi;
    spi_bus_config_t buscfg = {
        .miso_io_num = (gpio_num_t)VSPI_IOMUX_PIN_NUM_MISO,
        .mosi_io_num = (gpio_num_t)VSPI_IOMUX_PIN_NUM_MOSI,
        .sclk_io_num = (gpio_num_t)VSPI_IOMUX_PIN_NUM_CLK,
        .data2_io_num = -1,
        .data3_io_num = -1,
        .data4_io_num = -1,
        .data5_io_num = -1,
        .data6_io_num = -1,
        .data7_io_num = -1,
        .flags = SPICOMMON_BUSFLAG_IOMUX_PINS,
        .max_transfer_sz = 16
    };

    ret = spi_bus_initialize(VSPI_HOST, &buscfg, /*DMA_CHAN*/0);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Error initializing SPI bus");
        return ESP_FAIL;
    }
     
    spi_device_interface_config_t devcfg = {
        .command_bits = 0,
        .address_bits = 0,
        .dummy_bits = 0,
        .clock_speed_hz = SPI_MASTER_FREQ_40M,
        .mode = 3,          //SPI mode 3
        .spics_io_num = -1,
        .queue_size = 8,
        .flags = SPI_DEVICE_HALFDUPLEX,
        .input_delay_ns = SPI_INPUT_DELAY_NS,
    };

    // Configure SPI
    err = spi_bus_add_device(VSPI_HOST, &devcfg, &spi);
    if  (err != ESP_OK) {
        return err;
    }
    
    spi_transaction_t t = {
        .rxlength = 16,
        .length = 0,
        .flags = SPI_TRANS_USE_RXDATA,
        .tx_buffer = NULL
    };

#pragma GCC unroll 8
    for (int i = 0; i < 8; i++) {
       gpio_set_level(SPI_CS_IO, 0);
        esp_err_t err = spi_device_polling_transmit(ctx->spi, &t);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "Error %d in spi_device_polling_transmit", err);
            return err;
        }
        gpio_set_level(SPI_CS_IO, 1);
    }
    
How can I bring me ESP-IDF code to the same latencies that I see in Arduino code? How come it takes 2.5 times longer?

Who is online

Users browsing this forum: No registered users and 95 guests