24LC256 EEPROM

Development Log

Found datasheets:

Pinout

      +--------+                     # I used ~1k, just because that is what was around
  A0 -| 1    8 |- VDD
  A1 -| 2    7 |- WP (write protect if 1)
  A2 -| 3    6 |- SCL
 GND -| 4    5 |- SDA
      +--------+

Wired up a simple circuit, wiring addresses to 0 and WP (write protect) to an mbed pin:

Schematic

                         --+-------+--+-- 3.3v
                           |       |  |
         +--------+        |       #  # 1k pullups
 +-- A0 -| 1    8 |- VDD --+       #  #
 +-- A1 -| 2    7 |- WP ----- p29  |  |
 +-- A2 -| 3    6 |- SCL ----------+--|-- p27
 +- GND -| 4    5 |- SDA -------------+-- p28
 |       +--------+
GND

Ran I2CU - I2C device search code, and looked at terminal output:

Searching for I2C devices...
 - I2C device found at address 0xA0
1 devices found

So this suggests the device address is 0xA0 (which is confirmed in the datasheet!)

Now let us try and talk to it...

From data write section, it says the format is:

[ high address | low address | data byte ]

and also "Note: The 24XX256 does not generate any Acknowledge bits if an internal programming cycle is in progress.". This means the mechanism for writing should be write data, then poll for completion. So test doing a write, then polling to check it happens:

// test writing 24LC256, then polling for write complete

#include "mbed.h"

I2C i2c(p28, p27); // sda, scl
DigitalOut wp(p29);

int main() {
    printf("Writing byte 0 of 24LC256 with 0x5A\n");

    wp = 0; // disable write protect
    
    char data[] = {0x00, 0x00, 0x5A}; // address is 0x0000, data is 0x5A
    if(i2c.write(0xA0, data, 3)) {
        error("Write failed\n");
    }

    int poll = 0;
    while(i2c.write(0xA0, NULL, 0)) { // wait until we get an acknowledge
        poll++;
    }
    
    printf("Chip acknowledged after %d polls\n", poll);
}

The result is:

Writing byte 0 with 0x5A
Chip acknowledged after 34 polls

so now we need to test whether we can read and write useful data! For reading, we set the read pointer by doing a write to address with no data, then a read of 1 byte to get the data sequentially. Something like:

    printf("Setting read pointer to 0\n");

    data[0] = 0;  // MSB address
    data[1] = 0;  // LSB address
    if(i2c.write(0xA0, data, 2)) { // send address, but no data
        error("Write failed\n");
    }
        
    printf("Reading back data bytes 0-16\n");
    
    char response[1];
    for(int i=0; i<16; i++) {
        if(i2c.read(0xA0, response, 1)) {
            error("Read failed\n");
        }
        printf("address %03d = 0x%02X\n", i, response[0]); 
    }

So knitting that together we get a test program:

http://mbed.org/users/simon/published/431951f3d204eab8246d52bf6b468458/Test24LC256.zip

which gives us the results:

Writing bytes 0-16
Setting read pointer to 0
Reading back data bytes 0-16
address 000 = 0x00
address 001 = 0x03
address 002 = 0x06
address 003 = 0x09
address 004 = 0x0C
address 005 = 0x0F
address 006 = 0x12
address 007 = 0x15
address 008 = 0x18
address 009 = 0x1B
address 010 = 0x1E
address 011 = 0x21
address 012 = 0x24
address 013 = 0x27
address 014 = 0x2A
address 015 = 0x2D

so basically working. Would be natural to wrap this up for simple random read/write access.