Go Down

Topic: Arduino EEPROM Programmer: Burning a ROM image (Read 6 times) previous topic - next topic

PaulS


legendmythe

#6
Oct 29, 2012, 04:16 pm Last Edit: Oct 29, 2012, 05:55 pm by legendmythe Reason: 1
No, I hadn't looked there yet :s

Thanks i finally got an EEPROM programmer and I didn't spend hundred dollar :D

Here's the code if someone is interested:
Code: [Select]

#define ARDUINO_WAIT_TIME 2000

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class Serial
{
   private:
       //Serial comm handler
       HANDLE hSerial;
       //Connection status
       bool connected;
       //Get various information about the connection
       COMSTAT status;
       //Keep track of last error
       DWORD errors;

   public:
       //Initialize Serial communication with the given COM port
       Serial(char *portName);
       //Close the connection
       //NOTA: for some reason you can't connect again before exiting
       //the program and running it again
       ~Serial();
       //Read data in a buffer, if nbChar is greater than the
       //maximum number of bytes available, it will return only the
       //bytes available. The function return -1 when nothing could
       //be read, the number of bytes actually read.
       int ReadData(char *buffer, unsigned int nbChar);
       //Writes data from a buffer through the Serial connection
       //return true on success.
       bool WriteData(char *buffer, unsigned int nbChar);
       //Check if we are actually connected
       bool IsConnected();


};

Serial::Serial(char *portName)
{
   //We're not yet connected
   this->connected = false;

   //Try to connect to the given port throuh CreateFile
   this->hSerial = CreateFile(portName,
           GENERIC_READ | GENERIC_WRITE,
           0,
           NULL,
           OPEN_EXISTING,
           FILE_ATTRIBUTE_NORMAL,
           NULL);

   //Check if the connection was successfull
   if(this->hSerial==INVALID_HANDLE_VALUE)
   {
       //If not success full display an Error
       if(GetLastError()==ERROR_FILE_NOT_FOUND){

           //Print Error if neccessary
           printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);

       }
       else
       {
           printf("ERROR!!!");
       }
   }
   else
   {
       //If connected we try to set the comm parameters
       DCB dcbSerialParams = {0};

       //Try to get the current
       if (!GetCommState(this->hSerial, &dcbSerialParams))
       {
           //If impossible, show an error
           printf("failed to get current serial parameters!");
       }
       else
       {
           //Define serial connection parameters for the arduino board
           dcbSerialParams.BaudRate=CBR_9600;
           dcbSerialParams.ByteSize=8;
           dcbSerialParams.StopBits=ONESTOPBIT;
           dcbSerialParams.Parity=NOPARITY;

            //Set the parameters and check for their proper application
            if(!SetCommState(hSerial, &dcbSerialParams))
            {
               printf("ALERT: Could not set Serial Port parameters");
            }
            else
            {
                //If everything went fine we're connected
                this->connected = true;
                //We wait 2s as the arduino board will be reseting
                Sleep(ARDUINO_WAIT_TIME);
            }
       }
   }

}

Serial::~Serial()
{
   //Check if we are connected before trying to disconnect
   if(this->connected)
   {
       //We're no longer connected
       this->connected = false;
       //Close the serial handler
       CloseHandle(this->hSerial);
   }
}

int Serial::ReadData(char *buffer, unsigned int nbChar)
{
   //Number of bytes we'll have read
   DWORD bytesRead;
   //Number of bytes we'll really ask to read
   unsigned int toRead;

   //Use the ClearCommError function to get status info on the Serial port
   ClearCommError(this->hSerial, &this->errors, &this->status);

   //Check if there is something to read
   if(this->status.cbInQue>0)
   {
       //If there is we check if there is enough data to read the required number
       //of characters, if not we'll read only the available characters to prevent
       //locking of the application.
       if(this->status.cbInQue>nbChar)
       {
           toRead = nbChar;
       }
       else
       {
           toRead = this->status.cbInQue;
       }

       //Try to read the require number of chars, and return the number of read bytes on success
       if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
       {
           return bytesRead;
       }

   }

   //If nothing has been read, or that an error was detected return -1
   return -1;

}


bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
   DWORD bytesSend;

   //Try to write the buffer on the Serial port
   if(!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
   {
       //In case it don't work get comm error and return false
       ClearCommError(this->hSerial, &this->errors, &this->status);

       return false;
   }
   else
       return true;
}

bool Serial::IsConnected()
{
   //Simply return the connection status
   return this->connected;
}

int main (void)
{
   int sz;
   char *buffer;

   Serial serial("COM3");// Change this to your COM port

   FILE *fp;
   fp=fopen("rom.bin", "r");
   fseek(fp, 0L, SEEK_END);
   sz = ftell(fp);
   fseek(fp, 0L, SEEK_SET);

   buffer = (char *)malloc(sz);
   fread (buffer, 1, sz, fp);

   int i, n, r;
   n = sz/50;
   r = sz%50;
   for(i=0; i<n; i++)
   {
   serial.WriteData((char*)(buffer + (i*50)), 50);
   Sleep(1000);//Buffer overflow protection
   }
   serial.WriteData((char*)(buffer + (n*50)), r);


   printf("Done writing to serial port.\nSize: %d bytes", sz);
   return 0;
}

robtillaart

Thanks for sharing!

Can you post the final Arduino code too?
Can tell what EEPROM's you can write and how you connected them?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

gateway

Nice that you figured it out yourself!
You need to indeed just send the raw binary data.

A couple of simple dos commands would have also sufficed:

mode COMXX: 9600,n,8,1
copy /b [FILE] COMXX:

Where you would replace [FILE] with your file and COMXX with your com port.

Or you could create a batch file, on which you can drag the ROM image (not tested, but you get the idea):
Code: [Select]

@echo off
mode COMXX: 9600,n,8,1
copy /b %1 COMXX:

legendmythe

#9
Oct 29, 2012, 11:02 pm Last Edit: Oct 29, 2012, 11:05 pm by legendmythe Reason: 1

Thanks for sharing!

Can you post the final Arduino code too?
Can tell what EEPROM's you can write and how you connected them?

I used an Atmel AT28C64, but using a datasheet you should be able to modify the code to make it work with any other parallel EEPROM. The connections are pretty simple just check my code, one important detail: I added a pull-up resistor to WE because when the Arduino resets the i/O pins go to a high impedance state and the WE pin will pick up noise and you might end up using data loss (Not sure if this explanation is correct, but adding a pull up resistor somehow fixed the weird data corruption when resetting the arduino). For the rest it is just direcly connecting the pins of the EEPROM to the arduino pins(check my code)

Here's the full read and write code, but before you use it, download a datasheet and try it out yourself, you'll learn a lot and it'll give you a feeling of accomplishment.
Code: [Select]

/*
EEPROM Chip Reader
*/

#define memsize 8192

int STS   = 13;  // Status Indicator

