Every step described in this post is automatically performed by the setup script of the raspihats python package. Just install the raspihats package and the I2C clock stretch timeout should be set to the right value for operating the I2C-HATs.
Clock stretch timeout register – CLKT
TOUT field from
CLKT register provides a timeout on how long the master waits for the slave to stretch the clock before deciding that the slave has hung, the default value for
TOUT is 0x40(64 decimal), it is 16 bit long, this is from BCM2835-ARM-Peripherals doc.
Calculating timeout for the default baudrate(100kbps):
TOUT * 1/baudrate = 64 * 0.01ms = 0,64ms
During normal operation this clock stretch timeout can be too small, for example when the I2C-HAT is requested to save a parameter in on-board flash, like DigitalOutputs Safety Value, PowerOn Value or the Communication Watchdog Period Value, the flash saving operation may imply a mass erase operation which has the longest duration of the flash operations, about 40ms on STM32 micro present on the I2C-HAT, this is why the default clock stretch timeout value of 0,64ms is too small.
Clock stretching is also heavily used during I2C-HAT firmware update, also implying mass erase.
An appropriate value for the clock stretching timeout should be 200ms, it’s selected to be 5 times greater than 40ms, just for safety.
TOUT = 200ms / 0.01ms = 20000(0x4E20), for the default baudrate of 100kbps
Some C code
The next two pieces of C code are used to set/get the clock stretching timeout value on the Raspberry Pi:
Open a terminal on Raspberry Pi, go to the desired folder and download the two files:
Compile and link source files into executables:
Run the getter first, to see the value of your
CLKT.TOUT, should be 64(default value):
To set the 200ms desired clock stretching timeout run the following command:
This value will be used until next time Raspberry Pi boots.
Set desired clock stretching timeout at boot
You probably want to automatically set the clock stretching timeout every time Raspberry Pi boots. To do this you must edit your /etc/rc.local. More on runnig a script on startup you can find here
I’m using nano for editing the rc.local file.
Add the following line just before “exit 0”:
You should modify /home/pi/workspace/ path to point where you’ve build the executable with gcc.
Don’t forget to save the file using “Ctrl + O” than “Enter”. Exit nano with “Ctrl + X” and reboot.
After reboot you should use the getter to check that the value for CLKT.TOUT is 20000