AHTI-II accelerometer

June 2012 - The ahti-ii accelerometer was a Nokia concept. The name was the code name that engineers gave to the concept. Over the years I renamed in many different ways because I was never satisfied with it. I called it at the begnning smida, etzkx but then I decided to leave the original name that came from Nokia. I guess no one would mind now.

The development itself follows the sensors development model of 2012 where the interface to the userspace was through input events. One day I will clean it up, update and upstream!


The etzkx accelerometer is an ultra low-power device based on a differential capacitance arising from acceleration-induced motion of the sensor element. The device has a dynamically user selectable sensitivity scale of ±2/±4/±6/±8g. Moreover the user has the possibility to select the sampling frequency (odr) from 3.125Hz to 1.6kHz.

This manual has been taken from etezian.org

Table of contents


Next: Device driver, Previous: Top, [Index]

1 Introduction

The etzkx accelerometer is an ultra low-power device based on a differential capacitance arising from acceleration-induced motion of the sensor element. The device has a dynamically user selectable sensitivity scale of ±2/±4/±6/±8g. Moreover the user has the possibility to select the sampling frequency (odr) from 3.125Hz to 1.6kHz.

The X, Y, Z coordinates are accessible by polling the device. Interrupt generation on data ready is also possible if preferred.

The device is capable of running two state machines for gesture recognition such as orientation change, shake, tap, etc. Two sets of registers are used to load the algorithms for the state machine.

The communication with the CPU is done via I2C bus. Two interrupt lines allow signalling the state machines behavior and possibly the presence of new data.

The device implements a hardware selftest functionality which allows testing of the reliability of the device.


Next: Self test, Previous: Introduction, [Index]

2 Device driver

The driver is located under

driver/misc/etzkx.c
include/linux/i2c/etzkx.h
	

and is placed in between the I2C driver and the userspace interfaces

+--------------+-------+------------------+
|              |       |                  |
| input device | sysfs | character device |
|              |       |                  |
+--------------+-------+------------------+
|                                         |
|                etzkx                    |
|                                         |
+-----------------------------------------+
|                                         |
|              I2C SMBUS                  |
|                                         |
+-----------------------------------------+
|                                         |
|              I2C xfer                   |
|                                         |
+-----------------------------------------+
|                                         |
|          KXCNL-1010/LIS3DSH             |
|                                         |
+-----------------------------------------+
	

In the menuconfig the driver is reachable

	Device Drivers  --->
	   [*] Misc devices  --->
	      <*>   ETZKX kxcnl 3d digital accelerometer
	

Next: Driver usage, Previous: Device driver, [Index]

2.1 Interfaces

The driver generates three types of interfaces:


Next: Input interfaces, Previous: Interfaces, [Index]

2.1.1 Sysfs interfaces

Follows a list of all the sysfs interfaces generated by the driver.

hwid (RO) - shows the chip installed on the board.

enable (RW) - enables/disables the streaming of X, Y, Z coordinates which are readable from the input event file 1 enables the the streaming 0 disables the streaming.

odr (RW) - sets the output data rate of the chip, i.e. sets the frequency of working of the chip. The available data rates are (in Hz) 3.125, 6.25, 12.5, 25, 50, 100, 400, 1600. It is possible to write a generic frequency and the driver will normalize it to the closest available. When a state machine is running the user is prevented form changing the odr.

delay (RW) - sets the driver polling rate in ms. Usually is


		  1
	delay = -----
		 odr
	

but depending of some state machine conditions, odr and delay might not be synchronized.

range (RW) - sets the sensitivity measured in g. The available g range are ±2g, ±4g, ±6g, ±8g. When a state machine is running, the user is prevented from changing the range.

self_test (RW) - enables/disables the self-test functionality. When the self_test is enabled the X, Y, Z axes are affected by an offset, that offset allows to evaluate the liability of the device (refer to the datasheets for the self test patterns) 1 enables self test 0 disables self test.

drv_version (RO) - shows the driver version.


Next: Character device, Previous: System interfaces, [Index]

2.1.2 Input interface

The input event is generated under /dev/input/eventX, where X is an incremental number chosen by the input driver framework.

To eventX file is associated the 'etzkx' name which is discoverable using an ioctl function with EVIOCGNAME flag.

	DIR *dir;
	struct dirent *de;
	char *fname;
	[...]

	dir = opendir("/dev/input");
	while ( (de = readdir(dir)) )
	{
		fd = open(de->d_name, O_RDONLY))
		ioctl(fd, EVIOCGNAME(sizeof(fname) - 1), &fname)

		if (!strcmp(fname, "etzkx"))
			/*** found it! ***/

		close (fd);
	}
	

