ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Talesduque
Posts: 11
Joined: Wed Jul 08, 2020 1:40 pm

ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby Talesduque » Wed Jul 08, 2020 2:09 pm

Hello friends, I'm an ESP32 newbie and I'm getting some doubts. Right now I'm trying to make my FPGA communicate with my ESP32 via SPI. The FPGA is working as the master and its working as intended, but sometimes the ESP32 doesnt read the whole message. The image attached shows the received messages. The first one with hex numbers from 0180 to 8001 is the correct message, the second ones is incomplete (7a7a comes from the memset I do every iteration of the code). Can anyone help me understand this? The master is workin on a 1MHz clock.

Code: Select all

#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 23//12
#define GPIO_MISO 19//13
#define GPIO_SCLK 18//15
#define GPIO_CS 5//14

 
//Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high.
void my_post_setup_cb(spi_slave_transaction_t *trans) {
    WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1<<GPIO_HANDSHAKE));
}

//Called after transaction is sent/received. We use this to set the handshake line low.
void my_post_trans_cb(spi_slave_transaction_t *trans) {
    WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1<<GPIO_HANDSHAKE));
}

//Main application
void app_main()
{
    int n=0;
    esp_err_t ret;

    //Configuration for the SPI bus
    spi_bus_config_t buscfg={
        .mosi_io_num=GPIO_MOSI,
        .miso_io_num=GPIO_MISO,
        .sclk_io_num=GPIO_SCLK
    };

    //Configuration for the SPI slave interface
    spi_slave_interface_config_t slvcfg={
        .mode=0,
        .spics_io_num=GPIO_CS,
        .queue_size=3,
        .flags=0,
        .post_setup_cb=my_post_setup_cb,
        .post_trans_cb=my_post_trans_cb
    };

    //Configuration for the handshake line
    gpio_config_t io_conf={
        .intr_type=GPIO_INTR_DISABLE,
        .mode=GPIO_MODE_OUTPUT,
        .pin_bit_mask=(1<<GPIO_HANDSHAKE)
    };

    //Configure handshake line as output
    gpio_config(&io_conf);
    //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
    gpio_set_pull_mode(GPIO_MOSI, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(GPIO_SCLK, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);

    //Initialize SPI slave interface
    ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1);
    assert(ret==ESP_OK);
    uint16_t recvbuf[129];   
    spi_slave_transaction_t t;
    memset(&t, 0, sizeof(t));
    int cont = 0;
    memset(recvbuf, 122 , 256 );
    while(1) {
    
        memset(recvbuf, 122 , 256 );
        t.length = 128*16;
        t.trans_len = 128*16; 
        t.rx_buffer= recvbuf;
        /* This call enables the SPI slave interface to send/receive to the sendbuf and recvbuf. The transaction is
        initialized by the SPI master, however, so it will not actually happen until the master starts a hardware transaction
        by pulling CS low and pulsing the clock etc. In this specific example, we use the handshake line, pulled up by the
        .post_setup_cb callback that is called as soon as a transaction is ready, to let the master know it is free to transfer
        data.
        */

        ret=spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);

        //spi_slave_transmit does not return until the master has done a transmission, so by here we have sent our data and
        //received data from the master. Print it
        //printf("%04x ;", recvbuf[0]);
        for(int i=0;i<128;i++)
            printf("%04x; ", recvbuf[i]);
        
        printf("\n");
        n++;
    }

}
Im sending 128 16 bit numbers.

Regards, Tales.
Attachments
spi.png
spi.png (50.63 KiB) Viewed 9100 times

usulrasolas
Posts: 26
Joined: Tue Jun 09, 2020 5:27 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby usulrasolas » Wed Jul 08, 2020 5:52 pm

try adjusting

spi_device_inerface_config_t
.cs_ena_posttrans

first is what I would do

Talesduque
Posts: 11
Joined: Wed Jul 08, 2020 1:40 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby Talesduque » Wed Jul 08, 2020 6:27 pm

What do you mean? ty for replying!

usulrasolas
Posts: 26
Joined: Tue Jun 09, 2020 5:27 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby usulrasolas » Wed Jul 08, 2020 8:14 pm

try adding
.cs_ena_posttrans = 3;
to
spi_slave_interface_config_t

Talesduque
Posts: 11
Joined: Wed Jul 08, 2020 1:40 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby Talesduque » Thu Jul 09, 2020 1:35 pm

But that setting is for master only. This is the slave!

usulrasolas
Posts: 26
Joined: Tue Jun 09, 2020 5:27 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby usulrasolas » Thu Jul 09, 2020 4:32 pm

Okay I get it, the connection drop is happening on the slave device, my apologies.

I only suggest because in an spi driver I was building it was needed to use posttrans to keep information from gettting dropped at end of transmission. But in my case it was esp32-s2 as master and external adc. not esp as slave.

you could try extending the value on the master to see if it improves anything? I am unsure if it will help but could be tested quickly I think

Talesduque
Posts: 11
Joined: Wed Jul 08, 2020 1:40 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby Talesduque » Thu Jul 09, 2020 5:59 pm

What do you mean by extending on the master?

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby PeterR » Thu Jul 09, 2020 6:31 pm

Without a detailed review:
I would not use the ESP as SPI slave. If you do then you must think clearly about latency. The 7a7a seems to indicate that you only received part of the message which then suggests that you only started the SPI slave transaction after the master had already started transmitting.
Handshaking with the ESP will take some effort. The ESP drivers will take 20uS+ setup for each transaction. I don't think that you have either dual or circular buffer DMA options & so you will always have down time between transactions. Add in interrupt latency EDIT: & blocking (100 uS by the book but I see >2mS on 4.1 beta when Ethernet enabled) and you get the picture. You can minimise latency with careful core planning but even so you do not have dual/circular DMA and so have an amount of software latency.
Instead I would be inclined to make the ESP master. Then the slower ESP can control the transaction. The other way around has to have extra delays as margin for error (if you think about it) so ESP master can be 'fastest' solution. Also typically the silicon is slave & an FPGA is silicon in my book.

EDIT: Send 1,2,3,4 etc from master to confirm that slave was not ready. Or a slow saw if the master is an ADC etc etc
& I also believe that IDF CAN should be fixed.

stdenits
Posts: 24
Joined: Sun May 17, 2020 3:18 pm

Re: ESP-IDF SPI Slave Receiver Example - Not receiving whole message.

Postby stdenits » Sat Jul 11, 2020 4:31 am

@ Talesduque
Hi.

I came across a similar problem.

Try to add some extra bytes to the expected receiving value.
Let say you are assuming to get exactly 68*8 bits, then set the value to the 80*8.

You may still need to add some dummy bytes from the SPI Master side.

Who is online

Users browsing this forum: No registered users and 110 guests