I have a problem connecting to I2C device.
This is how I read a register from the device
void INA226_ReadReg(uint32_t slave_adr, uint8_t reg_addr, uint16_t *value)
{
uint8_t val[2];
//first - write register address
//for a write operation R/Wn bit should be low
uint8_t slave_address = slave_adr & 0xFE;
//start
I2C0_C1 |= I2C_C1_TX_MASK;
I2C0_C1 |= I2C_C1_MST_MASK
/* send slave address with W/R bit */
I2C0_D = slave_address;
//wait for ack
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
/* set register address */
I2C0_D = reg_addr;
//wait for ack
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
//stop
I2C0_C1 &= ~I2C_C1_MST_MASK;
I2C0_C1 &= ~I2C_C1_TX_MASK
//second - read from written register address
//slave address for read
slave_address = slave_adr | 0x01;
//repeated start
I2C0_C1 |= I2C_C1_RSTA_MASK;
I2C0_D = slave_address;
//wait for ack
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
// 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;
val[0] = I2C0_D;
//wait for ack
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
val[1] = I2C0_D;
//wait for ack
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
*value = (val[0] << 8) | val[1];
//stop
I2C0_C1 &= ~I2C_C1_MST_MASK;
I2C0_C1 &= ~I2C_C1_TX_MASK
}
It stucks on wait for acknowledge.
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
May be I do something wrong?
Solved! Go to Solution.
I replaced
while((I2C0_S & I2C_S_IICIF_MASK)==0) {}
I2C0_S |= I2C_S_IICIF_MASK;
with
while((I2C0_S & I2C_S_IICIF_MASK)==0)
{
timeout++;
if(timeout > I2C_TIMEOUT)
return I2C_ERROR;
}
And now I see the first part - slave address and register address. But no repeated start.
Dear Evgeny Erenburg,
I will attach some generic examples used in other devices please check the process that it follows to communicate using I2C.
have a great day !
Thank you very much!