TWI Stop condition - AVR315 bug?

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been using TWI comms based on the AVR application note AVR315 for some years.

I recently made some changes that changed teh timing of my TWI i/o and found I was getting errors. The errors were avoid if I inserted a tick (10mS) delay between ops but this seemed to be a poor solution :(

I think I have found the problem. The code below is used by AVR315 to detect when the TWI is ready for its next op.

/****************************************************************************
Call this function to test if the TWI_ISR is busy transmitting.
****************************************************************************/
unsigned char TWI_Transceiver_Busy( void )
{
    return ( TWCR & (1<<TWIE) ); // IF TWI Interrupt is enabled then the Transceiver is busy
}

If a stop condition has just been issued then TWIE will be cleared BUT the stop condition is still being transmitted. An attempt to start results in an error.

TWSTO is cleared automatically at the end of the stop conditon.

Changing the code as below seems to have cleared up the errors.

/****************************************************************************
Call this function to test if the TWI_ISR is busy transmitting.
****************************************************************************/
unsigned char TWI_Transceiver_Busy( void )
{
	unsigned char status;
	
	status = ( TWCR & (1<<TWIE) ); // ints enable means busy
	status |= ( TWCR & (1<<TWSTO) ); // stop condition then also busy
	return status;
}

Has anyone had similar issues?

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When TWI_STOP completes there is no interrupt.
The TWSTO bit clears from the TWCR register by hardware.

So you should test for TWSTO. i.e. exactly as you have shown.
Or perhaps by:

unsigned char TWI_Transceiver_Busy( void )
{
   return TWCR & ((1<<TWIE)|(1<<TWSTO)); // non-zero is busy
}

David.