Well there is some weird stuff going on. The particular code in question is this part from acquireBus_():
The only thing I can guess here is that the delay between setting Master mode in the top part, and checking to see if it is set in the auto retry part, is too small. Not sure, but maybe the block takes a while to register as Master mode (I've never "speed tested" it, but it's possible given I2C is a low speed block). There are other places where I had to use small delays to wait for I2C status to change.
One test might be putting this after the #if defined(I2C_AUTO_RETRY) line, if auto retry is defined:
Code:
while(timeout == 0 || deltaT < timeout)
{
// we are not currently the bus master, so check if bus ready
if(!(*(i2c->S) & I2C_S_BUSY)) [COLOR=#ff0000]<-- without timeout this loops until bus is not busy[/COLOR]
{
// become the bus master in transmit mode (send start)
i2c->currentMode = I2C_MASTER;
*(i2c->C1) = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; [COLOR=#ff0000]<-- once not busy this sets Master mode[/COLOR]
break;
}
}
#if defined(I2C_AUTO_RETRY) [COLOR=#ff0000]<-- #if/#endif block exists only if auto retry is defined[/COLOR]
// if not master and auto-retry set, then reset bus and try one last time
if(!(*(i2c->C1) & I2C_C1_MST)) [COLOR=#ff0000]<-- this should not occur since only way to exit above without timeout is to set Master mode[/COLOR]
{
resetBus_(i2c,bus); [COLOR=#ff0000]<-- this next part tries to clear bus and then reset master mode, but again this shouldn't happen in this case[/COLOR]
if(!(*(i2c->S) & I2C_S_BUSY))
{
// become the bus master in transmit mode (send start)
i2c->currentMode = I2C_MASTER;
*(i2c->C1) = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX;
}
}
#endif
// check if not master
if(!(*(i2c->C1) & I2C_C1_MST))
{
i2c->currentStatus = I2C_TIMEOUT; // bus not acquired, mark as timeout
return 0;
}
The only thing I can guess here is that the delay between setting Master mode in the top part, and checking to see if it is set in the auto retry part, is too small. Not sure, but maybe the block takes a while to register as Master mode (I've never "speed tested" it, but it's possible given I2C is a low speed block). There are other places where I had to use small delays to wait for I2C status to change.
One test might be putting this after the #if defined(I2C_AUTO_RETRY) line, if auto retry is defined:
Code:
#if defined(I2C_AUTO_RETRY)
delayMicroseconds(1);
...