1

I'm trying to use my Arduino Mega as an EEPROM memory writer. For this project, besides my Arduino Mega, I use an SD Card module, an LCD display and two push buttons to handle the events. Inside the SD card I have the binary files to be written into the EEPROM. Except for the burning process, my sketch seems to be correct. The user selects the memory size option (I'm only using the total memory size of 128kb), the file is written into the EEPROM. Apparently, the file is written. But when I use my other sketch to check the data written into the EEPROM, on the serial monitor, I only see bytes like FF and 0. Nothing else.

I think my problem is really in the process of writing the bytes, because of poor handling of the Output Enable, Chip Select and Write Enable pins. My data and address pin configuration, follows the logic of the Arduino Mega's port handling. PORT as the data pins and PORTC, PORTL and PORTG as the address pins. I will call the data pins dbit and the address pins abit, right? so, following this idea, my configuration with the Arduino Mega's ports looks like this:

Data pins: dbit0 = 22, dbit1 = 23, dbit2 = 24, dbit3 = 25, dbit4 = 26, dbit5 = 27, dbit6 = 28, dbit7 = 29.

Address pins: abit0 = 37, abit1 = 36, abit2 = 35, abit3 = 34, abit4 = 33, abit5 = 32, abit6 = 31, abit7 = 30, abit8 = 49, abit9 = 48, abit10 = 47, abit11 = 46, abit12 = 45, abit13 = 44, abit14 = 43, abit15 = 42, abit16 = 41.

Here is the EEPROM writer code.(UPDATED)

  #include <avr/pgmspace.h>
#include <Wire.h>  
#include <SPI.h>
#include <SD.h>



unsigned long addr = 0; 

int oe = 9;
int cs = 10;
int we = 11;

unsigned long fileSize = 0;



void setup()
{
   Serial.begin(115200);
   
pinMode(we, OUTPUT);
  pinMode(cs, OUTPUT);
  pinMode(oe, OUTPUT);
 digitalWrite(we, HIGH);
  digitalWrite(oe, HIGH);
  digitalWrite(cs, HIGH);
 DDRA = B11111111;
  PORTA = 0x00;

  DDRL = B11111111;
  PORTL = 0x00;

  DDRC = B11111111;
  PORTC = 0x00;

  DDRG = B11111111;
 PORTG = 0x00;
  

Serial.println("Now, erasing chip...");
DDRA = B11111111;
 delayMicroseconds(700);
 writeEEPROM(0x5555, 0xaa);
 writeEEPROM(0x2aaa, 0x55);
 writeEEPROM(0x5555, 0x80);
writeEEPROM(0x5555, 0xaa);
writeEEPROM(0x2aaa, 0x55);
writeEEPROM(0x5555, 0x10);
delayMicroseconds(50);


  delay(2500);



 Serial.println("All right! all done!");
    delay(2500);
     Serial.println("EEPROM Size will set to 0x2."); // just for test
 delay(2500);

PORTA = 0;
  PORTC = 0;
  PORTL = 0;
 PORTG = 0;
   
  }


  void loop(){
    
 dumpAndburn();
 while(1);// don't call this function anymore!!!!!!
  }// void loop







   void dumpAndburn(){
    
fileSize = 0x2; // just for test
  digitalWrite(oe, HIGH);
  digitalWrite(we, HIGH);
   
 while (addr < fileSize){/*
    
    https://www.dataman.com/dataman-eprom-memory-size-chart */
   

  


protect(); // is this right?
  writeEEPROM(addr, 0Xa5);// test
addr++; 

}
 
  
  digitalWrite(oe, HIGH);
  digitalWrite(we, HIGH); //write disable
  digitalWrite(cs, HIGH); 
 
  Serial.println("The process is done. Please, turn off the hardware.");

 




    
    
    }//void dumpAndburn 


void writeEEPROM(int adr, byte values) {
 

  digitalWrite(oe, HIGH); // output disable
  delayMicroseconds(0.01);
  PORTA = values;  // this is the DATA
  //delayMicroseconds(0.05);
  PORTC = lowByte(adr); // lower byte of the address (first 8 bits)
  PORTL = highByte(adr); // upper byte of the address (only 5 bits are used, the address is a 13 bit number)
 PORTG = highByte(adr); // upper byte of the address (only 5 bits are used, the address is a 13 bit number)
  delayMicroseconds(0.05);
  digitalWrite(cs, LOW);  //  |CE goes LOW  // Chip enable
 delayMicroseconds(0.07);

   digitalWrite(we, LOW);  //  |WE goes LOW  // Write enable

  delayMicroseconds(0.07);
  digitalWrite(we, HIGH); //  |WE goes HIGH // Write disable
  delayMicroseconds(0.15);
  digitalWrite(cs, HIGH); //  |CE goes HIGH // Chip disable
 
 
}

void protect(){
  DDRA = B11111111; // set portA as outputs.
 delayMicroseconds(700);
   writeEEPROM (0x5555, 0xAA);
  writeEEPROM (0x2AAA, 0x55);
   writeEEPROM (0x5555, 0xA0);
    delayMicroseconds(10);
  
  }  
    
  

Here is the EEPROM read code.

#include <avr/pgmspace.h> //necessário para Wire.h
#include <Wire.h>  //necessária, por conta do I2C
#include <SPI.h>

int oe = 9;
int cs = 10;
int we = 11;


void setup()
{

  int adr = 0;

pinMode(we, OUTPUT);
  pinMode(cs, OUTPUT);
  pinMode(oe, OUTPUT);
  digitalWrite(we, HIGH);
  digitalWrite(oe, HIGH);
  digitalWrite(cs, HIGH);
 DDRA = B00000000;
  PORTA = 0x00;

  DDRL = B00000000;
  PORTL = 0x00;

  DDRC = B00000000;
  PORTC = 0x00;

DDRG = B00000000;
PORTG = 0x00;

  
  Serial.begin(115200);
  for(int z=0; z<2; z++){
    delay(1000);
    }


printContents();
  }


  void loop(){
  

  }




byte readValue (int adr) {
  digitalWrite(we, HIGH); // disable write mode
  PORTC = lowByte(adr); // lower byte of the address (first 8 bits)
  PORTL = highByte(adr);// upper byte of the address (only 5 bits are used, the address is a 13 bit number)
 PORTG = highByte(adr);
  
  digitalWrite(oe, LOW);
  PORTA = 0;
  byte r = 0;


  delay(1); // we need a little delay to switch from input to output (at least 500 microseconds)
   digitalWrite(we, HIGH); 
  digitalWrite(cs, LOW);
  //delayMicroseconds(0.09);
  digitalWrite(oe, LOW);
 // delayMicroseconds(0.045);

  // read the data
  r = PINA;
digitalWrite(we, HIGH); 
  delayMicroseconds(1);
  digitalWrite(cs, HIGH);
  digitalWrite(oe, HIGH);
 // delayMicroseconds(0.09);
  return r;
}

void printContents() {
    DDRA = B00000000; //  portA as Inputs ports
  delayMicroseconds(500);
 int adr = 0;
byte value = 0;
byte checkValue;



//adr*=128;//test

while (adr < 0x2 ) { // 0x2 just for tests 
    checkValue = readValue (adr);
      

Serial.print(adr, HEX); Serial.print(" : "),Serial.println(checkValue, HEX);
  adr++;
}
 
}

Here is the link to the memory datasheet.

link

And when I try to see the content, I get the following results:

0 : 0
1 : 0

why can't retrieve 0: A5 1: A5 ?

Please guys, help me.

Any help will be greatly appreciated.

Thank you.

Best wishes.

8
  • Timing is absolutely critical when writing that kind of EEPROM. Your serial prints will be breaking that timing, and you must think in 128 byte pages - load a page at the right speed then delay the right amount of time to trigger a write.
    – Majenko
    Commented Jun 18, 2021 at 19:06
  • @Majenko , I really appreciate your comment. Thanks a lot! I think I will try to use a char buffer of 128, change the byte writing and see if I get any results. Thank you very much for this important information.
    – Dan Fayal
    Commented Jun 18, 2021 at 20:39
  • @jsotola, I'm really sorry about this, but, I can't do it now. I'm going to my house. I need to do this with my notebook. Sorry. Thank you.
    – Dan Fayal
    Commented Jun 18, 2021 at 23:29
  • Dear friends, I have made an update to the code. I took out the serial printing of the bytes to be written. I based this on a Serial EEPROM design. I created a 128 byte buffer. But is my reasoning correct? because I still don't get the bytes that seem to be written into memory.
    – Dan Fayal
    Commented Jun 19, 2021 at 16:59
  • If you read the datasheet (page 6) carefully, you will see that "The W29EE011 is shipped with the software data protection enabled. To enable the software data protection scheme, perform the three-byte command cycle at the beginning of a page load cycle", what this means is that you need to write 0xAA to addr 0x5555, 0x55 -> 0x2AAA, and '0xA0` -> 0x5555 before you write the address you want to access first.
    – hcheung
    Commented Jun 20, 2021 at 4:40

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.