# How is the clock frequency established between master and slave in I2C protocol?

This is a follow-up question to What happens if I omit the pullup resistors on I2C lines?

In a digital wall clock I designed (using the DS1307 RTC and the ATmega328 MCU), I accidentally omitted the pull-up resistors that must be wired to both I2C lines. In the end I was lucky enough that the internal pull-ups on the ATmega I2C lines were enough to (barely) allow the communication between the devices. The result were long rise times on the I2C lines and speed reduction to 32kHz as seen in the scope shots below.

What's puzzling me now is how the devices decided that 32kHz was enough for the communication to take place. The DS1307 datasheet says that the device supports 100kHz frequency on the I2C bus. How come it ended up using 32kHz instead. Is there some kind of handshake phase where the frequency is stablished?

In the end, my question really is this: How is the clock frequency established between master and slave in I2C protocol?

I couldn't find that information searching the Net.

In case this matters, I'm using Arduino IDE 1.03 and my firmware handles the RTC using the DS1307RTC Arduino lib (through its functions RTC.read() and RTC.write()). That lib in turn uses Wire.h to talk to the RTC.

-
The standard for I2C is here –  Warren Hill Mar 13 at 13:46
Couldn't this be you arbitrarily hard-coding that frequency without knowing it? –  Dzarda Mar 13 at 13:51
@Warren That reference is really helpful, thanks. I couldn't get Google to take me to THE SPEC. Instead, it took me to Wikipedia article and other tangencial docs. Still, I couldn't understand how speed is determined. I think what I want to know is in section 3.1.7 Clock synchronization, but I would really appreciate if someone could explain that to me in simpler terms, as it is still a bit over my head. –  Ricardo Mar 13 at 13:55
In your system the DS1307 is a slave and it's SCL line is an input only. The frequency is set by the master the MCU. Whoever wrote the firmware for it decided what speed they wanted. There is no negotiation its hard coded. –  Warren Hill Mar 13 at 14:04
Correct most systems have only one master, clock sync only makes sense in a multi-master environment –  Warren Hill Mar 13 at 14:17

For a rising clock edge occur in I2C, the master must assert the clock, which may cause some slaves to join in asserting it as well, and then the master and all slaves must concur in releasing the clock. Until all devices release the clock, it will remain asserted and all devices will see that it's asserted.

Once every device has released the clock, then each slave device will "re-arm" the clock-hold circuit unless or until it will be ready for the next rising edge [some devices are always "ready" for rising edges as fast as the master can send them, and thus don't need a clock-hold circuit at all; others may sometimes know they won't be interested in any rising edges until the next start condition appears, and not re-arm their clock-hold circuit until then]. When the master sees that the clock is released, it waiting some minimum length of time to ensure that anyone who needs to re-arm a bus-hold circuit has a chance to do so, and then re-assert the clock and ensure that it's held long enough to allow any armed bus-hold circuits to join in holding it. The cycle can then repeat.

Slave devices generally do not have a minimum speed of operation, but will have a maximum. Some devices synchronize all their I2C logic to an internal clock, and may thus require a cycle or two to arm or trigger their clock-hold circuit. Additionally, I2C requires that devices must 100% reliably determine whether edges on the clock wire happen before or after edges on the data wire; since data line changes often occur almost immediately after falling clock edges, devices may add some delay in when they perceive data-line changes. This requires adding a delay between any time the master changes its data output and the time it raises its clock. Provided every device has its minimum delay requirement satisfied, the master can delay as long as it wants; the longer the master delays, though, the longer it will take to send data.

-

Yes, the frequency is hard-coded into some specific I2C-related registers. At runtime.

That said, your Arduino library might be doing some probing and rise time measurement on the bus for determining a viable clock rate. Let's see.

After doing a bit of source-digging, the answer is in twi.h

#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif


Another piece from that very file:

TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;


Where TWBR stands for Two Wire Baudrate Register I suspect.

I'd call that enough evidence and definitely say, yes your I2C frequency is set directly by your library without any negotiations. If you want to change it, I'd suggest you #define TWI_FREQ before you #include twi.h (or indirectly through Wire.h)

-
"If you want to change it, I'd suggest #undef and #define on TWI_FREQ after you include Wire.h" No, that's incorrect. The way twi.h is written, you should #define your custom TWI_FREQ before you #include twi.h. (And what does "Wire.h" have to do with anything?) –  Dave Tweed Mar 13 at 16:07
Good point, thanks –  Dzarda Mar 13 at 16:14