cancel
Showing results for 
Search instead for 
Did you mean: 

I²C questions again

wolfgang2399
Associate II
Posted on November 02, 2007 at 10:33

I²C questions again

2 REPLIES 2
wolfgang2399
Associate II
Posted on October 09, 2007 at 07:46

Hi,

I simply want nothing but connecting an M24C32 EEProm to my ST72325. But I couldn't find any ''sophisticated sollution'', to be used as it is. So I'm going the way of an own development again :( . Any helpful hint would be appreciated!!

In the ST7_lib I found the C-file I2C.C and therein was the routine ''I2C_Generate_9Stops'' with the description ''Generate 9 consecutive stop bits to re-synchronize I2C bus''.

My questions:

-1- Do you know about further information of re-synchronization in this way (I couldn't even find it in the I²C-bus specification of Philips)?

-2- Why should the sequence of the routine

- SCL low - SDA low - SDA high - SCL high -

be a STOP-sequence????

-3- Has anybody experiences with this re-synchronization or even do use re-sync? If so, in which cases?

Thanks

WoRo

patm4
Associate II
Posted on November 02, 2007 at 10:33

The 'resync' procedure is to clear a so called 'stuck bus' condition. This can occur for example if you start reading from the eeprom/slave and don't ( for what ever reason, maybe a soft reset ) finish the sequence properly. The bus can be stuck in a condition were the slave (e.g. eeprom) could be driving the SDA line low i.e. logic zero when you stopped clocking the part. Under this condition the master cannot regain control as the SDA is held low by the slave.

The condition is cleared by clocking the part upto 9 times whilst monitoring the SDA line and waiting for it to go high again.

The following is an example of a bit banged I2C Init routine which checks and clears this condition before programming the port pins as SCL and SDA.

BYTE I2C_Init(void)

{

BYTE i=9; // may need to clock a slave upto 9 times if it is holding the bus low

// Initially program SDA as input and SCL as output high

I2CPORT_OR&= (BYTE)~SCL_PIN;

I2CPORT_DR |= (BYTE)SCL_PIN; // Make sure of open drain output

I2CPORT_DDR|= (BYTE)SCL_PIN;

I2CPORT_DDR&= (BYTE)~SDA_PIN; // make sure of floating input

I2CPORT_OR&= (BYTE)~SDA_PIN;

// Now check for a stuck bus

while( ((I2CPORT_DR & SDA_PIN) == 0)&& i ) // Is SDA held low by slave ?

{

// clock next bit from slave driving the bus

SCL_LO;

SCL_HI;

i--;

}

if(i == 0)

{

return 0; // still stuck we're screwed need to fail and power off

}

else

{

// got good bus here

I2CPORT_DR|= SDA_PIN;

I2CPORT_DDR|= SDA_PIN ; // now set SDA output high

// now have idle condition

return 1;

}

}