Wire Library

Wire Library from Wire for Akafuino: I2C protocol changes

In this document, I will explain the changes that it was made in Xmegaduino Wire library to it works with Lithne board.

The first change was related to the endTransmission() behavior. This function worked in the opposite way of Arduino Wire library: when you send false, you send a “Stop sequence” and true meant “Repeated Start”. So, I just changed the behavior, so it could work as Arduino.

The second change was made just to avoid future problems: the endTransmission() worked with the address in this line:

this->slaveAddress=slaveAddress << 1;

The problem is the function endTransmission doesn’t receive slaveAddress value, so, if we call the function twice, without upload the address, we would have sent the wrong address. So, this line was moved to the beginTransmission() function.

The third change is related to the behavior of the TWI protocol and the ATXMEGA. When we want to send a repeated start in the bus, we should call the function: endTransmission(false). So, in onMasterInterrupt(), it was treated in the following part:

else if(!slaveReadSize) {
/*
we wrote out all the data, but user also wants a
repeated start condition
*/
twi->MASTER.ADDR=this->slaveAddress | 0x01;
}
else {
/*
we are finished writing and have no pending read
send stop and thats it
*/
twi->MASTER.CTRLC=TWI_MASTER_CMD_STOP_gc;
twiResult=TWI_SUCCESS;
}

The first bold line was changed and it is related to the first change it was made (opposite behavior in comparison with Arduino). The second bold line is the repeated start function: when we change the value of MASTER.ADDR, but the bus is already owned, it sends a repeated start. The problem is that after this, the I2C protocol automatically sends the address again, now requesting data. So, the slave starts to send data even if the master is not “ready” for that. After sending the first data, the interruption is called again, but we still didn’t upload the value of slaveReadSize in requestFrom() and the function “thinks” we are not requesting data and sends a NACK and a stop sequence.

After an attentive reading to the datasheet and user manual, I discovered a different way to send the repeated start function, letting requestFrom() ask for data. The change is showed below.

twi->MASTER.CTRLC = 0x01; //repeated start

twi->MASTER.STATUS = 0x01;  //idle mode