user22725: The question is about how to have information/control of a variable length read for an Arduino acting as a slave device.
The concrete context is that I want to emulate an EEPROM IC.
A byte write to the EEPROM's address sets the internal EEPROM address to start reading from.
The subsequent read from the EEPROM's address, will start returning bytes from that internal address which is incremented for each byte read.
"Wire.onRequest(requestEvent);" allows us to set up a handler, but it seems to be called only once on the start of the read.
In the handler it is possible to provide a reply of multiple bytes.
However I did not find the documentation allowing to know how many bytes were effectively sent to the master.
I got the initial code from the arduino forum .  I've adapted it to this:
#include <Wire.h>
//#define DEBUG
byte XEEPROM[256] = {
  0x5D, 0x26, 0x31, 0x91, 0x3e, 0x12, 0x8e, 0x70, 0xa5, 0x57, 0x3d, 0xed, 0x91, 0x99, 0xb4, 0x11,
  0x38, 0xde, 0x1b, 0xd6, 0x4c, 0xd9, 0xf5, 0x13, 0x23, 0x94, 0xb8, 0x3d, 0x9c, 0xb0, 0xc4, 0x54,
  0xf0, 0x69, 0xca, 0xb3, 0x28, 0x84, 0xa5, 0xc1, 0x80, 0x53, 0x69, 0x0c, 0x38, 0x4f, 0x0c, 0x74,
  0xa1, 0x5b, 0x8c, 0x71, 0x34, 0x30, 0x38, 0x30, 0x30, 0x38, 0x31, 0x35, 0x33, 0x31, 0x30, 0x35,
  0x00, 0x12, 0x5a, 0x1e, 0xbd, 0x9e, 0x00, 0x00, 0x02, 0x82, 0x30, 0xaa, 0x10, 0xb7, 0x7f, 0x8d,
  0x0a, 0xcb, 0x2e, 0xc1, 0xeb, 0x52, 0x20, 0xdc, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x97, 0x55, 0x57, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4d, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x02, 0x03, 0x05, 0x00, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  0x68, 0xaa, 0xdd, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45,
  0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69,
  0x12, 0x03, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x02, 0x02, 0x46, 0x45, 0x8f, 0x8f,
  0x78, 0x56, 0xbb, 0x69, 0x12, 0x02, 0x84, 0x79, 0x80, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00
};
static volatile byte rQ;

void setup()
{
 Wire.begin(0x50);
 Wire.onReceive(receiveEvent);
 Wire.onRequest(requestEvent);
 Serial.begin(115200);
 Serial.println("I2C EEPROM EMULATION\n");
}

void loop()
{
}

void requestEvent(){ 
  //Wire.write(XEEPROM[rQ]); // Just 1
  Wire.write(XEEPROM+rQ,6); /// More than 1
  #ifdef DEBUG
  Serial.print("ADR:");
  Serial.print(rQ,HEX);
  Serial.print("R:");
  Serial.print(XEEPROM[rQ],HEX);  // print the character
  Serial.println();
  #endif
  rQ++; // Increment should depend on number of reads - not sure how to detect that.
}

void receiveEvent(int iData){
    rQ = Wire.read();
    Serial.print("ADR:");
    Serial.print(rQ,HEX);
    bool dwHeader=false;
    // loop through all but the last
    while(1 < Wire.available()) 
    {
      if(!dwHeader) {
          dwHeader=true;
          Serial.print("DATAW:");
      }
      XEEPROM[rQ]=Wire.read();;
      Serial.print(XEEPROM[rQ],HEX);  // print the character
    }
    Serial.println(); // new line
}

The question is about requestEvent and specifically:
void requestEvent(){ 
  //Wire.write(XEEPROM[rQ]); // Just 1
  Wire.write(XEEPROM+rQ,6); /// More than 1
  rQ++; // Increment should depend on number of reads - not sure how to 
}

I would like to send one at a time, or at least be able to increment rQ according to the number of bytes effectively sent.
If you want to look at a datasheet, you can look at the AT24C02 datasheet.
With regards to the incrementing internal EEPROM address, the EEPROM specification says:

