I2C Support on the Balloon Board

Introduction

The I2C bus is a simple 2-wire serial bus developed by Philips (see [Philips Semiconductors website | http://www.semiconductors.philips.com/markets/mms/protocols/i2c/]).

Balloon3

The pxa270 includes two I2C buses. One of these is used for power management on the board. The other is brought out for user control via the samtec and

It is exposed on the CUED IO board on the 9-pin D connection, and is taken to the PCF8574 to provide 8 channels of digital IO. A handy user-space library is provided to use it to drive things.

The i2C address space is fixed by soldered links so you need to avoid clashes with other devices when adding a new one. The address space is detailed [/hardware/300/balloon3_i2c_address_map.pdf | in this chart]

Balloon 2

There is no dedicated I2C hardware on the Balloon 2. However, two of the GPIO (General-Purpose I/O) lines on the board have been designated as I2C_DATA and I2C_CLOCK on the Balloon circuit diagrams and support for driving these lines as if they were an I2C master is provided in the Linux distributions available from [http://balloonboard.org/files/balloon2/205g/]

Hardware

CUED board

The CUED IO board provides many I2C options. The user i2c bus (i2c-1) is brought out on a 9-pin D and is also connected to two pcf8574s a pic and an analogue IO chip.

Balloon2 GPIOs

GPIO 11 is used for the SDA line (Serial DAta) and GPIO 20 is used for SCL (Serial CLock). These appear on the Samtek ExpansionConnector at E4 and E22 repectively.

http://www.balloonboard.org/hardware/205/con/samtek.jpg

Software

I2C Support Under Linux

Support for driving I2C bus masters is provided in the Linux 2.4 kernel. The Linux 2.6 kernel also has support reading the state of various devices that might be attached to the bus, and displaying them in /proc/bus/i2c.

I2C support is split between several modules:

i2c-core.o
Provides most generic I2C functionality
i2c-proc.o
Provides entries in /proc/bus/i2c for each I2C bus
i2c-dev.o
Provides user-space accesible device files for each bus in /dev

There are also modules that talk to specific hardware. These are split into algorithms and adapters. An Algorithm modules provides the code necessary for a specific type of hardware to produce I2C protocol compatible messages, and an Adapter modules knows how to talk to a specific peice of hardware.

Balloon 3

On balloon3 you should load:

i2c-pxa
Provides board-specific support and brings in core modules
i2c-dev
Provides /dev filesystem entries so you can read/write devices

If you want to talk to the pcf8754 in a convenient way you need to:

modprobe pcf8574

which will provide /sys/bus/i2c/device/0-0038/write (and corresponding read) files where you can read or write the status of all 8 IO lines.

Balloon 2

On the Balloon2 Board the two modules used are:

i2c-algo-bit.o

The bit-bashing algoroitm

l3-bit-sa1100.o
Manipulates the GPIO lines on the Balloon

The i2c-algo-bit.o module contains code that allows any two available wires to used as an I2C bus. The only Balloon-specific code is in l3-bit-sa1100.o. This provides get and set function for the SDA and SCL GPIO lines, and registers itself as an adapter provider with i2c-algo-bit.o.

Using i2c

You can use i2c at a very low level, or use device-specific drivers and interact with them at a higher level. The combination of multiple modules, 2 different buses, 2 different address nomenclatures and the ability to interact at the bus level via /dev or via a device driver via /sys allows for plenty of confusion. Hopefully the below will help.

i2cdump in the i2c-tools package (or in lm-sensors package on lenny-vintage distros) is handy for examing the bus at a low level and seeing what hardware is present.

i2c addressing is confusing because it is 8-bit but the bottom bit is the r/w bit so addresses can be written with/without this bit. The [/hardware/300/balloon3_i2c_address_map.pdf | i2C chart PDF linked above] used the 8-bit adresses, as does the kernel, whilst the i2cdump tools use the 7-bit adresses (how helpful!). To add to the confusion the PCF8574 shown on that chart at 0x40, actually appears in /sys/bus/i2c/devices/0-0038. (i.e at 0x38 (8-bit address))

The two I2C buses are 0 and 1. Bus 0 (/dev/i2c-0) is the general purpose bus. Bus 1 (/dev/i2c-1) is the power bus.

So to read the device at 0x38 on the general purpose bus do i2cdump 0 0x1C (0x38 is the 8-bit address, 0x1C is the same 7-bit address)

You could send commands in this way to get the device to change IO lines, but it's much easier to load the pcf8574 module and access it via /sys.

Balloon2 driver issues

Most of the code for I2C support is in the <kernel>/drivers/i2c directory, but the Balloon-specific code - l3-bit-sa1100.c is in the <kernel>/drivers/l3 directory. This file actually provides a combined l3 and I2C adapter, but only if I2C support is compiled into the kernel statically. This is because the I2C-specific code is wrapped in a #ifdef CONFIG_I2C_BIT_SA1100_GPIO / #endif block.

With the 2.4.25-vrs2-tcl1 kernel, L3 support must built into the kernel statically, rather than as a module.

There is also a bug in the code (now fixed in the 2.4.25-vrs2-tcl1 distribution but still in 2.6.8.1-tcl1 and in CVS at time of writing):

static void i2c_setscl(void *data, int state)
{
        struct bit_data *bits = data;
        unsigned long flags;
        local_irq_save(flags);

#if defined(CONFIG_SA1100_BALLOON)
        if (state)
                balloon_in_dir(BALLOON_I2C_''DATA'');
        else {
                balloon_clear(BALLOON_I2C_''DATA'');%%%
                balloon_out_dir(BALLOON_I2C_''DATA'');
        }
#else
        if (state)
                GPDR &= ~bits->scl;
        else {
                GPCR = bits->scl;%%%
                GPDR |= bits->scl;
        }
#endif
        local_irq_restore(flags);
}

The above function is to set SCL - the I2C clock line, but (on the Balloon) this function sets the data line. The references to BALLOON_I2C_DATA need to be changed to BALLOON_I2C_CLOCK.

Balloonboard: BalloonI2C (last edited 2012-06-20 22:50:47 by wookey)