View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001550 | FSS5PV210 | NI2C | public | 2013-01-24 13:27 | 2013-05-06 08:38 |
Reporter | zutter | Assigned To | |||
Priority | normal | Severity | minor | Reproducibility | sometimes |
Status | resolved | Resolution | fixed | ||
Product Version | V1.03 | ||||
Target Version | V1.05 | Fixed in Version | V1.05 | ||
Summary | 0001550: Sometimes many timeouts while heavy bus load | ||||
Description | Customer 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 | |||||