Hi,
Does anybody of you have happen that after reading some registers in a slave device the IICIF bit flag does not get activated after sendind the register address to the slave device?
This is happening after reading successfully a register and attempting to send the next register address with the same slave address. I think that the I2C module is properly configured because I can communicate with the accelerometer in the board, but when I try other devices I get stuck waiting to for the register address to be send.
This is my init code for the I2C
void init_I2C(void)
{
SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK; // Turn on clock to I2C0 module
BW_PORT_PCRn_MUX(PORTE_BASE,24u,kPortMuxAlt5); // Configure pin functionality for I2C0
BW_PORT_PCRn_MUX(PORTE_BASE,25u,kPortMuxAlt5);
I2C0_F = 0x17; // SLC divider is 128 for 50MHz clock (I2C works in ~390KHz).
I2C0_C1 = I2C_C1_IICEN_MASK; // enable IIC
}
This is how I read the registers:
unsigned char ReadRegister(unsigned char u8RegisterAddress)
{
unsigned char result;
/* Send Slave Address */
IIC_StartTransmission(SlaveID,MWSR);
i2c_Wait();
/* Write Register Address */
I2C0_D = u8RegisterAddress;
i2c_Wait();
/* Do a repeated start */
I2C0_C1 |= I2C_C1_RSTA_MASK;
/* Send Slave Address */
I2C0_D = (OV7740_I2C_ADDRESS << 1) | 0x01; //read address
i2c_Wait();
/* Put in Rx Mode */
I2C0_C1 &= (~I2C_C1_TX_MASK);
/* Turn off ACK since this is second to last byte being read*/
I2C0_C1 |= I2C_C1_TXAK_MASK;
/* Dummy read */
result = I2C0_D ;
i2c_Wait();
/* Send stop since about to read last byte */
i2c_Stop();
/* Read byte */
result = I2C0_D ;
return result;
}
#define i2c_Start() I2C0_C1 |= I2C_C1_TX_MASK;\
I2C0_C1 |= I2C_C1_MST_MASK
#define i2c_Stop() I2C0_C1 &= ~I2C_C1_MST_MASK;\
I2C0_C1 &= ~I2C_C1_TX_MASK
This is how I wait fo the byte to be transmited and were my code get stuck because the IICIF bit never gets active.
#define i2c_wait() while((I2C0_S & I2C_S_IICIF_MASK)==0) {} \
I2C0_S |= I2C_S_IICIF_MASK;
Solved! Go to Solution.
Luis
Are you sure that the first I2C message transmission has completed (stop condition completed) before sending a second message to a different device?
Try waiting for the bus to become idle before sending the second message - eg.
while (I2C0_S & IIC_IBB) {}
Regards
Mark
Thanks Mark,
Seems like this was causing the issue.
Hi,Luis,
I have the same question as yours, would you please tell me where you put this "while (I2C0_S & IIC_IBB) {}" to solve the problem?
Best Regards!
Hi Li,
It was needed to be added after the read of the data, like:
unsigned char ReadRegister(unsigned char u8RegisterAddress)
{
unsigned char result;
/* Send Slave Address */
IIC_StartTransmission(SlaveID,MWSR);
i2c_Wait();
/* Write Register Address */
I2C0_D = u8RegisterAddress;
i2c_Wait();
/* Do a repeated start */
I2C0_C1 |= I2C_C1_RSTA_MASK;
/* Send Slave Address */
I2C0_D = (OV7740_I2C_ADDRESS << 1) | 0x01; //read address
i2c_Wait();
/* Put in Rx Mode */
I2C0_C1 &= (~I2C_C1_TX_MASK);
/* Turn off ACK since this is second to last byte being read*/
I2C0_C1 |= I2C_C1_TXAK_MASK;
/* Dummy read */
result = I2C0_D ;
i2c_Wait();
/* Send stop since about to read last byte */
i2c_Stop();
/* Read byte */
result = I2C0_D ;
/* Wait for the bus to be free */
while (I2C0_S & I2C_S_BUSY_MASK)
{}
return result;
}
where I2C_S_BUSY_MASK is 0x20u
Hope this helps :smileysilly:
Hi,Luis,
Thanks for your reply.
It helps,my program works well now. I add while (I2C0_S & I2C_S_BUSY_MASK), and send nack.
Thanks again.
Best Regards!
Li
Luis
Are you sure that the first I2C message transmission has completed (stop condition completed) before sending a second message to a different device?
Try waiting for the bus to become idle before sending the second message - eg.
while (I2C0_S & IIC_IBB) {}
Regards
Mark