Skip to content

Commit

Permalink
handle repeated START condition correctly
Browse files Browse the repository at this point in the history
The Atmel TWI interface can indicate an "unexpected STOP" when
there's a repeated START condition. Don't try to treat it as a bus
error, and don't wait for TWSTO to clear even if we do have a bus
error (and it's not officially documented that reading TWSTO is
meaningful).

Previously, a repeated START condition would cause the receiver
to loop waiting for TWSTO to clear. This meant it would miss
an address match in a repeated START condition, resulting in a
default NAK until the next START condition (which might clear
TWSTO?).

Signed-off-by: Taylor Yu <[email protected]>
  • Loading branch information
tlyu committed May 28, 2022
1 parent 0c8e440 commit 793dc6f
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions firmware/twi-slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,12 @@ static void TWI_Start_Transceiver( unsigned char ack ) {
}

/**
* Call this function to send (and wait for) a bus stop condition.
* Call this function to clear a bus error condition. Do NOT wait.
* ---------------------------------------------------------------------------------------------- */
static void TWI_Stop( void ) {
TWCR = _BV(TWEN)| // Enable TWI-interface and release TWI pins
_BV(TWIE)|_BV(TWINT)| // Enable TWI Interupt
_BV(TWEA)|_BV(TWSTO); // Send ACK after next reception, stop bus

while(TWCR&_BV(TWSTO));
}

/**
Expand Down Expand Up @@ -127,10 +125,11 @@ ISR(TWI_vect) {
break;

case TW_SR_STOP: // A STOP condition or repeated START condition has been received while still addressed as Slave
TWI_Stop();
// Either way, treat it as end of transmission
if (TWI_Rx_Data_Callback) {
TWI_Rx_Data_Callback(TWI_buf, TWI_bufPtr);
}
// Release the bus and re-enable reception in un-addressed mode
TWI_Start_Transceiver(1);
break;

Expand Down

0 comments on commit 793dc6f

Please sign in to comment.