CURRENT ADDRESS READ: The internal data word address counter maintains
  the last address accessed during the last read or write operation,
  incremented by one. This address stays valid between operations as
  long as the chip power is maintained. The address “roll over” during
  read is from the last byte of the last memory page to the first byte
  of the first page. The address “roll over” during write is from the
  last byte of the current page to the first byte of the same page.

This is why the Arduino code emulating the EEPROM should know exactly how many bytes were read.
Thanks.

user10214: This is exactly what I stumbled upon when trying to create a I2C slave with a memory-based interface.
You are right, the requestEvent callback is called only once. So you have to prepare it beforehand. What is positive, however, is that the write function will discard all the unused bytes.
So, what can you do? Well, first of all a sum up of the I2C "messages". You, as a master, can

Send a "write" command, with a payload
Send a "read" command, with no payload, and the slave will reply with bytes as long as you continue to send ACKs

In my mind there were two different approaches:

The "write" command should contain the initial register and the number of registers to read; this approach, however, complicates distinguishing between a "read from EEPROM" and "write to EEPROM" commands
The write command should send only the initial register for reading from EEPROM, and the initial register + content to be written for writing to EEPROM.

In my project I chose the second approach. For this reason, when the master writes something on the I2C bus, the first byte of the payload is the register number, and then if there is no other data the slave prepares for sending the contents of the register and the next ones, while if there is any data this is treated as a write command.
The only problem with this approach is that the slave has to prepare a buffer, and the buffer size limits the maximum number of registers returned. I set this limit to 8 in my code; if the master asks for more than only 0s are returned.
Here is the library I wrote for this project.
File I2CInterface.h:
#ifndef I2CINTERFACE_H
#define I2CINTERFACE_H

#include <stdint.h>

class I2CInterface
{
  public:
    static I2CInterface instance;

  public:
    void start();

  private:
    I2CInterface();

    static void requestEvent();
    static void receiveEvent(int howMany);
    void resetSendingBuffer();

  private:
    static const uint8_t Address = 0x46;

    static const uint8_t MaxBufferLength = 8; // (max) 8 byte
    uint8_t sendingBuffer[MaxBufferLength];
};

#endif // I2CINTERFACE_H

File I2CInterface.cpp
#include <Arduino.h>
#include <Wire.h>
#include "I2CInterface.h"

I2CInterface I2CInterface::instance;

I2CInterface::I2CInterface()
{

}

void I2CInterface::start()
{
  Wire.begin(Address);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
  resetSendingBuffer();
}

void I2CInterface::requestEvent()
{
  Wire.write(instance.sendingBuffer, MaxBufferLength);
  instance.resetSendingBuffer();
}

void I2CInterface::receiveEvent(int howMany)
{
  if (howMany <= 0)
    return;
  else if (howMany == 1)
  { // Reading request
    uint8_t regist = Wire.read();
    for (uint8_t i = 0; i < MaxBufferLength; i++)
      instance.sendingBuffer[i] = Configuration.getRegister(regist++);
  }
  else
  { // Writing request
    uint8_t regist = Wire.read();
    while (Wire.available())
    {
      Configuration.setRegister(regist++, Wire.read());
    }
    instance.resetSendingBuffer();
  }
}

void I2CInterface::resetSendingBuffer()
{
  for (uint8_t i = 0; i < MaxBufferLength; i++)
    sendingBuffer[i] = 0x00;
}

Please note that the Configuration.getRegister and Configuration.setRegister are the functions I used to get and set some registers; you can substitute them with a direct EEPROM access or your own functions.
You just need to add, in your main file,
#include "I2CInterface.h"
...

void setup()
{
  ...
  I2CInterface::instance.start();
  ...
}


