Linux I2C Device Interface

I2C Dev Libraries

Look Ma! without Handles!

In the earlier section we saw how to communicate with the sensors using high level libraries, but imagine we are in the scenario where we are creating our own hardware, during the earlier stages of fine tuning our hardware it is very useful and easier to communicate using the linux low level tools and libraries :), libraries that even MRAA and almost all Linux drivers relies on.

Now lets start by creating a file called lcd.c and start adding the headers we're going to need and the body of the program:

root@edison:~# cd TheIoTLearningInitiative/Sensors
root@edison:~/TheIoTLearningInitiative/Sensors#
root@edison:~/TheIoTLearningInitiative/Sensors# mkdir I2CDL
root@edison:~/TheIoTLearningInitiative/Sensors# cd I2CDL/
root@edison:~/TheIoTLearningInitiative/Sensors/I2CDL#
root@edison:~/.../I2CDL# nano lcd.c
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c-dev-user.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>
#include <inttypes.h>


int main()
{

    return 0;
}

Now lets do some defines so we can have the registers we need at hand, lets start with those registers needed by the RGB controller of our Display.

As an practice excercise, please go to the PC9633 RGB Controller and determinate what we are doing with those values, are those values addresses or are they configuration settings?

Answer: they are register addresses, as depicted in page 11 of the PC9633 RGB Controller (that's our RGB Display controller). It is a good idea to try understand how this registers work together.

According to the linux documentation we have to open a device file in order to communicate with our device so this can act as a i2c context for any future communication so lets create a struct that can store all that information named I2CCONTEXT.

Now lets create a function where we are going to create the context, this function will receive the reference to an I2CCONTEXT variable, the address of the device and the bus where it is laying. as a return value we can send the errno value:ç

Now lets add some methods to do the reading and writing of the i2c registers, basically there are two flavors, one is using smbus or pure i2c methods, we will use smbus since it is supported in Edison, and is a bit easier since there are already methods that handle register lenghts of byte and word, otherwise we will have to create a buffer and fill it according hte i2c protocol, it is left as an excercise for the reader to use i2c pure methods.

Alright! so if you inspect the datasheets ( go figure! :P) you will notice that the length of the registers is 1 byte (8 bits) so from the i2c-dev methods there one that seems to be just what we need to write byte data:

And to read a register we can use:

Lets create two methods so we can handle any errors and return the error code in case something goes wrong.

Now lets test if we can get the I2C context of our RGB controller for that, add this to the main():

So far your lcd.c sourcecode should look like this:

Now lets create a Makefile with the following content:

Run make and when the compilation succesfully finishes run ./lcdtest

There are things missing like, specify the column and row where we want to start writing text so it will be left to you to investigate how to add that functionality.

Last updated