I am currently working on a project where I use an ESP32 as an SPI slave to receive data from another device. I follow the official ESP-IDF example for an SPI slave receiver, which can be found here:
https://github.com/espressif/esp-idf/bl ... app_main.c
I need to use a large buffer for my project. Now I set the buffer size to 1024 (buffer_size = 1024), but I anticipate needing an even larger buffer in the future.
Here is my code:
Code: Select all
// Slave as receiver for SPI communitation
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "lwip/igmp.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "soc/rtc_periph.h"
#include "driver/spi_slave.h"
#include "esp_log.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
// Pins in use
#define GPIO_MOSI 23
#define GPIO_MISO 19
#define GPIO_SCLK 18
#define GPIO_CS 5
#define buffer_size 1024
DMA_ATTR uint32_t recvbuf[buffer_size];
//Main application
void app_main(void)
{
//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,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
//Configuration for the SPI slave interface
spi_slave_interface_config_t slvcfg={
.mode=1,
.spics_io_num=GPIO_CS,
.queue_size=3,
.flags=0,
};
//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
spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO);
//WORD_ALIGNED_ATTR uint32_t recvbuf[buffer_size];
for (int i =0; i < buffer_size; i++){
recvbuf[i] = 0xA5000000;
}
spi_slave_transaction_t t;
memset(&t, 0, sizeof(t));
printf("Slave output:\n");
while(1) {
t.length=buffer_size*4*8;
t.rx_buffer=recvbuf;
spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
for (int i = 0; i < buffer_size; i++){
printf("Received: %08lX, term %d\n", (unsigned long)recvbuf[i] & 0xFFFFFFFF, i);
}
}
}
Initially, I used the following buffer declaration: WORD_ALIGNED_ATTR uint32_t recvbuf[buffer_size];, but it got a stack overflow issue. After consulting https://docs.espressif.com/projects/esp ... types.html, it seems that placing DMA buffers in the stack is possible but discouraged. The documentation suggests using the DMA_ATTR macro for global or local static variables instead. So I adjusted my buffer declaration to: DMA_ATTR uint32_t recvbuf[buffer_size];
This change seemed to resolve the stack overflow problem. However, I am now facing a new issue: the buffer continuously outputs its initialized contents, even when no SS (Slave Select) and CLK (Clock) signals are applied.
I would greatly appreciate any suggestions or advice on how to resolve this issue. Additionally, I wonder if there are any examples of SPI slave implementations using larger buffers that I could refer to? That would be very helpful.