|
|
View previous topic :: View next topic |
Author |
Message |
guest Guest
|
fast i2c question |
Posted: Fri Mar 18, 2005 6:23 am |
|
|
Hi to all.
I am reading/writing to a 24lc256 eeprom , and have a few questions.
When I write and then read back the whole 32768 bytes it takes
about 2 min 45 sec .
this is the basic code:
Code: | for(i=0;i<32767;i++)
{
write_ext_eeprom (i,100);
tmp = read_ext_eeprom(i);
} |
the i2c is set up like this:
Code: | #use i2c(MASTER,sda=EEPROM_SDA,scl=EEPROM_SCL)
|
if I now set up the i2c like this
Code: |
#use i2c(FAST , MASTER,sda=EEPROM_SDA,scl=EEPROM_SCL)
|
the test takes about 2min 20 sec.
The fast option only increaced the speed by about 15% or so.
Is this right , or is there something else I can do to make the i2c routines run faster.
Cheers
Rob |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 18, 2005 6:28 am |
|
|
The slowest thing here is the chip itself. The I2C speed only affects the communications, and on 'read' cycles, will save a lot (typically 75%). Most of the time you are seeing is the write time of the chip itself, which is typically in the order of 5mSec/byte. There is nothing you can do to change this, except use a different memory technology. Look at 'FRAM' chips, which have write times vastly better.
Best Wishes |
|
|
Guest Guest
|
|
Posted: Fri Mar 18, 2005 6:58 am |
|
|
Hi there , thanks for the reply.
I just redid the speed test , after commenting out the write command and the speed was doubled with the fast option , which matches up with what you say.
Now to throw a spanner in the works as it were.
I just programmed AND verified the same chip(24lc256) from address
0 to 7fff ( 32k) in a chipmax programmer in under 10 seconds!!!!
How do they manage that?
Cheers
Rob |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Mar 18, 2005 7:04 am |
|
|
Ttelmah wrote: | The slowest thing here is the chip itself. The I2C speed only affects the communications, and on 'read' cycles, will save a lot (typically 75%). Most of the time you are seeing is the write time of the chip itself, which is typically in the order of 5mSec/byte. There is nothing you can do to change this, except use a different memory technology. Look at 'FRAM' chips, which have write times vastly better.
Best Wishes |
Not entirely true. You can write by pages to speed things up.
Quote: | Hi there , thanks for the reply.
I just redid the speed test , after commenting out the write command and the speed was doubled with the fast option , which matches up with what you say.
Now to throw a spanner in the works as it were.
I just programmed AND verified the same chip(24lc256) from address
0 to 7fff ( 32k) in a chipmax programmer in under 10 seconds!!!!
How do they manage that?
Cheers
Rob |
Same answer, page mode. |
|
|
guest Guest
|
|
Posted: Fri Mar 18, 2005 7:12 am |
|
|
Thanks , things are starting to make sence.
Does CCS support page writing at all?
Cheers
Rob |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Mar 18, 2005 7:14 am |
|
|
Depends on what you mean by support. There isn't a function called "write_page" but you can easily do it in C. There should be code already posted in the forum for doing it. |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 18, 2005 7:35 am |
|
|
Yes. Page mode is the way to go if you are writing a lot of data. I was (of course), referring to the timing in the example given which is 'byte by byte'. The saving for page mode depends on the actual page size of the chip, but most of the larger chips support a 64 byte mode, and this makes a huge saving. On most chips all that is needed, is to send the control word, address, and data byte as normal, but then not send the stop, but instead carry on sending another 63 bytes of data. Sending the stop at the end of this triggers the 'page write'. This takes the same time as a single byte write...
The code would be something like:
Code: |
void write_page_ext_eeprom(long int address, BYTE data[])
{
short int status;
int count;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
for (count=0;count<64;)
i2c_write(data[count++]);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
}
|
I used something like this on another chip in the past, and it worked fine, so it should be a starting position for you. Obviously it needs to be called with the address, and an array of 64 bytes.
Best Wishes |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Mar 18, 2005 9:09 am |
|
|
Ttelmah wrote: | Yes. Page mode is the way to go if you are writing a lot of data. I was (of course), referring to the timing in the example given which is 'byte by byte'. The saving for page mode depends on the actual page size of the chip, but most of the larger chips support a 64 byte mode, and this makes a huge saving. On most chips all that is needed, is to send the control word, address, and data byte as normal, but then not send the stop, but instead carry on sending another 63 bytes of data. Sending the stop at the end of this triggers the 'page write'. This takes the same time as a single byte write...
The code would be something like:
Code: |
void write_page_ext_eeprom(long int address, BYTE data[])
{
short int status;
int count;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
for (count=0;count<64;)
i2c_write(data[count++]);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
}
|
I used something like this on another chip in the past, and it worked fine, so it should be a starting position for you. Obviously it needs to be called with the address, and an array of 64 bytes.
Best Wishes |
You should be sure not to exceed the page size or the buffer will wrap and overwrite an area not intended. Something like:
Code: |
/* *************************************************************************
DESCRIPTION: This function writes a block of data to the SEEPROM
RETURN: none
ALGORITHM: none
NOTES: The routine should handle going across chip boundaries
*************************************************************************** */
void I2C_Write_Block(
uint8_t device, /* I2C address of the device that we are writing to */
char *data, /* pointer to the block of data to write */
uint8_t len, /* number of bytes to write */
uint16_t address) /* EEPROM address to write data */
{
uint8_t control;
uint8_t lastpage;
uint8_t page;
/* determine the control word for the device */
control = device | ((uint8_t) (address >> 8) << 1);
/* Wait until our device is ready */
while (!I2C_Device_Ready(control));
/* Set the address pointer in the device */
I2C_WRITE((uint8_t) address);
page = (uint8_t) address >> 4;
lastpage = page;
while (len)
{
if (page != lastpage)
{
/* Issuing a STOP will start the write sequence */
I2C_STOP();
lastpage = page;
/* determine the control word for the device */
control = device | ((uint8_t) (address >> 8) << 1);
/* Wait until our device is ready */
while (!I2C_Device_Ready(control));
/* Set the address pointer in the device */
I2C_WRITE((uint8_t) address);
}
I2C_WRITE(*data);
data++;
address++;
/* The 24C08 has a 16 byte page for writing. */
page = (uint8_t) address >> 4;
len--;
}
I2C_STOP();
}
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|