Keywords

These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

There are some interesting serial communications technologies for adding peripheral devices. The I2C bus interface is one of the most capable, and there are many sensors and other devices that you can control and monitor with it. This chapter explores the Inter-Integrated Circuit (I2C) support in the ARTIK and extends the published coverage of it to show you the inner workings.

What Is I2C?

The Inter-Integrated Circuit (I2C) standard was designed to simplify communications between individual chips in highly integrated hardware designs. The original concept and design was by Philips Semiconductor, now known as NXP.

The documentation describes the nodes on an I2C bus as devices but sometimes calls them chips. It makes sense to describe them as devices from a software point of view, but when discussing the hardware, they can be described as chips.

The I2C bus is used inside the ARTIK module for the ARM CPU to talk with the peripheral chips that support the hardware I/O. Some of those chips are implemented on the developer reference board. The taxonomy of the I2C architecture (as found in a Commercial Beta ARTIK 5) is shown in Figure 20-1. This illustrates how the various parts of an I2C implementation relate to one another.

Figure 20-1.
figure 1

Taxonomy of an I2C interface

The top level I2C device driver owns the whole hierarchy. Within it are a number of separate I2C buses. Each of them has an SCL and SDA pinout from the ARTIK module. Within each bus is a sparsely populated 7-bit address space with devices mapped to the addresses. Usually only a few devices are allocated per bus because the hardware chips themselves only have a limited number of address pins. A chip with only three pins can only exist at one of eight possible addresses. Within each device, the data registers are accessible within an 8-bit range. The lowest numbered register is 0x00 and the highest is 0xFF.

Use the i2cdetect command to see the chips mapped onto a bus as I2C devices. The i2cget command yields the value of a register and the i2cset command sets it to a new value.

Read these online resources for more in depth information about the I2C bus and how it works:

https://en.wikipedia.org/wiki/NXP_Semiconductors

https://en.wikipedia.org/wiki/I2C

www.kernel.org/doc/Documentation/i2c/instantiating-devices

The data sheets for the model 520 and 1020 ARTIK modules have a lot of detailed specifications of the I2C timings and levels that is useful to know when you drive them from your own applications.

How Does I2C Work?

The I2C communications are designed to support multiple master nodes connected to a single bus. They automatically sense each other’s activity and avoid collisions when they all contend for access at the same time. Multiple slave destinations are supported so a single master can dispatch a message to multiple destinations in one transaction. The bus carries a serial data stream, which reduces the number of wires needed to implement the functionality. Figure 20-2 shows a simplified view of how the bus is implemented.

Figure 20-2.
figure 2

I2C bus layout

There are two wires in the I2C bus, both pulled up to the power supply voltage rail which makes them HIGH by default, so to assert a LOW value, the I2C master device needs to drive them to an active-low state.

The Serial Data Line (SDA) carries the information and the Serial Clock Line (SCL) tells the slave devices when it is safe to read it. The I2C master pulls the SCL bus line down while it asserts a value on the SDA bus line. Then the SCL is raised, telling the slaves to collect the data bit that has just been transmitted. The data is mapped to a 7-bit or 10-bit address space of the design. The ARTIK modules use a 7-bit addressing scheme, which allows for 128 distinct chip addresses in the range 0x00 to 0x7F. Typical bus data transfers can take place at 100 Kbits per second in standard mode. Alternatively, a slower 10 Kbits per second data rate can be used to economize the power consumption. The bus can operate at arbitrarily slow speeds, and recent innovations have raised the upper speed limit and allowed for larger address space when I2C is used in an embedded design such as the ARTIK. These performance improvements are possible because the tightly integrated design of embedded systems keeps the signal paths short.

The master node generates the clock signals on the SCL line and initiates the communication. The slave nodes listen for clock signals and respond when addressed by the master. Multiple master nodes can be present and the nodes can change their role from master to slave and back again as determined by the engineering design of the system. Each kind of node can be in transmit or receive mode. See Table 20-1.

Table 20-1. I2C Node Types and Modes of Operation

Messages are transmitted on the bus by sending the most significant bits first. These are framed by start and stop bits. A start bit is indicated by holding the SCL line HIGH and transitioning SDA from HIGH to LOW. See Figure 20-3.

Figure 20-3.
figure 3

I2C start bit indication

At the end of a message, a stop bit is signified in a similar way but with an SDA transition from LOW to HIGH. All other transitions of SDA that carry serial data happen while SCL is held LOW. See Figure 20-4.

Figure 20-4.
figure 4

I2C stop bit indication

Initially, a master node is in transmit mode and initiates transactions with the slaves when it chooses to. After sending a start bit, the master transmits the target address value of the slave it wants to communicate with. A final bit to indicate whether it wants to write (0) to the slave or read (1) data from it is followed by a stop bit. The write is signified by a 0 value bit and a read by a 1 value bit. See Figure 20-5 for an illustration of the relative timings between SDA and SCL.

