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 CCS Technical Support

What is the best way to prevent master i2c hang

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Manu59114



Joined: 22 Jan 2018
Posts: 34
Location: North of France

View user's profile Send private message

What is the best way to prevent master i2c hang
PostPosted: Tue Jun 18, 2019 3:10 pm     Reply with quote

Hello to all,

i have a headache!!
i try to find the best solution to not hang my master I2C processor when a cable is disconnected for example! (vibration test for example)

The situation:
A motherboard with a dsPIC33ep512mu810
ASCL1
ASDA1
2 x Pullup resistor 4K7
VCC: 3.3Volts
I2C HARDWARE

An external board connected with
1 PCA9675 (16 I/O I2C extender)
1 0.96" oled display


What i simulate:
Connect and disconnect the cable between the 2 boards when the boards are communicating. (cable length: between 10 -30cm)

Result:
I can have no problem but....sometime, the SDA on the master stay low and rarely the SCL Line stay low too?!?!? after i disconnect the cable of course!!!

The "Main" programme" is freezed or waiting for something!!!
but the timer 0 continue to toggle a LED on an output!!

I send text on the oled display.
I put all I/O line at 0XFF Before read all input.
That's it!


i tried the Ttelmah solution to add a If(i2c_write(device_Adress) == 0) after each I2C start but with no result!!!
Crying or Very sad Crying or Very sad

Is someone know a robust solution to avoid the processor hang in this situation? to exit and continu the program?

Thank you very much in advance for your help!!!

MAnu
_________________
CCS + ICD3 + PIC18F46K80
newguy



Joined: 24 Jun 2004
Posts: 1909

View user's profile Send private message

PostPosted: Tue Jun 18, 2019 3:24 pm     Reply with quote

Just before you start an i2c transaction, calculate the maximum amount of time the transaction will take. For example, I'm going to transfer x bytes, and at y clock speed that should take z milliseconds. Double that or perhaps triple it. Call this N.

Choose a timer. Set it up so that it should "expire" or "roll over" in N milliseconds. Enable its interrupt and ensure you have an interrupt handler for it. If that interrupt "fires", it means that your i2c transaction didn't complete in the amount of time you thought it should take. That interrupt handler should abort the i2c transaction. Easiest way is to probably disable the MSSP peripheral. Also ensure you disable the timer inside that same interrupt.

With this safety net, you start the timer, perform your i2c transaction, and when the transaction is complete, you disable the timer. If the i2c hangs, your safety net will save you.

Make sense?
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 18, 2019 4:32 pm     Reply with quote

It does to this old guy !!! I've done a similar method with RS-232 communications for decades. It sure works for when the cable 'magically' gets unplugged !!

Jay
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Jun 18, 2019 4:56 pm     Reply with quote

You also need to solve the problem of the slave holding the SCK line low (clock stretching) and the case of the slave holding the data line low (out of sync with the clock).

The sync problem is easy to solve by disabling the serial peripheral, set the pins to I/O mode and sending out 10 clock pulses.

The first problem, (the killer one), can only be done by fixing the issue on the slave. You could do this by power cycling the slaves on the I2C bus.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Wed Jun 19, 2019 12:47 am     Reply with quote

The thread title here is wrong!...
It's not actually a 'master' problem.

Key thing is the slave is 'off' and (if the pullups are on the slave), actually
permanently shorting the clock (and data) lines low. This (of course)
prevents an I2C transaction even being started.
Now you can't recover from this for as long as the slave is in this state.
If an I2C slave is in it's own 'hung' state, and still alive (and 'holding' the
clock low), then as asmallri says, sending 10 clock pulses is the correct
way to 'unhang' the slave and get back into sync.
What you can always do is to poll the I2C lines before trying to start a
transaction, and verify they are high.
So sequence becomes:
1) Use 'input_state' on both I2C lines.
2) Are they both high?. If so proceed to try the I2C transaction.
3) If not, is the data line high?. If so, disable the I2C peripheral, and
send ten clock pulses to try to 'unhang' the slave. Switch the peripheral
back on, and go back to '1'.
4) If both lines are low, then the peripheral is off. Abandon the transaction.

It is always worth having a timeout on any transaction of this sort, but
this is the 'pre transaction' test needed to code with the possibility
of a completely disabled peripheral.
Manu59114



Joined: 22 Jan 2018
Posts: 34
Location: North of France

View user's profile Send private message

PostPosted: Wed Jun 19, 2019 2:59 am     Reply with quote

Hi, thanks to all for your quick answers!

1/
To Ttelmah, what i observe / measure on SDA and SCLA is with the slave disconnected, SDA stay low on the master! and the pull up resistor is mounted on the master board!

2/ to disable the I2C module re enable it, do i use something like this?

The idea:


i2c_init(0);
Send 10 pulses on SCL pin output;
i2c_init(1);



Wish you all the best
Manu
_________________
CCS + ICD3 + PIC18F46K80
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Wed Jun 19, 2019 3:39 am     Reply with quote

The master SCL low, means you must have started an I2C transaction.
Basically the master drops the SDA as part of the I2C_START. It should then
stay low till the I2C_WRITE is done. When the first I2C_WRITE is done
this should return the ACK bit. Yet you say you are using this?.

What are you actually doing with the test:

If(i2c_write(device_Adress) == 0) ?.

You do realise that if this does not happen, you then just have to abandon
the I2C transaction?. Just send a stop, and do nothing else. You must only
carry on with the transaction if you have received the zero.

As one 'comment', 4K7, is a rather large resistor for a 3.3v system.
Rp(min) calculates as just under 1KR at this voltage. 4K7 would only
support a maximum bus capacitance of around 60pF. For a 200pF bus,
Texas's calculator gives a recommended resistance between 966.66R
and 1K77R at this voltage.
allenhuffman



Joined: 17 Jun 2019
Posts: 554
Location: Des Moines, Iowa, USA

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

PostPosted: Mon Sep 09, 2019 10:16 am     Reply with quote

Manu59114 wrote:
Hi, thanks to all for your quick answers!

1/
To Ttelmah, what i observe / measure on SDA and SCLA is with the slave disconnected, SDA stay low on the master! and the pull up resistor is mounted on the master board!

2/ to disable the I2C module re enable it, do i use something like this?

The idea:


i2c_init(0);
Send 10 pulses on SCL pin output;
i2c_init(1);



Wish you all the best
Manu


Did you get this working?
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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