Go Down

Topic: Due I2C slave sends 'x' when it runs out of things to say (Read 594 times) previous topic - next topic

MorganS

I've been digging deep into the Wire library for the Due. So far, I've discovered a few things different to the AVR version of the library but this one made me go WTF!
Code: [Select]
if (status == SLAVE_SEND) {
if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
uint8_t c = 'x';
if (srvBufferIndex < srvBufferLength)
c = srvBuffer[srvBufferIndex++];
TWI_WriteByte(twi, c);
}
}

This is inside the Due version of Wire.cpp, in the onService() function. This function seems to be called by the TWI interrupt someting-happened-we-don't-know-what and it has to check the status to find out what mode it's in and do the correct action.

So, it appears that if the master requests more bytes than are in the slave's outgoing buffer then it will send the letter 'x'. Am I reading that right?

If the master requests a block of data and I don't have that much to send, then I can't just add a NACK on the end of the data I have? The library will just send 'x' on my behalf?
"The problem is in the code you didn't post."

MorganS

Well, I think I've learned a bit more about I2C. When the master requests data from a slave, there's no way for the slave to say "I don't have data." The I2C protocol doesn't seem to allow that to happen. The slave must ACK its address when it's called and then the ACKs for the individual bytes are generated by the master.

I suppose the slave could NACK when it's called with a read bit set but that's certainly not how the Arduino I2C library works and it doesn't allow the slave to send a variable number of bytes.

It makes the 'number of bytes received' counter on the master side redundant - there's no way not to recieve that many if the slave gave an ACK when its address was called.

The solution is to add another layer to the protocol stack - perhaps the first byte the slave sends is the number of bytes to follow.
"The problem is in the code you didn't post."

Go Up