Figure 20-5.
figure 5

I2C bus timings

  • Data transfer is initiated with a Start bit signaled by SDA being pulled LOW while SCL stays HIGH.

  • SDA sets the first data bit level while keeping SCL LOW.

  • The data is sampled when SCL rises to a HIGH value for Bit 1.

  • This process repeats: SDA transitioning while SCL is LOW, and the data being read while SCL is HIGH (Bit 2 to Bit n).

  • A Stop bit is signaled when SDA is pulled HIGH while SCL is HIGH.

Because these are electrical signals, they may take a finite time to transition from low to high or vice versa. The voltage change vs. the time it takes is called the slewing rate. The longer the bus line, the lower the slewing rate and consequently the slower the bus must operate. To avoid inadvertent value detection, SDA is changed on the SCL falling edge and is sampled and captured on the rising edge of SCL.

Because the protocol is single-ended, it is possible to send out messages that do not correspond to any slaves on the bus. If there is a matching slave, it responds to the message with an ACK signal. The master knows that a slave is present and, depending on whether a read or write is indicated in the initial message, the two nodes communicate. If the master indicates it wants to read data, the slave transmits information while the master listens. Alternatively, if the master wants to write to the slave, it transmits the message while the slave receives the incoming data.

The handshaking happens as each byte is completed. The receiving node transmits an ACK signal to indicate that it received the data. If necessary, the master can assert its authority and send another start bit to seize control of the bus when it wants to interrupt the proceedings. Slave devices can hold the SCL line down to indicate they are busy and cannot yet receive more data. This is called clock stretching.

If there are multiple masters, they will not interrupt one another’s transactions while they are engaged in communicating with a slave. It is possible for two masters to initiate a new transaction at the same time. Such collisions are arbitrated automatically by the master nodes detecting that the SDA line has changed state from what it expects as a consequence of another master asserting a value on it. The first master to detect that the SDA does not have the value it expects to see relinquishes control and waits until it sees a Stop bit before attempting to transmit again.

Read the I2C Wikipedia article to find out more about the finer points of this communication protocol: https://en.wikipedia.org/wiki/I2C . There is a pseudo code example of how to program I2C communications.

I2C on the ARTIK Modules

The data sheets for the model 520 and 1020 ARTIK modules and the Type 5/10 developer reference board schematics have a lot of detailed specifications on the I2C timings and voltage levels. There is some variance in the naming conventions. Study both together very carefully to deduce what I2C bus connections are available.

The ARTIK 10 supports four high-speed I2C buses and four conventional I2C buses internally but not all of these are brought to the outside world via the AXT connectors. Some of them are used for internal control of chips on the ARTIK modules. The ARTIK 5 supports six conventional I2C buses and one additional I2C bus dedicated for use as a camera control interface.

Tables 20-2 and 20-3 list the I2C interfaces for each of the ARTIK 5 and 10 modules based on what is documented in the data sheets and schematic diagrams. The i2cdetect command line tool tells a slightly different story and lists an I2C-0 bus on an ARTIK 5, which is not described in the data sheets or schematics.

Table 20-2. ARTIK I2C Bus Connections
Table 20-3. ARTIK 10 I2C Bus Connections

I2C Tools

There is a small suite of I2C utilities provided with the ARTIK OS by default. They make it very easy to interact with the I2C bus from the bash command line.

i2cdetect: Probes an I2C bus and lists the devices (chips)

i2cget: Gets a register value from an I2C device

i2cset: Sets a register value in an I2C device

i2cdump: Dumps all registers from a I2C device

Read the manual pages about these tools from your bash command line with the man command.

The Device Detector Tool (i2cdetect)

Use the i2cdetect tool to detect devices on your I2C buses. The simplest variant of this command lists the active I2C buses on your system. Listing 20-1 illustrates how i2cdetect works.

Listing 20-1. Using the i2cdetect Tool on an ARTIK 5

i2cdetect -l i2c-0  i2c s3c2410-i2c I2C adapter i2c-1  i2c s3c2410-i2c I2C adapter i2c-3  i2c s3c2410-i2c I2C adapter i2c-7  i2c s3c2410-i2c I2C adapter

A variation of the i2cdetect command lists the functionalities supported on each bus. The example in Listing 20-2 examines bus I2C-0 and displays the current disposition.

Listing 20-2. Using the i2cdetect Tool to Display a Bus

