DIY EEPROM programmer

Not posted in a while, have I? It’s not because I haven’t been tinkering – actually, it’s the reverse. I’ve had so many projects on, but I’ve not been able to spend a serious amount of time documenting them. Which is a poor habit to get into, I admit. I should be documenting before I start on the next one.

Anyway, here’s one that’s been half-written-up for a while, that’s nice and self-contained. I hope it’s useful to someone.

There’s been a number of occasions recently where I’ve needed to program a parallel EEPROM. I’ve been experimenting with BBC micros, and building my own DIY-6502 single-board computer.

I like EEPROMs, certainly compared to EPROMs. There’s no blanking-under-UV process, no special programming voltage required … I always feel like EEPROMs behave how you’d expect a programmable, read-only memory component to behave.

Programming a parallel EEPROM is nice and logical and straightforward, and can be done with very few components. If I had the space to setup my RiscPC I might have been tempted to program it via its parallel printer port … but I don’t really have the space, and I’d ideally like the programmer to be small, that I can leave in a box when I don’t need it. So: I need a small, not particularly powerful computer, but with a good amount of digital I/O pins. An Arduino it is, then!

My initial design for a programmer involved an Arduino Nano and some 74xx595s for the address lines … in fact, when I discovered this site later on, I was pleasantly surprised to see someone else’s design use exactly the same approach. However, when I started looking at the small extra cost of an Arduino Mega (with all its many digital I/O pins) I realised that I could make just as simple a programmer (with NO extra components) in a much shorter time.

For a while I would just put a EEPROM programmer together with a Mega, a breadboard and a lot of jumper wires whenever I needed it, but that got annoying really quickly! And there was always the worry that one of the many wires could be loose, and the EEPROM programmed incorrectly.

So I’ve built a tiny PCB for the job. It just sits on top of the IO pins on the far end of the Mega, and routes those pins to a ZIF socket. I’ve also added red and green LEDs so I get visual feedback when it is reading or writing.


The circuit is just an iteration on my post about reading parallel ROMs … but now it writes, too.

Speed isn’t particularly an issue when programming parallel EEPROMs, so I didn’t feel any real need to control the digital pins at the port level (an optimisation which would allow us to control eight bits in one go, rather than each bit at a time). Instead, I chose to make the PCB design as simple as possible (so I could etch it with my CNC) and then deal with the complexity in software.

(Click for a larger version.)

Designed from the component side – looking down on it from above. (Click for a larger version.)

Here’s my PCB design. As you can see, it’s incredibly simple.

I’ve provided the PCB layout in case you have the ability to etch your own PCBs. I used my CNC to isolation-route the design. But to be honest, the circuit is so simple that you could do it with stripboard if that’s all you have.

It’s worth noting that I’ve chosen to put the tracks on the upper (component) side of the board rather than the lower (solder) side. This is because the pins that I have soldered onto the board to connect it to the Mega have those little bits of plastic on them … so they’re practically impossible to solder from underneath. Whereas the turned-pin DIL socket (which holds the ZIF socket) is slightly raised off the board, and is therefore easier to solder.

Software on the Arduino

The Arduino is programmed to listen on the serial port and accept commands. I’ve kept the protocol brief, but ASCII-based (so I can test it with a serial comms package). It reads ROMs in blocks of sixteen bytes, and sends them down the serial port as ASCII hex. And it accepts blocks of up to sixteen bytes to write, in the same format. There’s a primitive CRC check, just to verify that no corruption occurs along the serial link.

Latest version of the Arduino sketch is available on the Simple EEPROM Programmer project page. Just copy and paste it into a sketch in the Arduino editor.

If you want to quickly see it working, compile the code onto your Arduino, then enter “R0000” in the serial monitor and hit return. You should see the first 16 bytes sent to you in hex, with a checksum.

Software on the PC

So now we need a utility that’ll control the Arduino in a slightly friendlier manner. I put off writing a utility for ages – instead resorting to turning a ROM image into a C array, and then embedding that in my Arduino project. But that’s rubbish. Putting-off writing a reasonable toolset is just making your life difficult for yourself.

And then, when I finally got around to it … it turns out that accessing the serial port under Windows is really not that difficult!

Cmmand-line and window-app executables are available for Windows. Go visit the EEPROM Writer Project page to get them.


