Wednesday, 7 September 2011

21. Building An EEPROM Programmer (Part 2).

The Arduino can receive data via the Serial interface. This is how I want to send the Z80 programs to the EEPROM. The problem is the Arduino is not reading fast enough and so what gets sent is lost. Its fine for sending the odd few bytes now and then, but (using my zx81.rom as a test) sending 8K of data is a bit much for it to handle in one go.

The Serial buffer on the Arduino is 128 bytes, so all I was getting to start with was the first 128 bytes of the 8K successfully, after that it was a random sets of 128 bytes from the Serial port that it grabbed hold of before the stream of data ended.

To compensate for this, I decided to send 64 bytes at a time with 1 second interval. Now this is fairly easy to do in Linux with a script:

eeprom_send.sh
#!/bin/bash
split -C 64 ${1} ${1}.part.
for part in `ls ${1}.part.*`
do
 cat ${part} >> ${2}
 sleep 1
done
rm -f ${1}.part.*

To use it type:
./eeprom_send.sh zx81.rom /dev/ttyACM0

But first you just need to program the Arduino and then open the serial monitor window (dont ask me why).

Here is the Arduino program:
/*
 EEPROM Programmer
*/
#define memsize 8192

int STS   = 13;  // Status Indicator

int AP[16] = {22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52};
int AD[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int DP[8]  = {23,25,27,29,31,33,35,37};
int DD[8]  = {0,0,0,0,0,0,0,0};

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

int i;
int A;
int D;
int wait;

void setup() {
  
  Serial.begin(115200);
  Serial.flush();
  
  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);

  Serial.println("Waiting for Data...");
  while(Serial.available()==0) {
    digitalWrite(STS,LOW);
    delay(100);
    digitalWrite(STS,HIGH);
    delay(100);
  }

  for (A=0;A<memsize;A++) {
    
    D=Serial.read();
    digitalWrite(STS,HIGH);  //Signal that we're writing.

    // 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(1);
    
    digitalWrite(OE,LOW);   // Reads Disabled
    delay(1);

    digitalWrite(CE,HIGH);    // Chip Enable
    delay(1);

    digitalWrite(WE,HIGH);    // Write Enabled
    delay(1);
    
    // Setup Data Pins
    for (i=0;i<8;i++) {
      if((D&bit(i))>0) {
        DD[i]=HIGH;
      } else {
        DD[i]=LOW;
      }      
      digitalWrite(DP[i],DD[i]);
    }
    delay(1);

    digitalWrite(WE,LOW);      // Write Disabled
    delay(1);

    digitalWrite(CE,LOW);      // Chip Disabled
    delay(1);

    digitalWrite(OE,HIGH);       // Reads Enabled
    delay(1);
    
   digitalWrite(STS,LOW); // Signal that we're waiting
    wait=0;
    while(Serial.available()==0) {
      delay(1);
      if (wait>2000) {
        A=memsize;
        break;
      }
      wait++;
    }
    
  }
  
}

void loop() {
  digitalWrite(STS, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(STS, LOW);    // set the LED off
  delay(1000);              // wait for a second
}

13 comments:

  1. Hi Dave, I've used your code to write ROM data to a 4 Megabit EPROM chip (27C322). Seems to work well (still writing some data on it right now), but writing is extremely slow through the arduino; over two hours to write the whole chip.

    ReplyDelete
  2. I would try and reduce the delay between bursts as sleep will accept sub second values such as 0.1, or even use the whole 128 buffer by changing the value of 64 to 128 in the shell script. I think the baud rate is maxed at 115200 so that wont go any faster.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. It turns out nothing is being written to the EPROM at all. I might be having trouble setting the EPROM to program mode, the datasheet says programming mode is when "VPP input is at 12.V, GVPP is at VIH and E is pulsed to VIL. VCC is specified to be 6.25V ± 0.25V."

    ReplyDelete
  5. I used an EEPROM that works on 5V. See post http://z80dave.blogspot.co.uk/2011/08/18-pinups-oops-i-mean-pinouts.html, its only 64kbits though. You'd have to add a 5v to 12v step up circuit. This is similar to how you'd program the PIC microcontrollers, but I have programmer for these that I bought off the internet.

    ReplyDelete
  6. Thanks for putting this up, I was able to read my EEPROM. I wasn't sure about writing it back though. Not sure what format it needs to be in. I need to change a few values. Do I just read the chip, copy and paste into a text file from the serial window, change the values in a text editor, paste that into the serial window, and write it? I'm guessing the answer is no and I need to import it into a hex editor. However the format is not correct to import into a hex editor unless I do it line by line. Thanks, Max

    ReplyDelete
    Replies
    1. Hi Max,
      you could create a byte programmer to patch your eeprom and that gives me a great idea for a new project as it been quite a while since I posted anything, but to answer your question, with this code, you'd have to dump the eeprom to a file, edit the bytes using a hex editor, and then load it back in again.

      Delete
    2. Dave, thanks for the reply.

      I modified your read code to where it outputs the values separated with commas. From there I can import into a spreadsheet and from there into a hex editor. The part I'm still not clear of is how to upload it back. Third party upload software? Or through the Arduino serial monitor? If so, what format? Sorry for the trivial questions but this is a little over my head. Can't figure it out.

      Thanks again.

      Delete
    3. Ok, I'm embarrassed to say that I answered my own question. Your linix script... Will give that a try!

      Delete
  7. To take a screenshot of simply the active home window on your screen, hold back the Alt secret as well as press PrtScn. 토토사이트

    ReplyDelete
  8. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts 먹튀검증

    ReplyDelete
  9. I truly appreciate this post. I’ve been looking all over for this! Thank goodness I found it on Bing. You have made my day! Thank you again! 토토사이트

    ReplyDelete
  10. It should be noted that whilst ordering papers for sale at paper writing service,  토토

    ReplyDelete