espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.7k stars 7.3k forks source link

SPI issue in v4.1: DMA MOSI transmissions have gaps, but SCK does not. (IDFGH-4569) #6386

Open benpeoples opened 3 years ago

benpeoples commented 3 years ago

Environment

Problem Description

When doing large (4608 bytes, in this case) SPI transactions using DMA, there are gaps in the MOSI datastream that are not matched by the SCK datastream.

That is to say: there are the expected (due to RTOS task switching) disruptions in the MOSI line, but the SCK line continues clocking. This, of course, completely destroys the integrity of the data as the MOSI line is read as 0x00.

Expected Behavior

When MOSI pauses, SCK should pause as well.

Steps to reproduce

Execute the attached code

Code to reproduce this issue

https://gist.github.com/benpeoples/47d9837120fe606ac625795654f43447

This fills the framebuffer with a repeating pattern of 0x01 0x02 0x03 and then transmits it, using DMA as the buffer is larger than 64 bytes.

Revising the lcd_cmd function with this:

void lcd_cmd(spi_device_handle_t spi)
{
    esp_err_t ret;
    spi_transaction_t t;

    for(int x = 0; x < 72; x++)
    {
    memset(&t, 0, sizeof(t));       //Zero out the transaction
    t.length=64*8;                     //Command is 8 bits
    t.tx_buffer=framebuffer+x*64;               //The data is the cmd itself
    ret=spi_device_transmit(spi,&t); 
    assert(ret==ESP_OK);            //Should have had no issues.
    }

}

is the workaround I'm currently using, and this works with short (44us) gaps between the transmissions. I took manual control of the CS line so we don't toggle that between spi_device_transmits

Here are the SPI traces in PulseView: https://imgur.com/a/5Iabif7

The top signal is MOSI, the lower signal is SCK. While I did not zoom all the way in, the SCK clock is clean and consistent through these MOSI pauses.

Alvin1Zhang commented 3 years ago

Thanks for reporting.