One of the problems that we had with our previous PiWars entry was unreliable I2C communication from the Pi to all our peripherals. One reason for that was that we had a lot of devices on the bus.
We’re using a Pi 5 this year and one of its advantages is that there GPIO header has been massively upgraded. It defaults to the same functions as the Pi 4 but it can be reconfigured to trade GPIO pins for extra I2C busses, PWMs and several other functions. So, this evening I had a go at remaking a second I2C bus and, after a bit of digging, it turned out to be very easy.
After reading the device tree documentation in /boot/overlay/README, right on the Pi, it turns out that there’s a pre-made configuration “overlay” for each peripheral that you might want to enable.
The overlays are all listed in that file along with their configuration flags. All I needed to do to enable the I2C2 bus was to add this line to /boot/config.txt and then reboot:
Then, to check it was working, I put my oscilloscope on those pins and ran
sudo i2cdetect 2
That gave the output down at the top of the article. The rise time looks slow, which I think is because it’s using the internal pull up. I probably need to add an external pull up radiator if the right value.
Along the way I find the pinctrl command helpful. It can be used to show the function and current state of the pins.
pinctrl funcs 0-27 # show the alternate functions of GPIO pins
pinctrl get 12-13 # get current state of pins 12 and 13