## I2C Clock Stretching

In I2C communication the master device determines the clock speed. The I2C bus provides an explicit clock signal which relieves master and slave from synchronizing exactly to a predefined baud rate.

However, there are situations where an I2C slave is not able to co-operate with the clock speed given by the master and needs to slow down a little. This is done by a mechanism referred to as clock stretching.

An I2C slave is allowed to hold down the clock if it needs to reduce the bus speed. The master on the other hand is required to read back the clock signal after releasing it to the high state and wait until the line has actually gone high.

It appears that the I2C master on the Broadcom chip at the heart of the Raspberry Pi does not comply with clock stretching requirements. I have read that the Broadcom device does not check the clock signal after releasing it simply assuming that it has gone high. If the slave device has attempted to employ clock stretching I2C communication will break. The data sheet or documentation for your device should state if the device uses clock stretching.

There appears to be no proper solution to this issue but there is a workaround that you may be able to succesfully employ if one of your devices employs clock stretching.

You can slow down the whole I2C bus so that perhaps your attached device may be able to complete tasks within longer clock times.

The i2c_bcm2708 module accepts a parameter 'baudrate' that sets the I2C clock speed used by the master. This isn't really a true baudrate but it does control the I2C clock speed.

Lowering the i2c baudrate from the default 100000 can often allow a clock stretching device to work.

Assuming you are using the device tree, to set the i2c device driver baud rate to 32000 whenever it is loaded, add the following to /boot/config.txt

    i2c_arm_baudrate=32000

Unfortunatley setting the clock speed this low my cause other devices on your I2C bus to stop functioning. That's a fault of the external device as a compliant device ought to support lower speeds. Determing the correct speed that works for all your devices is a matter of trial and error.

You can set the 'baudrate' on the fly by reloading the i2c_bcm2708 module with the chosen parameter. The HiPi module includes a function that will do this for you.

    HiPi::Device::I2C->set_baudrate(32000);

    HiPi::Device::I2C->set_baudrate(100000);

HiPi Modules Copyright © 2013 - 2016 Mark Dootson