Introduction: Raspberry Pi Python EEPROM Programmer

This simple tutorial will guide users through the process of interfacing an EEPROM chip to a Raspberry Pi using the GPIO pins and performing operations with Python scripts.

Let's start with some basics on EEPROM:

1) CE, OE, WE - What does it all mean?

In order to read, write and erase data from an EEPROM chip, we must first bring the chip at the correct state. This is done using 3 control pins typically named Chip Enable, Output Enable and Write Enable.

Chip Enable controls whether or not the chip is powered up. Depending on the type of chip, connecting this pin to the ground or to voltage will turn the chip on or off. Needless to say, that if we want to perform any operation we need to enable the chip. Disabling the chip allows us to power down the chip while leaving it electrically connected to our circuit. This way the chip consumes less power.

Output Enable is a pin used to tell the chip that you want to read from it. Once again, depending on the chip, connecting this pin to the ground or to voltage will tell the chip to present you with the contents of given memory address (more on that later). Disabling the Output completes the read operation.

Write Enable is similar to Output Enable but used for writing data to the chip. Depending on the type of chip, connecting it to ground or to voltage will make the chip write data to a selected memory address (more on that later).

2) So how do I control the pins?

It is easy! Depending on your EEPROM chip, you enable or disable these pins by connecting them to a voltage source or to the ground. The jargon used for the operation is "pull up" for connecting to voltage and "pull down" for connecting to the ground. In some cases (and in our case in particular), pulling up a pin causes the corresponding state to be Disabled instead of Enabled. This may sound counter intuitive since you expect to pull up to turn on something but such is life sometimes.

Warning!!!: Leaving one of these pins disconnected from the circuit does not equal to it being pulled down! If any of the pins are left disconnected from the circuit we call them "floating" and essentially their state is random and undetermined. For example, RF interference may cause a high or low signal and therefore make the pin act as if it is enabled or disabled. Always connect all the pins to your circuit!

3) It is all about sequencing!

Suppose I want to read some data from my EEPROM, what do I need to do with these pins to make it all work? Performing operations on EEPROM is all about doing things in the right order. So if we wish to read from the chip, our sequence would be as follows:

Set the memory address (pull up/down Address bus pins to form an address in binary format)

Enable chip (power up)

Enable output (read that address)

Read the memory address (the Data bus pins will now be set high/low according to the data in the address)

Disable output (the Data bus output is still enabled at this point so I can read the data)

Disable chip (power down, no output on the Data bus at this point)

Repeat the above for the next address you wish to read.

4) What was that bus you talked about?

Data Bus and Address Bus. The EEPROM chip, along with the CE, OE and WE pins, will also have a set of pins for setting an address and a set of pins for reading/writing data to the selected address. The number of pins for the Address Bus depends on the capacity of the chip. The higher the capacity, the more addresses are needed and therefore the more pins the bus will have. To set an address we pull up/down the pins to represent 1/0. Each address represented by any combination of bits contains 1 byte. So a chip with 2048 addresses will have 2048 byte capacity. The pins on the Address Bus are typically numbered like so: A0, A1, A2, A3,... A(n)

The Data Bus, in contrast with the Address Bus, can be either input or output, depending on the operation selected. If we choose to write to the chip, we set the address we wish to write to via the Address Bus and then we set the Data Bus by pulling its pins up/down to represent one byte. If we choose to read from the chip, then the Data Bus pins will be set high/low to represent the 1/0 of the byte contained in the address we selected. The pins on the Data Bus as numbered: D0, D1, D2,... D7

5) One last thing: Most Significant Bit

Most Significant Bit is essentially the bit that represents the highest value in a byte. Different chips may use a different ordering scheme when storing bytes. The documentation of your chip will define if the Most Significant Bit is at the highest or lowest pin number on the Data Bus. Once you know which pin has the MSB, the rest of the pins represent the rest of the bits in ascending or descending order. For example, if the MSB is on pin D7 of the Data Bus, then the Least Significant Bit is going the be on pin D0.

Step 1: Let's Put Things Together

