General Category > Discussion - Drivers

FT4222_I2CMaster_ResetBus() not working (1.4.4.44 Windows 64-bit)

(1/2) > >>

allenhuffman:
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: ---    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);
                }
--- End code ---

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


--- Code: ---FT4222_STATUS I2CMasterResetBus (FT_HANDLE ftHandle)
{
    return FT4222_I2CMaster_ResetBus (ftHandle);
}

--- End code ---

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.

allenhuffman:
*** 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: ---    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);
--- End code ---

FTDI Community:
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

allenhuffman:
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?

FTDI Community:
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

Navigation

[0] Message Index

[#] Next page

Go to full version