This is an old revision of the document!
The ADXL345 is a small, thin, ultra low power, 3-axis accelerometer with high resolution (13-bit) measurement up to ±16 g. Digital output data is formatted as 16-bit twos complement and is accessible through either a SPI (3- or 4- wire) or I2C digital interface.
The ADXL345 is well suited for mobile device applications. It measures the static acceleration of gravity in tilt-sensing applications, as well as dynamic acceleration resulting from motion or shock. Its high resolution (4mg/LSB) enables resolution of inclination changes of as little as 0.25°.
Several special sensing functions are provided. Activity and inactivity sensing detect the presence or lack of motion and if the acceleration on any axis exceeds a user-set level. Tap sensing detects single and double taps. Free-Fall sensing detects if the device is falling. These functions can be mapped to interrupt output pins. An integrated 32 level FIFO can be used to store data to minimize host processor intervention.
Low power modes enable intelligent motion-based power management with threshold sensing and active acceleration measurement at extremely low power dissipation.
ADXL345 - Small, Ultra Low Power, 3-Axis, ±2/4/8/16g Digital Accelerometer
ADXL346 - Ultra Low Power, Three-Axis, +-2/4/8/16g Digital Accelerometer
ADXL345/346:
ADXL346:
Selectable ADXL34X I2C Device Address:
SDO | I2C Address |
---|---|
0 | 0x53 |
1 | 0x1D |
ADXL345/346:
ADXL346:
Function | File |
---|---|
driver | drivers/input/misc/adxl34x.c |
i2c bus support | drivers/input/misc/adxl34x-i2c.c |
spi bus support | drivers/input/misc/adxl34x-spi.c |
include | include/linux/input/adxl34x.h |
Starting with linux-2.6.36 the ADXL34x driver is mainlined. If you are using an pre linux-2.6.36 kernel get the source from our repositories and add them to your kernel tree.
If you are using a kernel version without the threaded irq capabilities (< 2.6.30) get there driver from here:
For the latest version of checkout the Files section of this document.
Add following lines to linux-2.6.x/drivers/input/misc/Kconfig:
config INPUT_ADXL34X tristate "Analog Devices ADXL34x Three-Axis Digital Accelerometer" default n help Say Y here if you have a Accelerometer interface using the ADXL345/6 controller, and your board-specific initialization code includes that in its table of devices. This driver can use either I2C or SPI communication to the ADXL345/6 controller. Select the appropriate method for your system. If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the module will be called adxl34x. config INPUT_ADXL34X_I2C tristate "support I2C bus connection" depends on INPUT_ADXL34X && I2C default y help Say Y here if you have ADXL345/6 hooked to an I2C bus. To compile this driver as a module, choose M here: the module will be called adxl34x-i2c. config INPUT_ADXL34X_SPI tristate "support SPI bus connection" depends on INPUT_ADXL34X && SPI default y help Say Y here if you have ADXL345/6 hooked to a SPI bus. To compile this driver as a module, choose M here: the module will be called adxl34x-spi.
Add following lines to linux-2.6.x/drivers/input/misc/Makefile:
obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o
For compile time configuration, it’s common Linux practice to keep board- and application-specific configuration out of the main driver file, instead putting it into the board support file.
For devices on custom boards, as typical of embedded and SoC-(system-on-chip) based hardware, Linux uses platform_data to point to board-specific structures describing devices and how they are connected to the SoC. This can include available ports, chip variants, preferred modes, default initialization, additional pin roles, and so on. This shrinks the board-support packages (BSPs) and minimizes board and application specific #ifdefs in drivers.
Digital Accelerometer characteristics are highly application specific and may vary between boards and models. The platform_data for the device's “struct device” holds this information.
<source trunk/include/linux/input/adxl34x.h c linux-kernel>
Unlike PCI or USB devices, SPI devices are not enumerated at the hardware level. Instead, the software must know which devices are connected on each SPI bus segment, and what slave selects these devices are using. For this reason, the kernel code must instantiate SPI devices explicitly. The most common method is to declare the SPI devices by bus number.
This method is appropriate when the SPI bus is a system bus, as in many embedded systems, wherein each SPI bus has a number which is known in advance. It is thus possible to pre-declare the SPI devices that inhabit this bus. This is done with an array of struct spi_board_info, which is registered by calling spi_register_board_info().
For more information see: Documentation/spi/spi-summary.rst
These snippets are all from the same file. arch/blackfin/mach-bf548/boards/ezkit.c
:
#include <linux/spi/adxl34x.h>
<source trunk/arch/blackfin/mach-bf548/boards/ezkit.c:adxl34x_info{} c linux-kernel> <source trunk/arch/blackfin/mach-bf548/boards/ezkit.c:spi_adxl34x_chip_info{} c linux-kernel> <source trunk/arch/blackfin/mach-bf548/boards/ezkit.c:bfin_spi_board_info[] c linux-kernel>
Unlike PCI or USB devices, I2C devices are not enumerated at the hardware level. Instead, the software must know which devices are connected on each I2C bus segment, and what address these devices are using. For this reason, the kernel code must instantiate I2C devices explicitly. There are different ways to achieve this, depending on the context and requirements. However the most common method is to declare the I2C devices by bus number.
This method is appropriate when the I2C bus is a system bus, as in many embedded systems, wherein each I2C bus has a number which is known in advance. It is thus possible to pre-declare the I2C devices that inhabit this bus. This is done with an array of struct i2c_board_info, which is registered by calling i2c_register_board_info().
So, to enable such a driver one need only edit the board support file by adding an appropriate entry to i2c_board_info.
For more information see: Documentation/i2c/instantiating-devices.rst
These snippets are all from the same file. arch/blackfin/mach-bf548/boards/ezkit.c
:
<source trunk/arch/blackfin/mach-bf548/boards/ezkit.c:adxl34x_info{} c linux-kernel> <source trunk/arch/blackfin/mach-bf548/boards/ezkit.c:bfin_i2c_board_info1[] c linux-kernel>
Configure kernel with “make menuconfig” (alternatively use “make xconfig” or “make qconfig”)
Input device support -*- Generic input layer (needed for keyboard, mouse, ...) < > Support for memoryless force-feedback devices < > Polled input device skeleton < > Sparse keymap support library *** Userland interfaces *** < > Mouse interface < > Joystick interface <*> Event interface < > Event debugging *** Input Device Drivers *** [ ] Keyboards ---> [ ] Mice ---> [ ] Joysticks/Gamepads ---> [ ] Tablets ---> [ ] Touchscreens ---> [*] Miscellaneous devices ---> < > Analog Devices AD714x Capacitance Touch Sensor <*> Analog Devices ADXL34x Three-Axis Digital Accelerometer <*> support I2C bus connection (NEW) <*> support SPI bus connection (NEW) Hardware I/O ports --->
I2C Interface:
root:~> modprobe evdev root:~> modprobe adxl34x input: ADXL34x accelerometer as /devices/platform/i2c-bfin-twi.1/i2c-adapter/i2c-1/1-0053/input/input1 adxl34x 1-0053: ADXL345 accelerometer, irq 140
SPI Interface:
root:~> modprobe evdev root:~> modprobe adxl34x input: ADXL34x accelerometer as /devices/platform/bfin-spi.1/spi1.2/input/input1 adxl34x spi1.2: ADXL345 accelerometer, irq 140
Your kernel startup messages should include something like this
I2C Interface:
input: ADXL34x accelerometer as /devices/platform/i2c-bfin-twi.1/i2c-adapter/i2c-1/1-0053/input/input1 adxl34x 1-0053: ADXL345 accelerometer, irq 140
SPI Interface:
input: ADXL34x accelerometer as /devices/platform/bfin-spi.1/spi1.2/input/input1 adxl34x spi1.2: ADXL345 accelerometer, irq 140
In case you see a message like this
adxl34x spi1.2: Failed to probe ADXL34x accelerometer
This means that the SPI communication and initilaization with the ADXL34x failed. check bus_num and chip_select in your platform device file
After the kernel boot your device folder should include at least one device node for the accelerometer
root:/> ls -al /dev/input/ drw-r--r-- 2 root root 0 Jan 1 00:03 . drwxr-xr-x 5 root root 0 Jan 1 00:03 .. crw-rw-r-- 1 root root 13, 64 Jan 1 00:03 event0 crw-rw-r-- 1 root root 13, 65 Jan 1 00:03 event1 root:/>
Check that the interrupt is registered.
root:~> cat /proc/interrupts | grep adxl34x 140: 0 adxl34x
root:~> cat /sys/class/input/input1/name ADXL34x accelerometer
root:/> event_test /dev/input/event1 Input driver version is 1.0.0 Input device ID: bus 0x18 vendor 0x0 product 0x159 version 0x0 Input device name: "ADXL34x accelerometer" Supported events: Event type 0 (Reset) Event code 0 (Reset) Event code 1 (Key) Event code 3 (Absolute) Event type 1 (Key) Event code 330 (Touch) Event type 3 (Absolute) Event code 0 (X) Value 15 Min -4096 Max 4096 Fuzz 3 Flat 3 Event code 1 (Y) Value -15 Min -4096 Max 4096 Fuzz 3 Flat 3 Event code 2 (Z) Value 242 Min -4096 Max 4096 Fuzz 3 Flat 3 Testing ... (interrupt to exit) Event: time 107831.548000, type 3 (Absolute), code 0 (X), value -7 Event: time 107831.548000, type 3 (Absolute), code 1 (Y), value -2 Event: time 107831.548000, type 3 (Absolute), code 2 (Z), value 12 Event: time 107831.548000, type 0 (Reset), code 0 (Reset), value 0 Event: time 107831.588000, type 3 (Absolute), code 0 (X), value -17 Event: time 107831.588000, type 3 (Absolute), code 1 (Y), value 4 Event: time 107831.588000, type 0 (Reset), code 0 (Reset), value 0 Event: time 107831.632000, type 3 (Absolute), code 0 (X), value -16 Event: time 107831.632000, type 3 (Absolute), code 2 (Z), value 11
evtest: No such device
, it's likely that you have not install the necessary modules
root:/> df_input & ~~~~~~~~~~~~~~~~~~~~~~~~~~| DirectFB 1.2.7 |~~~~~~~~~~~~~~~~~~~~~~~~~~ (c) 2001-2008 The world wide DirectFB Open Source Community (c) 2000-2004 Convergence (integrated media) GmbH ---------------------------------------------------------------- (*) DirectFB/Core: Single Application Core. (2009-05-27 15:03) [1] 401 df_input root:/> (*) Direct/Thread: Started 'VT Switcher' (405) [CRITICAL OTHER/OTHER 0/0] <12288>... (*) Direct/Thread: Started 'Keyboard Input' (406) [INPUT OTHER/OTHER 0/0] <12288>... (*) DirectFB/Input: Keyboard 0.9 (directfb.org) (*) Direct/Thread: Started 'Linux Input' (407) [INPUT OTHER/OTHER 0/0] <12288>... (*) DirectFB/Input: bf54x-keys (1) 0.1 (directfb.org) (*) Direct/Thread: Started 'Linux Input' (408) [INPUT OTHER/OTHER 0/0] <12288>... (*) DirectFB/Input: ADXL34x accelerometer (2) 0.1 (directfb.org) (*) DirectFB/Graphics: Generic Software Rasterizer 0.6 (directfb.org) (*) DirectFB/Core/WM: Default 0.3 (directfb.org) (*) FBDev/Surface: Allocated 480x272 24 bit RGB24 buffer (index 0) at offset 0 and pitch 1440. (*) FBDev/Surface: Allocated 480x272 24 bit RGB24 buffer (index 0) at offset 0 and pitch 1440. (*) Direct/Interface: Loaded 'FT2' implementation of 'IDirectFBFont'. (*) Direct/Interface: Loaded 'PNG' implementation of 'IDirectFBImageProvider'. root:/>
root:/> cd sys/class/input/input1/device/ root:/sys/devices/platform/bfin-spi.1/spi1.2> ls -al drwxr-xr-x 3 root root 0 Jan 2 10:39 . drwxr-xr-x 4 root root 0 Jan 2 10:39 .. -rw-rw-r-- 1 root root 4096 Jan 2 12:01 autosleep -rw-rw-r-- 1 root root 4096 Jan 2 12:01 calibrate -rw-rw-r-- 1 root root 4096 Jan 2 12:01 disable lrwxrwxrwx 1 root root 0 Jan 2 12:01 driver -> ../../../../bus/spi/drivers/adxl34x drwxr-xr-x 3 root root 0 Jan 2 10:39 input -r--r--r-- 1 root root 4096 Jan 2 12:01 modalias -rw-rw-r-- 1 root root 4096 Jan 2 12:01 rate lrwxrwxrwx 1 root root 0 Jan 2 12:01 subsystem -> ../../../../bus/spi -rw-r--r-- 1 root root 4096 Jan 2 12:01 uevent root:/sys/devices/platform/bfin-spi.1/spi1.2>
root:/sys/devices/platform/bfin-spi.1/spi1.2> echo 1 > calibrate root:/sys/devices/platform/bfin-spi.1/spi1.2> cat calibrate 2,10,-204
Output Data Rate (Hz) | Bandwidth (Hz) | Value |
---|---|---|
3200 | 1600 | 15 |
1600 | 800 | 14 |
800 | 400 | 13 |
400 | 200 | 12 |
200 | 100 | 11 |
100 | 50 | 10 |
50 | 25 | 9 |
25 | 12.5 | 8 |
12.5 | 6.25 | 7 |
6.25 | 3.125 | 6 |
3.125 | 1.563 | 5 |
1.563 | 0.782 | 4 |
0.782 | 0.39 | 3 |
0.39 | 0.195 | 2 |
0.195 | 0.098 | 1 |
0.098 | 0.048 | 0 |
Writing 'value' into rate sets the desired sample rate
Reading rate returns the current value
See table above for supported sample rates
root:/sys/devices/platform/bfin-spi.1/spi1.2> echo 8 > rate root:/sys/devices/platform/bfin-spi.1/spi1.2> cat rate 8
Very high output data rates are only possible via fast I2C (400kHz) or the SPI interface.
Writing '1' into disable - disables the ADXL34x (low power suspend mode)
Writing '0' into disable - enables the ADXL34x
root:/sys/devices/platform/bfin-spi.1/spi1.2> echo 1 > disable root:/sys/devices/platform/bfin-spi.1/spi1.2> echo 0 > disable root:/sys/devices/platform/bfin-spi.1/spi1.2>
Writing '1' into autosleep - enables Autosleep Upon Inactivity
Writing '0' into autosleep - disables Autosleep Upon Inactivity
root:/sys/devices/platform/bfin-spi.1/spi1.2> echo 1 > autosleep root:/sys/devices/platform/bfin-spi.1/spi1.2> echo 0 > autosleep root:/sys/devices/platform/bfin-spi.1/spi1.2>
Using this driver under Android as Acceleration Sensor Follow the link here ADXL345 Android Sensor