View Issue Details

IDProjectCategoryView StatusLast Update
0001550FSS5PV210NI2Cpublic2013-05-06 08:38
Reporterzutter Assigned To 
PrioritynormalSeverityminorReproducibilitysometimes
Status resolvedResolutionfixed 
Product VersionV1.03 
Target VersionV1.05Fixed in VersionV1.05 
Summary0001550: Sometimes many timeouts while heavy bus load
DescriptionCustomer info:
We are having some problems with the I2C driver, it sometimes gives reports timeouts (When it is the only master on the bus), and also when sending data it sometimes comes back with the following error
NI2C0: [59718] 0xd31a2340: Message aborted, 2 byte(s) left, chFlags=0x04

I switched on Debug to see all output for this..

Sometimes when I send a lot of data it even spams me with that error (See attached debug output), although all I2C commands did succeed. (I think ? )

I also get timeouts at random intervals

I looked at the driver sources and saw some things that my opinion could be tricky

Unfortunately I don’t have the time to delve deeper into the driver, as normally I will, but I think there is either a race condition or a threading issue

When I have more time I will look at it again, but for now I will only report it.


? Below is a part of the source code, and 3 remarks

static DWORD NI2CBusIst(LPVOID lpParameter)
{
    DWORD dw;

    NI2C_DEVICE_BUFFER* pDev = (NI2C_DEVICE_BUFFER*) lpParameter;

    while (!pDev->bStopThread)
    {
        /* Wait for I2C bus interrupt; return every second to check if thread
           should end; if transfer is in progress and the thread was not
           called for a second, we assume a transfer error and a stalled I2C
           bus. So force handling of the next byte in this case. */
        dw = WaitForSingleObject(pDev->event, 1000
                                 /*(pDev->bState == STATE_IDLE) ? 1000 : 130*/);
#ifdef __SHOW_TIMEOUT__
        {
            static DWORD timeout = 0;
            if (dw == WAIT_TIMEOUT)
            {
                if (pDev->bState == STATE_IDLE)
                    RETAILMSG(pDev->dwDebug & 0x08,
                              (DTAGx TEXT("Idle Timeout(%d)\r\n"),
                                           pDev->dwDevAryIndex, timeout));
                else
                {
                    /* Timeout on I2C port, most probably due to transfer
                       error. Force handling of next message. */
                    RETAILMSG(1, (DTAGx TEXT("[%d] 0x%08x: ") //mvz When a timout occurs the variable timeout is always 1 at this point,
                                  TEXT("I2C Transmission Timeout(%d)\r\n"), //meaning that he must have had a timeout before when the state was STATE_IDLE
                                                 pDev->dwDevAryIndex, //Although I call the I2C driver atleast once every 20 ms,
                                  GetTickCount(), pDev->entry.pFileBuffer,
                                  timeout));
                    dw = WAIT_OBJECT_0; //mvz Is this right? (I assume because you want to call the HandleTransfer(pDev); function)
                    pDev->bState = STATE_TIMEOUT;
                }
                timeout++;
            }
            else
                timeout = 0;
        }
#else
        if ((dw == WAIT_TIMEOUT) && (pDev->bState != STATE_IDLE))
        {
            /* Timeout on I2C port, most probably due to transfer error. Force
               handling of next message. */
            dw = WAIT_OBJECT_0;
            pDev->bState = STATE_TIMEOUT;
        }
#endif

        if (dw == WAIT_OBJECT_0)
        {
            /* We've received an interrupt */
            HandleTransfer(pDev);
            InterruptDone(pDev->IicIrq); //mvz So even when a timeout occurs you will reset the HW event, possibly missing a HW event
        }
    }

    return 0;
}
Found Driver Version
Fixed Driver Version
Forum Link

Activities

There are no notes attached to this issue.