dvdb
Joined: 12 Jan 2004 Posts: 6 Location: Brussels, Belgium
|
Fast page read/write routines for i2c EEPROMS |
Posted: Thu Dec 23, 2004 12:19 pm |
|
|
The drivers for the 24LCXX EEPROMS provided by CCS do not contain fast multibyte read/write routines. The multibyte reads are quite straightforward, but the multibyte write routines are a little more tricky since they have to stay within a page.
The snippet that I provide here will check page crossing and split up the write into the minimal number of page writes.
I didn't check but I suspect writing large amounts of data will speed up as much as a factor of 100 (for a 128-byte page) compared to single byte writes.
Mind the i2c address - EEPROM2 is 2*address
Enjoy!
Code: |
#define pagesize 128
#define pagemask ~((long)pagesize-1) //this is for the 24LC512
#define hi(x) (*(&x+1))
#define EEPROM2 0b00001100
#define control_byte_read 0xa1
#define control_byte_write 0xa0
void init_ext_eeprom() {
output_float(PIN_C4);
output_float(PIN_C3);
}
BOOLEAN ext_eeprom2_ready() {
int1 ack;
i2c_start(); // If the write command is acknowledged,
ack = i2c_write(control_byte_write|EEPROM2); // then the device is ready.
i2c_stop();
return !ack;
}
void write_ext_eeprom2(long int address, BYTE data) {
while(!ext_eeprom2_ready());
i2c_start();
i2c_write(control_byte_write|EEPROM2);
i2c_write(hi(address));
i2c_write(address);
i2c_write(data);
i2c_stop();
}
BYTE read_ext_eeprom2(long int address) {
BYTE data;
while(!ext_eeprom2_ready());
i2c_start();
i2c_write(control_byte_write|EEPROM2);
i2c_write(hi(address));
i2c_write(address);
i2c_start();
i2c_write(control_byte_read|EEPROM2);
data=i2c_read(0);
i2c_stop();
return(data);
}
void multiread_ext_eeprom2(long int address, int number, int* dest )
{
if(number>0)
{
while(!ext_eeprom2_ready());
i2c_start();
i2c_write(control_byte_write|EEPROM2);
i2c_write(hi(address));
i2c_write(address);
i2c_start();
i2c_write(control_byte_read|EEPROM2);
while (number>1)
{*dest=i2c_read(1); //1 because do ACK after each byte read
dest++;
number--;
}
*dest=i2c_read(0); //0 because no ACK
i2c_stop();
};
}
void multiwrite_ext_eeprom2(long int address, int number, int* data )
{ long strt_adress;
while(number!=0)
{
strt_adress=address&pagemask;
while(!ext_eeprom2_ready());
i2c_start();
i2c_write(control_byte_write|EEPROM2);
i2c_write(hi(address));
i2c_write(address);
while ((number!=0)&&((address&pagemask)==strt_adress))
{i2c_write(*data);
data++;
number--;
address++;
};
i2c_stop();
}; |
_________________ Dirk Van den Berge |
|