View previous topic :: View next topic |
Author |
Message |
daveh
Joined: 30 Aug 2013 Posts: 19
|
|
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: 19358
|
|
Posted: Tue Dec 05, 2017 3:21 pm |
|
|
Looks good. |
|
|
daveh
Joined: 30 Aug 2013 Posts: 19
|
|
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: 19358
|
|
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: 19
|
|
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: 19358
|
|
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: 19
|
|
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? |
|
|
Baskar Veerappan
Joined: 17 Feb 2019 Posts: 9
|
dsPIC33EP512GP502 I2C Read Not Working |
Posted: Sun Feb 17, 2019 2:17 am |
|
|
Hello My Dear Friend,
I am Facing The Same Issue with same dsPIC33EP512GP502.
I am interfacing dsPIC33EP512GP502 with two slaves one is DS3231 RTC and another one is 20x4 LCD with PCF8574T[8 Bit I2C IO Expander].
While writing to both devices its working fine but if try to read from any one slave the SDA goes Low permanently and SCL goes High permanently. Thereafter no change in I2C Bus even if I start writing again. Bus collision bit I2C2STAT.BCL sets to high.
I tried making BCL =0 and restarted I2C Module but there is no change in bus level.
Until power off and on it again the bus level remains same.
I am using MPLAB X IDE v5.05 XC16 v1.34 Compiler.
Please Support me..... _________________ Regards
Baskar V |
|
|
Baskar Veerappan
Joined: 17 Feb 2019 Posts: 9
|
dsPIC33EP512GP502 I2C Read Not Working |
Posted: Sun Feb 17, 2019 3:58 am |
|
|
I tried your idea by giving 9 clock pulses after SDA Goes Low, now the SDA becomes high but if I try to read again from slave by setting RW bit =1.
i.e (DS3231_ID | 1u) again the SDA goes low and again i'm applying 9 clock pulses then SDA becomes high. This process keeps on repeating. Finally there is no data read from slave device....
Do you have any solution.. _________________ Regards
Baskar V |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Sun Feb 17, 2019 4:07 am |
|
|
The most likely cause of this is you are doing some part of the I2C
transaction 'too fast' for the slave device. The commonest issue that
causes the bus collision, is that when you send an I2C_stop, the bus
actually takes a short time to rise to the high level, and for the I2C
'engine' to go idle. If you try to send an I2C_start, before this
happens, you get an immediate bus collision from the I2C. This is
why I have a 1uSec delay after every I2C stop, in my library for the
SSD1306. On PIC16's and 18's this is not needed, but on the PIC24/30/33
the engine returns before the stop has actually completed, and this little
extra delay allows the time for this.
However it sounds as if your timings may be OK since write is working
which then brings us to number 2:
Another thing that will cause issues, is if your master device does not
invert the ACK bit on the last byte read. If this is not done the slave device
will remain waiting, and lock the bus.
Clearing this:
You need to use I2C_poll, and read every byte from the engine that
may be waiting to be read. Then disable the I2C peripheral, release the SDA
line and clock the SCL line. Test SDA. If it has not gone high, repeat the
clock and try again. Once it goes high, re-enable the I2C peripheral, and
send a 'stop'.
This should leave both the slave device and the PIC I2C ready to go
again.
Since it sounds as if the slave device is actually hung, I'd suspect that
failing to properly handle the ACK on the last byte is the problem. |
|
|
Baskar Veerappan
Joined: 17 Feb 2019 Posts: 9
|
|
Posted: Tue Feb 19, 2019 3:49 am |
|
|
Dear Ttelmah,
Thank you very much for spending your valuable time for me,
I am Operating the dsPIC33E engine at 16MHz and I2C Speed as 125KHz [First I tried with 400KHz then I reduced it to 125 KHz I tried the same slave device with PIC18F47K42 @125KHz its working fine with that 8 bit device]
To ensure that bus is Idle I'm Checking START Bit, RESTART Bit, STOP Bit,
and TBF bit before applying any sequence on I2C bus
After Power ON and once the I2C Module is Initialized
if I write ((DS3231_ID <<1u) | 1u ) after I2C_Start() as a first data in bus also causing Collision and Making SDA Low Permanently, since there is no other previous transaction on the bus I am confused why this happens
Uint08 Read_DS3231(Uint08 Adrs )
{
Uint08 RxD =0;
I2C2CONbits.RCEN = TRUE ; /* Receive Enable */
dsPIC33EP512GP502_IIC2(START); /* Start */
IIC2_Transmit(DS3231_RD); /*Read Command #define DS3231_RD ((104u << 1u)|1u) */
RxD = IIC2_Recieve();
PutAcknowledgeI2C2(NACK);
dsPIC33EP512GP502_IIC2(STOP);
return RxD ;
}
I can Share you My Code and Snapshots of I2C Transactions. But I don't see any options to upload in this forum. is there any way to upload files ?
Today I will try by further reducing the I2C Clock to 100KHz and get back to you My dear Ttelmah.
Thank you very much.... _________________ Regards
Baskar V
Last edited by Baskar Veerappan on Tue Feb 19, 2019 6:21 am; edited 1 time in total |
|
|
Baskar Veerappan
Joined: 17 Feb 2019 Posts: 9
|
Note:- |
Posted: Tue Feb 19, 2019 5:25 am |
|
|
The Slave devices are operating at 5V while the dsPIC33EP @3.3V
I have disabled the internal pullups[Configured as open drain] SCL and SDA Pins are pulled to 5V with 3.3K ohm Resistors since these pins are tolerant to 5V. I believe this wont create any issues. _________________ Regards
Baskar V |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Tue Feb 19, 2019 7:51 am |
|
|
quick comment, I haven't checked the data sheets but generally speakng...
Slave(5V) requires minimum of 3.5 for a logic '1' when using I2Cperipheral(hw)
Master(3V3) might send a '1' as 3.2 volts, not high enough.
Would need to download the datasheets and read the electrical specs for I/O pins. What 'mode' the I/O pin is used has a HUGE bearing on what is seen as a '1' or '0' ! |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Tue Feb 19, 2019 8:43 am |
|
|
Baskar Veerappan wrote: |
I can Share you My Code and Snapshots of I2C Transactions. But I don't see any options to upload in this forum. is there any way to upload files ?
Today I will try by further reducing the I2C Clock to 100KHz and get back to you My dear Ttelmah.
Thank you very much.... |
For code, you can use the code tags provided in the forum
For images, there are a lot of image hosts that you can use, and then use the image tags to embed them in your posts.
I used tinypic.com to host this particular image |
|
|
Baskar Veerappan
Joined: 17 Feb 2019 Posts: 9
|
|
Posted: Tue Feb 19, 2019 8:55 am |
|
|
The I2C Bus is connected to 5V Supply using 3.3K Pullup Resistors as Per dsPIC33EP512GP502 datasheet the SCL and SDA Pins are 5V tolerance so Logic 1 will be more the 4.5V which meets the requirement of 5V device. _________________ Regards
Baskar V |
|
|
|