@Sergey78

ESP32, SPI-Slave, откуда «лишние» байты?

Добрый день. Пытаюсь связать stm32 и esp32 по SPI. Stm32 как мастер, ESP как slave.
От мастера шлю в формате 8-bit. Цель - принять байт на ESP32, ответить байтом обратно.
Поскольку обмен по 1 байту, DMA не использую.
В качестве примера взял код из ESP-IDF, (esp-idf/examples/peripherals/spi_slave/receiver).
Немного упростил, убрал буферы приема, в итоге получилось:
Код
#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++;
    }
}



С stm32 шлю 8-bit данные, каждый раз увеличивая значение на 3 и читаю, что в ответ от esp пришло.
На ESP32 после каждого вызова spi_slave_transmit увеличиваю значение n и отправляю его обратно на следующей передаче.
Код из примера изменен в части вызова spi_slave_initialize, последний параметр 0, т.е. не использовать DMA и в инициализации spi_slave_interface_config_t, queue_size установлен в 1.
Скорость SPI минимальная.
Собственно суть проблемы: на каждый отправленный байт с stm32, значение n увеличивается трижды. Т.е. и spi_slave_transmit вызывается трижды и вывод в консоль. Но реально передается только первое значение (я со стороны stm32 смотрю в отладчике).
Для наглядности, вот вывод в консоли от esp32:
Вывод
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



Выводится соответственно значение n и полученное значение. Как видно, на каждый полученный байт, значение n увеличивается трижды.
От stm32 пришло значение 46, обратно отослали 218. Это на стороне stm32 я вижу, 218 пришло. А вот 219 и 220 нет. Оно и не может придти, поскольку передачей мастер заведует, а шлет он одно значение только 1 раз. Код там примитивный, но на всякий случай осциллографом проверил.

Откуда эти лишние вызовы? Если останавливаю передачу со стороны stm32, вывод со стороны esp32 тоже останавливается, т.е. в spi_slave_transmit она ждет приема.
  • Вопрос задан
  • 819 просмотров
Пригласить эксперта
Ответы на вопрос 1
AndyKorg
@AndyKorg
Кнопконажиматель и припоерасплавлятель
Че-то подозреваю, что надо очередь приема очищать. Потому как вот тут пишут:
"Receive an item from a queue without removing the item from the queue...."
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы