For the RoadRunner SOM (SAMA5D27) please read this article.
This is the list of I2C ports implemented in hardware. Any other GPIO pin can be used as I2C in bitbanging mode.
Signal | Dir | Description | Acqua | Aria G25 | Arietta |
---|---|---|---|---|---|
TWD0 | I/O | Serial data | J3.42 (PA30) | W17 (PA30) | J4.14 (PA30) |
TWCK0 | O | Clock | J3.41 (PA31) | W18 (PA31) | J4.12 (PA31) |
TWD1 | I/O | Serial data | J3.26 (PC26) | N2 (PC0) | J4.39 (PC0) |
TWCK1 | O | Clock | J3.28 (PA27) | N3 (PC1) | J4.37 (PC1) |
TWD2 | I/O | Serial data | J3.36 (PA18) | ||
TWCK2 | O | Clock | J3.41 (PA31) |
Probably the Kernel used on your Acme Board is already configured to have the I2C bus enabled. To check it just type:
ls /dev/i2c*
/dev/i2c-0 /dev/i2c-1
in this case two busses are already configured on your board. To know on which pins are available the I2C signals, read the pinout section of this page.
However if no device is present you have to check the Kernel drivers setup and the device tree contents.
Follow this tutorial: to know how to cross compile the Linux Kernel and how to configure the drivers to enable inside it.
Inside the make menuconfig enable the following items:
Device drivers --->
I2C support --->
<*> I2C support
[*] Enable compatibility bits for old user-space
<*> I2C device interface
<*> I2C bus multiplexing support
Multiplexer I2C Chip support --->
[*] Autoselect pertinent helper modules
I2C Hardware Bus support --->
<*> Atmel AT91 I2C Two-Wire interface (TWI)
<*> GPIO-based bitbanging I2C
then compile the Kernel image, save it on the microsd and reboot.
The faster way to do the first experiments with this board is by installing and using the i2c-tools.
i2c-tools is a package contains a heterogeneous set of I2C tools for Linux such as:
To install i2c-tools on the FOX Board just type:
sudo apt update
sudo apt install i2c-tools
i2cdetect is an userspace program to scan an I2C bus for devices. It outputs a table class='acmetable' with the list of detected devices on the specified bus.
Example of use:
sudo i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
In this case a device has been detected on address 20 hex.
i2cset is a small helper program to set registers visible through the I2C bus.
The follow simple command writes the byte value 255 to the I2C device at address 20 hex on the i2c bus 0 (/dev/i2c-0).
sudo i2cset -y 0 0x20 255
If for example you are using a DAISY-22 module with a PCF8574 I2C I/O expander this command will set all the GPIO lines to 1.
i2cget i2cget is a small helper program to read registers visible through the I2C bus.
The follow simple command read a byte from an I2C device at address 20 hex on the i2c bus 0 (/dev/i2c-0).
sudo i2cget -y 0 0x20 0x01
python-smbus is a Python module allows SMBus access through the I2C /dev interface on Linux hosts. The host kernel must have I2C support, I2C device interface support, and a bus adapter driver.
The following example sends a sequence of values from 0 to 255 to the PCF8574 I2C I/O expander at address 0x20.
This example will be available as soon as possible
Run it by typing:
python write.py
The following read the GPIO status of a PCF8574 I2C I/O expander at address 0x20. Note that we have to write 1 on the input line we want to read.
import smbus
I2C_ADDRESS = 0x20
bus = smbus.SMBus(0)
#Set all ports in input mode
bus.write_byte(I2C_ADDRESS,0xFF)
#Read all the unput lines
value=bus.read_byte(I2C_ADDRESS)
print "%02X" % value
Run it by typing:
python read.py
The following example sends a sequence of values from 0 to 255 to the PCF8574 I2C I/O expander at address 0x20 in C language.
#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define I2C_ADDR 0x20
int main (void) {
int value;
int fd;
fd = open("/dev/i2c-0", O_RDWR);
if (fd < 0) {
printf("Error opening file: %s\n", strerror(errno));
return 1;
}
if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0) {
printf("ioctl error: %s\n", strerror(errno));
return 1;
}
for (value=0; value<=255; value++) {
if (write(fd, &value, 1) != 1) {
printf("Error writing file: %s\n", strerror(errno));
}
usleep(100000);
}
return 0;
}
Compile it by typing:
gcc write.c -o write
Then launch it:
./write
The following example get the state of the GPIO line from a PCF8574 I2C I/O expander at address 0x20.
#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define I2C_ADDR 0x20
int main (void) {
char buffer[1];
int fd;
fd = open("/dev/i2c-0", O_RDWR);
if (fd < 0) {
printf("Error opening file: %s\n", strerror(errno));
return 1;
}
if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0) {
printf("ioctl error: %s\n", strerror(errno));
return 1;
}
buffer[0]=0xFF;
write(fd, buffer, 1);
read(fd, buffer, 1);
printf("0x%02X\n", buffer[0]);
return 0;
}
Compile it by typing:
gcc read.c -o read
Then launch it:
./read