I am attaching the GPIO layout of Raspberry Pi B+ along with the pin connections to the chip. Be very careful with the 5v pin on the Pi because although your EEPROM chip may function at 5v, it will also output 5v on the Data Bus when you read from it. And this means that it will feed 5v into the GPIO of the Pi which is really bad news because Pi uses 3.3v logic and you will fry your Pi.

So DO NOT use the 5v pins on the Pi!!!! Power your chip from the 3.3v pins!

1) OK, show me your gear

The rest of the guide is based on connecting the Pi to the EEPROM chip that I have. It is an SST 39SF020A which I scavenged from an old digital amp. You can search online for the documentation for the chip. It is freely available from many sources. I am not attaching it here in case of Copyright issues. There are three different version of this chip, each one with different capacity and therefore a different number of Address Pins. If you can get one of the three models of my chip, you can follow this guide closely. If you have a different chip, you need to find the documentation of your chip from the manufacturer and create a table that maps your chip's pins to mine. The notation for Address, Data and Enable pins is standard in the industry, so it should not be difficult. It is also worth noting that my chip considers the CE, OE and WE pins to be enabled when they are pulled down. Therefore, to activate the chip, I need to pull CE down. If I want to deactivate the chip, I need to pull CE up. This is done by setting the GPIO pins on/off. This does not apply to Data and Address pins. So for Data and Address pins, a "1" is an "on" signal on the connected GPIO pin. You see where this is going, right?

2) JEDEC write-protection: Keeping our data safe and making our life tougher!

Remember when I said that it is all about sequencing when you want to perform operations on the chip? Well sometimes it just happens that due to interference or voltage spikes (or any other undesirable occurrences in the circuit), a chip may be put in "write mode" and accidentally lose some of your data. To avoid this, JEDEC has come up with a standard for protecting the data. All it means, is that the chip will not enter "write mode" by simply enabling the WE pin. It expects a sequence of Addresses and Bytes before the chip "unlocks" its "write mode" and allows you to write data to an address. Your chip's documentation will define what this sequence is and it will all make more sense once you have a look at the code. For now, just keep in your mind that this mechanism complicates things a bit when we want to write data because it adds an overhead to the operation.

3) We got everything we need, let's do this!

I will assume you know how to use a breadboard and wires to connect your chip to the GPIO pins as shown in the attached diagram. Because my chip happens to have more pins than my Pi's GPIO, I have chosen to permanently attach the three highest pins on the Address Bus permanently to the ground. Therefore, those pins always read 0 and I cannot access the entire memory of my chip. Feel free to do the same if your chip also has too many Address pins. You may also choose to permanently pull down the CE pin so the chip is always on. It is entirely up to you. So, to clarify, I am permanently attaching A17, A16 and A15 on my chip to the ground and through the Pi's GPIO pins, I control pins A15 to A0. So I have a 16bit Address Bus and 8 bit Data Bus. I also control CE, OE and WE. And one last thing, on my chip, the Most Significant Bit is always the highest numbered pin.

Step 2: Reading From the Chip

In this step, I am attaching the Python script for reading from the chip. To execute it on your Pi, simply download the file and in your terminal navigate to the folder where you saved the file and type: sudo python EEPROMr.py

I have placed lots of comments in the code, so I will not analyse here what I did. It is pretty self-explanatory once you read the comments. I have tried to use try and catch loops to handle exceptions when things go wrong or when the user interrupts the program before it completes.

One thing to note is that the first comment in the script: "#Use chip numbering scheme" refers to the Pi's BroadCom chip and not to the EEPROM chip. Don't confuse the two.

Step 3: Erasing the Chip - This Wipes Out EVERYTHING!

So in this step I am attaching the script that deletes the entire EEPROM chip. This will set all the bits in every address of the chip with "1".

In this case the JEDEC write-protection kicks in, so if you follow the code closely, you will see the steps that correspond to the sequence of Addresses and Data that unlock the "write mode" of the chip. As you are going through the code, keep in mind how the CE and WE pins are being enabled/disabled to "latch" addresses and data.

To execute the script, navigate to the folder where you saved it and type: sudo python EEPROMd.py

You will get a prompt asking you to confirm the operation before it wipes all the data.

Step 4: Storing Data to the Chip

OK, so this script is a bit more interesting than the others. You execute it by typing: sudo python EEPROMw.py

It will first ask you to define an address of 15 bits. Enter the address starting with the Most Significant Bit in binary format. The script checks to validate that you used only 1/0 and that there is 15 of them. Once it is happy, it will ask you to define the data you want to store in the selected address. Once again, type a full Byte (8 bits) in binary format. Once it is happy, it will perform the write operation for you and inform you when it is complete. JEDEC write-protection is in effect in this script also, so watch out in the code for the sequence that "unlocks" the chip.

This script has a little oversight in that it does not catch Keyboard Interrupts when it prompts the user for addresses in data. This means that if you Ctrl+C during those steps, the script will terminate without cleaning up the GPIO pins. Feel free to add this functionality to the code for practice.

This concludes the EEPROM programming guide using Python on the Pi. You are free to use these scripts, modify them and distribute them for individual use and educational purposes.

Please give credit to Headamage and a link back to this page. The software is available under the GNU General Public Licence v2.

Comments

author
JamesS511 (author)2016-07-11

I am willing to bet a $40 Pi3B that I can backpower using the 5v GPIO pins and ground pins without breaking it. A decent GPIO power supply would of course include surge protection and voltage regulation, and the supply I want to convert from using a step down transformer is already clean and regulated at the source. I will let you know if I make a brick or not. ;)

author
JamesS511 (author)2016-06-28

You are stating that we should use the 3.3v rail to power these, but the munfacturer states the operating range as 4.5v - 5.5v. Is this stable?

http://www.microchip.com/wwwproducts/en/SST39SF020A

author
headamage (author)JamesS5112016-07-10

also, be careful with the voltages on the RPi. If you feed 5v to any of the GPIO, you will fry the CPU.

author
headamage (author)JamesS5112016-07-10

For the tutorial, I never noticed any odd behaviour with my chip. If you wish to build something that accesses the memory faster, you may have to supply more volts.

author
JamesS511 (author)2016-06-28

You are stating that we should use the 3.3v rail to power these, but the munfacturer states the operating range as 4.5v - 5.5v. Is this stable?

http://www.microchip.com/wwwproducts/en/SST39SF020A

author
JohnL156 (author)2015-10-20

Guide looks good. I am about to attempt interfacing an EEPROM I salvaged with my raspberry pi and my robotic arm. I would like to have the correct values sent to the PWM driver such that the robotic arm starts in the state which I set. I figure there are a few ways to go about this; EEPROM/Flash memory happens to be one of them.

Ill be attempting to use an atmel546-24C32AN-SU27 if that doesnt work I have several other options to try.

author
JohnL156 (author)JohnL1562015-10-20

Im still in research phase on this one. Maybe you can help though. I am using http://www.adafruit.com/product/815 which utilizes PCA9685 and i2c bus to control many servos or PWM outputs. I believe the Atmel EEPROM I am looking at http://www.atmel.com/images/doc0336.pdf uses SDA and SCL aka serial. I will need to verify my current setup to ensure I am using the proper pins, as well as, identify possible solutions for my current design revision.

I am a Mechanical Engineer first and foremost, but I have a strong background in robotics, controls, programming; computing.

author
tomatoskins (author)2015-02-24

I've never gotten into Python. It's always intreaged me however. Thanks for sharing!

author
headamage (author)tomatoskins2015-02-24

4 months ago, the only thing I knew about Python is that it is a scripting language. That's when I got a Pi and started playing around with the GPIO. 2 months later, I decided to try my luck with the EEPROM chip and it worked straight away. I didn't have time to make the guide at the time but the last couple of weeks, I have been slowly compiling the info to build the guide. Thanks for dropping by and leaving a comment. I will have one more guide ready soon. It will be a Python script for finding prime numbers using multiprocessing to make use of the extra cores in Pi 2.