1
\$\begingroup\$

0xC8 is called Last data byte status in Atmel's TWI's Slave transmitter mode, but what does it really mean? If TWEA==0 is for the Master receiver, then a Data byte in TWDR has been transmitted; NOT ACK has been received: 0xC0 status should be received.

enter image description here

Looks like the guy who wrote the application note for Atmel even had no idea what this status is.

#define TWI_STX_DATA_ACK_LAST_BYTE 0xC8 // Last data byte in TWDR has been transmitted (TWEA = ??; ACK has been received 

and it's treated as an error code instead, what a shame!

 case TWI_SRX_ADR_DATA_NACK: // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned case TWI_SRX_GEN_DATA_NACK: // Previously addressed with general call; data has been received; NOT ACK has been returned case TWI_STX_DATA_ACK_LAST_BYTE: // Last data byte in TWDR has been transmitted (TWEA = ??; ACK has been received case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition TWI_state = TWSR; //Store TWI State as error message, operation also clears noErrors bit TWCR = (1<<TWSTO)|(1<<TWINT); //Recover from TWI_BUS_ERROR, this will release the SDA and SCL pins thus enabling other devices to use the bus break; 
\$\endgroup\$
3
  • \$\begingroup\$ Would you mind adding which specific AVR model you are referring to? They might have subtle differences in the TWI peripheral. \$\endgroup\$ Commented Mar 6, 2020 at 14:51
  • \$\begingroup\$ @Justme wrong answer. All AVR TWI modules are the same. \$\endgroup\$ Commented Mar 7, 2020 at 1:29
  • \$\begingroup\$ But that was not an answer, it was a request for more details so you get a better answer, because then I know which specific datasheet to open as they can have differences in the description as well. And the AVR TWI modules do differ, maybe not by design, but due to hardware bugs and other quirks they might need, described in the datasheet errata section. I once copied a perfectly working TWI driver from one project to another with different AVR models, and it did not work without modifications, because the TWI bit rate register needed a minimum value of 10 to work. \$\endgroup\$ Commented Mar 7, 2020 at 9:24

1 Answer 1

2
\$\begingroup\$

The 0xC8 state is relevant for the Slave Transmitter mode of AVR only.

Last byte means last from the point of view from the AVR as a Slave Transmitter, not from the other MCU as Master Receiver, which may want to receive in more or less bytes than the AVR expects to be transmitted out

Depending on what kind of data transaction messages are exchanged via TWI, and the AVR may or may not know the message length how many bytes to transfer. For example, an I2C EEPROM with size of 256 bytes, or a GPIO expander, you can always read one or 10000 bytes continuously out of it and it does not care how much you read.

If the AVR does know the message size, it may in some cases be important for the AVR to know that the Master Receiver tries to read an unequal amount of bytes. The Master may transfer only smaller amount of bytes, or larger amount of bytes.

When AVR writes the last byte it knows to be transmitted over TWI, the TWEA bit is set accordingly to what kind of response to expect from master, ACK or NAK.

If the Master responds NAK to the last known byte of AVR, then AVR knows that Master does not transfer more bytes and everything is good. TWSR status will be 0xC0 to indicate transmission of last byte AVR knows of went as expected.

But if the Master responds ACK to the last known byte of AVR, then AVR knows that the Master wants to transfer more bytes but AVR has no more to send, so the status code will be 0xC8 to indicate this. The TWI hardware knows that last byte is already transmitted so it just keeps the SDA released and the master just receives additional 0xFF bytes, and the TWI hardware does not emit interrupt requests to load more data. So the TWI hardware helps the firmware to ignore further data byte requests.

Quote from the datasheet, which basically explains the same in more compressed form:

State 0xC8 is entered if the Master demands additional data bytes (by transmitting ACK), even though the Slave has transmitted the last byte (TWEA zero and expecting NACK from the Master)

\$\endgroup\$
2
  • \$\begingroup\$ Sorry. It's a definitely wrong answer. I highly highly doubted that byte transmissions will continue when the status literally called Last data byte status. I don't know about you, but last means not more in my country. \$\endgroup\$ Commented Mar 7, 2020 at 1:32
  • \$\begingroup\$ I edited it to be more clear and quoted the datasheet. And what last byte means in any country has nothing to do what it means in an AVR. The master can freely demand any amount of bytes. The AVR just has a feature that capability to say to the TWI module that firmware does not want to transmit more bytes and the state just says if the Master stopped at the same byte or continued to demand more. It is up to the firmware to decide if these situations need detecting or not, and if that is error or not. \$\endgroup\$ Commented Mar 7, 2020 at 13:33