Electronic – Minimum Clock Source for the I2C Driver

atmeli2cmicrocontroller

I am curious to know which figure in the MCU (microcontroller) datasheet would reveal the minimum clock source you could use to feed the I2C driver so it can generate it's CLK and Data line.

Looking to find an answer for this question, I have bumped into this paragraph here,

Question: I have a 32.768kHz oscillator. Ideally, I'd like to have the I2C bus clock rate run at 400kHz or 100kHz. But even with a value of SSPADD = 0, the (I2C Master mode clock) Fscl is only around 8 kHz

Answer: The I2C clock is generated by dividing down your clock
frequency/4, so there is no way it can be faster than a quarter of
your clock frequency.

If assumed true, I would like to know the analogy behind this.

In this case I am using Atmel SAMD21, however, I honestly don't mind if you use a different MCU as your example.

In SAMD21 the standard speed runs in 100KHz baud rate and this is the baud rate I am interested to know about unless you would like to expand your answer for the faster speeds.

SAMD21 uses the following calculations to eliminate an incorrect clock source in its I2C driver,

tmp_baud = (int32_t)(div_ceil(
        fgclk - fscl * (10 + (fgclk * 0.000000001)* trise), 2 * fscl));

/* For High speed mode, set the SCL ratio of high:low to 1:2. */
if (config->transfer_speed == I2C_MASTER_SPEED_HIGH_SPEED) {
    tmp_baudlow_hs = (int32_t)((fgclk * 2.0) / (3.0 * fscl_hs) - 1);
    if (tmp_baudlow_hs) {
        tmp_baud_hs = (int32_t)(fgclk / fscl_hs) - 2 - tmp_baudlow_hs;
    } else {
        tmp_baud_hs = (int32_t)(div_ceil(fgclk, 2 * fscl_hs)) - 1;
    }
}

/* Check that baudrate is supported at current speed. */
if (tmp_baud > 255 || tmp_baud < 0 || tmp_baud_hs > 255 || tmp_baud_hs < 0) {
    /* Baud rate not supported. */
    tmp_status_code = STATUS_ERR_BAUDRATE_UNAVAILABLE;
}

with fgclk being the clock source (e.g. 8MHz) and fscl the baud rate of i2c I believe (e.g. 100k) and trise=215, which results to tmp_baud=35 and tmp_baud_hs=0.

enter image description here

Best Answer

I²C defines a maximum speed (actually, a different one for each mode), but the purpose of that is only to ensure that the electrical signals can be handled by the circuit without degradation.

The speed of the transmission itself is not fixed, but can be defined by the clock signal sent by the master (optionally slowed down by the slave through clock stretching), so the master can choose to use a slower speed, and can even use different lengths for different bits.

The I²C specification does not define a minimum speed, so in theory, you could use any clock source, or even clock out the bits by hand with a (debounced) button.
In practice, SMBus (which is derived from, but not identical to, I²C) defines a timeout of 35 ms for a low clock signal, and some I²C implementations might have a similar timeout in order to detect hung devices.
So for those cases, a minimum speed of at least 50 Hz (0.05 kHz) might be advisable.

The code you've shown does not put an absolute limit on the I²C clock; it just checks that it is actually possible to derive the chosen I²C clock from the chosen clock source (with a divider between 1 and 256 if I'm reading it correctly). So you can use any speed, as long as you have a matching clock source.