SPI EEPROM with Arduino (25AA / 25LC)

I'm using some 25AA640 chips for a project. I'm having trouble getting any response from the chip. My most basic verification step right now is making sure I can read the status register. This is currently my wiring setup.

#include <SPI.h>
#define WP 8
#define HOLD 9
#define SCK 13
#define MOSI 11
#define MISO 12
#define CS 10

#define READ 0x03 // Read data from memory array beginning at selected address
#define WRITE 0x02 // Write data to memory array at beginning of selected address
#define WREN 0x06 // Set the write enable latch (enable write operations)
#define WRDI 0x04 // Reset the write enable latch (disable write operations)
#define RDSR 0x05 // Read Status register
#define WRSR 0x01 // Write STATUS register

uint8_t b;
uint8_t data[256];

char ch[30];
uint8_t counter = 0;

uint8_t readStatusRegister(boolean verbose=false) {
  SPI.beginTransaction(SPISettings(50000,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(0b00000101);
  b = SPI.transfer(0x00);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  delay(10);
  if (verbose) {
    sprintf(ch, "\nStatus Register=0x%02X", readStatusRegister());
    Serial.print(ch);
  }
  return b;
}

void writeEnable() {
  SPI.beginTransaction(SPISettings(400000,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(0x01);
  SPI.transfer(0x00);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  
  SPI.beginTransaction(SPISettings(400000,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(WREN);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
}

void writeDisable() {
  SPI.beginTransaction(SPISettings(400000,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(WRDI);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(19200);
  pinMode(HOLD, OUTPUT);
  pinMode(CS, OUTPUT);
  pinMode(WP, OUTPUT);
  digitalWrite(WP, LOW); // Disable Write
  digitalWrite(HOLD, HIGH); // Run active - Do not hold
  digitalWrite(CS, LOW); // A High-Low Transistion required
  digitalWrite(CS, HIGH);  // prior to operation
  digitalWrite(CS, LOW); // A High-Low Transistion required
  SPI.begin();
  readStatusRegister(true);
  digitalWrite(WP, HIGH); // Enable Write
  writeDisable(); // Disable Software Write
  readStatusRegister(true);
  writeEnable(); // Enable Software Write
  digitalWrite(WP, LOW); // Disable Hardware Write
  readStatusRegister(true);
}

void loop() {
  readStatusRegister(true);
  delay(10);
}

Here is what I am expecting from the datasheet.

I've already been through the datasheet and a few forums to try to figure out my issue but nothing has worked. Any advice would be much appreciated!

  1. 25LC256 issue
  2. example for SPI EEPROM (25LC512 )?

Schematic
EEPROM_Schematic.drawio

Oscope Results - I find the reflections and amplitude of the signal werid.

Do you have anything else connected to the MISO signal? The low signal level can be caused by cheap crappy SD card readers that don't release the MISO line.

Which Arduino are you using?

@astraeus1
1. Connect your EEPROM with UNO/NAONO as per Fig-1 (borrowed from post #2).
EEPROM_Schematic.drawio
Figure-1:

2. Uplod the following sketch in UNO.

#include <SPI.h>
volatile bool flag = false;
volatile byte y;

void setup ()
{
  Serial.begin(9600);
  SPI.begin();  //LH --> SPE-bit, LH--> I-bit
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  digitalWrite(SS, LOW);   //Slave is selceted
  SPI.attachInterrupt(); //LH--->SPIE-bit
}

void loop()
{
  SPI.transfer(0x05); //SPDR = 0x05
  if(flag == true)
  {
    Serial.println(y, HEX);
    flag = false;
  }
  delay(1000);
}

ISR(SPI_STC_vect)
{
  flag = true;
  y = SPDR;
}

3. Check that the Serial Monitor shows some meaningful 8-bit data (xheck with data sheet) coming from the Status Register of the EEPROM at 1-sec interval.

1 Like

Awesome that code worked! I incorporated the general idea into my design.

Here's the problem now, writing is being a pain. I have proved that I can read and write to the status register, but the actual execution of my write isn't being committed.

"Single Loop Print Log"
w // Entering Write statement
// Enable Write
Status Register=0x02 // Inital Status Register Result
Status Register=0x02 // Enable Write Latch
Status Register=0x8C // Turn on all bits in Status Register (write santity check)
Status Register=0x8E // Enable Write Latch
Status Register=0x00 // Turn off block protection bits and WPEN (Write-Protect Enable)
// Turn Enable Write Latch back on
Now Writing
Status Register=0x02 // Pre Write Check
Status Register=0x02 // Post Write Check <- This should be 0x00 after a write??
r0x1110: 0x00 // Read result

I'm not sure if I'm missing something or if the timing is just off.
The only Write Protection should be the hardware pin and control register bit. Both should be configured properly.

This is per the datasheet. I still need to scope out what is actually being sent.
byte_write
TWC (Internal Write) is rated for 5ms. I'm waiting for at least 10ms.
Latest Code

#include <SPI.h>
#define WP 8
#define HOLD 9
#define SCK 13
#define MOSI 11
#define MISO 12
#define CS 10

#define READ 0x03 // Read data from memory array beginning at selected address
#define WRITE 0x02 // Write data to memory array at beginning of selected address
#define WREN 0x06 // Set the write enable latch (enable write operations)
#define WRDI 0x04 // Reset the write enable latch (disable write operations)
#define RDSR 0x05 // Read Status register
#define WRSR 0x01 // Write STATUS register

uint8_t b;
uint8_t data[256];
double SPI_Speed = 10000;
char ch[30];
uint8_t counter = 0;

uint8_t readStatusRegister(boolean verbose=false) {
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(0b00000101);
  b = SPI.transfer(0xFF);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  delay(10);
  if (verbose) {
    sprintf(ch, "\nStatus Register=0x%02X", readStatusRegister());
    Serial.print(ch);
  }
  return b;
}

void writeEnable() {
  
  digitalWrite(WP, HIGH); // Turn off WP

  readStatusRegister(true); 
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Write Enable latch 
  SPI.transfer(WREN);
  digitalWrite(CS, HIGH); 
  SPI.endTransaction(); 
  
  readStatusRegister(true); // 0x02 WEL should be high
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0)); // Write to status register
  digitalWrite(CS, LOW); // Write to status register 
  SPI.transfer(WRSR);
  SPI.transfer(0xFF); // Leave all address open to change
  digitalWrite(CS, HIGH); 
  SPI.endTransaction(); 

  readStatusRegister(true); // 0x8C All bits high except WIP and WEL
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Write Enable latch 
  SPI.transfer(WREN);
  digitalWrite(CS, HIGH); 
  SPI.endTransaction();
  
  readStatusRegister(true); // 0x8E All bits high except WIP
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0)); // Write to status register
  digitalWrite(CS, LOW); // Write to status register 
  SPI.transfer(WRSR);
  SPI.transfer(0x00); // Leave all address open to change
  digitalWrite(CS, HIGH); 
  SPI.endTransaction();

  readStatusRegister(true); // Effective Clear
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Write Enable latch 
  SPI.transfer(WREN);
  digitalWrite(CS, HIGH); 
  SPI.endTransaction();
 
}

void writeDisable() {
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Reset the enable latch
  SPI.transfer(WRSR);
  SPI.transfer(0x8C); // Prevent writes
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Reset the enable latch
  SPI.transfer(WRDI);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  digitalWrite(WP, LOW);
  delay(10);
}

void writeData(uint16_t address, uint8_t value) {
  writeEnable();
  Serial.print("\nNow Writing ");
  readStatusRegister(true);
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(WRITE); // WRITE command
  SPI.transfer(address); // Specify address
  SPI.transfer(0xCC);
  digitalWrite(CS, HIGH); // Disable EEPROM Chip
  SPI.endTransaction();

  readStatusRegister(true);
  delay(10); // wait for TWS (internal write)
  
  //writeDisable();
}

uint8_t readData(uint16_t address) {
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(READ); // READ command
  SPI.transfer(address >> 3); // Specify address
  b = SPI.transfer(0xFF); // Value at address
  digitalWrite(CS, HIGH); // Disable EEPROM Chip
  SPI.endTransaction();
  return b;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(19200);
  pinMode(HOLD, OUTPUT);
  pinMode(CS, OUTPUT);
  pinMode(WP, OUTPUT);
  digitalWrite(WP, LOW); // Disable Write
  digitalWrite(HOLD, HIGH); // Run active - Do not hold
  digitalWrite(CS, LOW); // A High-Low Transistion required
  digitalWrite(CS, HIGH);  // prior to operation
  digitalWrite(CS, LOW); // A High-Low Transistion required
  SPI.begin();
  readStatusRegister(true);
  digitalWrite(WP, HIGH); // Enable Write
  writeDisable(); // Disable Software Write
  readStatusRegister(true);
  writeEnable(); // Enable Software Write
  digitalWrite(WP, LOW); // Disable Hardware Write
  readStatusRegister(true);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("\nr");
  data[0] = readData(0x1111); // Read data at 0x1111
  Serial.print("0x1110: ");
  sprintf(ch," 0x%02X",data[0]); // Print values within page
  Serial.print(ch);
  Serial.print("\nw");
  delay(1000);
  writeData(0x1111, 0xCC); // Write 0xCC to address 0x1111
  delay(1000);
}```

I'm using an Ardunio Uno with a DIP ATMega chip. Nothing else is in line right now.

Create your sketch based on the the program of post #5.

#include <SPI.h>

void setup ()
{
  Serial.begin(9600);
  SPI.begin();  //LH --> SPE-bit, LH--> I-bit
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  digitalWrite(SS, LOW);   //Slave is selceted
  //---------------------------------------
  SPI.transfer(0x06);  //WREN instruction
  delayMicroseconds(50);
  digitalWrite(SS, HIGH);
  delayMicroseconds(50);
  //---------------------------------------
  digitalWrite(SS, LOW);
  SPI.transfer(0x02); //WRITE instruction
  SPI.transfer(0x07); //07 of address 0700
  SPI.transfer(0x00);  //lower byte of address
  SPI.transfer(0x13);   //data for the above location
  delay(5);             //write cycle delay 
  //-----------------------------------------
  //add read codes and check that you have got 13 back
}

void loop()
{

}

Yep that'll do it. The SPI.transfer function only transfers one byte at a time. I was trying to pass over 2 through the same command.

Here's my corrected version of code. Not perfect but she'll work with this device. Hopefully I'll add a GitHub link to a library once I've cleaned this up.

#include <SPI.h>
#define WP 8
#define HOLD 9
#define SCK 13
#define MOSI 11
#define MISO 12
#define CS 10

#define READ 0x03 // Read data from memory array beginning at selected address
#define WRITE 0x02 // Write data to memory array at beginning of selected address
#define WREN 0x06 // Set the write enable latch (enable write operations)
#define WRDI 0x04 // Reset the write enable latch (disable write operations)
#define RDSR 0x05 // Read Status register
#define WRSR 0x01 // Write STATUS register

uint8_t b;
uint8_t data[0x0100];
double SPI_Speed = 1000000;
char ch[30];
uint8_t counter = 0;
boolean verbose = false;
uint8_t readStatusRegister() {
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(0b00000101);
  b = SPI.transfer(0xFF);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  delay(10);
  if (verbose) {
    sprintf(ch, "\nStatus Register=0x%02X", b);
    Serial.print(ch);
  }
  SPI.endTransaction(); 
  return b;
}

void writeEnable() {
  
  digitalWrite(WP, HIGH); // Turn off WP

  readStatusRegister(); 
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Write Enable latch 
  SPI.transfer(WREN);
  digitalWrite(CS, HIGH); 
  SPI.endTransaction(); 
  
  readStatusRegister(); // 0x02 WEL should be high
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0)); // Write to status register
  digitalWrite(CS, LOW); // Write to status register 
  SPI.transfer(WRSR);
  SPI.transfer(0xFF); // Leave all address open to change
  digitalWrite(CS, HIGH); 
  SPI.endTransaction(); 

  readStatusRegister(); // 0x8C All bits high except WIP and WEL
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Write Enable latch 
  SPI.transfer(WREN);
  digitalWrite(CS, HIGH); 
  SPI.endTransaction();
  
  readStatusRegister(); // 0x8E All bits high except WIP
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0)); // Write to status register
  digitalWrite(CS, LOW); // Write to status register 
  SPI.transfer(WRSR);
  SPI.transfer(0x00); // Leave all address open to change
  digitalWrite(CS, HIGH); 
  SPI.endTransaction();

  readStatusRegister(); // Effective Clear
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Write Enable latch 
  SPI.transfer(WREN);
  digitalWrite(CS, HIGH); 
  SPI.endTransaction();
 
}

void writeDisable() {
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Reset the enable latch
  SPI.transfer(WRSR);
  SPI.transfer(0x8C); // Prevent writes
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Reset the enable latch
  SPI.transfer(WRDI);
  digitalWrite(CS,HIGH);
  SPI.endTransaction();
  digitalWrite(WP, LOW);
  delay(10);
}

void writeData(uint16_t address, uint8_t value) {
  writeEnable();
  readStatusRegister();
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(0x02); // WRITE command
  SPI.transfer(highByte(address)); // Specify address
  SPI.transfer(lowByte(address)); // Specify address
  SPI.transfer(value);
  digitalWrite(CS, HIGH); // Disable EEPROM Chip
  delay(100); // wait for TWS (internal write)
  SPI.endTransaction();

  readStatusRegister();
  
  //writeDisable();
}

uint8_t readData(uint16_t address) {
  SPI.beginTransaction(SPISettings(SPI_Speed,MSBFIRST,SPI_MODE0));
  digitalWrite(CS, LOW); // Select EEPROM Chip
  SPI.transfer(0x03); // READ command
  //SPI.transfer(address >> 3); // Specify address
  SPI.transfer(highByte(address));
  SPI.transfer(lowByte(address));
  b = SPI.transfer(0xFF); // Value at address
  digitalWrite(CS, HIGH); // Disable EEPROM Chip
  SPI.endTransaction();
  return b;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(19200);
  pinMode(HOLD, OUTPUT);
  pinMode(CS, OUTPUT);
  pinMode(WP, OUTPUT);
  digitalWrite(WP, LOW); // Disable Write
  digitalWrite(HOLD, HIGH); // Run active - Do not hold
  digitalWrite(CS, LOW); // A High-Low Transistion required
  digitalWrite(CS, HIGH);  // prior to operation
  digitalWrite(CS, LOW); // A High-Low Transistion required
  SPI.begin();
  readStatusRegister();
  digitalWrite(WP, HIGH); // Enable Write
  writeDisable(); // Disable Software Write
  readStatusRegister();
  writeEnable(); // Enable Software Write
  digitalWrite(WP, LOW); // Disable Hardware Write
  readStatusRegister();
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("\nReading");
  for (int i=0x0000; i< 0x0100; i++) {
    data[i] = readData(i);
    if (true) {
      if((i&15)==0){
      sprintf(ch, "\n0x%04X: ",i);
      Serial.print(ch);
    }
    sprintf(ch," 0x%02X",data[i]);
    Serial.print(ch);
    delay(1);
    }
  }
  Serial.print("\nNow Writing ");
  for (int i=0x0000; i< 0x0100; i++) {  
    writeData(i, 0xFF); // Write
  }
}

Hola un saludo. me gustaría aprender más sobre el tema. Algo que me pueda ayudar.

@rafaa900909, please post in English.

You might be better of starting your own topic. If you prefer to ask the question in Spanish, ask the question in Español - Arduino Forum.

You will have to explain in more detail what you exactly want to know.

google translate:
@rafaa900909, publique en inglés.

Es mejor que empieces tu propio tema. Si prefiere hacer la pregunta en español, haga la pregunta en Español - Arduino Forum.

Tendrás que explicar con más detalle qué es exactamente lo que quieres saber.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.