user42015: Note, that I haven't tested the code below, since I currently don't have enough time for it. But it may help you to get, what you want to do.
The way the I2C interface works is, that after each byte read from the slave, the master will answer with ACK or NACK, depending on if he wants to read more data or not. So the slave doesn't know beforehand, how many bytes the master wants to read.
But you can change the Wire library, to call the onRequest callback for every single byte, instead of every request. The important code lies in the path of your Arduino installation at hardware/arduino/avr/libraries/Wire/src/utility/twi.c at line 575 (I refer to my installation of version 1.8.5; might be slightly different for you):
case TW_ST_SLA_ACK:          // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
      // enter slave transmitter mode
      twi_state = TWI_STX;
      // ready the tx buffer index for iteration
      twi_txBufferIndex = 0;
      // set tx buffer length to be zero, to verify if user changes it
      twi_txBufferLength = 0;
      // request for txBuffer to be filled and length to be set
      // note: user must call twi_transmit(bytes, length) to do this
      twi_onSlaveTransmit();
      // if they didn't change buffer & length, initialize it
      if(0 == twi_txBufferLength){
        twi_txBufferLength = 1;
        twi_txBuffer[0] = 0x00;
      }
      // transmit first byte from buffer, fall
case TW_ST_DATA_ACK: // byte sent, ack returned
      // copy data to output register
      TWDR = twi_txBuffer[twi_txBufferIndex++];
      // if there is more to send, ack, otherwise nack
      if(twi_txBufferIndex < twi_txBufferLength){
        twi_reply(1);
      }else{
        twi_reply(0);
      }
      break;

When receiving a request with correct address, the first case will be executed (of course after other stuff with receiving address and sending ACK). The twi_onSlaveTransmit() function will execute the onRequest callback. When that is done, the code falls directly into the next case statement, which sends the first byte. When the slave receives an ACK after that byte, it should come back to this case and send another byte.
We can now put the buffer filling code into the second case statement, so that the callback will be executed for every requested byte. In this case we also need to change the if statement after that, so that it only triggers and sends NACK, if the user didn't write a byte in the callback. The original library seems to write at minimum 1 byte (even it nothing is in the buffer; it is set to zero). So we will also do this by setting a flag in the first case statement. The code now looks like this:
case TW_ST_SLA_ACK:          // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
      // enter slave transmitter mode
      twi_state = TWI_STX;
      twi_slave_transmit_first_byte = 1;
      // transmit first byte from buffer, fall
case TW_ST_DATA_ACK: // byte sent, ack returned
      // ready the tx buffer index for iteration
      twi_txBufferIndex = 0;
      // set tx buffer length to be zero, to verify if user changes it
      twi_txBufferLength = 0;
      // request for txBuffer to be filled and length to be set
      // note: user must call twi_transmit(bytes, length) to do this
      twi_onSlaveTransmit();
      if(twi_slave_transmit_first_byte == 1){
          twi_slave_transmit_first_byte = 0;
          // if they didn't change buffer & length, initialize it
          if(0 == twi_txBufferLength){
            twi_txBufferLength = 1;
            twi_txBuffer[0] = 0x00;
          }
      }
      // copy data to output register
      TWDR = twi_txBuffer[twi_txBufferIndex++];
      // if there is more to send, ack, otherwise nack
      if(twi_txBufferIndex < twi_txBufferLength){
        twi_reply(1);
      }else{
        twi_reply(0);
      }
      break;

And we have to add the flag declaration at the top of the file (where all the other static volatile variables are defined) as static volatile:
static volatile uint8_t twi_slave_transmit_first_byte = 0;

In the onRequest callback you can now write a single byte to the buffer and incrementing your counter.

I think, that should work. If someone knows better, please correct me.

22725: <p>The question is about how to have information/control of a variable length read for an Arduino acting as a slave device.</p>

<p>The concrete context is that I want to emulate an EEPROM IC.
A byte write to the EEPROM's address sets the internal EEPROM address to start reading from.
The subsequent read from the EEPROM's address, will start returning bytes from that internal address which is incremented for each byte read.</p>

<p>"Wire.onRequest(requestEvent);" allows us to set up a handler, but it seems to be called only once on the start of the read.</p>

<p>In the handler it is possible to provide a reply of multiple bytes.
However I did not find the documentation allowing to know how many bytes were effectively sent to the master.</p>

<p>I got the initial code from <a href="http://forum.arduino.cc/index.php?topic=17897.0" rel="nofollow noreferrer">the arduino forum</a> .  I've adapted it to this:</p>

