Temperature Sensing on the BR-6104K

all.jpg

Introduction

Recent changes in OpenWrt have seen the introduction of better support for i2c. It's no longer necessary to resort to custom kernel modules and custom userland programs to get up to 4 i2c busses on your BR-6104K(P) and use them in your projects. Here's what to do.

OpenWrt Configuration

When running 'make menuconfig' you will need to ensure you have selected the relevant modules. Your screen should look like this:

<*> kmod-i2c-core................................ I2C support
---   kmod-i2c-algo-bit........... I2C bit-banging interfaces
< >   kmod-i2c-algo-pca.............. I2C PCA 9564 interfaces
< >   kmod-i2c-algo-pcf.............. I2C PCF 8584 interfaces
---   kmod-i2c-gpio................ GPIO-based bitbanging I2C
<*>   kmod-i2c-gpio-custom...... Custom GPIO-based I2C device

You will find i2c-gpio and i2c-algo-bit get selected automatically when selecting the i2c-gpio-custom module.

Now run make, so that the kernel gets extracted and patched.

Kernel Configuration

You will need to decide which GPIO connections to use for your i2c port. The easiest to access are the LED connections. Now take a look at linux-2.6.23/include/asm/mach-adm5120/gpio.h. There are a series of #defines in this file giving the logical IO pins for the real IO pins. Make a note of the two numbers, and then run:

make kernel_menuconfig

Select the i2c-gpio-custom driver (all other required drivers will be included). Then append to the kernel command-line:

i2c-gpio-custom.bus0=0,<SDA>,<SCL>

Where <SDA> and <SCL> are the logical pins numbers from the header file.

An Example

led.jpg

I want to use the two LEDs in the corner of the board with the lower one (nearest the edge) as SDA, and the upper one as SCL. This is port 4, the lower LED is the 'LINK' LED, or P40, the upper one is the 'SPEED' LED, or P41, so looking at the header we have:

#define ADM5120_GPIO_P4L0       20
#define ADM5120_GPIO_P4L1       21

So my kernel command-line requires:

i2c-gpio-custom.bus0=0,20,21

Note: The 'DUPLEX' LED on my board (P42) is not readily available, but it may be on yours!

i2c Utilities

Presumably you will want to talk to the device(s) on your i2c bus from some kind of application or script.

When running 'make menuconfig' you should get an option under 'Utilities' in the menu for 'i2c-tools', which will create for you i2cget, i2cset and i2cdetect.

Example application

temp.jpg

I have wired up a TCN75 i2c temperature sensor to the Edimax. I used two 10k pull-up resistors for SDA and SCL. The circuit is very simple apart from the fact that TCN75 is only available in surface mount packaging. Yes, you can solder bell wire on the pins, perhaps I should create another page about how to do that - it took a few tries :). The TCN75 is setup for address b1001000. The upper 4 bits (1001) are fixed, and the pins 5,6 and 7 determine the lower 3 bits of the address.

i2cdetect is handy for finding the addresses of devices on the bus. I already know the address of my device but for the purpose of demonstration :-):

root@OpenWrt:/$ i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
root@OpenWrt:/$

Once the device is located, i2cget can get the temperature. This is achieved by a 16-bit read of the temperature register, which is unsurprisingly register '0'. The 'w' argument tells i2cget to read a 16-bit word:

root@OpenWrt:/$ i2cget 0 0x48 0 w
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-0, chip address 0x48, data address
0x00, using read word data.
Continue? [Y/n]
0x0016
root@OpenWrt:/$

...so that makes the temperature about 22 degrees.

The firmware that brings this all together can be found in the download section: http://sourceforge.net/project/showfiles.php?group_id=138655.