View previous topic :: View next topic |
Author |
Message |
daveh
Joined: 30 Aug 2013 Posts: 17
|
|
Posted: Tue Dec 05, 2017 3:00 pm |
|
|
Thanks Ttelmah and temtronic for all your help!
I added this piece of code before my I2C communication to check for and deal with a SDA stuck low fault condition:
Code: | #bit I2C2EN_BIT = 0x0216.15 // I2CEN bit to enable/disable hardware I2C module
#define i2c2_SDA PIN_B5
if(!input(i2c2_SDA)){ // SDA stuck low - Fault Condition
I2C2EN_BIT=0; // disable I2C2 Hardware Module
output_drive(i2c2_SCL); // set SCL as output
while(!input(i2c2_SDA)){ // Toggle clock line till fault clears
output_toggle(i2c2_SCL);
delay_us(1);
}
output_float(i2c2_SCL); // set SCL as input
I2C2EN_BIT=1; // enable I2C2 Hardware Module
} |
|
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 12844
|
|
Posted: Tue Dec 05, 2017 3:21 pm |
|
|
Looks good.  |
|
 |
daveh
Joined: 30 Aug 2013 Posts: 17
|
|
Posted: Wed Jan 10, 2018 12:35 pm |
|
|
So apparently when the hardware I2C module is enabled "input(i2c2_SDA)" will always read '0'. [Someone please correct me if I'm wrong]
So instead I'm using the following code which disables the hardware I2C before testing the pin:
Code: | #bit I2C2EN_BIT = 0x0216.15 // I2CEN bit to enable/disable hardware I2C module
#define i2c2_SDA PIN_B5
I2C2EN_BIT=0; // disable I2C2 Hardware Module
if(!input(i2c2_SDA)){ // SDA stuck low - Fault Condition
output_drive(i2c2_SCL); // set SCL as output
while(!input(i2c2_SDA)){ // Toggle clock line till fault clears
output_toggle(i2c2_SCL);
delay_us(1);
}
output_float(i2c2_SCL); // set SCL as input
}
I2C2EN_BIT=1; // enable I2C2 Hardware Module
|
|
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 12844
|
|
Posted: Wed Jan 10, 2018 12:51 pm |
|
|
It should read as normal.
If you look at the internal pin logic, the read path still remains connected when there is a peripheral connected. |
|
 |
daveh
Joined: 30 Aug 2013 Posts: 17
|
|
Posted: Wed Jan 10, 2018 1:25 pm |
|
|
I guess I'm confused then, if I have the following code it does not beep. If I comment out the first line then it beeps.
When I look with the scope both SDA and SCL are pulled high prior to this piece of code.
Code: | I2C2EN_BIT=0; // disable I2C2 Hardware Module
if(input(i2c2_SDA)==0) beep(); // SDA stuck low - Fault Condition
I2C2EN_BIT=1; // enable I2C2 Hardware Module
|
|
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 12844
|
|
Posted: Wed Jan 10, 2018 3:17 pm |
|
|
Implies the LAT bit is set to zero.
So when you disable the I2C, the line is then driven low. The read sees if momentarily as low, so beeps, at the same time as releasing the line. |
|
 |
daveh
Joined: 30 Aug 2013 Posts: 17
|
|
Posted: Thu Jan 11, 2018 10:50 am |
|
|
I'm sorry, maybe I wasn't clear. If I use the code as shown (which disables the hardware I2C module) then it doesn't beep which indicates the line is high as it should.
If however I comment out the first line (so I leave the hardware I2C module enabled). Then it beeps which indicates SDA is low but it is actually high on the scope.
So it seems to read correctly when the I2C hardware module is disabled but doesn't seem to read correctly when it's enabled.
Is it possible that the I2C hardware module prevents the tris bits from being changed by the input() command? |
|
 |
|