int AP[13] = {24,26,30,32,36,38,42,44,48,50,47,51,53};
int AD[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
int DP[8]  = {23,25,29,31,35,37,41,43};
int DD[8]  = {0,0,0,0,0,0,0,0};

int CE  = 6;
int OE  = 4;
int WE  = 2;

int i;
int j;
int D;
int A;

void setup()
{
 Serial.begin(9600);
 D=0;
 for (i=0;i<8;i++)
 {
  DD[i] = 0;
 }
 // Setup Control Pins
 pinMode(CE, OUTPUT);
 pinMode(WE, OUTPUT);
 pinMode(OE, OUTPUT);
 
 // Disable Chip, and disable read and write.
 digitalWrite(WE, HIGH);
 digitalWrite(CE, LOW);
 digitalWrite(OE, HIGH);

 
 
 Serial.println("Reading EEPROM...");
 
 pinMode(STS,   OUTPUT);
 digitalWrite(STS,HIGH);
 
 // Setup Address Pins
 for (i=0;i<16;i++)
 {
   pinMode(AP[i],OUTPUT);
 }
 
 // Setup Data Pins
 for (i=0;i<8;i++)
 {
   pinMode(DP[i],INPUT);
 }

 delay(100);
 
 for (A=0;A<memsize;) {
   
   if (A<4096) Serial.print("0");
   if (A<256)  Serial.print("0");
   if (A<16)   Serial.print("0");
   Serial.print(A,HEX);
   Serial.print(" ");

   for (j=0;j<16;j++) {
   
     // Setup Address Pins
     for (i=0;i<16;i++) {
       if((A&bit(i))>0) {
         AD[i]=HIGH;
       } else {
         AD[i]=LOW;
       }      
       digitalWrite(AP[i],AD[i]);
     }
   
     delay(10);
     digitalWrite(OE,LOW);      // Read Enabled
     delay(10);
   
     // Read Data Pins
     D=0;
     for (i=0;i<8;i++) {
       DD[i]=digitalRead(DP[i]);
       D=D+bit(i)*DD[i];
     }
   
     if (D<16) Serial.print("0");
     Serial.print(D,HEX);
     Serial.print(" ");
     
     A++;
   }
   
   Serial.println();
   
 }
 
}

void loop() {
 while (Serial.available()==0) delay(1);
 Serial.print(Serial.read());
 digitalWrite(STS, HIGH);   // set the LED on
 delay(500);              // wait for a second
 digitalWrite(STS, LOW);    // set the LED off
 delay(500);              // wait for a second
}

Code: [Select]

/*
EEPROM Programmer
*/

#define memsize 8192

int STS   = 13;  // Status Indicator

int AP[13] = {24,26,30,32,36,38,42,44,48,50,47,51,53};
int AD[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int DP[8]  = {23,25,29,31,35,37,41,43};
int DD[8]  = {0,0,0,0,0,0,0,0};

int CE  = 6;
int OE  = 4;
int WE  = 2;

int i;
int A;
char D;

void setup() {

 Serial.begin(9600);
 Serial.println("Writing EEPROM...");
 
 
 // Led that shows activity
 pinMode(STS,   OUTPUT);
 
 // Setup Address Pins
 for (i=0;i<16;i++)
 {
   pinMode(AP[i],OUTPUT);
 }
 
 // Setup Data Pins
 for (i=0;i<8;i++)
 {
   pinMode(DP[i],OUTPUT);
 }
 
 // Setup Control Pins
 pinMode(CE, OUTPUT);
 pinMode(WE, OUTPUT);
 pinMode(OE, OUTPUT);
 
 // Setup Chip
 digitalWrite(CE, LOW);
 digitalWrite(WE, LOW);
 digitalWrite(OE, HIGH);


 // Loop that writes Byte per byte
 for (A=0;A<memsize;A++)
 {
   while (Serial.available()==0) delay(1);
   D = Serial.read();
   Serial.print(D,HEX);
   Serial.println("");
   digitalWrite(STS,HIGH);  //Signal that we're writing.

   // Setup Address Pins
   for (i=0;i<13;i++)
   {
      digitalWrite(AP[i], bitRead(A,i));
   }
   
   // Setup Control bus
   digitalWrite(OE,LOW);   // Reads Disabled
   delay(1);               // Give the EEPROM some time to catch up
   digitalWrite(CE,HIGH);  // Chip Enable
   digitalWrite(WE,HIGH);  // Write Enabled
   
   // Setup Data Pins
   for (i=0;i<8;i++)
   {
     digitalWrite(DP[i], bitRead(D,i));
   }
   
   // Write data (D)
   digitalWrite(WE,LOW);      // Write Disabled
   digitalWrite(CE,LOW);      // Chip Disabled
   digitalWrite(OE,HIGH);     // Reads Enabled
   delay(1);
   
  digitalWrite(STS,LOW);      // Signal that we're waiting
 
 }
 
   // We got through the loop, signal that the write was successful
   Serial.println("Done...");
}

void loop() {
 // Small loop to show that data was written and device can be removed
 digitalWrite(STS, HIGH);  
 delay(1000);              
 digitalWrite(STS, LOW);    
 delay(1000);              
}


I'll probably make a post somewhere on this website explaining exactly what I did, but first I want to solder it and sadly I don't have time for that until Christmas.

Go Up