An I2C Library for BeagleBone

I2C is one of the common and popular communication interfaces used in Embedded Systems. It supports interfacing of a wide variety of external devices such as sensors, displays etc.. The I2C bus can support far more devices compared to that of SPI. But when it comes to speed, SPI is way ahead in the game.

A year ago, I had bought an SSD1306 OLED display and decided to check it out by interfacing it with my BeagleBone. To do this, there were two things missing. One is the I2C API’s which I could use to easily talk to the display. Second is the driver library for the display that I can use to develop applications.

The development of the SSD1306 driver library requires us to first test the I2C bus. And then have a set of I2C API’s intact for use.

1. I2C Utilities for Linux

Embedded Linux distro’s consists of I2C utilities that can be used to detect and probe the available I2C buses. We will be using this tool to check if the I2C bus is able to detect the devices connected to it.

If you don’t have this tool installed, you can install it by running the below commands.

Install I2C Tools Package

Shell

1

2

sudo apt-getupdate

sudo apt-getinstall i2c-tools

Now check for the available I2C buses by running the below command.

Detect the I2C buses

Shell

1

2

3

root@beaglebone:~# i2cdetect -l

i2c-0i2c OMAP I2C adapter I2C adapter

i2c-2i2c OMAP I2C adapter I2C adapter

I decided to use the i2c-2 bus, as there are no devices connected to it and is free for use. You can check if there are any devices connected to the bus. You can do that by using the below command.

In the above, you can see that currently there are no devices connected to the bus. At some addresses, you can see UU which basically means those bits are reserved. The I2C pins corresponding to the i2c-2 bus is shown below.

i2c-2 bus Pins on the BeagleBone

1

2

3

4

5

P9_19-I2C2_SCL

P9_20-I2C2_SDA

----------------

P9_02-GND

P9_03-DC_3.3V

Now, just for demonstration purpose, let us connect the SSD1306 OLED display to the i2c-2 bus to the pins on the Beaglebone described above. The image on the left shows the complete setup. Once the connections are done, let us run the command again as shown below, to see if the Beaglebone is able to detect the display.

In the above, you can see that the SSD1306 OLED display has been detected on the i2c-2 bus with the address 0x3C. So if we want to talk to the SSD1306, we have to address it by using 0x3C i.e. 7-bit address. So, If you wish to perform a write operation, then you should address the SSD1306 with the R/W bit set to zero i.e. 0x78. Similarly, If you wish to perform a read operation, then you have to address the SSD1306 with the R/W bit set to one i.e. 0x79.

As a programmer, I have always liked and abided by this beautiful quote shown below 🙂

Talk is cheap. Show me the code.

-Linus Torvalds

So, let me share the code and provide you folks with some information on how to use this Library in the next section.

2. Source Code and Using the BeagleBone I2C Library

The Library contains just two files i.e I2C.c and I2C.h. The I2C.c contains definitions for all the standard I2C operations and some are customized to support use for talking to most of the I2C devices.

The Application Engineer can use some other i2c-x bus as well. He/She can do this just by creating a new object representing that i2c bus. To include this library, just add the two files in your project.

You can download the library from my Github repo or clone it by using the below command.

One can also test the i2c bus through command line using the I2C utilities. For example, to send a byte on the i2c-2 bus, run the below command.

Shell

1

12cset-y20x3C0xAA

The above selects i2c-2 bus and sends a byte of data i.e. 0xAA preceding the slave address i.e. 0x3C. If you check this transaction on an oscilloscope, then you will notice that the data 0xAA precedes with the slave address being 0x78. This is because the R/W bit will be set to zero for a write operation. This will become evident once we view the signals on the logic analyzer for analysis.

3. Testing and Analysis of the I2C Library

In this section, let’s capture the i2c-2 bus signals generated by the API’s present in the Library for analysis. I have done this using the Saleae Logic Analyzer.

Note: The SSD1306 Library for the BeagleBone has been completed. Hence, I have updated this note. You can download the Library from my Github repo.

3.1 Single Write Test

The image above shows the signals captured while performing a single write transaction. If you look into the picture closely, you can see a sequence as shown below.

1

2

ADDR DATA

0x78+ACK0x55+ACK

3.2 Dual Write Test

The image above shows the signals captured while performing a dual write transaction. If you look into the picture closely, you can see a sequence as shown below.

1

2

ADDR CNTRL CMD

0x78+ACK0x00+ACK0xA0+ACK

3.3 Multiple Writes Test

Similarly, the image above shows the signals captured while performing multiple write transactions. If you look into the picture closely, you can see a sequence as shown below.

1

0x78+ACK0xFF+ACK0xA0+ACK0xAA+ACK0xF0+ACK0x0F+ACK

There were a few existing Libraries, however, they were all written in C++ and I found them to be quite overwhelming. Hence, I have written this I2C Library in C for simplicity and ease of use. A while ago, I had also written an SPI Library for the BeagleBone. Feel free to check it out here.