<pre><code>#include &lt;Wire.h&gt;
//#define DEBUG
byte XEEPROM[256] = {
  0x5D, 0x26, 0x31, 0x91, 0x3e, 0x12, 0x8e, 0x70, 0xa5, 0x57, 0x3d, 0xed, 0x91, 0x99, 0xb4, 0x11,
  0x38, 0xde, 0x1b, 0xd6, 0x4c, 0xd9, 0xf5, 0x13, 0x23, 0x94, 0xb8, 0x3d, 0x9c, 0xb0, 0xc4, 0x54,
  0xf0, 0x69, 0xca, 0xb3, 0x28, 0x84, 0xa5, 0xc1, 0x80, 0x53, 0x69, 0x0c, 0x38, 0x4f, 0x0c, 0x74,
  0xa1, 0x5b, 0x8c, 0x71, 0x34, 0x30, 0x38, 0x30, 0x30, 0x38, 0x31, 0x35, 0x33, 0x31, 0x30, 0x35,
  0x00, 0x12, 0x5a, 0x1e, 0xbd, 0x9e, 0x00, 0x00, 0x02, 0x82, 0x30, 0xaa, 0x10, 0xb7, 0x7f, 0x8d,
  0x0a, 0xcb, 0x2e, 0xc1, 0xeb, 0x52, 0x20, 0xdc, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x97, 0x55, 0x57, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4d, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x02, 0x03, 0x05, 0x00, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  0x68, 0xaa, 0xdd, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45,
  0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69,
  0x12, 0x03, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x02, 0x02, 0x46, 0x45, 0x8f, 0x8f,
  0x78, 0x56, 0xbb, 0x69, 0x12, 0x02, 0x84, 0x79, 0x80, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00
};
static volatile byte rQ;

void setup()
{
 Wire.begin(0x50);
 Wire.onReceive(receiveEvent);
 Wire.onRequest(requestEvent);
 Serial.begin(115200);
 Serial.println("I2C EEPROM EMULATION\n");
}

void loop()
{
}

void requestEvent(){ 
  //Wire.write(XEEPROM[rQ]); // Just 1
  Wire.write(XEEPROM+rQ,6); /// More than 1
  #ifdef DEBUG
  Serial.print("ADR:");
  Serial.print(rQ,HEX);
  Serial.print("R:");
  Serial.print(XEEPROM[rQ],HEX);  // print the character
  Serial.println();
  #endif
  rQ++; // Increment should depend on number of reads - not sure how to detect that.
}

void receiveEvent(int iData){
    rQ = Wire.read();
    Serial.print("ADR:");
    Serial.print(rQ,HEX);
    bool dwHeader=false;
    // loop through all but the last
    while(1 &lt; Wire.available()) 
    {
      if(!dwHeader) {
          dwHeader=true;
          Serial.print("DATAW:");
      }
      XEEPROM[rQ]=Wire.read();;
      Serial.print(XEEPROM[rQ],HEX);  // print the character
    }
    Serial.println(); // new line
}
</code></pre>

<p>The question is about requestEvent and specifically:</p>

<pre><code>void requestEvent(){ 
  //Wire.write(XEEPROM[rQ]); // Just 1
  Wire.write(XEEPROM+rQ,6); /// More than 1
  rQ++; // Increment should depend on number of reads - not sure how to 
}
</code></pre>

<p>I would like to send one at a time, or at least be able to increment rQ according to the number of bytes effectively sent.</p>

<p>If you want to look at a datasheet, you can look at the <a href="http://ww1.microchip.com/downloads/en/devicedoc/doc0180.pdf" rel="nofollow noreferrer">AT24C02 datasheet</a>.
With regards to the incrementing internal EEPROM address, the EEPROM specification says:</p>

<blockquote>
  <p><strong>CURRENT ADDRESS READ</strong>: The internal data word address counter maintains
  the last address accessed during the last read or write operation,
  incremented by one. This address stays valid between operations as
  long as the chip power is maintained. The address “roll over” during
  read is from the last byte of the last memory page to the first byte
  of the first page. The address “roll over” during write is from the
  last byte of the current page to the first byte of the same page.</p>
