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