I2C write buffer -or- improve EEPROM write access

Where does the Atmega328 datasheet state anything about the 32 byte buffer / maximum length of data per one transmission used in I2C?

Motivation:
I want to increase the write speed of an I2C EEPROM.
Quite a few web pages explain how to write several bytes to an I2C EEPROM in one transmission using "page-write" (eg http://www.hobbytronics.co.uk/eeprom-page-write). With this command one page (up to 32 or 64 bytes) can be written at once, but the Arduino buffer size limits the data length at 30 bytes (+2 address bytes) at once, though I could not find this info in the datasheet, hence question on top.
Because of this limitation the usual page-write examples breakdown the data in 16 byte chunks (followed with a mandatory 5ms delay).

Idea
Assuming f the I2C TX buffer is of the type "first in, first out", then the buffer is filled with 29 bytes of data and the 2 address bytes. After waiting 1ms (during which the transmission is already going on and thus creating space in the buffer), additional bytes are written into the buffer.

Test
In the linked example, a total of 280 bytes is written in 16 byte pieces.
The total transmission time was ~146 ms, one chunk of 16 bytes took 1.9ms (not counting the following 5ms delay). Note that this is the run time of the program code, not the actual time measured on signal wires.
My modified code took only 100 ms for the total write time.

PROBLEM:
Only most of the data is stored correctly. I notice quite a few errors when reading the data, not just around the 30-32 byte boundary. So the question is why?

Here is my modified code:

void writeEEPROMnew(int deviceaddress, unsigned int eeaddress, char* data) {
  unsigned char i=0, counter=0;
  unsigned int  address;
  unsigned int  page_space;
  unsigned int  page=0;
  unsigned int  num_writes;
  unsigned int  data_len=0;
  unsigned char first_write_size;
  unsigned char last_write_size;  
  unsigned char write_size;  
  
    // Calculate length of data
    do{ data_len++; } while(data[data_len]);   
   
    // Calculate space available in first page
    page_space = int(((eeaddress/64) + 1)*64)-eeaddress;
    first_write_size=page_space;   //modified
    if (first_write_size==0) first_write_size=32;  //was 16 instead of 32

  // calculate size of last write  
  if (data_len>first_write_size) 
     last_write_size = (data_len-first_write_size)%32;   //was 16
  
  // Calculate how many writes we need
  if (data_len>first_write_size)
     num_writes = ((data_len-first_write_size)/32)+2;  // was 16
  else
     num_writes = 1;  
     
  i=0;   
  address=eeaddress;
  for(page=0;page<num_writes;page++) 
  {
     if(page==0) write_size=first_write_size;
     else if(page==(num_writes-1)) write_size=last_write_size;
     else write_size=32;//was 16
  
     Wire.beginTransmission(deviceaddress);
     Wire.write((int)((address) >> 8));   // MSB
     Wire.write((int)((address) & 0xFF)); // LSB
     counter=0;
     do{ 
        Wire.write((byte) data[i]);
        i++;
        counter++;
        if (counter == 29)    delay(1);
     } while((data[i]) && (counter<write_size));  
     Wire.endTransmission();
     address+=write_size;   // Increment address for next write
     delay(5);  // needs 5ms for page write
  }

Where does the Atmega328 datasheet state anything about the 32 byte buffer / maximum length of data per one transmission used in I2C?

Nowhere because that buffer is a software feature, the buffer is only available if you use the Wire library.

If you access the hardware yourself or if you modify the Wire library you can increase the buffer or circumvent it completely.

When you want to increase the write speed to an I2C EEPROM, buy a SPI EEPROM.

@pylon
Thanks to your post regarding the buffer size implementation in software I found this thread on changing / increasing the buffer size
http://forum.arduino.cc/index.php/topic,54439.0.html

@Peter_n
True, SPI is faster (~30x), but I was more wondering, if there is a way to decrease the number of delays in the I2C transfer. Personally, I have no need switching to faster chips.

Apart from the binary system, is there any reason against setting the buffer size limit to the "odd" size of 34 byte?

As far as I know, you can adapt the buffer size for Serial and Wire as you like.

I have used this one:-

It allows a lot more data to be transferred in one go than the 32 bytes in the normal library. It also has a choice of speeds and an option to turn on / off the internal pull up resistors.

The datasheet for my 24LC512 states that page writes should only occur on the beginning address of the page. It seemed to indicate that a write to another address will complete with the data wrapping within the page. This is probably not the behavior most expect.

I rewrote the Wire and TWI libraries to allow different TX and RX buffer lengths. I did full page writes (128 bytes) out to my 24LC512 without much trouble. I didn't notice any corruption.

Side questions:

  1. Do you have a long transmission line that might introduce issues?
  2. Have you considered changing the TWI bus speed? My EEPROM is rated to 400kHz (100kHz is the normal).