i2cdetect -F 0 Functionalities implemented by /dev/i2c-0: I2C                              yes SMBus Quick Command              yes SMBus Send Byte                  yes SMBus Receive Byte               yes SMBus Write Byte                 yes SMBus Read Byte                  yes SMBus Write Word                 yes SMBus Read Word                  yes SMBus Process Call               yes SMBus Block Write                yes SMBus Block Read                 no SMBus Block Process Call         no SMBus PEC                        yes I2C Block Write                  yes I2C Block Read                   yes

The third variant of the i2cdetect command scans the named bus for devices and if they are correctly addressed and powered up, they are displayed in a 16 x 16 address grid. The example command in Listing 20-3 scans bus I2C-0 for recognizable devices. The two devices are indicated by the UU symbols at addresses 0x06 and 0x66.

Listing 20-3. Listing the Devices on an I2C Bus

i2cdetect -y 0      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f 00:          -- -- -- UU -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- UU -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

The Value Reading Tool (i2cget)

The i2cget tool reads the values of registers in devices that are visible on the I2C bus. Specify a valid bus number, chip address, and register index with the command. An optional mode parameter can be added to alter the way that i2cget operates on the data it accesses. The basic i2cget command format is

i2cget {bus_number} {chip_address} {data_register}

Download and read the data sheet for any sensors you are adding to your ARTIK. Somewhere in that data sheet is a list of registers and their values. Look for manufacturer ID codes and test that you get the correct value back for them. This assures you that the sensor chip is working.

The following command reads the byte value from the embedded PMIC (S2MPS14) ID register of the ARTIK 5 at register number 0x00 of chip address 0x66 on bus I2C-0:

i2cget -f -y 0 0x66 0x0

The Value Setting Tool (i2cset)

The i2cset tool writes values to the registers that are visible on the I2C bus. Specify one of the valid bus numbers, chip addresses, and registers with this command. The command format is

i2cset {bus_number} {chip_address} {data_register} {value} ...

A single value can be written or multiple values in a sequence. An optional mode parameter can be added to alter the way that i2cset operates on the data it accesses. Additionally, the -m option flag indicates a protective mask, which can be applied to the write so the tool internally performs a Read ➤ Modify ➤ Write operation.

Download and read the data sheet for any sensors you are adding to your ARTIK. Somewhere in that data sheet is a list of registers and their values. Look for manufacturer ID codes and test that you get the correct value back for them. This reassures you that the sensor chip is working. Then you can write values to it.

The following command writes a zero value to an imaginary location at register number 0x10 of chip address 0x50 on bus I2C-0:

i2cset -f -y 0 0x50 0x10 0x00

The Register Dump Tool (i2cdump)

The i2cdump tool displays all of the registers belonging to a chip address on an IC bus. The example command in Listing 20-4 forces the i2cdump command to display all 256 registers on chip address 0x06 of bus I2C-0. This is mapped to the dummy device.

Listing 20-4. Example i2cdump Tool Usage

i2cdump -y -f 0 0x06 No size specified (using byte-data access)      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef 00: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? 10: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ 20: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? 30: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ 40: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? 50: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ 60: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? 70: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ 80: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? 90: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ a0: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? b0: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ c0: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? d0: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........ e0: 02 c3 00 f8 2e 2c 4c 20 0a 06 10 00 00 0c 01 01    ??.?.,L ???..??? f0: 01 00 00 00 0c 01 01 01 00 00 00 00 00 00 00 00    ?...????........

Accessing I2C via sysfs

The Samsung documentation states that the I2C bus cannot be accessed via the sysfs virtual file system in the same way that user space applications could use it to control GPIO pins. Nevertheless, many of the properties of the I2C bus structures can be inspected by exploring the sysfs directories. Use the Samsung recommended tools to set or get I2C values. You will learn a lot more about I2C by inspecting the values that the kernel reflects into sysfs.

There are a lot of useful locations within the /sys virtual file system. Others are located in the /proc virtual file system. Knowing where they are suggests how to build dynamic self-configuring applications that are resilient to OS upgrades, which is when base addresses are likely to move.

According to the kernel documentation, it is possible to add or delete devices from an I2C bus using sysfs file locations. This is covered shortly under the heading of “Instantiating and Removing Devices.”

I2C Device Nodes

Listing the /sys/bus/i2c/devices directory in the Commercial Beta ARTIK 5 module reveals the currently active I2C devices within each bus system. The built-in chips are accessed within a 7-bit address space. The addresses can range from 0x00 to 0x7F. They are summarized in Table 20-4. Other devices may be visible when you add your own peripherals and sensors or check out this directory on an ARTIK 10 module.

Table 20-4. I2c Device Nodes

I2C Containers and Properties

Each I2C bus is represented in the sysfs virtual file system by a container or object. The properties of that object provide some limited capabilities for interacting with the bus. Look inside the directory to view the properties for one of the bus containers. All the other usual kernel-provided properties are present, such as name, power, and uevent. Table 20-5 enumerates the properties displayed by this command:

