First SPI Transaction is Wrong
Posted: Fri Dec 06, 2024 10:17 pm
Hello Everyone!
I have been developing a program with a ESP32-C6 DevKitC-1(WROOM-1) and ESP-IDF v5.3.1 and have encountered an odd issue with SPI.
With the ESP configured as a slave, and restarting it, its first SPI transaction it receives is "wrong".
The data received is wrong, and the data it transmit is wrong.
All subsequent transactions have no problems receiving or sending.
Both the master and slave are transmitting 4 0x33 bytes.
After investigating with the logic analyzer, the only problem seems to be the firs transaction's MISO data.
All other transactions look fine on the logic analyzer.
I have attached a minimal example code that reproduces this: (SPI clk is 10MHz)
Here is the ESP32 Log: (Master Log Level set to DEBUG)
First Transaction: Second Transaction: Third Transaction: Any ideas or recommendations would be appreciated.
I have been developing a program with a ESP32-C6 DevKitC-1(WROOM-1) and ESP-IDF v5.3.1 and have encountered an odd issue with SPI.
With the ESP configured as a slave, and restarting it, its first SPI transaction it receives is "wrong".
The data received is wrong, and the data it transmit is wrong.
All subsequent transactions have no problems receiving or sending.
Both the master and slave are transmitting 4 0x33 bytes.
After investigating with the logic analyzer, the only problem seems to be the firs transaction's MISO data.
All other transactions look fine on the logic analyzer.
I have attached a minimal example code that reproduces this: (SPI clk is 10MHz)
Code: Select all
#include <stdio.h>
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "driver/spi_slave.h"
#include "driver/gpio.h"
#include "freertos/task.h"
// Logging Tag
static const char* TAG = "TEST";
// Define SPI pins
#define GPIO_MISO 20
#define GPIO_MOSI 19
#define GPIO_CLK 18
#define GPIO_CS 9
// Transaction buffer size
#define TRANSACTION_SIZE 4 // bytes
// Task for handling SPI transactions
void spi_task(void* parameters) {
ESP_LOGI(TAG, "SPI Task Start");
// Send and recieve buffers
uint8_t rx_buffer[TRANSACTION_SIZE];
uint8_t tx_buffer[TRANSACTION_SIZE];
// spi transaction struct
spi_slave_transaction_t trans;
memset(&trans, 0, sizeof(trans));
while (true) {
ESP_LOGI(TAG, "SPI Loop Start");
// Initialize transmit buffer
tx_buffer[0] = 0x33;
tx_buffer[1] = 0x33;
tx_buffer[2] = 0x33;
tx_buffer[3] = 0x33;
// Initialize receive buffer
memset(rx_buffer, 0, TRANSACTION_SIZE);
// Prepare the transaction
trans.length = TRANSACTION_SIZE * 8; // Transaction length in bits
trans.rx_buffer = rx_buffer;
trans.tx_buffer = tx_buffer;
// Wait for a transaction from the master
ESP_ERROR_CHECK(spi_slave_transmit(SPI2_HOST, &trans, portMAX_DELAY));
ESP_LOGI(TAG, "SPI Transaction Completed");
// Print the received data
printf("Received data: ");
for (int i = 0; i < TRANSACTION_SIZE; i++) {
printf("0x%02X ", rx_buffer[i]);
}
printf("\n");
}
ESP_LOGI(TAG, "SPI Task End");
}
void app_main(void) {
ESP_LOGI(TAG, "App Main Start");
// Setup GPIO
gpio_set_pull_mode(GPIO_MOSI, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(GPIO_CLK, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);
// Configuration for SPI slave interface
spi_bus_config_t spi_bus_cfg = {
.mosi_io_num = GPIO_MOSI,
.miso_io_num = GPIO_MISO,
.sclk_io_num = GPIO_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
//.max_transfer_sz = TRANSACTION_SIZE,
.flags = SPICOMMON_BUSFLAG_SLAVE,
};
spi_slave_interface_config_t spi_slave_cfg = {
.mode = 2,
.spics_io_num = GPIO_CS,
.queue_size = 1,
.flags = 0,
};
// Initialize SPI slave
ESP_ERROR_CHECK(spi_slave_initialize(SPI2_HOST, &spi_bus_cfg, &spi_slave_cfg, SPI_DMA_CH_AUTO));
// Start SPI Task
BaseType_t task_status = xTaskCreate(spi_task, "SPI_TASK", 4096, (void*)1, 2, NULL);
if (task_status != pdPASS) {
ESP_LOGE(TAG, "SPI Task Creation Failed");
abort();
}
ESP_LOGI(TAG, "App Main End");
}
And here are the three SPI transactions on the logic analyzer:D (320) spi_flash: trying chip: generic
I ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x15 (USB_UART_HPSYS),boot:0x1c (SPI_FAST_FLASH_BOOT)
Saved PC:0x400294a6
--- 0x400294a6: uart_hal_get_txfifo_count in ROM
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875720,len:0x1338
load:0x4086c110,len:0xc70
load:0x4086e610,len:0x2c18
entry 0x4086c110
I (49) cpu_start: Unicore app
D (49) cpu_start: Pro cpu up
--- Error: ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))
--- Waiting for the device to reconnect
D (502) intr_alloc: Connected src 72 to int 11 (cpu 0)
I (502) TEST: SPI Task Start
I (512) TEST: SPI Loop Start
I (512) TEST: App Main End
I (512) main_task: Returned from app_main()
I (16062) TEST: SPI Transaction Completed
Received data: 0x66 0x66 0x66 0x33
I (16062) TEST: SPI Loop Start
I (17022) TEST: SPI Transaction Completed
Received data: 0x33 0x33 0x33 0x33
I (17022) TEST: SPI Loop Start
I (18062) TEST: SPI Transaction Completed
Received data: 0x33 0x33 0x33 0x33
I (18062) TEST: SPI Loop Start
First Transaction: Second Transaction: Third Transaction: Any ideas or recommendations would be appreciated.