Pond Electronics - Home of the µFlash876 & µFlash876B embedded controllers, µStack & µConnect Bus.

Accessing the µFlash876 I2C EEPROM

Introduction

This application notes shows how to access the serial EEPROM on the µFlash876 & µFlash876B and provides a library support module to implement a simple file system. For the purposes of this application note we will assume use of the CCS PIC C compiler and the uconn.h (supplied by Pond) µConnect support header file. Use with other C compilers may require small modifications.

The 24LC64 8KByte serial EEPROM

The 24LC64 is an 8KByte serial EEPROM. It is accessed using the industry standard I2C serial protocol. Use of the I2C bus is simplified by the inclusion of the uconn.h header file which provides high level support for the I2C & µConnect (buffered I2C) bus.

 

24LC64 Memory Organization

For read access the memory is available as a single 8kByte block, but for write access it is divided into 256 X 32 byte pages.

For read operations the memory in the 24LC64 is arranged as a single 8K Byte block of data. It is therefore possible to read the entire contents of the EEPROM with a single multibyte I2C read. For write operations the memory is divided into 256 pages of 32 bytes each. You may write up to a single page (32 bytes) of data at a time using an I2C multibyte write. However any single multibyte write may not cross a page boundary. To write data over a page boundary requires multiple I2C write transactions.

For example while it is legal to read (say) 4 bytes extending from EEPROM address 30-33 in a single I2C read operation, those same 4 bytes must be written using at least two I2C write calls (30-31 and 32-33). This complexity often means it is more convenient (though much slower) to accomplish all EEPROM writes using multiple single byte I2C write transactions.

 

Accessing the 24LC64 (Write)

In order to access the EEPROM you must first address it on the I2C bus, this is done using the µConnect function uc_wstart:

     uc_wstart(0x50); // access the 24LC64 on the I2C bus

You must follow this with the target address of the data you wish to write, this is done with two uc_write commands, high byte of address first:

     uc_write(0x01); // address EEPROM location 0x0123
     uc_write(0x23);

You can now send the data to write as one or more uc_write commands, note that the target address is automatically incremented following each write:

     uc_write(23);   // write 23 to location 0x0123
     uc_write('b');  // write 'b' to location 0x0124
     uc_write(17);   // write 17 to location 0x0125

As pointed out earlier it is important that the sequential writes do not cross a 32 byte page boundary.

The write sequence can be terminated by using the uc_stop function:

     uc_stop();      // end of write sequence

Following the call to uc_stop the 24LC64 copies the data from its write buffer to EEPROM memory, this process takes up to 5mS during which the 24LC64 is unavailable for new read or write commands. While it is possible to determine when the write is complete and the chip is once again available, the simplest approach is to simply wait 10mS following the end of each write sequence.

Accessing the 24LC64 (Read)

As before the 24LC64 must be addressed on the I2C bus using the uc_write function:

     uc_wstart(0x50); // access the 24LC64 on the I2C bus

You must follow this with the target address of the data you wish to read, this is done with two uc_write commands, high byte of address first:

     uc_write(0x01);  // address EEPROM location 0x0123
     uc_write(0x23);

Now you must switch to I2C read mode using the uc_rstart function:

     uc_rstart(0x50); // start an I2C read sequence

You can now read one one or more bytes from the EEPROM using the uc_read function, note that the parameter of the uc_read function should be 1 for all reads except the last. Once again the address is automatically incremented after each read:

     x0=uc_read(1);   // read byte from location 0x0123
     x1=uc_read(1);   // read byte from location 0x0124
     x2=uc_read(0);   // read byte from location 0x0125

Unlike write access, multibyte reads may cross 32 byte page boundaries without any adverse consequences.

Following the last read you may terminate the sequence using:

     uc_stop();       // end of read sequence

Again, unlike the write sequence there is no need to insert a delay following the end of read as the chip is immediately available for further access.

 

Simple "file" access to the 24LC64

The following functions provide simple "file" type access to the 24LC64. The package includes functions for "seeking" an address in the EEPROM as well as reading and writing common data types.

Limitations of use

To provide the best possible speed, word and float writes to the EEPROM are implemented as multibyte I2C writes. As indicated earlier multibyte writes may not extend over a 32 byte boundary. To ensure that word or float writes do not fail, it is necessary to ensure the above restriction is observed. The easiest way to do this is to restrict word writes to even addresses only (0,2,4,6.....) and float writes to addresses divisible by 4 (0,4,8,12.....). This must be done by your application code. By increasing the complexity of the code it would be possible to implement word and float write functions that do not have these restrictions, however for most applications it is probably not worth the effort.

The EEPROM File access module

The file access module consists of the following functions:

file_seek(WORD x)
Sets the address of the next read or write to address x. Note that the address is maintained internally in ram for use by the next read or write function, no access to the 24C64 is necessary.

file_writeb(BYTE x)
Write a single byte to the EPROM at the current file address (set by file_fseek). The file address is incremented after the write. This function includes a 10mS delay to allow 24LC64 to copy the data from the write buffer to EEPROM. Note that there no page boundary restrictions in using this function as it does not attempt to write more than on one byte in an I2C transaction.

file_writew(WORD x)
Write a single word to the EEPROM at the current file address (set by file_fseek). The file address is incremented by 2 after the write. This function includes a 10mS delay to allow 24LC64 to copy the data from the write buffer to EEPROM. Since this is a multibyte write, precautions should be taken to ensure that a 32 byte page is not crossed by a single call to this function.

file_writef(float x)
Write a single float to the EEPROM at the current file address (set by file_fseek). The file address is incremented by 4 after the write. This function includes a 10mS delay to allow 24LC64 to copy the data from the write buffer to EEPROM. Since this is a multibyte write, precautions should be taken to ensure that a 32 byte page is not crossed by a single call to this function.

BYTE file_readb(void)
Returns a single byte from the location addressed by the current file address. Increments the address following the read.

WORD file_readw(void)
Returns a single word from the location addressed by the current file address. Increments the address by 2 following the read.

float file_readf(void)
Returns a single float from the location addressed by the current file address. Increments the address by 4 following the read.

View source of I2C EEPROM file library.

 

A simple example

The following code fragment assumes that the EEPROM file module is present.

#include <uf876.h>   // include uf876 support
#include <uconn.h>   // uConnect support

main(void)
    {
    float x;

    file_seek(0x100);     // EEPROM address 0x100
    file_writef(32.1234); // write a float value

    /* other code here */

    file_seek(0x100);     // EEPROM address 0x100
    x=file_readf();       // read the stored value     
    printf("%f/r/n",x);   // and print it
    }

 

If you have any questions or comments regarding this application note, please contact us.

 

Copyright (c) Paul O Neill & Pond Electronics 2003

Home | Products | Technical Info | How to Order | Contact Us | Links