Page 1 of 1

[help needed] SPI communication between two esp32

Posted: Thu Dec 15, 2022 8:59 pm
by olupolup
[This question have also been posted on reddit]

Hi,

I am trying to send a picture from an esp32 to another esp32 through spi.The slave's code is provided by the board maker and can be found here. They also provide a python code to run on a master Raspberry Pi.

They implemented a kind of state machine on the slave that is run by sending spi command (start, start jpeg send, piece of data sent, end process, etc...). The command consists of a trigger (2x 0x55), the command number (2 bytes) the length of the payload (2 bytes) the payload (x bytes), and padding to make it all dividable by 8.

Only, I want to manage this slave with another esp32 rather than a Raspberry. I tried porting the python code to Arduino c, the parts I need anyway, and I can't make it work. The worst part is that individual commands works, sometimes. The whole shebang, never.

To reduce to something manageable (without throwing in a JPEG size payload) just sending a single command works around 3 out of 5 tries. Here is an example code (it's using the Arduino based library, the slave uses esp-idf):

Code: Select all

#include <Arduino.h>
#include <SPI.h>

#define HSPI_MISO 19 // not used

#define HSPI_MOSI 23
#define HSPI_SCLK 22
#define HSPI_SS 18

#define PACKET_SIZE 4000 // unused in this example

SPIClass *hspi = NULL;

// called in the init()
void setup_spi()
{

    Serial.println("Seting up SPI");
    // initialise instance of the SPIClass attached to HSPI
    hspi = new SPIClass(HSPI);

    // alternatively route through GPIO pins
    hspi->begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS); // SCLK, MISO, MOSI, SS

    // set up slave select pins as outputs as the Arduino API
    // doesn't handle automatically pulling SS low
    pinMode(HSPI_SS, OUTPUT); // HSPI SS
}

void send_run_cmd()
{
    uint8_t payload[8] = {0x55, 0x55, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
    hspi->writeBytes(payload, 8);
}

// called at the end of init()
void test_spi()
{

    hspi->beginTransaction(SPISettings(3900000, MSBFIRST, 0b11));
    digitalWrite(HSPI_SS, LOW);

    send_run_cmd();

    digitalWrite(HSPI_SS, HIGH);
    hspi->endTransaction();
    Serial.println("cmd sent");
}
So is there something clearly obvious I am doing wrong? Some classical mitigation path?
I'll add that I tried a couple of ways to debug already:

- I used two printf statements on the slave to debug: one showing the number of bytes received, and the one with the command decoded (number of commands)

So sometimes the commands are received, but most of the time not. Nb of bytes received is sometimes 0. Sending three commands in a row results sometimes in those three, sometimes just two, sometimes just one, and sometimes nothing.

- I tried different boards, different pins, and different clock speeds. However, on this, I used random numbers, but I understand now that actually specific clock speed should be used. I couldn't find exactly what clock speed should be authorized - but from experience, anything under 125 kHz did not work at all. I haven't been over the example's 3.9 MHz

- I use the same clock type as the slave (3)

- I tried sending everything in a single operation (one CS low before, one CS high after) or having one transaction per command. I tried waiting between command as well. This did not have significant impact.

All in all, I think I have a half cooked knowledge on SPI, so some discovery/testing steps are unknown to me. Any idea on how I can go further ?