Pages: [1]   Go Down
Author Topic: I2C freezes arduino  (Read 8114 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi. I have a I2C network with slaves. My problem is that periodically Arduino Freezes. This bug can be also forced if you put a screewdriver on I2C Analog Pins 4 or 5 during a moment. Arduino freezes and it is in unrecoverable state until next reset.

Investigating, the problem is <twi.c> blocking behavior without timeouts. (endless loops "while")

Code:
uint8_t twi_writeTo(...
...
while(TWI_READY != twi_state){
    continue;
  }
...
while(wait && (TWI_MTX == twi_state)){
    continue;
  }
...

I have "solved" it with a counter timeout in all "while" loops. Now Arduino doesn't freezes, but I cannot found, there is no way to initialize or recover again the I2C Network without Reset Arduino.

Investigating more, the reason is in Interrupt Vector Code:

Code:
SIGNAL(TWI_vect)
switch(TW_STATUS){
...
case TW_MT_SLA_NACK:  // address sent, nack received
   twi_stop();
...

it it always entering with TW_MT_SLA_NACK code an then twi_stop, and from here I don't know how to continue.

I think this is a severe problem with Arduino and I2C networks, because any bus problem freezes arduino by code, or if you avoid freezing I2C network is unrecoverable.

Any trail or solution?







Logged

0
Offline Offline
Edison Member
*
Karma: 0
Posts: 1103
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A good analysis of some hidden bug..
I think you should not just leave the wait loops, but rather re-initialize the TWI hardware completly in that time-out case. This might need more changes in the library...
Logged

Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I have "solved" it with a counter timeout in all "while" loops. Now Arduino doesn't freezes, but I cannot found, there is no way to initialize or recover again the I2C Network without Reset Arduino.

I handle this pretty much the way you suggest (using a 5000 microseconds timeout), but when a state timeout is detected (assuming a bus issue), I call twi_init. For this to be effective, you also need to add the following statement to the top of twi_init:

Code:
void twi_init(void)
{
  // disable twi module (to allow for reinitialize)
  TWCR = 0;

  // ... original code follows

  // initialize state
  twi_state = TWI_READY;

« Last Edit: September 08, 2010, 01:32:01 am by borref » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK with your solution, TWCR = 0 is the key. Now I2C autorecover after failure.

These are my "final" twi.c and twi.h:

http://liken.otsoa.net/pub/ntwi/twi.h
http://liken.otsoa.net/pub/ntwi/twi.c

Expecting for a better and elegant solution...


Logged

Pages: [1]   Go Up
Jump to: