Blog: How-Tos
How to read from an EEPROM
I’ve been messing around with different pieces of hardware recently in an attempt to either get something useful out of them, or even reprogram them.
One of these is a set of Fitbit scales – I’ve mentioned them previously.
That time I concentrated on the way it interfaces to my network and to the Fitbit website.
Because I wasn’t really getting anywhere with decompiling the firmware, or abusing the UART ports on the motherboard, I thought I’d drop lower this time and go straight for the flash memory.
Here’s the motherboard and I’ve highlighted the two chips I’ve found:
The chip highlighted in red is sat next to a set of jumper holes labelled MSPI and SSPI, which suggests it’s part of the SPI bus, which the wireless daughter board (the thing with cables coming off it) talks on.
The chip highlighted in purple is next to the CPU and the screen controller, suggesting that it’s either the boot rom or the system memory.
To check this out I used a USB microscope to photograph the chips, then entered the codes into a search engine to find the datasheets, so we have:
Colour | Type | Purpose | Communication |
Red | Winbond 25P80VP | 8 Mb (1 MB) serial Flash memory | SPI |
Purple | UNI U24C02 | 2 Kb (256 B) EEPROM | I2C |
So, we have a 1 MB memory chip attached to the SPI bus, which the wireless card also uses – so I’m guessing that this is the main flash store for the scales. We also have a 256 byte EEPROM attached via I2C, this is most likely the boot EEPROM.
The one way to see is to read it. As I’ve said before my soldering isn’t very good, so removing the chip from the board isn’t going to happen, well, not without me breaking it.
So what we could do is to connect directly to the communication pins and try and read data as it flows through. We can do this using some hooks – basically metal grips in a plastic surround that are small enough to grab the individual leg of the chip. The hooks are then connected to a logic analyser which is sampling and interpreting the traffic during a normal boot up (performed by removing the batteries).
This is a very delicate setup as there isn’t much space and the hooks can slip off very easily. This is what it looks like:
Now that really doesn’t look comfortable, right? You really wouldn’t have wanted to hear the swearing that went on while trying to get all this working.
To actually do this we need to discover the pin “outs” from the chips. Fortunately these are normally bought directly off the shelf and the datasheets are publically available.
Winbond 25P80P: http://www.datasheet-pdf.com/datasheetdownload.php?id=718369
Uni U23C02 EEPROM: http://www.uni-semi.com/Spec/UNI%20-%20SP%20-%20U24C02~16%20%28U24C02~16-V.H2.0E%29.pdf
As both of the chips are totally different in format, I’m going to deal with just one, the Uni U23C02 EEPROM. The method for taking a reading using hooks and the logic analyser is the same.
This is a simple 256 byte EEPROM which can be read using the I2C protocol. The 8 pins break out as:
PIN | Use |
A0 | Address 0 – the LSB of the I2C address of the chip |
A1 | Address 1 – the ESB of the I2C address of the chip |
A2 | Address 2 – the MSB of the I2C address of the chip |
GND | Ground |
Vcc | Positive voltage, between 1.8V to 5.5V |
WP | Write Protect |
SCL | I2C Clock |
SDA | I2C Data |
This tells us that the chip uses I2C to communicate. I2C, which stands for Inter-Integrated Circuit, also known as two-wire, is a bus that allows chips to talk to each other on a simple serial connection.
It can support up to 128 chips on the bus with a simple addressing scheme. To communicate it uses two wires: a clock (SCL) and a data line (SDA).
The destination of the data is assigned by a 7-bit address (hence the limit of 128 devices).
This chip, specifically has some things that we know about from reading the datasheet: the address bits will always be:
1 | 0 | 1 | 0 | A2 | A1 | AO | R/W |
As this is the only I2C chip on the board gave a hint when tracing the connections and A0, A1 and A2 are all connected to ground, meaning that we know that the address will be 10100001 (0xA1) for read and 10100000 (0xA0) for write.
For initial reading I connected SDA to probe 0 and SCL to probe 1. I got garbage back, until I realised that I needed to connect ground to give a well, grounding to the signals. Once I had connected these three probes I got something sensible back.
Here’s a sample reading:
Here we can see the clock doing what a clock does: ticking at a regular basis and then actual data traverse (the wibbly bit at the end of the packet is the ACK).
Now I know it was working, I connected up the probes, started the analyser collecting and did a full power cycle of the scales.
What I got back was:
7.843189,0,’160′ (0xA0),’ ‘ (0x20),Write,ACK
7.8437685,1,’161′ (0xA1),B (0x42),Read,NAK
7.844373,2,’160′ (0xA0),! (0x21),Write,ACK
7.8449525,3,’161′ (0xA1),o (0x6F),Read,NAK
7.8455575,4,’160′ (0xA0),” (0x22),Write,ACK
7.846137,5,’161′ (0xA1),n (0x6E),Read,NAK
7.8467415,6,’160′ (0xA0),# (0x23),Write,ACK
7.847321,7,’161′ (0xA1),s (0x73),Read,NAK
7.847926,8,’160′ (0xA0),$ (0x24),Write,ACK
7.8485055,9,’161’ (0xA1),o (0x6F),Read,NAK
Looks like not much? But notice the pattern: we get a write packet to an increasing value starting from 0x20 (i.e. 32) followed by a read packet with a value. Let’s check this against the datasheet:
RANDOM READ: A random read requires a “dummy” byte write sequence to load in the data word address. Once the device address word and data word address are clocked in and acknowledged by the EEPROM, the microcontroller must generate another start condition. The microcontroller now initiates a current address read by sending a device address with the read/write select bit high. The EEPROM acknowledges the device address and serially clocks out the data word. The microcontroller does not respond with a “0” but does generate a following stop condition (see Figure 8).
Wow, that paragraph is really hard to read, but in essence it says that a random read is a write of the one byte address to be read, then it can be read from line.
To minimise the amount of copy and paste of raw data, what happens is that after boot up, the whole EEPROM is read via this channel. This means that we’ve basically dumped it all.
After mangling the analyser’s output here’s the hex dump of the EEPROM:
What I find interesting is that the first thing read are the 5 bytes are address 0x20 – 0x25, which equate to the string “Bonso”. Now if we type that into Google, we find a company called Bonso Electronics International who do a selection of electronic and precision scales. I guess we know who made the scales now!