S
S
Sergey782019-01-11 17:46:38
Iron
Sergey78, 2019-01-11 17:46:38

ESP32, SPI-Slave, where are the "extra" bytes from?

Good afternoon. I'm trying to connect stm32 and esp32 via SPI. Stm32 as master, ESP as slave.
From the master I send in 8-bit format. The goal is to receive a byte on the ESP32, respond with a byte back.
Since the exchange is 1 byte, I do not use DMA.
As an example, I took the code from ESP-IDF, (esp-idf/examples/peripherals/spi_slave/receiver).
I simplified it a bit, removed the receive buffers, as a result it turned out:

The code
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "driver/spi_slave.h"
#include "esp_spi_flash.h"

#define GPIO_MOSI 13
#define GPIO_MISO 12
#define GPIO_SCLK 14
#define GPIO_CS 15

uint8_t n=0;
uint8_t recvbuf=0;
QueueHandle_t spi_data;

void my_post_trans_cb(spi_slave_transaction_t *trans) {
    xQueueSend(spi_data,&recvbuf,0);
}


void print_task(void *pvParameter)
{
    uint8_t data=0;
    while(1) {
        xQueueReceive(spi_data,(void *)&data,portMAX_DELAY);
        printf("Send (n): %d Received: %d\n", n, data);
    }
}


//Main application
void app_main()
{
    
    spi_slave_transaction_t t;

    spi_bus_config_t buscfg={
        .mosi_io_num=GPIO_MOSI,
        .miso_io_num=GPIO_MISO,
        .sclk_io_num=GPIO_SCLK
    };

    spi_slave_interface_config_t slvcfg={
        .mode=0,
        .spics_io_num=GPIO_CS,
        .queue_size=1,
        .post_trans_cb=my_post_trans_cb,
        .flags=0
    };

    spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 0);
    spi_data=xQueueCreate(1,sizeof(uint8_t));
    xTaskCreate(&print_task, "print_task", 8*1024, NULL, 5, NULL);
 
    while(1) {
        t.length=8;
        t.trans_len=8;
        t.tx_buffer=&n;
        t.rx_buffer=&recvbuf;
        spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
        n++;
    }
}


With stm32 I send 8-bit data, each time increasing the value by 3 and I read what came in response from esp.
On the ESP32, after each call to spi_slave_transmit, I increase the value of n and send it back on the next transfer.
The code from the example has been changed in the part of the call to spi_slave_initialize, the last parameter is 0, i.e. do not use DMA and in spi_slave_interface_config_t initialization, queue_size is set to 1.
SPI speed is minimum.
Actually the essence of the problem: for each byte sent from stm32, the value of n increases three times. Those. and spi_slave_transmit is called three times and output to the console. But only the first value is really transmitted (I look from the stm32 side in the debugger).
For clarity, here is the console output from esp32:
Conclusion
Send (n): 218 Received: 46
Send (n): 219 Received: 46
Send (n): 220 Received: 46
Send (n): 221 Received: 49
Send (n): 222 Received: 49
Send (n): 223 Received: 49
Send (n): 224 Received: 52
Send (n): 225 Received: 52
Send (n): 226 Received: 52


The value of n and the resulting value are output, respectively. As you can see, for each received byte, the value of n increases three times.
The value 46 came from stm32, 218 was sent back. I see it on the stm32 side, 218 came. But 219 and 220 are not. It cannot come, since the master is in charge of the transfer, and he sends one value only 1 time. The code there is primitive, but just in case I checked it with an oscilloscope.
Where do these extra calls come from? If I stop the transfer from the stm32 side, the output from the esp32 side also stops, i.e. in spi_slave_transmit, it is waiting to be received.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Skorzhinsky, 2019-01-12
@AndyKorg

Che something I suspect that it is necessary to clear the reception queue. Because here they write:
"Receive an item from a queue without removing the item from the queue...."

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question