It takes around 5ms to latch a byte when writing. And when you’ve added-in the serial-comms, verifying the data, etc, writing a 32K EEPROM takes about 5-10 minutes. This is OK for what I need, but will get irritating if I need a quicker iteration time.

The solution is page write, which is a facility that many EEPROMs provide that lets you write about 64 bytes in about the same amount of time as it currently takes to write just one byte! I might have a go at implementing that one day – a 64x writing increase sounds like a good win!

[To the EEPROM Writer Project page]

31 thoughts on “DIY EEPROM programmer

  1. Very interesting project. For computers without serial ports do you think a USB to serial port adapter would cause any problems?

  2. Hi Chris!

    This project doesn’t use an RS-232 port – it uses USB. When you connect the Arduino Mega to your computer, it adds a “virtual” (pretend) COM port. You treat it the same as an RS232 port … but it’s a USB device.

  3. Hi! It’s a very interesting project you have made 🙂 I’m having a bit of a problem tho. I programmed your code into my Mega and change the pinouts to match my own. I can’t seem to be able to write anything to the EEPROM. It’s a Xicor X28C64 from Jameco and all I have been able to read is 0xff in every single address.

    Any help would be greatly appreciated!

  4. If it’s reading nothing but 0xFFs, then it’s probably in its high-impedance state. So I’d be checking that the select and output lines are being pulled-low during the read cycle.

    Of course, if the ROM is blank, then it’s possible that it IS filled with 0xFFs! Might be an idea to get a pre-programmed ROM (say, from an old 8-bit computer) and try to read that first. When the reading side of it is working, you can look at writing. But at this stage, you probably don’t know whether it’s the reading that is failing, or the writing … or both.

  5. Kurt Kellner, make sure you connect all the enable pins, specifically the chip select. It sounds just like that to me

  6. I made a fast check and found some issue, unfortunately 🙁

    1) there’s a #DEFINE in upper-case letters that returns an error (it must be written with lower-case letters);
    2) if i upload the sket on my mega with nothing connected and type “R000” on the serial and then run it, i have nothing on the serial monitor;
    3) if i try running eeprommer.exe on my system (XP), the OS returns an error (eprommer.exe is not a valid win32 applcation) … did you compiled it in win64 eventually?


  7. 1. Whoops. I’ll sort that soon. Well spotted!
    2. What happens if you just enter “V” and press return? You should get a version number. If you don’t, then I’d guess that your comms package is sending a [13] for the carriage return, and not a [10]. The software waits until it receives a [10] before parsing the line.
    3. Not intentionally … but I might have made a mistake. It was compiled on Win10. I’ll check.

  8. I do not get the version number. I declared correctly the COM port number (the same the IDE report), so I am not sure what’s the problem.
    Just noticed that the EPROM lower dimension you can declare is said to be 1K in the readme text file, 8K in the command prompt line (i made some testing on a 64 bit OS)… what is the lower? Are 2708 readable?
    Thank you for the hard work!

  9. Configure your comms package so that when you press RETURN, it sends CR *and* NL, not just CR. The code is waiting to receive a NL before it attempts to decode the string.

    Or perhaps modify the sketch so that it works with CR too. To do this, modify the ReadString() function by changing the while loop to read: while (c != 10 && c != 13);

  10. Tried the modified ReadString() function, but it still doesn’t work for me: typing “R0000” or “V” on the serial monitor return nothing; eeprommer.exe reports that it fails to initialize COM port.
    Still toying without an eprom connected.

  11. You’re not trying to run eeprommer while your other serial-port software is running, are you? It won’t be able to initialise the com port if something else is accessing it.

  12. I had the IDE open, but not the serial monitor. Will try and report soon.
    What about the eprom dimensions? is the lower limit 1K or 8K?

  13. I made some additional test, still with no eprom connected, 64 bit OS.
    I am trying to read the “fake” rom (nothing connected) and let eeprommer generate a bin file with the “fake” rom content.
    If i type on the command prompt:
    eeprommer -comport 23 -romsize 1K -read fake.bin
    With the IDE closed, eeprommer starts reading! Then nothing 🙁
    It reads (or at least it what it says) in a loop with outputting nothing… any clue?
    Thanks for the help!

  14. 1K won’t work – just because I never wrote eeprommer to accept that as a parameter (I had no idea people used 1K roms). If you read a 16K rom all it should mean is that you get the same ROM images 16 times in the file.

    That assumes that the pinouts for the 1K rom are the same as for 16K roms … but obviously, with fewer address lines.

    But as I said before: get the reader working just with your serial monitor, before you use eeprommer. I can always make you a new version of eeprommer that will only read 1K, if you need it.

  15. Nothing: I cannot get an output on my serial monitor (nor the arduino, nor with “others” software, i.e. CoolTherm). Could it be that i am using an arduino mega clone with serial to usb CH340 chip?

  16. An arduino with non CH340G serial chip is on it’s way to me and i will then start testing with that. In the mean time it would be great to see a Win32 compatible version of eprommer and, why not, a version for 1K EEPROMs (which is the main reason i approached this great project) 😉

    Thanks for the patience and help!

  17. I am having the same exact problem than Kurt Kellner! Impossible to write to a Xicor X28C64 from Jameco… I’ve tried all day, all I get out of it is 0xFF. I know for sure it’s not in high-impedance, because I see the level go from LOW to HIGH on all bits as soon as I have both CE and OE LOW. I’ve checked the pinout a million time. I’ve checked every single signal with a volt meter and doing step-by-step, and everything looks fine.

    I ended up using a Xicor X2816 that I had hanging around, and it worked first try… So there’s definitely something odd about the X28C64. I’ve also tried disabling the “software protection”, no luck. It’s driving me insane… Unfortunately, the working X2816 isn’t large enough, so I absolutely need to get this X28C64 working.

  18. I’m gonna end up buying one of these, aren’t I? 🙂 I wonder if it’s something daft like the X28C64 only supporting page-write and not single-byte-write.

  19. The datasheet says it supports byte write. There\’s this software protection too, I\’ve tried to do the un-protect procedure (even though the datasheet states the chips shall not be protected coming from the factory) but no luck. I\’m going to try again. For now, I\’ve fixed up the wiring of my project to support both 2K and 8K EEPROMs.

  20. Just a quick update: I’ve upgraded the command-line software to v3. This supports ROM sizes from 1K all the way up to 64K, and should now work on XP.

    One of those X28C64 devices arrived this week, so I’ll have a go with that too.

  21. … and, I’ve just successfully written and then re-read the X28C64 IC.

  22. i would love to buy one of these pre assembled would it be possible to purchase one from the gentleman whoms project this is

  23. That’s very flattering of you – but the article was really about how easy it is to do this sort of thing, so if you’re any good with a soldering iron and stripboard you could easily make one of your own!

    However … I have designed and ordered some slightly better quality boards from a PCB prototyping company. I can sell one on to you if you want to find the few parts you need and solder them yourself?

  24. Excelente es justo lo que nesecitaba para continuar con mi trabajo de implementar un Kit con ell VIejo pero aun poderoso 68000.

    Thank you i just need that for continue with mi job for make some board with the oldest MC68000 thanks a lot.

  25. Will this work for chips larger than 64k? Specifically a 256k.

  26. Not as it stands – that circuit assumes the EEPROM is a 28-pin device, and larger ones are 32-pin. But my original motivation for the article was to show how they should be controlled – so making your own version that just adds a few extra address lines is pretty straightforward.

    Next time I’m doing a Farnell order, maybe I’ll get a 32-pin ZIF socket and do an updated design. It’s something I could do with too.

  27. Hi

    Thanks for your work

    May be could you help me…

    When i test it from arduino serial port the “programmer” read and response

    EEPROM Version=0.01

    But the eeprom.exe software doesn’t do nothing…. Green red is not turning on and i dont see any output


  28. I’ve knocked-together a Python script for (Linux..) dumping, programming, and verifying EEPROMS using the above firmware’s interface. The link to the source is my website link.

    Warning: the code is as good as I personally need it to be. 🙂

  29. That’s marvellous! I have on my to-do list to rewrite a better app in C# – if I have to update the protocol too then I’ll make sure I let you know!

    Would you mind if I updated the blog to link to your Python script directly? Or would you prefer it if I kept a copy locally?

  30. Just a heads up, on the Atmel AT28C256 (32K chip) datasheet the command addresses to enable/disable write protect are different – you will need to change the 1555 to 5555 and 0AAA to 2AAA. After this, removing/setting write protect works fine.