The Ben Eater EEPROM Programmer, 28C256 and Software Data Protection

Many people are learning, like I did, about computer hardware by following Ben Eater’s 8-bit breadboard computer build. And many of those are either moving on to more advanced projects or using slightly different hardware for the build. And some of those are using larger EEPROM chips such as the 28C256.

But there’s a catch with the 28C256: it has something called software data protection (SDP), which protects data from being accidentally overwritten. With the smaller 28C16 (as used by Ben) you can write data in the same way you would with a RAM chip, just by strobing the write pin. You can do the same with the 28C256 if the SDP is disabled, but if it’s enabled then you need to send a specific ‘command sequence’ to the chip. The SDP can be disabled but this requires a similar command sequence1.

If you have a dedicated EEPROM programmer this is not a problem, the programmer will handle the data protection for you, but many hobbyists prefer to save a few pennies and using Ben’s own breadboard EEPROM programmer.

My original 'BenPrommmer' with 28C16 EEPROM
My original ‘BenPrommmer’ with 28C16 EEPROM

Since I’ve already written code to write to a chip with software data protection via a Z80 I thought it would be helpful to update my own ‘BenPrommer’ to handle the 28C256 and to document both the hardware and software changes needed.

Hardware Changes

I’m assuming here that you already have Ben’s programmer for the 28C16 available to modify

Ben’s design permanently connects /CE to ground and drives /OE via one of the 74HC595 shift registers. To get this to work we need be able to drive all three of the EEPROMs control lines. I’m also going to move /WE away from pin 13 of the Arduino. This is also the pin driving the on board LED and I’d rather use that for status information without risking corrupting the EEPROM. For now, just remove the wire between the ‘595 and /OE (the rightmost white wire in the photo above).

Comparing the pinouts for the 28C16 and 28C256 shows that they both have pretty similar layouts. On the left hand side of the chip everything is the same just with the new pins 1 and 2 added (A14 and A12). On the right hand side we need to move Vcc to the new pin 28 and add A13 and A11 to replace the it and /WE.

28C16 pinout
28C16 pinout
28C256 pinout
28C256 pinout


These four new address pins now need to be connected to the rest of the board. Fortunately the existing 74HC595 shift registers have enough space left to add the extra lines. Just connect A11 to Q3, A12 to Q4, A13 to Q5 and A14 to Q6.

74xx595 pinout
74xx595 pinout

And we can finish off by moving the /WE connection from Arduino pin D13 to pin A2 and adding connections from A1 to /OE and from A0 to /CE.

On the photo below you can see the new address wires in a slightly different shade of blue, and the white wires connecting the control signals.

I found that that this design was /very/ unstable until I added some decoupling capacitors (0.1uF). You can find mine next to the power pin for teh EEPROM, the ground pin for the EEPROM and the power pin from the Arduino. Three capacitors is probably overkill but it took me a lot of debigging before I realised I needed them.

The upgraded BenPrommer with 28C256 EEPROM
The upgraded BenPrommer with 28C256 EEPROM
The upgraded BenPrommer with 28C256 EEPROM
Schematic for the upgraded BenPrommer

Software Changes

We can now turn to the software. I’ve made a fair few changes to the original software, largely to improve performance and remove redundancy.

The key routines for this article are writeEEPROMSDP which writes a byte of data whilst SDP is enabled and disableSDP which disables SDP so you can write to the chip with the normal writeEEPROM function.

disableSDP()

Let’s examine the disableSDP function, with reference to section 20 (page 10) of the datasheet.

It begins by setting the data pins to output and asserting /CE

{
  Serial.println("Disabling SDP");

  setDataPinMode(OUTPUT);

  digitalWrite(CHIP_EN, LOW);

We then sent the command sequence by writing specific bytes to specific addresses

  setAddress(0x5555);
  writeEEPROMCurrent(0xaa);
  setAddress(0x2aaa);
  writeEEPROMCurrent(0x55);
  setAddress(0x5555);
  writeEEPROMCurrent(0x80);
  setAddress(0x5555);
  writeEEPROMCurrent(0xaa);
  setAddress(0x2aaa);
  writeEEPROMCurrent(0x55);
  setAddress(0x5555);
  writeEEPROMCurrent(0x20);

and the clear the /CE line.

  digitalWrite(CHIP_EN, HIGH);

  //(No delay needed)
}

and as per the comment, the chip does not need any kind of delay after this code.

writeEEPROMSDP()

writeEEPROMSDP is very similar, just with it’s own command sequence and finishing up with writing the actual byte to the actual address. And then we finish by waiting for the write operation to complete.

bool writeEEPROMSDP(word address, byte data) 
{
  setDataPinMode(OUTPUT);

  digitalWrite(CHIP_EN, LOW);
  setAddress(0x5555);
  writeEEPROMCurrent(0xaa);
  setAddress(0x2aaa);
  writeEEPROMCurrent(0x55);
  setAddress(0x5555);
  writeEEPROMCurrent(0xa0);

  setAddress(address);
  writeEEPROMCurrent(data);
  
  digitalWrite(CHIP_EN, HIGH);

  return writeWait(data);
}

If you check note 4 on the datasheet under the programming sequence (section 19, page 10) you’ll see that you can actually write up to 64 bytes in one go via this procedure. I’ll leave you to add that functionality if desired but if you do pay attention to the section 4.3 ‘Page Write’ (page 3) which explains that each byte written must be within the same 64 byte page. Also, note that there are strict timing requirements to doing page writes and you’ll probably need to write directly to the Arduino’s ports to be able to hit them.

Wrapping Up

And that’s it. I found I didn’t need any delays within the code and, despite what the datasheet shows, I didn’t need to toggle /CE between every write, but I’ve left them commented out within the code in case you have problems.

I’ve only been able to test this code with a single Atmel branded 28C16 which came from Ebay so it could be another chip with changed markings and slightly different timings.

Code and schematics are available on my Github.

Footnotes

  1. My understanding is that the chips, from new, should have SDP disabled, but people are buying supposedly new chips with the protection enabled and getting stuck.

Leave a Reply

Your email address will not be published. Required fields are marked *