Orophilia
Orophilia

Reputation: 1

SPI Data Transfer ESP32-H2 to ESP32-H2, Arduino IDE. Can't get Slave to receive data

I'm an old guy (70) developing a complex instrument, and I have almost everything else working. The only thing left is SPI communication between two ESP32-H2 chips hardwired on the same board. This is my first post to any forum, so please inform me about how to use it effectively and not waste your time. I've tried three days of AI bots, Espressif documentation, reading forum posts, etc., without luck.

I can get the master to work, as verified with an o-scope, but I never get received data in the slave. It's always zero.

Here is an example of the many things I've been trying:

#include <SPI.h>

const int MOSI_PIN = 25;
const int MISO_PIN = 26;
const int SCLK_PIN = 27;
const int CS_PIN = 22;

volatile byte receivedData = 0;
volatile bool dataReceived = false;

// Interrupt Service Routine (ISR)
void IRAM_ATTR handleSPInterrupt() {
  receivedData = SPI.transfer(0); // Receive data while sending dummy byte
  dataReceived = true;
}

void setup() {
  Serial.begin(115200);

  // Initialize SPI with custom pins
  SPI.begin(SCLK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);
  SPI.setClockDivider(SPI_CLOCK_DIV16); // Adjust clock divider if needed

  // Configure CS pin as input with pullup
  pinMode(CS_PIN, INPUT_PULLUP);

  // Attach interrupt handler
  attachInterrupt(digitalPinToInterrupt(CS_PIN), handleSPInterrupt, FALLING); 

  Serial.println("SPI Slave Initialized.");
}

void loop() {
  if (dataReceived) {
    Serial.print("Received: ");
    Serial.println(receivedData, HEX);
    dataReceived = false; 
  }
}

This produces a clear bus conflict. SCLK and MOSI are half amplitude with overlapping data interspersed. If I use pinMode() to set MOSI and SCLK as inputs the signals from the master are normal, but the received data is still always zero. I've tried many other things not documented here. Thanks for any help you can provide!

Upvotes: 0

Views: 44

Answers (1)

Tom V
Tom V

Reputation: 5510

You know you need one master and one (or more) slaves, right?

From the Arduino docs, SPI.begin() can only ever set up an SPI master. Setting up an SPI master and then turning the pins to input will prevent the hardware bus conflict, but won't make it work. Your master will still think it is driving the clock, even though though the pins aren't outputting anything. It will read the data line synchronously with the clock it thinks it is outputting. You want it to read the data line synchronously with the clock it receives.

Making an SPI slave is more complicated. Here is one tutorial and another code sample.

Upvotes: 0

Related Questions