contiki/platform/z1/dev/adxl345.h

294 lines
12 KiB
C

/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Device drivers header file for adxl345 accelerometer in Zolertia Z1.
* \author
* Marcus Lundén, SICS <mlunden@sics.se>
* Enric Calvo, Zolertia <ecalvo@zolertia.com>
*/
#ifndef ADXL345_H_
#define ADXL345_H_
#include <stdio.h>
#include "dev/i2cmaster.h"
#define DEBUGLEDS 0
#if DEBUGLEDS
#undef LEDS_ON(x)
#undef LEDS_OFF(x)
#define LEDS_ON(x) (LEDS_PxOUT &= ~x)
#define LEDS_OFF(x) (LEDS_PxOUT |= x)
#else
#undef LEDS_ON
#undef LEDS_OFF
#define LEDS_ON(x)
#define LEDS_OFF(x)
#endif
#define LEDS_R 0x10
#define LEDS_G 0x40
#define LEDS_B 0x20
#define L_ON(x) (LEDS_PxOUT &= ~x)
#define L_OFF(x) (LEDS_PxOUT |= x)
/* Used in accm_read_axis(), eg accm_read_axis(X_AXIS);*/
enum ADXL345_AXIS {
X_AXIS = 0,
Y_AXIS = 2,
Z_AXIS = 4,
};
/* -------------------------------------------------------------------------- */
/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C,
default threshold values etc. */
void accm_init(void);
/* Write to a register.
args:
reg register to write to
val value to write
*/
void accm_write_reg(uint8_t reg, uint8_t val);
/* Write several registers from a stream.
args:
len number of bytes to read
data pointer to where the data is read from
First byte in stream must be the register address to begin writing to.
The data is then written from the second byte and increasing. The address byte
is not included in length len. */
void accm_write_stream(uint8_t len, uint8_t *data);
/* Read one register.
args:
reg what register to read
returns the value of the read register
*/
uint8_t accm_read_reg(uint8_t reg);
/* Read several registers in a stream.
args:
reg what register to start reading from
len number of bytes to read
whereto pointer to where the data is saved
*/
void accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto);
/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 bit int.
The resolution of the acceleration measurement can be increased up to 13 bit, but
will change the data format of this read out. Refer to the data sheet if so is
wanted/needed. */
int16_t accm_read_axis(enum ADXL345_AXIS axis);
/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to +2 g
on every axis). Possible values:
ADXL345_RANGE_2G
ADXL345_RANGE_4G
ADXL345_RANGE_8G
ADXL345_RANGE_16G
Example:
accm_set_grange(ADXL345_RANGE_4G);
*/
void accm_set_grange(uint8_t grange);
/* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2).
This must come after accm_init() as the registers will otherwise be overwritten. */
void accm_set_irq(uint8_t int1, uint8_t int2);
/* Macros for setting the pointers to callback functions from the interrupts.
The function will be called with an uint8_t as parameter, containing the interrupt
flag register from the ADXL345. That way, several interrupts can be mapped to
the same pin and be read from the */
#define ACCM_REGISTER_INT1_CB(ptr) accm_int1_cb = ptr;
#define ACCM_REGISTER_INT2_CB(ptr) accm_int2_cb = ptr;
/* -------------------------------------------------------------------------- */
/* Application definitions, change if required by application. */
/* Interrupt suppress periods */
/*
// XXX Not used yet.
#define ADXL345_INT_OVERRUN_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_WATERMARK_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_FREEFALL_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_INACTIVITY_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_ACTIVITY_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_DOUBLETAP_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_TAP_BACKOFF CLOCK_SECOND/8
#define ADXL345_INT_DATAREADY_BACKOFF CLOCK_SECOND/8
*/
/* Time after an interrupt that subsequent interrupts are suppressed. Should later
be turned into one specific time per type of interrupt (tap, freefall etc) */
#define SUPPRESS_TIME_INT1 CLOCK_SECOND/4
#define SUPPRESS_TIME_INT2 CLOCK_SECOND/4
/* Suggested defaults according to the data sheet etc */
#define ADXL345_THRESH_TAP_DEFAULT 0x48 // 4.5g (0x30 == 3.0g) (datasheet: 3g++)
#define ADXL345_OFSX_DEFAULT 0x00 // for individual units calibration purposes
#define ADXL345_OFSY_DEFAULT 0x00
#define ADXL345_OFSZ_DEFAULT 0x00
#define ADXL345_DUR_DEFAULT 0x20 // 20 ms (datasheet: 10ms++)
#define ADXL345_LATENT_DEFAULT 0x50 // 100 ms (datasheet: 20ms++)
#define ADXL345_WINDOW_DEFAULT 0xFF // 320 ms (datasheet: 80ms++)
#define ADXL345_THRESH_ACT_DEFAULT 0x15 // 1.3g (62.5 mg/LSB)
#define ADXL345_THRESH_INACT_DEFAULT 0x08 // 0.5g (62.5 mg/LSB)
#define ADXL345_TIME_INACT_DEFAULT 0x02 // 2 s (1 s/LSB)
#define ADXL345_ACT_INACT_CTL_DEFAULT 0xFF // all axis involved, ac-coupled
#define ADXL345_THRESH_FF_DEFAULT 0x09 // 563 mg
#define ADXL345_TIME_FF_DEFAULT 0x20 // 160 ms
#define ADXL345_TAP_AXES_DEFAULT 0x07 // all axis, no suppression
#define ADXL345_BW_RATE_DEFAULT (0x00|ADXL345_SRATE_100) // 100 Hz, normal operation
#define ADXL345_POWER_CTL_DEFAULT 0x28 // link bit set, no autosleep, start normal measuring
#define ADXL345_INT_ENABLE_DEFAULT 0x00 // no interrupts enabled
#define ADXL345_INT_MAP_DEFAULT 0x00 // all mapped to int_1
/* XXX NB: In the data format register, data format of axis readings is chosen
between left or right justify. This affects the position of the MSB/LSB and is
different depending on g-range and resolution. If changed, make sure this is
reflected in the _read_axis() function. Also, the resolution can be increased
from 10 bit to at most 13 bit, but this also changes position of MSB etc on data
format so check this in read_axis() too. */
#define ADXL345_DATA_FORMAT_DEFAULT (0x00|ADXL345_RANGE_2G) // right-justify, 2g, 10-bit mode, int is active high
#define ADXL345_FIFO_CTL_DEFAULT 0x00 // FIFO bypass mode
/* -------------------------------------------------------------------------- */
/* Reference definitions, should not be changed */
/* adxl345 slave address */
#define ADXL345_ADDR 0x53
/* ADXL345 registers */
#define ADXL345_DEVID 0x00 // read only
/* registers 0x01 to 0x1C are reserved, do not access */
#define ADXL345_THRESH_TAP 0x1D
#define ADXL345_OFSX 0x1E
#define ADXL345_OFSY 0x1F
#define ADXL345_OFSZ 0x20
#define ADXL345_DUR 0x21
#define ADXL345_LATENT 0x22
#define ADXL345_WINDOW 0x23
#define ADXL345_THRESH_ACT 0x24
#define ADXL345_THRESH_INACT 0x25
#define ADXL345_TIME_INACT 0x26
#define ADXL345_ACT_INACT_CTL 0x27
#define ADXL345_THRESH_FF 0x28
#define ADXL345_TIME_FF 0x29
#define ADXL345_TAP_AXES 0x2A
#define ADXL345_ACT_TAP_STATUS 0x2B // read only
#define ADXL345_BW_RATE 0x2C
#define ADXL345_POWER_CTL 0x2D
#define ADXL345_INT_ENABLE 0x2E
#define ADXL345_INT_MAP 0x2F
#define ADXL345_INT_SOURCE 0x30 // read only
#define ADXL345_DATA_FORMAT 0x31
#define ADXL345_DATAX0 0x32 // read only, LSByte X, two's complement
#define ADXL345_DATAX1 0x33 // read only, MSByte X
#define ADXL345_DATAY0 0x34 // read only, LSByte Y
#define ADXL345_DATAY1 0x35 // read only, MSByte X
#define ADXL345_DATAZ0 0x36 // read only, LSByte Z
#define ADXL345_DATAZ1 0x37 // read only, MSByte X
#define ADXL345_FIFO_CTL 0x38
#define ADXL345_FIFO_STATUS 0x39 // read only
/* ADXL345 interrupts */
#define ADXL345_INT_DISABLE 0X00 // used for disabling interrupts
#define ADXL345_INT_OVERRUN 0X01
#define ADXL345_INT_WATERMARK 0X02
#define ADXL345_INT_FREEFALL 0X04
#define ADXL345_INT_INACTIVITY 0X08
#define ADXL345_INT_ACTIVITY 0X10
#define ADXL345_INT_DOUBLETAP 0X20
#define ADXL345_INT_TAP 0X40
#define ADXL345_INT_DATAREADY 0X80
/* Accelerometer hardware ports, pins and registers on the msp430 µC */
#define ADXL345_DIR P1DIR
#define ADXL345_PIN P1PIN
#define ADXL345_REN P1REN
#define ADXL345_SEL P1SEL
#define ADXL345_SEL2 P1SEL2
#define ADXL345_INT1_PIN (1<<6) // P1.6
#define ADXL345_INT2_PIN (1<<7) // P1.7
#define ADXL345_IES P1IES
#define ADXL345_IE P1IE
#define ADXL345_IFG P1IFG
#define ADXL345_VECTOR PORT1_VECTOR
/* g-range for DATA_FORMAT register */
#define ADXL345_RANGE_2G 0x00
#define ADXL345_RANGE_4G 0x01
#define ADXL345_RANGE_8G 0x02
#define ADXL345_RANGE_16G 0x03
/* The adxl345 has programmable sample rates, but unexpected results may occur if the wrong
rate and I2C bus speed is used (see datasheet p 17). Sample rates in Hz. This
setting does not change the internal sampling rate, just how often it is piped
to the output registers (ie the interrupt features use the full sample rate
internally).
Example use:
adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) | ADXL345_SRATE_50));
*/
#define ADXL345_SRATE_3200 0x0F // XXX NB don't use at all as I2C data rate<= 400kHz (see datasheet)
#define ADXL345_SRATE_1600 0x0E // XXX NB don't use at all as I2C data rate<= 400kHz (see datasheet)
#define ADXL345_SRATE_800 0x0D // when I2C data rate == 400 kHz
#define ADXL345_SRATE_400 0x0C // when I2C data rate == 400 kHz
#define ADXL345_SRATE_200 0x0B // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_100 0x0A // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_50 0x09 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_25 0x08 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_12_5 0x07 // 12.5 Hz, when I2C data rate >= 100 kHz
#define ADXL345_SRATE_6_25 0x06 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_3_13 0x05 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_1_56 0x04 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_0_78 0x03 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_0_39 0x02 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_0_20 0x01 // when I2C data rate >= 100 kHz
#define ADXL345_SRATE_0_10 0x00 // 0.10 Hz, when I2C data rate >= 100 kHz
/* Callback pointers for the interrupts */
extern void (*accm_int1_cb)(uint8_t reg);
extern void (*accm_int2_cb)(uint8_t reg);
/* Interrupt 1 and 2 events; ADXL345 signals interrupt on INT1 or INT2 pins,
ISR is invoked and polls the accelerometer process which invokes the callbacks. */
extern process_event_t int1_event, int2_event; // static ?
#define ACCM_INT1 0x01
#define ACCM_INT2 0x02
/* -------------------------------------------------------------------------- */
#endif /* ifndef ADXL345_H_ */