I’m learning from an example of an I2C peripheral driver (master mode), which came with IAR Embedded Workbench. It has a low level function for accessing the I2STAT register. It’s used a lot for polling for bits in I2CSTAT. Here’s the source code:
U8 MA_CheckStatus_I2C( void )
{
U8 Status;
while( I2CONSET_bit.SI == 0 ) { ; } // Wait for I2C Status changed --- [Q] Is this necessary?
Status = I2STAT; // Read I2C State
/*--- NOTE! SI flag is not cleared here ---*/
return Status;
}
This function waits until the SI bit is set before it reads the register of interest. Is it always necessary to wait? If so, then why?
Nick
P.S. It strikes me that a lowest level function like this has a loop without a timeout.
I have only ever implemented I2C master code in LPC2000 as interrupt driven (IRQ) ISR. Polling seems to be extraordinarily inefficient.
There are some better examples in the “Insider’s Guide to Philips ARM7-Based Microcontrollers” which can be used with just a few tweaks/modifications. If you haven’t already googled and downloaded a PDF version of this, I’d recommend it.
This function waits until the SI bit is set before it reads the register of interest. Is it always necessary to wait? If so, then why?
Nick
Yes. You are dealing with a low-speed state machine inside of the part and you have to wait until the status has changed before the other bits are valid. As the other poster stated it's horribly inefficient but I highly recommend using the polling method to understand the bus and then move to the ISR with states handler.
You will find a very detailed state guide in the NXP manual.