Table 20-5. I2C Object Properties

ls -la /sys/bus/i2c/devices/i2c-3/

Built-in Drivers

The /sys/bus/i2c/drivers directory reveals drivers for very specific built-in hardware chips. Use these device part numbers in a web search engine to find data sheets and other resources for them. On an ARTIK, this reveals that the AK4953 device driver is for a hardware-implemented stereo audio codec. Searching for that chip online reveals a data sheet with much useful information about how it works. Refer to Chapter 22 where that codec chip and other audio-related topics are discussed.

Inside the device driver directories are properties that reveal which I2C bus is used and the chip address. Although this is undocumented material, the address can be deduced by a process of inspection. The Commercial Beta ARTIK 5 reveals the devices listed in Table 20-6.

Table 20-6. Built-in I2C Devices

The battery charger is listed as a device but is not allocated an address because it is not plugged in. An address is reserved for it to use when it comes online.

Instantiating and Removing Devices

If you add new external I2C-compatible chips to your ARTIK, tell the ARTIK about them so it can communicate with them. This kernel reference document shows how to instantiate new devices in several different ways: www.kernel.org/doc/Documentation/i2c/instantiating-devices .

Instantiate a new device from user space with this command line instruction:

echo test_device 0x50 > /sys/bus/i2c/devices/i2c-3/new_device

The example creates a new device on bus I2C-3 at address 0x50 with a symbolic name of test_device and it manufactures a new container for the device. Verify that it exists with this command, which shows you that a new directory named 3-0050 has been created:

ls -la /sys/bus/i2c/devices/i2c-3/

For this to be useful there must be some hardware connected to the specified bus. This hardware must also have its address configured to match the address you just used to create the device. If that hardware is not present, then this address will not show up as being activated with the i2cdetect command. If there is a directory present for the device but i2cdetect does not show it as active, perhaps you connected your hardware to the wrong address, or accidentally switched the SDA and SCL connections round or perhaps the device is broken or unpowered. Learning about diagnostic techniques is a useful skill to have at your disposal. Remove the device again later with this command:

echo 0x50 > /sys/bus/i2c/devices/i2c-3/delete_device

An error message is presented if the device does not exist. This may indicate you typed the device address incorrectly or chose the wrong bus.

Access I2C from the C Language

The i2ctools are a useful command line solution to access the I2C bus from the bash shell and they simplify things a lot. You can learn how to access the I2C bus from the C language by inspecting the source code for the i2ctools. Make a copy of the open source files, and dismantle the i2cget and i2cset tools to find out how to read and write directly to the I2C bus architecture inside the kernel via the ioctl() function.

This approach works by opening files in the /dev/i2c file system tree. The i2ctools package all this accessibility into a couple of useful files with useful functions. Download the i2ctools package from https://fossies.org/dox/i2c-tools-3.1.2/index.html .

Here is another set of source code archives that contains older versions for comparison: http://i2c-tools.sourcearchive.com .

Breakout Connections

Tables 20-7 and 20-8 list the I2C interfaces that are presented via breakout connectors on the developer reference boards for the ARTIK 5 and 10 modules based on what is documented in the data sheets and schematic diagrams.

Table 20-7. ARTIK 5 - I2C Bus Breakout Connections
Table 20-8. ARTIK 10 - I2C Bus Breakout Connections

The so-called boot mode switch on the developer reference board (SW2-2) appears to be dedicated to enabling a voltage level convertor that couples the internal bus I2C-3 SDA/SCL lines coming out of the ARTIK 5 to the SDA/SCL lines on the J510 external connector where a higher voltage is needed. When SW2-2 is on, the I2C signals are enabled on J510; otherwise they are not driven.

I2C-Related AXT Connectors

Tables 20-9 and 20-10 summarize the I2C-related connections available on the AXT connectors underneath your ARTIK module. The connections for the ARTIK 5 and 10 are each shown in their own tables. Refer to the data sheets for more information about voltage levels and other detailed specifications regarding these pins.

Table 20-9. ARTIK 5 - I2C AXT Pinouts
Table 20-10. ARTIK 10 - I2C AXT Pinouts

In addition to the SDA and SCL lines for each I2C bus, there are two pins that can control the voltage level for the SDA and SCL lines. Refer to the data for more details about this. The pins are summarized in Table 20-11.

Table 20-11. ARTIK 10 - I2C Management and Control

Summary

The I2C bus control of peripheral sensor devices rounds out your interfacing skills very usefully. Now you can interact with some very powerful chips. You may only want to read a temperature value, but you now have all the controls at your disposal to manage complex chips. You only need to add the SPI and I2S buses to have all peripheral interconnect and control options covered.