|
|
View previous topic :: View next topic |
Author |
Message |
Manu59114
Joined: 22 Jan 2018 Posts: 34 Location: North of France
|
What is the best way to prevent master i2c hang |
Posted: Tue Jun 18, 2019 3:10 pm |
|
|
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!!!
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
|
|
Posted: Tue Jun 18, 2019 3:24 pm |
|
|
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
|
|
Posted: Tue Jun 18, 2019 4:32 pm |
|
|
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
|
|
Posted: Tue Jun 18, 2019 4:56 pm |
|
|
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
|
|
Posted: Wed Jun 19, 2019 12:47 am |
|
|
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
|
|
Posted: Wed Jun 19, 2019 2:59 am |
|
|
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
|
|
Posted: Wed Jun 19, 2019 3:39 am |
|
|
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
|
|
Posted: Mon Sep 09, 2019 10:16 am |
|
|
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 ? |
|
|
|
|
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
|