FTDI Community

Please login or register.

Login with username, password and session length.
Advanced Search  

News:

Welcome to the FTDI Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ FTDI Support


New Bridgetek Community is now open

Please note that we have created the Bridgetek Community to discuss all Bridgetek products e.g. EVE, MCU.

Please follow this link and create a new user account to get started.

Bridgetek Community

Author Topic: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called  (Read 16106 times)

a4711

  • Newbie
  • *
  • Posts: 9
    • View Profile

I am observing an issue when calling FT4222_I2CMaster_GetStatus() after FT4222_I2CMaster_Write().

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.
« Last Edit: September 27, 2022, 09:37:39 PM by a4711 »
Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 892
    • View Profile
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #1 on: October 04, 2022, 10:25:42 AM »

Hello,

Yes this errata may affect your operation.

FT4222_I2CMaster_Write is not a synchronous function. It stores the i2c command and data into the USB buffer.
There is a firmware bug and it happens on i2c data transaction and querying status at the same time.
Even these two actions are executed at the same time. The error rate is very low.
That is why you can run the test case for a long time but finally fails.

See the following code modifications.
You can see the bold section:

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) {
        // Wait for the i2c transmission done, the waiting time depend on the i2c transaction time
        // for example:
        // 100Kbps to transfer 10 bytes , wait 8(bit) * 10us (1bit time)* 10 (bytes) = 800 us
        // 1Mbps to transfer 10 bytes , wait 8(bit) * 1us (1bit time)* 10 (bytes) = 80 us

        Sleep(1);

        stat = FT4222_I2CMaster_GetStatus(data_handle, &flags);
        if (stat == FT4222_OK)
            break;

    }
    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));

Best Regards,
FTDI Community
Logged

a4711

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #2 on: October 10, 2022, 07:39:24 AM »

Thank you for the reply. Please consider to update the wording in the errata sheet and mention the affected libFT4222 APIs explicitly.
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 49
  • Mostly harmless.
    • View Profile
    • Sub-Etha Software
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #3 on: October 26, 2022, 07:07:26 PM »

Thank you for the reply. Please consider to update the wording in the errata sheet and mention the affected libFT4222 APIs explicitly.

Having just ran in to this on our project, yes, please.
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 49
  • Mostly harmless.
    • View Profile
    • Sub-Etha Software
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #4 on: October 27, 2022, 05:44:35 PM »

Since there is a separate byte for the address, and since there are 9 pulses for each byte (ack/nak bit), a formula probably needs to take that in to consideration. Something like:

Code: [Select]
#define I2C_KHZ 400

ms = ((8+1) /*bits*/ * (1000/(I2C_KHZ)) /*us*/ * (bytesTransferred+1)) / 1000;

if (ms < 1) ms = 1;

Sleep (ms);

When looking at the FTDI Master (Windows 11) in a Salae capture, I also see gaps between each byte that range from 10us to 14us, so I added some worst-case extra bits (6 for my case) to that to cover it:

ms = ((8+1+6) ....etc...

I am not sure what the FTDI driver does that causes those gaps, but I expect the reason they vary in length is due to Windows not being a realtime OS.  Perhaps the gaps are even larger when using more CPU time or running more stuff.  That would throw all these calculations off.

There really should be a way to query the driver and find out if it's done writing.
Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 892
    • View Profile
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #5 on: October 28, 2022, 04:15:37 PM »

Hello,

This will be included in the LibFT422 release notes in future releases.

I will also check if anything can be done in the driver or library to help improve this.

Best Regards,
FTDI Community
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 49
  • Mostly harmless.
    • View Profile
    • Sub-Etha Software
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #6 on: November 03, 2022, 01:47:35 PM »

Hello,

This will be included in the LibFT422 release notes in future releases.

I will also check if anything can be done in the driver or library to help improve this.

Best Regards,
FTDI Community

Thank you. A simple blocking option (don't return until all bytes have been sent) would be great.
Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 892
    • View Profile
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #7 on: November 04, 2022, 03:54:56 PM »

Hello,

The feedback from our R&D team is that there is nothing that can be done with the library.

The issue is not related to the driver but the I2C IP.

Adding a delay is the only solution.

Best Regards,
FTDI Community
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 49
  • Mostly harmless.
    • View Profile
    • Sub-Etha Software
Re: I2C data is corrupt when FT4222_I2CMaster_GetStatus is being called
« Reply #8 on: April 11, 2023, 09:26:35 PM »

The feedback from our R&D team is that there is nothing that can be done with the library.

The issue is not related to the driver but the I2C IP.

Adding a delay is the only solution.

FYI to others who find this topic:  Calculating the delay is problematic when the output (under Windows, at least) has inconsistent gaps between each byte. In my testing today, I've seen some as small as 7 uS and as long as 63 uS. (See attachment.)  You really do end up Sleeping way too long to cover "worst case", and even then be sure to error check in case the data corruption does occur.


Logged