</blockquote>

<p>This is why the Arduino code emulating the EEPROM should know exactly how many bytes were read.</p>

<p>Thanks.</p>
 10214: <p>This is exactly what I stumbled upon when trying to create a I2C slave with a memory-based interface.</p>

<p>You are right, the <code>requestEvent</code> callback is called only once. So you have to prepare it beforehand. What is positive, however, is that the <code>write</code> function will discard all the unused bytes.</p>

<p>So, what can you do? Well, first of all a sum up of the I2C "messages". You, as a master, can</p>

<ul>
<li>Send a "write" command, with a payload</li>
<li>Send a "read" command, with no payload, and the slave will reply with bytes as long as you continue to send ACKs</li>
</ul>

<p>In my mind there were two different approaches:</p>

<ul>
<li>The "write" command should contain the initial register and the number of registers to read; this approach, however, complicates distinguishing between a "read from EEPROM" and "write to EEPROM" commands</li>
<li>The write command should send only the initial register for reading from EEPROM, and the initial register + content to be written for writing to EEPROM.</li>
</ul>

<p>In my project I chose the second approach. For this reason, when the master writes something on the I2C bus, the first byte of the payload is the register number, and then if there is no other data the slave prepares for sending the contents of the register and the next ones, while if there is any data this is treated as a write command.</p>

<p>The only problem with this approach is that the slave has to prepare a buffer, and the buffer size limits the maximum number of registers returned. I set this limit to 8 in my code; if the master asks for more than only 0s are returned.</p>

<p>Here is the library I wrote for this project.</p>

<p>File I2CInterface.h:</p>

<pre><code>#ifndef I2CINTERFACE_H
#define I2CINTERFACE_H

#include &lt;stdint.h&gt;

class I2CInterface
{
  public:
    static I2CInterface instance;

  public:
    void start();

  private:
    I2CInterface();

    static void requestEvent();
    static void receiveEvent(int howMany);
    void resetSendingBuffer();

  private:
    static const uint8_t Address = 0x46;

    static const uint8_t MaxBufferLength = 8; // (max) 8 byte
    uint8_t sendingBuffer[MaxBufferLength];
};

#endif // I2CINTERFACE_H
</code></pre>

<p>File I2CInterface.cpp</p>

<pre><code>#include &lt;Arduino.h&gt;
#include &lt;Wire.h&gt;
#include "I2CInterface.h"

I2CInterface I2CInterface::instance;

I2CInterface::I2CInterface()
{

}

void I2CInterface::start()
{
  Wire.begin(Address);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
  resetSendingBuffer();
}

void I2CInterface::requestEvent()
{
  Wire.write(instance.sendingBuffer, MaxBufferLength);
  instance.resetSendingBuffer();
}

void I2CInterface::receiveEvent(int howMany)
{
  if (howMany &lt;= 0)
    return;
  else if (howMany == 1)
  { // Reading request
    uint8_t regist = Wire.read();
    for (uint8_t i = 0; i &lt; MaxBufferLength; i++)
      instance.sendingBuffer[i] = Configuration.getRegister(regist++);
  }
  else
  { // Writing request
    uint8_t regist = Wire.read();
    while (Wire.available())
    {
      Configuration.setRegister(regist++, Wire.read());
    }
    instance.resetSendingBuffer();
  }
}

void I2CInterface::resetSendingBuffer()
{
  for (uint8_t i = 0; i &lt; MaxBufferLength; i++)
    sendingBuffer[i] = 0x00;
}
</code></pre>

<p>Please note that the <code>Configuration.getRegister</code> and <code>Configuration.setRegister</code> are the functions I used to get and set some registers; you can substitute them with a direct EEPROM access or your own functions.</p>

<p>You just need to add, in your main file,</p>

<pre><code>#include "I2CInterface.h"
...

void setup()
{
  ...
  I2CInterface::instance.start();
  ...
}
</code></pre>
 42015: <p>Note, that I haven't tested the code below, since I currently don't have enough time for it. But it may help you to get, what you want to do.</p>

