CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

dsPIC33 I2C Hardware Issue
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
daveh



Joined: 30 Aug 2013
Posts: 19

View user's profile Send private message

PostPosted: Tue Dec 05, 2017 3:00 pm     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Tue Dec 05, 2017 3:21 pm     Reply with quote

Looks good. Smile
daveh



Joined: 30 Aug 2013
Posts: 19

View user's profile Send private message

PostPosted: Wed Jan 10, 2018 12:35 pm     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Wed Jan 10, 2018 12:51 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 10, 2018 1:25 pm     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Wed Jan 10, 2018 3:17 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 11, 2018 10:50 am     Reply with quote

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

View user's profile Send private message Send e-mail

dsPIC33EP512GP502 I2C Read Not Working
PostPosted: Sun Feb 17, 2019 2:17 am     Reply with quote

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

View user's profile Send private message Send e-mail

dsPIC33EP512GP502 I2C Read Not Working
PostPosted: Sun Feb 17, 2019 3:58 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Sun Feb 17, 2019 4:07 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Feb 19, 2019 3:49 am     Reply with quote

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.... Smile
_________________
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

View user's profile Send private message Send e-mail

Note:-
PostPosted: Tue Feb 19, 2019 5:25 am     Reply with quote

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: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 19, 2019 7:51 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 19, 2019 8:43 am     Reply with quote

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.... Smile


For code, you can use the code tags provided in the forum
Code:
like this


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

View user's profile Send private message Send e-mail

PostPosted: Tue Feb 19, 2019 8:55 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group