How to use VisionSOM-6ULL I2C interface in command line and C programs
From SomLabs Wiki
How to use VisionSOM-6ULL I2C interface in command line and C programs
Configuring device tree to enable I2C interface
To enable I2C interface you may need to add (or modify) interface definition, your dts file should contain:
&i2c2 { clock_frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; };
In iomux section add or modify i2c pin definition:
pinctrl_i2c2: i2c2grp { fsl,pins = < MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 >; }
Those definitions may need modifications depending on which interface and pins you want to use. You can find more informations on customizing device tree in this tutorial.
In this example there is used VisionSOM-6ULL, VisionCB-STD and PModRTCC. PModRTCC module is connected to Raspberry Pi connector on VisionCB-STD:
VisionSOM-CB-STD RPi connector pin number | PModRTCC pin |
---|---|
1 | VCC |
6 | GND |
3 | SDA |
5 | SCL |
I2C operations
By default i2c devices are controlled by a kernel driver. If your interfaces are enabled and driver is loaded then you should be able to see them in /sys/class/ directory:
root@somlabs:~# ls /sys/class/i2c-adapter i2c-0 i2c-1
It is also possible to access i2c devices from userspace through the /dev interface. To do that you need to install some packages:
root@somlabs:~# apt install libi2c-dev i2c-tools
Now make i2c-dev module load at system boot, edit /etc/modules file:
root@somlabs:~# nano /etc/modules
At the end of the file add line:
i2c-dev
Press Ctrl+O to save then file and Ctrl+X to exit. Now reboot your system.
Using I2C interface in console
You can list i2c interfaces in /dev:
root@somlabs:~# ls /dev autofs loop3 ram13 tty10 tty31 tty52 vcs1 ... i2c-0 pps0 rtc tty22 tty43 tty7 vhci i2c-1 ptmx rtc0 tty23 tty44 tty8 video0 ... loop2 ram12 tty1 tty30 tty51 vcs
At this point you should connect something to your boards I2C interface, after you do it you can try to detect (i2cdetect parameter is I2C interface number):
root@somlabs:~# i2cdetect 1 WARNING! This program can confuse your I2C bus, cause data loss and worse! I will probe file /dev/i2c-1. I will probe address range 0x03-0x77. Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 6f 70: -- -- -- -- -- -- -- --
You can see that there are two devices detected, their addresses are 0x57 and 0x6f. In some cases you will see 'UU' instead of address in i2cdetect output, that means that device is used by some driver. In this case there is MCP78410 chip connected to I2C, it is RTC (0x6f) and EEPROM (0x57) in a single chip. The commands below will write EEPROM at address 0x00 and 0x01 and read back written values:
root@somlabs:~# i2cset -y 1 0x57 0x00 0x11 root@somlabs:~# i2cget -y 1 0x57 0x00 0x11 root@somlabs:~# i2cset -y 1 0x57 0x01 0x22 root@somlabs:~# i2cget -y 1 0x57 0x01 0x22
Using I2C interface in C program
Example below reads MCP78410 EEPROM at 0x00 address, increments read value, writes it back, all this happens in a loop.
#include <stdio.h> #include <linux/i2c-dev.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> void main() { char data; int fd = open("/dev/i2c-1", O_RDWR); ioctl(fd ,I2C_SLAVE, 0x57); while(1) { printf("Reading EEPROM data at 0x00.\n"); data = i2c_smbus_read_byte_data(fd, 0x0); printf("Value at 0x00 is %2x.\n", data); usleep(100000); printf("Writing incremented data to EEPROM.\n"); i2c_smbus_write_byte_data(fd, 0x0, ++data); usleep(100000); printf("Reading back incremented data.\n"); data = i2c_smbus_read_byte_data(fd, 0x0); printf("EEPROM at 0x00 value is %2x.\n\n", data); sleep(2); } }
Note that in real-life application you should check all I/O commands results to detect errors.