1
Discussion - Software / I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« on: September 27, 2022, 06:34:18 PM »
I am observing an issue when calling FT4222_I2CMaster_GetStatus() after FT4222_I2CMaster_Write().
I am doing this:
I read the status after the write operation because FT4222_I2CMaster_Write() returns before the FT4222 has written all data. I need to verify that the transaction completed.
After about 90 minutes of heavy traffic I am sometimes observing that the SCL line is stuck low and flags reports 0x40 (bus busy) forever. I can confirm that the peripheral is not the problem. The SCL line remains low even when I disconnect the peripheral in that situation. It seems that the FT422 is the problem. In that case, the last message being sent is corrupted: The address is wrong and hence the peripheral device does not acknowledge the message.
Now I found this information in the errata sheet https://ftdichip.com/wp-content/uploads/2022/03/TN_161_FT4222H-Errata-Technical-Note.pdf:
The wording in the errata sheet is confusing. In above code snippet I call FT4222_I2CMaster_GetStatus() after FT4222_I2CMaster_Write(). But I also know that FT4222_I2CMaster_Write() may return while the transmission on the bus is ongoing which is not explicitly described in the application note.
Could you therefore please answer the following questions:
Thank you in advance.
I am doing this:
Code: [Select]
FT4222_STATUS stat = FT4222_I2CMaster_Write(data_handle, slaveAddress_, data, size, &bytesWritten);
if (stat != FT4222_OK)
throw std::runtime_error("Error writing data over FT4222");
uint8_t flags = 0;
do {
for (uint32_t retries = 3; retries > 0; --retries) {
stat = FT4222_I2CMaster_GetStatus(data_handle, &flags);
if (stat == FT4222_OK)
break;
// Add an arbitrary wait time
Sleep(100);
}
if (stat != FT4222_OK)
throw std::runtime_error("Error reading status from FT4222");
if (I2CM_DATA_NACK(flags) || I2CM_ADDRESS_NACK(flags))
throw std::runtime_error("The peripheral did not acknowledge the message as expected");
} while (!I2CM_IDLE(flags));
I read the status after the write operation because FT4222_I2CMaster_Write() returns before the FT4222 has written all data. I need to verify that the transaction completed.
After about 90 minutes of heavy traffic I am sometimes observing that the SCL line is stuck low and flags reports 0x40 (bus busy) forever. I can confirm that the peripheral is not the problem. The SCL line remains low even when I disconnect the peripheral in that situation. It seems that the FT422 is the problem. In that case, the last message being sent is corrupted: The address is wrong and hence the peripheral device does not acknowledge the message.
Now I found this information in the errata sheet https://ftdichip.com/wp-content/uploads/2022/03/TN_161_FT4222H-Errata-Technical-Note.pdf:
Quote
Issue:
An error would happen when i2c master is writing data and FT4222_I2CMaster_GetStatus is being called
at the same time.
Workaround:
Call FT4222_I2CMaster_GetStatus after the end of i2c transmission.
The wording in the errata sheet is confusing. In above code snippet I call FT4222_I2CMaster_GetStatus() after FT4222_I2CMaster_Write(). But I also know that FT4222_I2CMaster_Write() may return while the transmission on the bus is ongoing which is not explicitly described in the application note.
Could you therefore please answer the following questions:
- Is above code affected by the problem described in the errata?
- If yes, how do I determine the end of the i2c transmission so that I can immediately verify success/fail of the transaction? Feel free to take and change my code from above.
Thank you in advance.