<p>The way the I2C interface works is, that after each byte read from the slave, the master will answer with ACK or NACK, depending on if he wants to read more data or not. So the slave doesn't know beforehand, how many bytes the master wants to read.</p>

<p>But you can change the <code>Wire</code> library, to call the <code>onRequest</code> callback for every single byte, instead of every request. The important code lies in the path of your Arduino installation at <code>hardware/arduino/avr/libraries/Wire/src/utility/twi.c</code> at line 575 (I refer to my installation of version 1.8.5; might be slightly different for you):</p>

<pre><code>case TW_ST_SLA_ACK:          // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
      // enter slave transmitter mode
      twi_state = TWI_STX;
      // ready the tx buffer index for iteration
      twi_txBufferIndex = 0;
      // set tx buffer length to be zero, to verify if user changes it
      twi_txBufferLength = 0;
      // request for txBuffer to be filled and length to be set
      // note: user must call twi_transmit(bytes, length) to do this
      twi_onSlaveTransmit();
      // if they didn't change buffer &amp; length, initialize it
      if(0 == twi_txBufferLength){
        twi_txBufferLength = 1;
        twi_txBuffer[0] = 0x00;
      }
      // transmit first byte from buffer, fall
case TW_ST_DATA_ACK: // byte sent, ack returned
      // copy data to output register
      TWDR = twi_txBuffer[twi_txBufferIndex++];
      // if there is more to send, ack, otherwise nack
      if(twi_txBufferIndex &lt; twi_txBufferLength){
        twi_reply(1);
      }else{
        twi_reply(0);
      }
      break;
</code></pre>

<p>When receiving a request with correct address, the first <code>case</code> will be executed (of course after other stuff with receiving address and sending ACK). The <code>twi_onSlaveTransmit()</code> function will execute the <code>onRequest</code> callback. When that is done, the code falls directly into the next <code>case</code> statement, which sends the first byte. When the slave receives an ACK after that byte, it should come back to this <code>case</code> and send another byte.</p>

<p>We can now put the buffer filling code into the second <code>case</code> statement, so that the callback will be executed for every requested byte. In this case we also need to change the <code>if</code> statement after that, so that it only triggers and sends NACK, if the user didn't write a byte in the callback. The original library seems to write at minimum 1 byte (even it nothing is in the buffer; it is set to zero). So we will also do this by setting a flag in the first <code>case</code> statement. The code now looks like this:</p>

<pre><code>case TW_ST_SLA_ACK:          // addressed, returned ack
case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
      // enter slave transmitter mode
      twi_state = TWI_STX;
      twi_slave_transmit_first_byte = 1;
      // transmit first byte from buffer, fall
case TW_ST_DATA_ACK: // byte sent, ack returned
      // ready the tx buffer index for iteration
      twi_txBufferIndex = 0;
      // set tx buffer length to be zero, to verify if user changes it
      twi_txBufferLength = 0;
      // request for txBuffer to be filled and length to be set
      // note: user must call twi_transmit(bytes, length) to do this
      twi_onSlaveTransmit();
      if(twi_slave_transmit_first_byte == 1){
          twi_slave_transmit_first_byte = 0;
          // if they didn't change buffer &amp; length, initialize it
          if(0 == twi_txBufferLength){
            twi_txBufferLength = 1;
            twi_txBuffer[0] = 0x00;
          }
      }
      // copy data to output register
      TWDR = twi_txBuffer[twi_txBufferIndex++];
      // if there is more to send, ack, otherwise nack
      if(twi_txBufferIndex &lt; twi_txBufferLength){
        twi_reply(1);
      }else{
        twi_reply(0);
      }
      break;
</code></pre>

<p>And we have to add the flag declaration at the top of the file (where all the other static volatile variables are defined) as static volatile:</p>

<pre><code>static volatile uint8_t twi_slave_transmit_first_byte = 0;
</code></pre>

<p>In the <code>onRequest</code> callback you can now write a single byte to the buffer and incrementing your counter.</p>

<hr>

<p>I think, that should work. If someone knows better, please correct me.</p>
