From 793dc6f1fc1fab1915fab5046d2a5f7e5db4ce0d Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Fri, 27 May 2022 20:06:55 -0500 Subject: [PATCH] handle repeated START condition correctly 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 --- firmware/twi-slave.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/firmware/twi-slave.c b/firmware/twi-slave.c index ca0cf31..f5b7be5 100644 --- a/firmware/twi-slave.c +++ b/firmware/twi-slave.c @@ -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)); } /** @@ -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;