0

I'm trying to simulate an EEPROM like M95040 with an Arduino Mega 2560 (SPI-Slave) and make requests with an ESP32 WROOM (SPI-Master).

This is the Arduino code based on Nick Gammon's:

#include <SPI.h>

static const byte transactionSize = 3;

#define EEPROM_TOTAL_BYTES  512
static uint8_t eeprom_memory[EEPROM_TOTAL_BYTES];

void setup()
{
  pinMode(MISO, OUTPUT);
  pinMode(MOSI, INPUT);
  pinMode(SS, INPUT);
  pinMode(SCK, INPUT);

  // Turn on SPI
  SPCR |= _BV(SPE);
  // Select slave mode
  SPCR &= ~_BV(MSTR);
  // Turn on interrupts
  SPCR |= _BV(SPIE);

  Serial.begin(9600);

  eeprom_memory[0] = 0xFA;
}

// SPI interrupt routine
ISR(SPI_STC_vect)
{
  static uint8_t received_data[transactionSize];
  static byte received_index = 0;

  received_data[received_index] = SPDR; // Read SPI-buffer

  if (received_index == transactionSize - 1)
  {
    byte command = received_data[0];
    byte address = received_data[1];
    byte response = 0;

    switch (command)
    {
      // Read memory array
      case 0x03:
        response = eeprom_memory[address];
        break;
    }

    SPDR = response; // Write response byte

    received_index = 0;

    Serial.print("Received command: 0x");
    Serial.print(command, HEX);
    Serial.print(", Address: 0x");
    Serial.print(address, HEX);
    Serial.print(", Response: 0x");
    Serial.println(response, HEX);
  }
  else
  {
    received_index++;
  }
}

void loop()
{}

And this is the ESP-IDF code:

#include <stdio.h>
#include "esp_log.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"

#define EEPROM_CMD_READ 0x03

static const char *TAG = "EEPROM";
static spi_device_handle_t spi;

void spi_init()
{
    spi_bus_config_t bus_config = {
        .miso_io_num = GPIO_NUM_19,
        .mosi_io_num = GPIO_NUM_23,
        .sclk_io_num = GPIO_NUM_18
    };

    ESP_ERROR_CHECK(spi_bus_initialize(VSPI_HOST, &bus_config, 1));

    spi_device_interface_config_t dev_config = {
        .clock_speed_hz = 1000000,
        .mode = 0,
        .spics_io_num = GPIO_NUM_5,
        .queue_size = 1,
        .command_bits = 8,
        .address_bits = 8
    };

    ESP_ERROR_CHECK(spi_bus_add_device(VSPI_HOST, &dev_config, &spi));
}

void eeprom_read(uint8_t addr, uint8_t *data)
{
    spi_transaction_t trans = {
        .flags = 0,
        .cmd = EEPROM_CMD_READ,
        .addr = addr,
        .length = 8,
        .rxlength = 8,
        .tx_buffer = NULL,
        .rx_buffer = data,
    };

    ESP_ERROR_CHECK(spi_device_transmit(spi, &trans));
}

void app_main()
{
    esp_log_level_set(TAG, ESP_LOG_DEBUG);
    spi_init();

    uint8_t data;
    uint8_t addr = 0;

    eeprom_read(addr, &data);
    printf("Data read from EEPROM at address 0x%02X: 0x%02X\n", addr, data);
}

The wiring is correct and I get the following output in Arduino's serial monitor:

Received command: 0x3, Address: 0x0, Response: 0xFA

But the ESP32 reads the address instead of the actual data:

Data read from EEPROM at address 0x00: 0x00

Elliot
  • 37
  • 7

0 Answers0