cancel
Showing results for 
Search instead for 
Did you mean: 

SMBUS Clock Stretching Not Obeyed

pshields
Associate II
Posted on July 02, 2012 at 00:05

I am using an STM32F103 chip using I2C1 configured as an SMBUS Host (also tried normal I2C) to talk to a smart battery charger and smart battery.  The charger comms are fine both in software and look perfect on the logic analyzer.  The problem I'm having is communicating with the battery since it seems to be utilizing the SMBUS support for clock stretching.   

Here is what the comms between the charger and the battery look like with proper handling of clock stretching.

0690X000006050jQAA.png

Here is what happens when i try to talk to the battery with the STM32...

0690X000006050tQAA.png

It seems to me that the STM32F103 chip is NOT following the clock stretching requirements of the SMBUS standard.  Is there anything I could be missing here?  I can't think of anyway to make this work that doesn't involve writing my own bit banged version of SMBUS.  Has anyone else out there seen this or have any thoughts or ideas?

Thanks....

#smbus-clock-stretch-i2c
5 REPLIES 5
emalund
Associate III
Posted on July 02, 2012 at 20:18

are both pins (SDA and SCL) configured as open drain?

what is the distance?

what are the pullup resistors?

Erik
pshields
Associate II
Posted on July 05, 2012 at 01:08

Both pins are configured as open drain

the distance is about 18''

pull-ups are 4.7k

I2C waveform is perfect for most devices (ones that do not utilize slave clock stretching) and high level functionality works as expected as well.

I also tried a hack where I wait static time periods to be a bit longer than the times the battery usually stretches the clock.  However when I do this the master isn't holding the clock low (my next step is to also manually pull the the clock low while I am ''over-stretching'' the clock).  

The problem with this stretching is that if I don't command the I2C module to send the next byte it won't setup the data line to the correct level and wait on pulsing the clock line until it's released.   I was thinking another hack could be to try and put the I2C into slave mode and manually control the clock line.  

Now that I think about it, I might be able to get away with manually pushing the data line to the correct next bit value and then wait until the clock is released to command the next byte (assuming the module doesn't reclock the first bit out).

Thoughts?

emalund
Associate III
Posted on July 05, 2012 at 17:05

the first requirement for getting help is answering questions

Erik
pshields
Associate II
Posted on July 09, 2012 at 02:37

Erik,

  So I finally solve this... I brushed off your questions at first because I had checked thevalues seemed fine to me.  But I did take a close look at the voltages with a scope and noticed that the voltage when the battery pulled low wasn't as low as the other pulses (~0.8V instead of 0.4v).  Because of convenience I had been looking between 2 of the I2C muxes in my system, I then probed on the STM32 side of the first mux and found those higher ''low''s weren't making it across the mux because of it's low voltage requirement (<=0.4V).  Long story short I needed to change to 15kohm pull-ups to ensure the voltages go low enough.   Once the stretching was seen by the micro it actually worked, crazy!

Thank you Erik for helping to guide me to find the real problem.

kyc
Associate II
Posted on July 22, 2014 at 09:37

Hi,

I am writing the code for I2C slave.

may I ask where should I insert the function ''I2C_StretchClockCmd(I2C2, ENABLE)'' ?

Inside the Interrupt Handler? or just at the very beginning of the INITIALISATION?

Thank you.