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: FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)  (Read 1200 times)

allenhuffman

  • Newbie
  • *
  • Posts: 23
    • View Profile

FTDI added FT4222_I2CMaster_ResetBus() in the 1.4.4 release (I believe).  It is supposed to send 9 I2C clock pulses to unstick the I2C bus. I recall testing this when I first received this version, and saw it work.

But today, I am noticing it is not sending clock pulses.  Attached is a screen shot of the Saleae capture.

To verify my Saleae was working, I swapped my two input probes and saw the pulses move to the other input.

My code is very simple and is doing this:

Code: [Select]
    ftStatus = FT_OpenEx ("MyDeviceNameHere", FT_OPEN_BY_DESCRIPTION,
                          &ftdiInfoPtr->ftHandle);
   
    if (ftStatus == FT_OK)
    {
        ResetDevice ();
        // Need to wait for the FTDI device to complete the reset.
        Sleep (ONE_THOUSAND);

        // Set the device timeouts.
        ftStatus = FT_SetTimeouts (ftdiInfoPtr->ftHandle,
                                   FT_DEFAULT_RX_TIMEOUT,
                                   FT_DEFAULT_TX_TIMEOUT);

        // Initialize the I2C master.
        if (ftStatus == FT_OK)
        {
            // Initialize the FTDI device chosen.
            ft4222Status = I2CMasterInit (ftdiInfoPtr->ftHandle, I2C_SPECIAL_FAST_CLK);

            // Initialization is done.
            if (ft4222Status == FT4222_OK)
            {
                for (int idx=0; idx < 10; idx++)
                {
                    // Send nine clock pulses to reset a stuck Slave device.
                    ft4222Status = I2CMasterResetBus (ftdiInfoPtr->ftHandle);
                    Sleep (1);
                }

We have wrappers for the different functions, so I2CMasterResetBus is just:

Code: [Select]
FT4222_STATUS I2CMasterResetBus (FT_HANDLE ftHandle)
{
    return FT4222_I2CMaster_ResetBus (ftHandle);
}

And ResetDevice() is just calling FT_ResetDevice ();

Anyone used this? It's new, and wasn't even documented at first (beyond header file entries).

Thanks, much.
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)
« Reply #1 on: August 16, 2021, 05:22:31 PM »

*** UPDATE ***

I switched over to GPIO mode and notice I can toggle the data line, but not clock.  At this point, I believe one of the devices on my bus is holding it low and this "unstick trick" will not work for me.

I have learned about FT4222_UnInitialize() which lets me open the device, initialize it for GPIO, unitialize it, the initialize it for I2C. I did not know about that, back then, or I would have tried this trick before the library had ResetBus.

My test code:

Code: [Select]
    FT_HANDLE ftHandle = NULL;
   
    ftStatus = FT_OpenEx ("PrecisePower B", FT_OPEN_BY_DESCRIPTION,
                          &ftHandle);
   
    if (ftStatus == FT_OK)
    {
         GPIO_Dir gpioDir[4] = { GPIO_OUTPUT, GPIO_OUTPUT, GPIO_OUTPUT, GPIO_OUTPUT };
         
         ft4222Status = FT4222_GPIO_Init(ftHandle, gpioDir);

         //disable suspend out , enable gpio 2
         //ft4222Status = FT4222_SetSuspendOut(ftdiInfoPtr->ftHandle, false);
         
         //disable interrupt , enable gpio 3
         //ft4222Status = FT4222_SetWakeUpInterrupt(ftdiInfoPtr->ftHandle, false);
         
         // set gpio0/gpio1/gpio2/gpio3 output level high
         for (int pulse=0; pulse<9; pulse++)
         {
            ft4222Status = FT4222_GPIO_Write(ftHandle, GPIO_PORT0, 1); // Clock pin
            Sleep (1);
            ft4222Status = FT4222_GPIO_Write(ftHandle, GPIO_PORT0, 0); // Clock pin
            Sleep (1);
         }
         Sleep (1);
         
         FT4222_UnInitialize(ftHandle);           
    }
    FT_Close (ftHandle);
Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 686
    • View Profile
Re: FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)
« Reply #2 on: August 17, 2021, 05:07:28 PM »

Hi,

Thanks for your update,

Yes it sounds like another device may be holding the clock low and so it depends if this other device can release the clock or if it has locked up and may need reset. You could try disconnecting the I2C lines for each device on the bus to check if the other device has got the line held low,

Best Regards, FTDI Community
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)
« Reply #3 on: August 17, 2021, 11:23:14 PM »

Thanks. I am still trying to work through best practices. In this case, nothing could be done, but I often find the
c program gets stuck doing an FTDI library call. You can’t kill it with task manager, and have to reboot Windows, or unplug the USB cable. It releases when that is done.

How can I detect if a bus is stuck?
Logged

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 686
    • View Profile
Re: FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)
« Reply #4 on: August 18, 2021, 11:29:27 AM »

Hi,

One thing to check is that you have set timeouts to a finite value (e.g. 5000ms) which will avoid the read and writes hanging if they are unable to complete. You should check the status value once a call returns as well as comparing the sizeTransferred, which is provided by the read and write functions, to what you had requested, to see if all data was written/read.

Best Regards, FTDI Community
Logged

allenhuffman

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)
« Reply #5 on: August 18, 2021, 03:09:35 PM »

During some early testing, I noticed that Write worked even if nothing was on the other side (no address ACK). Today, I am doing the write, and if it returns OK, I am checking controller status looking to see if the write was acknowledged.

But, I also saw the errata saying reading that register while a write was in progress could corrupt data.
Logged