I2C Slave with register pointers

I want to create an arduino I2C slave that acts similarly the the SRF08, the SRF08 uses registers which can me accessed using a write from the master. see code below: How can I get this done?

- SRF08 code-------------------

#include <TwoWire.h>

void setup()
{
 Wire.begin();                // join i2c bus (address optional for master)
 Serial.begin(19200);          // start serial communication at 19200bps
}

int reading = 0;

void loop()
{
 // step 1: instruct sensor to read echoes
 Wire.beginTransmission(112); // transmit to device #112 (0x70)
 // the address specified in the datasheet is 224 (0xE0)
 // but i2c adressing uses the high 7 bits so it's 112
 Wire.send(0x00);             // sets register pointer to the command register (0x00)  
 Wire.send(0x51);             // command sensor to measure in cm (0x51)
 // use 0x52 for ping microseconds
 Wire.endTransmission();      // stop transmitting

 // step 2: wait for readings to happen
 delay(70);                   // datasheet suggests at least 65 milliseconds

 // step 3: instruct sensor to return a particular echo reading
 Wire.beginTransmission(112); // transmit to device #112
 Wire.send(0x02);             // sets register pointer to echo #1 register (0x02)
 Wire.endTransmission();      // stop transmitting

 // step 4: request reading from sensor
 Wire.requestFrom(112, 2);    // request 2 bytes from slave device #112

   // step 5: receive reading from sensor
 if(2 <= Wire.available())    // if two bytes were received
 {
   reading = Wire.receive();  // receive high byte (overwrites previous reading)
   reading = reading << 8;    // shift high byte to be high 8 bits
   reading |= Wire.receive(); // receive low byte as lower 8 bits
   Serial.println(reading);   // print the reading
 }

 delay(250);                  // wait 250ms
}

There's nothing "magic" about the register pointer: it's simply the first data byte in the packet. So just write your I2C slave code so it examines the first received byte and treats it as an "opcode" for deciding how to interpret the rest of the packet.

Ran

Some languages expect a register when accessing I2C like Lejos

getData:
public int getData(int register, byte[] buf, int len)

Executes an I2C read transaction and waits for the result.
Parameters:
register - I2C register, e.g 0x41
buf - Buffer to return data
len - Length of the return data
Returns:
status == 0 success, != 0 failure

sendData:
public int sendData(int register, byte[] buf, int len)

Executes an I2C write transaction.
Parameters:
register - I2C register, e.g 0x42
buf - Buffer containing data to send
len - Length of data to send
Returns:
status zero=success, non-zero=failure

so instead of using "registers" could I have a case construct which selects different operations or data stored in varibales based on a variable which stores the first byte. eg algorithm

wait for first byte from master [register?]
store first byte in a variable called option
use a case construct that selects based on the value in 'option'
execute case

would that work?

Yes. There are lots of protocols that use this type of approach for communication. Basically, you want your arduino to sit and listen on its data line for some kind of trigger (the SRF08 uses registers, other protocols use sync bits, etc.) This is usually a unique byte that tells your device to get ready to do something. Once that's triggered, you know the next message you receive is going to be a command. Then you can use a case statement or something to compare the command you read with the list of commands your arduino is able to execute. If it matches something, execute the command and return your data, otherwise you can ignore the command and/or throw back some kind of error code. At this point you go back to listening for your trigger. Your psuedocode correctly prototyped this sequence.

The SRF08 uses different registers to access different categories of functionality (commands, configuration, etc). It just provides a way to organize the command set, and makes sure you're never going to mess up the configuration if all of your requests are for the command register.

Some languages expect a register when accessing I2C like Lejos

That "register" is just a slightly-confusing way to refer to the I2C address. It corresponds to the "112" in your SFR08 example.

Ran

No, the address is separate from the register. The address specifies which device on the bus you want to talk to, and then the register is used to request information/change device settings, depending on which one you use. The list of registers for the srf08 are here: SRF08 Ultra sonic range finder