Greetings!
I’m pretty new to this, and this is the first time I’ve tried to use SPI or work with an EEPROM chip.
After scouring the datasheet, I am fairly certain my SPI settings are correct, but I cannot get a simple write/retrieve routine to work. The bytes that come back from the device are not the bytes that I set.
There is obviously something that I am missing, but I can’t figure out what it is. I would really appreciate any feedback or suggestions.
The device in question is the Microchip 25LC2014 EEPROM (Datasheet)
Here is my code, in its entirety:
#include "application.h"
/* executes once at startup */
void setup() {
Serial.begin(115200);
// setup SPI
SPI.setBitOrder(MSBFIRST);
SPI.setClockSpeed(1,MHZ);
SPI.setDataMode(SPI_MODE3);
SPI.begin(SPI_MODE_MASTER);
Serial.println("Starting up...");
delay(2000);
}
void writeEnable() {
byte rec;
digitalWrite(A2,LOW); // select this device on the SPI bus
rec = SPI.transfer(6); // send write enable command
Serial.printf("Got back from write enable command: %d\n",rec);
digitalWrite(A2,HIGH); // de-select this device on the SPI bus to enable latch
delay(100); // wait for latch to set
digitalWrite(A2,LOW); // select this device on the SPI bus
rec = SPI.transfer(2); // send the write command
Serial.printf("Got back from write command: %d\n",rec);
}
void selectAddress(size_t address) {
byte rec;
rec = SPI.transfer((char)(address>>16)); // send MSB
Serial.printf("Got back from address command 1: %d\n",rec);
rec = SPI.transfer((char)(address>>8)); // send next bit
Serial.printf("Got back from address command 2: %d\n",rec);
rec = SPI.transfer((char)(address)); // send LSB
Serial.printf("Got back from address command 3: %d\n",rec);
}
void writeDisable() {
digitalWrite(A2,HIGH); // release the chip
}
/* executes continuously after setup() runs */
void loop() {
byte rec;
uint8_t rx_buffer[12] = {};
uint8_t tx_buffer[12] = {};
for (int i = 0; i < sizeof(tx_buffer); i++)
tx_buffer[i] = random(254);
Serial.print("Generated: ");
for (int i = 0; i < sizeof(tx_buffer); i++) {
Serial.print(tx_buffer[i]);
Serial.print(",");
}
Serial.printf("\n");
writeEnable();
selectAddress(128);
for (int i = 0; i < sizeof(tx_buffer); i++) {
rec = SPI.transfer(tx_buffer[i]);
Serial.printf("Sent byte: %d\n",rec);
}
writeDisable();
delay(100);
digitalWrite(A2,LOW); // select this device on the SPI bus
rec = SPI.transfer(3); // send read command
Serial.printf("Got back from read command: %d\n",rec);
selectAddress(128);
for (int i = 0; i < sizeof(rx_buffer); i++) {
rx_buffer[i] = SPI.transfer(0);
Serial.printf("Received byte: %d\n",rx_buffer[i]);
}
digitalWrite(A2,HIGH); // deselect this device on the SPI bus
delay(100);
Serial.print("Retrieved: ");
for (int i = 0; i < sizeof(rx_buffer); i++) {
Serial.print(rx_buffer[i]);
Serial.print(",");
}
Serial.printf("\n\n");
delay(5000);
}
I have tried both forms of the SPI.transfer method (loop myself vs DMA), but neither one seems to work. I don’t know whether the issue is that the data isn’t being set properly or if it is that the data isn’t being read properly after set. Unfortunately, I do not have access to an oscilloscope, so I’m flying a bit blind right now.
Here’s an example of the output from running the program:
Generated: 37,183,108,211,2,110,122,182,124,199,235,109,
Got back from write enable command: 254
Got back from write command: 2
Got back from address command 1: 0
Got back from address command 2: 0
Got back from address command 3: 128
Sent byte: 37
Sent byte: 183
Sent byte: 108
Sent byte: 211
Sent byte: 2
Sent byte: 110
Sent byte: 122
Sent byte: 182
Sent byte: 124
Sent byte: 196
Sent byte: 235
Sent byte: 109
Got back from read command: 3
Got back from address command 1: 0
Got back from address command 2: 0
Got back from address command 3: 128
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Received byte: 0
Retrieved: 0,0,0,0,0,0,0,0,0,0,0,0,
I do not know if SPI.transfer() simply returns what was passed to it, or if it returns what it read from the device. My EEPROM says to send clock pulses to read bytes after sending the read command+address bytes. Perhaps I need to use a different way of reading, rather than using SPI.transfer?
Thanks in advance for any help!