Thursday, November 13, 2008

The I2C bus - learning the hard way

After completing a I2C bus driver recently ( and struggling a bit in doing this activity), I thought i would just pen down something which might be of interest to others who are doing similar activity. For those who are new to I2C bus; In a nutshell, I2C is a synchronous bus with only two lines ( usually called SDA and SCL which stand for serial data , serial clock respectively) for communication. I would be just re-doing the work if try to explain the whole I2C bus here. A very detailed description of the protocol is availabe here.

The reason for me writing these few lines here are to draw your attention towards a specific problem that one might face when using the IIC bus.

The Start
The story began on a very fine monday morning when i just started the system and did some basic debugging and finally got the bus to run. I was really happy when i saw the RX and TX happen smoothly and the Philips IIC interface based EEPROM getting updated. Everything was fine and i took my much deserved coffee break.

The Coffee Break
Two sips of coffee woke up the paranoid engineer in me and i wanted to somehow break my drivers functionality, secretly hoping that nothing bad turns up. I started putting breakpoints here and there and corrupting status variables, resetting the systems at odd points etc just to see how the system worked. Suddenly, disaster struck and my Rx interrupts vanished. Might be a glitch, so i just pressed the reset button in the debugger window and try to do it again. Oh My God!! Now even my Tx interrupts vanished. After stuggling for some time with the debugger controls and trying single stepping through my code several times i found myself looking a big zero. I could not figure out how the code had to do something with my hot coffee else why should it suddenly stop?!!. I just powered down the whole system, went out for my lunch.

Problem Found
Post lunch, i ran the system again and suddenly i heard the chime from the debugger saying it had hit a breakpoint. What is this now, i thought and just looked in to the debugger window; Aha, My Tx interrupt is back.. i just disabled the breakpoint and hit go. Now both my Rx and Tx intterupts where coming alright and the data was all flowing smooth. So, what had happened earlier?? After wondering, struggling and googling for about a couple of hours i figured out that what happened. The IIC bus was being held low. This typically happens, when the slave device is transmitting data and the master undergoes a restart or reset in which case the slave might pull the bus low and would be expecting the further clocks to come to it via the master. Since, the master module has undergone a reset, it is not able to create the clocks without doing some intialization ( sending of START condition), which it fails because the slave has pulled the bus (SDA) low.

Hence, after spending about more than 8 hours with the IIC bus and reading a lot of material i was a bit wiser now knowing about this potential problem with the IIC bus where in your bus can be simply hung for a long time because the slave has no way of knowing when to release the bus. (The power-on of the whole ckt had removed this state from the slave in which case the slave device had relinquished the bus.)







No comments: