Добрый день. Пытаюсь связать 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 она ждет приема.