Hi, I've been reading this forum for any answers regarding the behaviour of I2C bus and find allways different answers depending on who's responding. I hade a project where it ended up in such long time before production so I hade to change the bus to SPI and it didin't took long before that was working .Unfortunatelly I needed som devices that required I2C(crap) bus in a new project. In this case I use I2C1 bus and have only one device(VL53L1X) and the other channel(I2C0) I have a 24LC16 eeprom. Now it seems that the writing to the EEprom is working, but the reading is a mess since I simply don't understand the datasheet from Freescale and never has at least regarding the I2C. Below are the functions and I do not use interrupt for I2C.
bool I2C_ByteWrite(I2C_Type *base, uint8_t dev_adr, uint8_t reg_adr, uint8_t source)
{
if(I2C_Busy(I2C0))
{
i2c_start(base);
}
else
{
return(false);
}
if(!(I2C_WriteByte(base, (dev_adr + I2C_WRITE))))
{
return(false);
}
if(!(I2C_WriteByte(base, reg_adr)))
{
return(false);
}
if(!(I2C_WriteByte(base, source)))
{
return(false);
}
i2c_stop(base);
return(true);
}
and now the actually write function
bool I2C_WriteByte(I2C_Type *base, uint8_t data)
{
uint32_t timeout = 0U;
base->D = data;
while(!(base->S & I2C_S_IICIF_MASK))
{
if(timeout++ > I2C_TIMEOUT)
{
i2c.status |= I2C_TX_ERR;
return(false);
}
}
base->S |= I2C_S_IICIF_MASK;
timeout = 0U;
while(base->S & I2C_S_RXAK_MASK)
{
if(timeout++ > I2C_TIMEOUT)
{
i2c.status |= I2C_NO_ACK;
return(false);
}
}
return(true);
}
Here is the read function
bool I2C_ByteRead(I2C_Type *base, uint8_t dev_adr, uint8_t reg_adr, uint8_t *dest)
{
if(I2C_Busy(I2C0))
{
i2c_start(base);
}
else
{
return(false);
}
if(!(I2C_WriteByte(base, (dev_adr + I2C_WRITE))))
{
return(false);
}
if(!(I2C_WriteByte(base, reg_adr)))
{
return(false);
}
i2c_repeated_start(base);
if(!(I2C_WriteByte(base, (dev_adr + I2C_READ))))
{
return(false);
}
i2c_set_rx_mode(I2C0);
if(!(I2C_ReadByte(base, &dummy, _ACK)))
{
return(false);
}
if(!(I2C_ReadByte(base, dest, _NACK)))
{
return(false);
}
i2c_stop(base);
return(true);
}
and now the actually read function
bool I2C_ReadByte(I2C_Type *base, uint8_t *dest, bool ack)
{
// uint32_t timeout = 0U;
dest[0U] = base->D;
if(ack)
{
base->C1 |= I2C_C1_TXAK_MASK;
}
else
{
base->C1 &=~I2C_C1_TXAK_MASK;
}
/* while(!(base->S & I2C_S_IICIF_MASK))
{
if(timeout++ > I2C_TIMEOUT)
{
i2c.status |= I2C_RX_ERR;
return(false);
}
}
*/
base->S |= I2C_S_IICIF_MASK;
return(true);
}
I have changed the read function a million times and the problem allways come with a dummy read becaus I don't have any control over the received byte.
The oscilloscope picture's which I haven't attached is correct for writing but when switching over rx mode and reading the dummy byte or even the last byte(NACK) I allways get 0xFF.
I have even tryed with some modification the KL05 I2C driver but that caused me to com up with a recovery solution whe I2C got stucked. I do have pullups(4K7) and I'm running at 100KHz.
Regards
Claes