OMAP-L138 I2C controller problem ??
We optimized software for the OMAP-L138:
- Speed 456Mhz,
- Code and Data Cache enable.
- Compiler optimized -O2
We have a I2C problem since we speed up the hardware over 300Mhz.
It seems that we are too fast for the controller.
A STOP interrupt doesn't correspond to it's internal idle state.
The starterware functions say:
I2CMasterIsBusy = idle
I2CMasterBusBusy = idle
But that seems to be wrong.
Internally the controller still seems to be busy (probably with the stop sequence).
An immediate next transfer will fail.
We found a solution which helps !
We can poll I2C_CON for Bits 10 and 11.
Only if these two bits are zero, the controller is really ready for a new transfer.
I posted the function below.
The maximum loop i saw till now was 10 hardware register reads.
What we do is undocumented !
Can somebody explain me what happens !!!!!!
//============================================================================
// Function : I2cDelay
// Description: In case of 456MHz we seen to have a i2c hardware problem.
// We have to poll until controller has finished something.
//============================================================================
static void I2cDelay(unsigned int instanceNum)
{
int loops;
Boolean b1,b2;
#define I2C_CON (0xA4) /* */
#define I2C_CON_STB (1 << 11) /* Start byte mode (master mode only) */
#define I2C_CON_MST (1 << 10) /* Master/slave mode */
b1 = I2CMasterIsBusy(i2c[instanceNum].regBaseAddr);
b2 = I2CMasterBusBusy(i2c[instanceNum].regBaseAddr);
for (loops=0; loops<100; loops++) {
if ( (HWREG(i2c[instanceNum].regBaseAddr + I2C_CON) & (I2C_CON_STB|I2C_CON_MST)) == 0)
break;
}
if (loops > 0) {
LogPrintf(LOG_ERROR, "I2c needed loops = %d, (%d,%d)", loops, b1, b2);
}
}
Output of log function:
I2c needed loops = 4, (0,0)
I2c needed loops = 2, (0,0)
I2c needed loops = 7, (0,0)
I2c needed loops = 2, (0,0)
I2c needed loops = 2, (0,0)
I2c needed loops = 1, (0,0)
I2c needed loops = 2, (0,0)
I2c needed loops = 3, (0,0)
I2c needed loops = 3, (0,0)
I2c needed loops = 1, (0,0)
I2c needed loops = 1, (0,0)
I2c needed loops = 6, (0,0)
I2c needed loops = 1, (0,0)
I2c needed loops = 7, (0,0)
I2c needed loops = 5, (0,0)
I2c needed loops = 4, (0,0)
I2c needed loops = 3, (0,0)
I2c needed loops = 3, (0,0)
I2c needed loops = 2, (0,0)
I2c needed loops = 1, (0,0)
I2c needed loops = 1, (0,0)
I2c needed loops = 4, (0,0)
I2c needed loops = 4, (0,0)