Two lines in /boot/config.txt enable the I2C hardware and set the I2C bus speed:
However, the actual SCL frequency comes from dividing the CPU’s core clock by an even integer, so you can’t always get what you want. The Pi 3 ticks along at 1.2 GHz (actually 1.1 GHz, because marketing) from a core clock of 550 MHz, so a 200 kHz clock calls for a 2750 divider: 550 MHz / 2750 = 200 kHz.
Actually measuring the SCL frequencies suggests something else is going on:
D0, the bottom trace, is SCL, D1 is SDA, and D2 is a trigger output not used in this setup. The yellow analog trace is the current in the SCL line between the Pi and the BNO055, about which more later.
So a 200 kHz nominal frequency produces a 125 kHz actual frequency.
The BNO055 pulls the clock low (“clock stretching”), which can (and does) cause problems, but it’s not active during the main part of the transfer where the Pi determines the SCL frequency.
More measurement along those lines produces a table:
|CPU Core Clock:||550||MHz|
|I2C SCL kHz|
Apparently, the code converting the nominal I2C rate in
config.txt uses a table of divider values intended for another CPU core clock. AFAICT, the boot code could divide the actual core clock by the desired I2C frequency to produce the appropriate value.
I have no particular desire to Use The Source to figure out what’s going on …
[Update: Perhaps this comes along with CPU clock throttling due to temperature. For completeness, I should dump the temperature and actual clock speed.]