There are more small snags around Plib libraries for different devices.
For some devices, OpenI2C(...) take care of (re)setting Tristate register bits to input,
while for other devices, no such action is attempted.
Then for some operations, there are both macro definition and functions with the same name,
but with different functionality:
E.g for StartI2C1() the macro will wait in a busy loop until signalling is complete,
#define StartI2C1() SSP1CON2bits.SEN=1;while(SSP1CON2bits.SEN)
but the function with the same name, just set the control bit and return to caller.
void StartI2C1( void )
SSP1CON2bits.SEN = 1; // initiate bus start condition
Both blocking and non-blocking functions may be useful depending on circumstances,
but identical function names with different behaviour?
Neither of these perform error checking of any kind.
As far as I know, I2C specification suggest that master device should check that bus is free and not jammed before initiating Start condition signalling.
I2C hardware do this checking, both before signalling is started, and during the procedure,
and what happen when hardware decide there is a problem?
I2C give up the signalling attempt, set some status bits and do nothing more:
The SEN bit that was set by software is cleared (there is No start condition signalling going on any more),
S bit or P bit may be set or clear depending on the reason for the failure.
BCL bit is probably set (Bus Collision), but that bit is Not in the SSPxSTAT register,
it is in a interrupt register, PIR2bits.BCL1IF or PIR3bits.BCL2IF.
IdleI2Cx(); function do Not check this, and do not return a function value,
so cannot report a problem even if it was detected.
This is a possible cause for the problem and workaround reported earlier in this thread.
In fact, IdleI2Cx() function do not check if the I2C Bus is i a Idle state as defined by I2C specification,
what it do, is to wait for previous operation started by the same MSSP module to be completed.
Also Note, that Write Collision (SSPxCON2bits.WCOL) is different from Bus Collision (PIRybits.BCLxIF).
Write Collision is caused by code stumbling in its own logic, while Bus Collision is caused by events on the I2C bus.
In Device support file for PIC18F26K22, for I2C Status register SSP2STAT, there are several alternative names declared for some bits:
SSP2STATbits.R_NOT_W, SSP2STATbits.R_nW, SSP2STATbits.R, SSP2STATbits.W,
SSP2STATbits.nW, SSP2STATbits.R_W, SSP2STATbits.NOT_WRITE, SSP2STATbits.nWRITE,
SSP2STATbits.I2C_READ2, SSP2STATbits.READ_WRITE2, SSP2STATbits.RW2, SSP2STATbits.R_W2, SSP2STATbits.R_nW2, SSP2STATbits.nW2, SSP2STATbits.nWRITE2.
All these for the same bit
For SSP1STAT there is also a selection, but not quite the same, there is a SSP1STATbits.NOT_W that is not available for SSP2STAT.
In addition to these typedefs, there is a similar selection of bitfield macro definitions, and a heap of single bit macro definitions. There are also definitions for SSPSTAT as alias to SSP1STAT.
Doing a file compare between Device support file for PIC18F26K22 and PIC18F46K22 show no differences between definitions for any MSSP registers.
Most Plib I2C examples I have seen, show wery simple blocking code.
That is not very suitable for I2C communication.
A few days ago, I tried MPLAB Code Configurator (MCC) for PIC18F26K22,
and it came up with a Interrupt-based non-blocking I2C driver that work with the sensor I tried.
I have not tested it much, but on first impression, it looks reasonable.
post edited by Mysil - 2015/02/03 08:33:26