The driver streams the coordinates every "delay" ms (or "odr" Hz) through this interface. The input driver sends a struct input_event to the interface buffer, which has the following structure:

	#include <linux/input.h>

	struct input_event {
		struct timeval time;
		__u16 type;
		__u16 code;
		__s32 value;
	};
	

where the type event is EV_ABS, the code of the event is ABS_X, ABS_Y, ABS_Z corresponding to the X, Y, Z coordiantes and in the end the value field is the specific coordinate value. The driver sends three different events for each coordinate followed by a synchronization event which has type=0, code=0 and value=0.

A possible reading algorithm can be

	while (1)
	{
		do {
			read(fd, &ev, sizeof(struct input_event));

			if (ev.type == EV_ABS)
				switch (ev.code) {
				case ABS_X:
					X = ev.value;
					break;
				case ABS_Y:
					Y = ev.value;
					break;
				case ABS_Z:
					Z = ev.value;
					break;
				}
		} while (ev.type != EV_SYN);
	}
	

Next: Driver usage, Previous: Input interfaces, [Index]

2.1.3 Character device

The character device is used to report to the userspace the running state machine's outcome. The interface is capable of polling so that it is possible to use select() or poll() on it. The character interface is generated as

	/dev/etzkx_stm
	

The driver communicates with userspace by writing 64 bit structure on the interface

32 algorithm id
32 specific algorithm data

Currently, three algorithms are implemented:

ID description specific data
ETZKX_STM_ID_TIMING timing algorithm used for testing. It sends an interrupt every 16 odr
0-31 not relevant, uninitialized
ETZKX_STM_ID_ORIENTATION sends an interrupt every orientation change (portrait or landscape)
0-15 1 if portrait, 0 otherwize
16-31 1 if landscape, 0 otherwize
ETZKX_STM_ID_DOUBLE_TAP sends an interrupt every time that a double tap is detected
0-7 1 if +x, 2 if -x, 0 otherwise
8-15 1 if +y, 2 if -y, 0 otherwise
16-23 1 if +z, 2 if -z, 0 otherwise
24-31 double tap peak

The /dev/etzkx_stm file is capable of ioctl with the following flags:

if no state machine is loaded, the id is equal to ETZKX_STM_ID_NO_STM.


Next: The source code, Previous: Interfaces, [Index]

2.2 Driver usage

The driver follows a state machine way of working and at any time it tracks the state which the driver is in.

etzkx operation state flow

Enable/disable streaming (STRM state):

	echo 1 > /sys/.../enable
	echo 0 > /sys/.../enable
	

Enable/disable state machine (STM1/STM2 state):

	ioctl (fd, ETZKXIO_ENABLE_ORIENTATION,  0);
	ioctl (fd, ETZKXIO_ENABLE_DOUBLE_TAP,   0);
	ioctl (fd, ETZKXIO_DISABLE_ORIENTATION, 0);
	ioctl (fd, ETZKXIO_DISABLE_DOUBLE_TAP,  0);
	

Next: Self test, Previous: Driver usage, [Index]

2.3 The source code

The source code is available via git on etezian.org:

	git clone git://git.etezian.org/etzkx.git
	

or you can download the tarball


Next: The device, Previous: Device driver, [Index]

3 Self test

The self test checks the electromechanical functionality of the sensor. The driver sets the self test state as a specific branch of the driver state machine:

Self test state machine

To enable/disable the self test

	echo 1 > /sys/.../self_test
	echo 0 > /sys/.../self_test
	

This applies an extra capacitance to every axes which adds an offset to the X, Y, Z output, it can be different for each coordinate.

The suppliers provides the minimum δx, δy, δz offset in order to consider the device reliable. The evaluation should be done like follows:

|Xst - X| > δX
|Yst - Y| > δY
|Zst - Z| > δZ

where Xst, Yst and Zst are the coordinates measured after applying the self test on the accelerometer.


Next: FOSDEM 2013, Previous: Self test, [Index]

4 The device

There are two companies who produce the etzkx accelerometer: Kionix and ST Microelectronics.

The devices are distributet respectively under the name of kxcnl-1010 and lis3dsh . While kxtnk-100 and lisn3dsh were two versions of them produced under Nokia instrucions.

The main difference between the two devices is that the ST version supports FIFO implemented on hardware for a lower overhead, while the Kionix one doesn't. Currently the device driver supports only the version without fifo provided by Kionix.

Other small differences may appear on the behavior. Indeed the lis3dsh is a bit more precise than kxcnl-1010, but the price to pay is a slightly higher power consumption (of the order or few μA).


Next: Bottom, Previous: The device, [Index]

5 FOSDEM 2013

FOSDEM

The etzkx accelerometer has been presented at FOSDEM 2013.

The slides of the presentation can be downloaded from here.


Home / Index / Top / Last: FOSDEM 2013

Andi Shyti
email: andi (at) smida (dot) it
IRC: cazzacarna