FridgeFreezer

mcf52259 I2C routines - an extra (dummy) read?

Discussion created by FridgeFreezer on Sep 2, 2011
Latest reply on Sep 5, 2011 by FridgeFreezer

I am currently writing an I2C interrupt-routine for MCF52259, based on Freescale's own I2C driver (which can only Tx/Rx single bytes). There seems to be an extra (dummy) read going on in their code though, just before the STOP condition, and I can't work out what it's for or if I'm reading the code/data sheet wrong?

 

/* * I2CreceiveByte: I2C read byte * * Parameters: address: address to read *      id: I2C device to read * * Return : data: byte read it from device */uint8 I2CreceiveByte(uint8 address, uint8 id){ uint8 data;  /* setting in Tx mode */ MCF_I2C_I2CR |= MCF_I2C_I2CR_MTX;     /* send start condition */ MCF_I2C_I2CR |= MCF_I2C_I2CR_MSTA;  /* devide ID to write */ MCF_I2C_I2DR = id;         /* wait until one byte transfer completion */ while( !(MCF_I2C_I2SR & MCF_I2C_I2SR_IIF )) ; /* clear the completion transfer flag */ MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;  /* memory address */ MCF_I2C_I2DR = address;        /* wait until one byte transfer completion */ while( !(MCF_I2C_I2SR & MCF_I2C_I2SR_IIF )) ; /* clear the completion transfer flag */ MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;    /* resend start */  MCF_I2C_I2CR |= MCF_I2C_I2CR_RSTA;    /* device id to read */  MCF_I2C_I2DR = (uint8)(id | 0x01);       /* wait until one byte transfer completion */ while( !(MCF_I2C_I2SR & MCF_I2C_I2SR_IIF )) ; /* clear the completion transfer flag */ MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;  /* setting in Rx mode */ MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MTX;   /* send NO ACK */  MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK;   /* dummy read */   data = MCF_I2C_I2DR;        /* wait until one byte transfer completion */ while( !(MCF_I2C_I2SR & MCF_I2C_I2SR_IIF )) ; /* clear the completion transfer flag */ MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;  /* read data received */ data = MCF_I2C_I2DR;        /* wait until one byte transfer completion */ while( !(MCF_I2C_I2SR & MCF_I2C_I2SR_IIF )) ;        /*** ^^^ WHY??? ^^^ ***/ /* clear the completion transfer flag */ MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF;  /* generates stop condition */ MCF_I2C_I2CR &= ~MCF_I2C_I2CR_MSTA;  /* send the received data */ return data;}

 

As soon as you read from I2DR (data = MCF_I2C_I2DR:smileywink: you trigger a data transfer, which means you're sending out an extra 9 pulses on SCL after the last byte is Rx'd. This seems like a dodgy thing to do, even if it shouldn't cause problems in real life.

Outcomes