Second I2C bus on Raspberry Pi running FreeBSD

The Raspberry Pi Rev 2.0 has I2C1 bus on the expansion header, marked as P1.
SCL1 [BCM2835/GPIO3] routed to P1 pin 5
SDA1 [BCM2835/GPIO2] routed to P1 pin 3
But I2C0 bus is still available.

Here is a description how to use second (or first) I2C bus on the Ruspberry Pi running FreeBSD.

SCL0 [BCM2835/GPIO1] routed to S5 pin 13
SDA0 [BCM2835/GPIO0] routed to S5 pin 14
S5 is the CSI camera interface.

But Rev 2.0 has a new connector P5.
This are 8 holes near the expansion header P1.

P5

This carries the four GPIO signals [BCM2835/GPIO28 – BCM2835/GPIO31], along with +5V0, +3V3 and two 0V.

This GPIO allocation provides access to one of:

  • SDA0, SCL0 (Operating independently of P1 SDA1, SCL1); or
  • PCM_CLK, PCM_FS, PCM_DIN, PCM_DOUT or I2S; or
  • Four GPIO signals.

So, we can use I2C0 on P5.

But first we need to solder any header for this holes.
P5 is right up against the main GPIO header (P1).
This is a problem, because cable on P1 will compete with the header on P5.
I cut off the tab on the cable connector.

After that we can connect any device to the new header on P5.

pi2i2c

SDIM6557

If we try to use iic0 device now we will fail.

If we look at source code of the BCM2835 BSC we will see pins 0, 1 for the I2C0 (BSC0).
But we don’t need to change this and recompile the kernel.
BCM2835 BSC driver just sets this pins to mode alt0 (see lines 278-279)

In the Device tree source we can see bsc0_a on pins 0, 1 and bsc0_b on pins 28, 29.

It’s time now to configure FreeBSD to use I2C0 on P5.

Let’s check the mode of pins 0, 1, 28 and 29:

si2c1
si2c2

As we see pins 0, 1 are in alt0 mode and pins 28, 29 are in input mode.
To change mode we can use the sysctl(8) utility:

sysctl dev.gpio.0.pin.0.function=input
sysctl dev.gpio.0.pin.1.function=input
sysctl dev.gpio.0.pin.28.function=alt0
sysctl dev.gpio.0.pin.29.function=alt0

But this is not all.
We need to use pull-up resistors for I2C pins.
They can be external or can be configured internal by the gpioctl(1) utility:
gpioctl -f /dev/gpioc0 -c 28 PU
gpioctl -f /dev/gpioc0 -c 29 PU

si2c5

Now we can try to use I2C0. I connected the DS1307 RTC device:

si2c6

It’s works!

To make this settings permament we need to update /etc/sysctl.conf:

si2c3

And to create a startup script to configure internal pull-up resistors:

si2c4

And now an example of two I2C devices connected to both I2C buses.

si2c7

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s