Performance figures look good, no I2C need at the moment but I had quick look at the code: (some remarks to improve)
Several places:
returnStatus = 0;
returnStatus = start();
The 1st assignment (=0) is overridden by the 2nd assignment, so remove the 1st.
void I2C::setSpeed(uint8_t _fast) why not use bool _fast?
the speed parameter should be part of the begin() which could be rewritten to:
void I2C::begin(uint8_t _fast)
{
activate(true);
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
setSpeed(_fast);
// enable twi module and acks
TWCR = _BV(TWEN) | _BV(TWEA);
}
The scan() function is very usefull but it uses the Serial port internally. If I wanted to use the Serial for other purposes I have a conflict.
You can solve this by a slightly different scanfunction, that find the first in a range of addresses.
(Not tested, but you should get the idea)
int I2C::scan(uint8_t startAddr, uint8_t stopAddr)
{
for(int addr = startAddr; addr <= stopAddr; addr++)
{
returnStatus = start();
if (!returnStatus)
{
returnStatus = sendAddress(SLA_W(addr));
if (returnStatus == 1) return -1;
else
{
stop();
return addr;
}
}
}
return -1;
}
The firstcall to deviceId = scan(0, 127) returns the first deviceId found or -1 if error. By filling in the found deviceId you can scan further e.g. in a simple myScan function.
void myScan()
{
int deviceId = 0;
while ( (deviceId = I2C.scan(deviceId, 127)) > -1)
{
Serial.println(deviceId); //or SoftSerial.print() or LCD.print() whatever I like
}
}
This allows me to print all device ID's s on the bus without a call to serial in the lib itself. Furthermore you can control the range of the scan process by making it parameterized.
Finally I think there can a merge of parts of the read/write functions as they have quite similar parts. [too late for me to dive into that one now]
my 3 cents ,