Removed unused blocks and made functions static

This commit is contained in:
Antonio Lignan 2016-02-22 11:24:50 +01:00
parent 151f532225
commit 1be30d52dc
3 changed files with 182 additions and 335 deletions

View file

@ -42,10 +42,7 @@
#include <stdio.h> #include <stdio.h>
#include "contiki.h" #include "contiki.h"
#include "serial-shell.h" #include "dev/leds.h"
#include "shell-ps.h"
#include "shell-file.h"
#include "shell-text.h"
#include "dev/adxl345.h" #include "dev/adxl345.h"
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#define LED_INT_ONTIME (CLOCK_SECOND / 2) #define LED_INT_ONTIME (CLOCK_SECOND / 2)
@ -91,7 +88,7 @@ print_int(uint16_t reg)
void void
accm_ff_cb(uint8_t reg) accm_ff_cb(uint8_t reg)
{ {
L_ON(LEDS_B); leds_on(LEDS_BLUE);
process_post(&led_process, led_off_event, NULL); process_post(&led_process, led_off_event, NULL);
printf("~~[%u] Freefall detected! (0x%02X) -- ", printf("~~[%u] Freefall detected! (0x%02X) -- ",
((uint16_t)clock_time()) / 128, reg); ((uint16_t)clock_time()) / 128, reg);
@ -105,11 +102,11 @@ accm_tap_cb(uint8_t reg)
{ {
process_post(&led_process, led_off_event, NULL); process_post(&led_process, led_off_event, NULL);
if(reg & ADXL345_INT_DOUBLETAP) { if(reg & ADXL345_INT_DOUBLETAP) {
L_ON(LEDS_G); leds_on(LEDS_GREEN);
printf("~~[%u] DoubleTap detected! (0x%02X) -- ", printf("~~[%u] DoubleTap detected! (0x%02X) -- ",
((uint16_t)clock_time()) / 128, reg); ((uint16_t)clock_time()) / 128, reg);
} else { } else {
L_ON(LEDS_R); leds_on(LEDS_RED);
printf("~~[%u] Tap detected! (0x%02X) -- ", printf("~~[%u] Tap detected! (0x%02X) -- ",
((uint16_t)clock_time()) / 128, reg); ((uint16_t)clock_time()) / 128, reg);
} }
@ -122,7 +119,7 @@ PROCESS_THREAD(led_process, ev, data) {
PROCESS_WAIT_EVENT_UNTIL(ev == led_off_event); PROCESS_WAIT_EVENT_UNTIL(ev == led_off_event);
etimer_set(&led_etimer, LED_INT_ONTIME); etimer_set(&led_etimer, LED_INT_ONTIME);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&led_etimer)); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&led_etimer));
L_OFF(LEDS_R + LEDS_G + LEDS_B); leds_off(LEDS_RED + LEDS_GREEN + LEDS_BLUE);
} }
PROCESS_END(); PROCESS_END();
} }
@ -133,11 +130,6 @@ PROCESS_THREAD(accel_process, ev, data) {
{ {
int16_t x, y, z; int16_t x, y, z;
serial_shell_init();
shell_ps_init();
shell_file_init(); /* for printing out files */
shell_text_init(); /* for binprint */
/* Register the event used for lighting up an LED when interrupt strikes. */ /* Register the event used for lighting up an LED when interrupt strikes. */
led_off_event = process_alloc_event(); led_off_event = process_alloc_event();

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2010, Swedish Institute of Computer Science. * Copyright (c) 2010, Swedish Institute of Computer Science.
* Copyright (c) 2016, Zolertia <http://www.zolertia.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -29,59 +30,42 @@
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
*/ */
/*---------------------------------------------------------------------------*/
/** /**
* \file * \file
* Device drivers for adxl345 accelerometer in Zolertia Z1. * Device drivers for adxl345 accelerometer in Zolertia Z1.
* \author * \author
* Marcus Lundén, SICS <mlunden@sics.se> * Marcus Lundén, SICS <mlunden@sics.se>
* Enric M. Calvo, Zolertia <ecalvo@zolertia.com> * Enric M. Calvo, Zolertia <ecalvo@zolertia.com>
* Antonio Lignan, Zolertia <alinan@zolertia.com>
*/ */
/*---------------------------------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
#include "contiki.h" #include "contiki.h"
#include "adxl345.h" #include "adxl345.h"
#include "cc2420.h" #include "cc2420.h"
#include "i2cmaster.h" #include "i2cmaster.h"
#include "isr_compat.h" #include "isr_compat.h"
/*---------------------------------------------------------------------------*/
/* Callback pointers when interrupt occurs */ /* Callback pointers when interrupt occurs */
void (*accm_int1_cb)(uint8_t reg); void (*accm_int1_cb)(uint8_t reg);
void (*accm_int2_cb)(uint8_t reg); void (*accm_int2_cb)(uint8_t reg);
/*---------------------------------------------------------------------------*/
process_event_t int1_event, int2_event;
/* Bitmasks for the interrupts */ /* Bitmasks for the interrupts */
static uint16_t int1_mask = 0, int2_mask = 0; static uint16_t int1_mask = 0, int2_mask = 0;
/* Keep track of when the interrupt was last seen in order to reduce the amount /* Default values for adxl345 at startup.
of interrupts. Kind of like button debouncing. This can't be per int-pin, as * This will be sent to the adxl345 in a
there can be several very different int per pin (eg tap && freefall). */ * stream at init to set it up in a default state
// XXX Not used now, only one global timer. */
//static volatile clock_time_t ints_lasttime[] = {0, 0, 0, 0, 0, 0, 0, 0};
/* Bitmasks and bit flag variable for keeping track of adxl345 status. */
enum ADXL345_STATUSTYPES {
/* must be a bit and not more, not using 0x00. */
INITED = 0x01,
RUNNING = 0x02,
STOPPED = 0x04,
LOW_POWER = 0x08,
AAA = 0x10, // available to extend this...
BBB = 0x20, // available to extend this...
CCC = 0x40, // available to extend this...
DDD = 0x80, // available to extend this...
};
static enum ADXL345_STATUSTYPES _ADXL345_STATUS = 0x00;
/* Default values for adxl345 at startup. This will be sent to the adxl345 in a
stream at init to set it up in a default state */
static uint8_t adxl345_default_settings[] = { static uint8_t adxl345_default_settings[] = {
/* Note, as the two first two bulks are to be written in a stream, they contain /* Note, as the two first two bulks are to be written in a stream, they contain
the register address as first byte in that section. */ * the register address as first byte in that section.
/* 0--14 are in one stream, start at ADXL345_THRESH_TAP */ * 0--14 are in one stream, start at ADXL345_THRESH_TAP
ADXL345_THRESH_TAP, // XXX NB Register address, not register value!! */
/* XXX NB Register address, not register value!! */
ADXL345_THRESH_TAP,
ADXL345_THRESH_TAP_DEFAULT, ADXL345_THRESH_TAP_DEFAULT,
ADXL345_OFSX_DEFAULT, ADXL345_OFSX_DEFAULT,
ADXL345_OFSY_DEFAULT, ADXL345_OFSY_DEFAULT,
@ -98,7 +82,8 @@ static uint8_t adxl345_default_settings[] = {
ADXL345_TAP_AXES_DEFAULT, ADXL345_TAP_AXES_DEFAULT,
/* 15--19 start at ADXL345_BW_RATE */ /* 15--19 start at ADXL345_BW_RATE */
ADXL345_BW_RATE, // XXX NB Register address, not register value!! /* XXX NB Register address, not register value!! */
ADXL345_BW_RATE,
ADXL345_BW_RATE_DEFAULT, ADXL345_BW_RATE_DEFAULT,
ADXL345_POWER_CTL_DEFAULT, ADXL345_POWER_CTL_DEFAULT,
ADXL345_INT_ENABLE_DEFAULT, ADXL345_INT_ENABLE_DEFAULT,
@ -108,18 +93,10 @@ static uint8_t adxl345_default_settings[] = {
ADXL345_DATA_FORMAT_DEFAULT, ADXL345_DATA_FORMAT_DEFAULT,
ADXL345_FIFO_CTL_DEFAULT ADXL345_FIFO_CTL_DEFAULT
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS(accmeter_process, "Accelerometer process"); PROCESS(accmeter_process, "Accelerometer process");
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Write to a register. static void
args:
reg register to write to
val value to write
*/
void
accm_write_reg(uint8_t reg, uint8_t val) { accm_write_reg(uint8_t reg, uint8_t val) {
uint8_t tx_buf[] = {reg, val}; uint8_t tx_buf[] = {reg, val};
@ -132,15 +109,10 @@ accm_write_reg(uint8_t reg, uint8_t val) {
PRINTFDEBUG("WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); PRINTFDEBUG("WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Write several registers from a stream. /* First byte in stream must be the register address to begin writing to.
args: * The data is then written from second byte and increasing.
len number of bytes to read */
data pointer to where the data is read from static void
First byte in stream must be the register address to begin writing to.
The data is then written from second byte and increasing. */
void
accm_write_stream(uint8_t len, uint8_t *data) { accm_write_stream(uint8_t len, uint8_t *data) {
i2c_transmitinit(ADXL345_ADDR); i2c_transmitinit(ADXL345_ADDR);
while (i2c_busy()); while (i2c_busy());
@ -152,13 +124,7 @@ accm_write_stream(uint8_t len, uint8_t *data) {
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Read one register. static uint8_t
args:
reg what register to read
returns the value of the read register
*/
uint8_t
accm_read_reg(uint8_t reg) { accm_read_reg(uint8_t reg) {
uint8_t retVal = 0; uint8_t retVal = 0;
uint8_t rtx = reg; uint8_t rtx = reg;
@ -178,16 +144,8 @@ accm_read_reg(uint8_t reg) {
return retVal; return retVal;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Read several registers in a stream. static void
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) { accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) {
uint8_t rtx = reg; uint8_t rtx = reg;
PRINTFDEBUG("READ_STR %u B from 0x%02X\n", len, reg); PRINTFDEBUG("READ_STR %u B from 0x%02X\n", len, reg);
@ -206,11 +164,12 @@ 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. /* Read an axis of the accelerometer (x, y or z). Return value is a signed
The resolution of the acceleration measurement can be increased up to 13 bit, but * 10 bit int.
will change the data format of this read out. Refer to the data sheet if so is * The resolution of the acceleration measurement can be increased up to 13 bit,
wanted/needed. */ * but will change the data format of this read out. Refer to the data sheet if
* so is wanted/needed.
*/
int16_t int16_t
accm_read_axis(enum ADXL345_AXIS axis){ accm_read_axis(enum ADXL345_AXIS axis){
int16_t rd = 0; int16_t rd = 0;
@ -224,44 +183,27 @@ 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 void
accm_set_grange(uint8_t grange){ accm_set_grange(uint8_t grange){
if(grange > ADXL345_RANGE_16G) { if(grange > ADXL345_RANGE_16G) {
// invalid g-range.
PRINTFDEBUG("ADXL grange invalid: %u\n", grange); PRINTFDEBUG("ADXL grange invalid: %u\n", grange);
return; return;
} }
uint8_t tempreg = 0; uint8_t tempreg = 0;
/* preserve the previous contents of the register */ /* Keep the previous contents of the register, zero out the last two bits */
tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); // zero out the last two bits (grange) tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC);
tempreg |= grange; // set new range tempreg |= grange;
accm_write_reg(ADXL345_DATA_FORMAT, tempreg); accm_write_reg(ADXL345_DATA_FORMAT, tempreg);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C,
default threshold values etc. */
void void
accm_init(void) { accm_init(void) {
if(!(_ADXL345_STATUS & INITED)){
PRINTFDEBUG("ADXL345 init\n"); PRINTFDEBUG("ADXL345 init\n");
_ADXL345_STATUS |= INITED;
accm_int1_cb = NULL; accm_int1_cb = NULL;
accm_int2_cb = NULL; accm_int2_cb = NULL;
int1_event = process_alloc_event();
int2_event = process_alloc_event();
/* Set up ports and pins for interrups. */ /* Set up ports and pins for interrups. */
ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN);
@ -281,16 +223,14 @@ accm_init(void) {
/* Enable msp430 interrupts on the two interrupt pins. */ /* Enable msp430 interrupts on the two interrupt pins. */
dint(); dint();
ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); // low to high transition interrupts /* low to high transition interrupts */
ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); // enable interrupts ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN);
/* enable interrupts */
ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN);
eint(); eint();
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* 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 void
accm_set_irq(uint8_t int1, uint8_t int2){ accm_set_irq(uint8_t int1, uint8_t int2){
/* Set the corresponding interrupt mapping to INT1 or INT2 */ /* Set the corresponding interrupt mapping to INT1 or INT2 */
@ -302,44 +242,16 @@ accm_set_irq(uint8_t int1, uint8_t int2){
accm_write_reg(ADXL345_INT_ENABLE, (int1 | int2)); accm_write_reg(ADXL345_INT_ENABLE, (int1 | int2));
accm_write_reg(ADXL345_INT_MAP, int2); // int1 bits are zeroes in the map register so this is for both ints accm_write_reg(ADXL345_INT_MAP, int2); // int1 bits are zeroes in the map register so this is for both ints
} }
/*---------------------------------------------------------------------------*/
#if 0
/* now unused code that is later supposed to be turned into keeping track of every
interrupt by themselves instead of only one per INT1/2 */
/* XXX MUST HAVE some way of resetting the time so that we are not suppressing
erronous due to clock overflow.... XXX XXX XXX */
/* Table with back off time periods */
static volatile clock_time_t ints_backoffs[] = {ADXL345_INT_OVERRUN_BACKOFF, ADXL345_INT_WATERMARK_BACKOFF,
ADXL345_INT_FREEFALL_BACKOFF, ADXL345_INT_INACTIVITY_BACKOFF,
ADXL345_INT_ACTIVITY_BACKOFF, ADXL345_INT_DOUBLETAP_BACKOFF,
ADXL345_INT_TAP_BACKOFF, ADXL345_INT_DATAREADY_BACKOFF};
/*---------------------------------------------------------------------------*/
/* Checks to see if an event occurred after backoff period (returns time period
past since) or not (returns 0) */
static clocktime_t
backoff_passed(clocktime_t happenedAt, const clocktime_t backoff){
if(timenow-lasttime >= backoff) {
return 0;
} else {
return (timenow-lasttime);
}
}
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Invoked after an interrupt happened. Reads the interrupt source reg at the /* Invoked after an interrupt happened. Reads the interrupt source reg at the
accelerometer, which resets the interrupts, and invokes the corresponding * accelerometer, which resets the interrupts, and invokes the corresponding
callback. It passes the source register value so the callback can determine * callback. It passes the source register value so the callback can determine
what interrupt happened, if several interrupts are mapped to the same pin. */ * what interrupt happened, if several interrupts are mapped to the same pin.
*/
static void static void
poll_handler(void){ poll_handler(void){
uint8_t ireg = 0; uint8_t ireg = 0;
ireg = accm_read_reg(ADXL345_INT_SOURCE); ireg = accm_read_reg(ADXL345_INT_SOURCE);
//printf("0x%02X, 0x%02X, 0x%02X, 0x%02X\n", ireg, ireg2, int1_mask, int2_mask);
/* Invoke callbacks for the corresponding interrupts */ /* Invoke callbacks for the corresponding interrupts */
if(ireg & int1_mask){ if(ireg & int1_mask){
@ -354,33 +266,32 @@ poll_handler(void){
} }
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* This process is sleeping until an interrupt from the accelerometer occurs, which /* This process is sleeping until an interrupt from the accelerometer occurs,
polls this process from the interrupt service routine. */ * which polls this process from the interrupt service routine. */
PROCESS_THREAD(accmeter_process, ev, data) { PROCESS_THREAD(accmeter_process, ev, data) {
PROCESS_POLLHANDLER(poll_handler()); PROCESS_POLLHANDLER(poll_handler());
PROCESS_EXITHANDLER(); PROCESS_EXITHANDLER();
PROCESS_BEGIN(); PROCESS_BEGIN();
while(1){ while(1){
PROCESS_WAIT_EVENT_UNTIL(0); // should do nothing in while loop. PROCESS_WAIT_EVENT_UNTIL(0);
} }
PROCESS_END(); PROCESS_END();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* XXX This interrupt vector is shared with the interrupts from CC2420, so that /* This interrupt vector is shared with the interrupts from CC2420, so that
was moved here but should find a better home. XXX */ * was moved here
*/
#if 1
static struct timer suppressTimer1, suppressTimer2; static struct timer suppressTimer1, suppressTimer2;
ISR(PORT1, port1_isr) ISR(PORT1, port1_isr)
{ {
ENERGEST_ON(ENERGEST_TYPE_IRQ); ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* ADXL345_IFG.x goes high when interrupt occurs, use to check what interrupted */
if ((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ /* ADXL345_IFG.x goes high when interrupt occurs, use to check what
* interrupted
*/
if((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){
/* Check if this should be suppressed or not */ /* Check if this should be suppressed or not */
if(timer_expired(&suppressTimer1)) { if(timer_expired(&suppressTimer1)) {
timer_set(&suppressTimer1, SUPPRESS_TIME_INT1); timer_set(&suppressTimer1, SUPPRESS_TIME_INT1);
@ -388,11 +299,13 @@ ISR(PORT1, port1_isr)
process_poll(&accmeter_process); process_poll(&accmeter_process);
LPM4_EXIT; LPM4_EXIT;
} }
} else if ((ADXL345_IFG & ADXL345_INT2_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ } else if((ADXL345_IFG & ADXL345_INT2_PIN) &&
!(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){
/* Check if this should be suppressed or not */ /* Check if this should be suppressed or not */
if(timer_expired(&suppressTimer2)) { if(timer_expired(&suppressTimer2)) {
timer_set(&suppressTimer2, SUPPRESS_TIME_INT2); timer_set(&suppressTimer2, SUPPRESS_TIME_INT2);
ADXL345_IFG &= ~ADXL345_INT2_PIN; // clear interrupt flag /* clear interrupt flag */
ADXL345_IFG &= ~ADXL345_INT2_PIN;
process_poll(&accmeter_process); process_poll(&accmeter_process);
LPM4_EXIT; LPM4_EXIT;
} }
@ -404,7 +317,4 @@ ISR(PORT1, port1_isr)
} }
ENERGEST_OFF(ENERGEST_TYPE_IRQ); ENERGEST_OFF(ENERGEST_TYPE_IRQ);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2010, Swedish Institute of Computer Science. * Copyright (c) 2010, Swedish Institute of Computer Science.
* Copyright (c) 2016, Zolertia <http://www.zolertia.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -29,158 +30,105 @@
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
*/ */
/*---------------------------------------------------------------------------*/
/** /**
* \file * \file
* Device drivers header file for adxl345 accelerometer in Zolertia Z1. * Device drivers header file for adxl345 accelerometer in Zolertia Z1.
* \author * \author
* Marcus Lundén, SICS <mlunden@sics.se> * Marcus Lundén, SICS <mlunden@sics.se>
* Enric Calvo, Zolertia <ecalvo@zolertia.com> * Enric Calvo, Zolertia <ecalvo@zolertia.com>
* Antonio Lignan, Zolertia <alinan@zolertia.com>
*/ */
/*---------------------------------------------------------------------------*/
#ifndef ADXL345_H_ #ifndef ADXL345_H_
#define ADXL345_H_ #define ADXL345_H_
#include <stdio.h> #include <stdio.h>
#include "dev/i2cmaster.h" #include "dev/i2cmaster.h"
/*---------------------------------------------------------------------------*/
#define DEBUGLEDS 0 /* Used in accm_read_axis(), eg accm_read_axis(X_AXIS) */
#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 { enum ADXL345_AXIS {
X_AXIS = 0, X_AXIS = 0,
Y_AXIS = 2, Y_AXIS = 2,
Z_AXIS = 4, Z_AXIS = 4,
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C, /* Init the accelerometer: ports, pins, registers, interrupts (none enabled),
default threshold values etc. */ * I2C, default threshold values etc.
*/
void accm_init(void); void accm_init(void);
/* Write to a register. /* Read an axis of the accelerometer (x, y or z). Return value is a signed 10
args: * bit int.
reg register to write to * The resolution of the acceleration measurement can be increased up to 13 bit,
val value to write * but will change the data format of this read out. Refer to the data sheet if
*/ * so is wanted/needed.
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); 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 /* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to
on every axis). Possible values: * +2 g on every axis). Possible values:
ADXL345_RANGE_2G * - ADXL345_RANGE_2G
ADXL345_RANGE_4G * - ADXL345_RANGE_4G
ADXL345_RANGE_8G * - ADXL345_RANGE_8G
ADXL345_RANGE_16G * - ADXL345_RANGE_16G
Example:
accm_set_grange(ADXL345_RANGE_4G);
*/ */
void accm_set_grange(uint8_t grange); void accm_set_grange(uint8_t grange);
/* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). /* 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. */ * This must come after accm_init() as the registers will otherwise be
* overwritten.
*/
void accm_set_irq(uint8_t int1, uint8_t int2); void accm_set_irq(uint8_t int1, uint8_t int2);
/* Macros for setting the pointers to callback functions from the interrupts. /* 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 * The function will be called with an uint8_t as parameter, containing the
flag register from the ADXL345. That way, several interrupts can be mapped to * interrupt flag register from the ADXL345. That way, several interrupts can be
the same pin and be read from the */ * mapped to the same pin and be read
*/
#define ACCM_REGISTER_INT1_CB(ptr) accm_int1_cb = ptr; #define ACCM_REGISTER_INT1_CB(ptr) accm_int1_cb = ptr;
#define ACCM_REGISTER_INT2_CB(ptr) accm_int2_cb = ptr; #define ACCM_REGISTER_INT2_CB(ptr) accm_int2_cb = ptr;
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Application definitions, change if required by application. */ /* Application definitions, change if required by application. */
/* Interrupt suppress periods */ /* Time after an interrupt that subsequent interrupts are suppressed. Should
/* * later be turned into one specific time per type of interrupt (tap, freefall.
// XXX Not used yet. * etc)
#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_INT1 CLOCK_SECOND/4
#define SUPPRESS_TIME_INT2 CLOCK_SECOND/4 #define SUPPRESS_TIME_INT2 CLOCK_SECOND/4
/* Suggested defaults according to the data sheet etc */ /* Suggested defaults according to the data sheet etc */
#define ADXL345_THRESH_TAP_DEFAULT 0x48 // 4.5g (0x30 == 3.0g) (datasheet: 3g++) #define ADXL345_THRESH_TAP_DEFAULT 0x48 /* 4.5g (0x30 == 3.0g) */
#define ADXL345_OFSX_DEFAULT 0x00 // for individual units calibration purposes #define ADXL345_OFSX_DEFAULT 0x00 /* for calibration only */
#define ADXL345_OFSY_DEFAULT 0x00 #define ADXL345_OFSY_DEFAULT 0x00
#define ADXL345_OFSZ_DEFAULT 0x00 #define ADXL345_OFSZ_DEFAULT 0x00
#define ADXL345_DUR_DEFAULT 0x20 // 20 ms (datasheet: 10ms++) #define ADXL345_DUR_DEFAULT 0x20 /* 20 ms (datasheet: 10ms++) */
#define ADXL345_LATENT_DEFAULT 0x50 // 100 ms (datasheet: 20ms++) #define ADXL345_LATENT_DEFAULT 0x50 /* 100 ms (datasheet: 20ms++) */
#define ADXL345_WINDOW_DEFAULT 0xFF // 320 ms (datasheet: 80ms++) #define ADXL345_WINDOW_DEFAULT 0xFF /* 320 ms (datasheet: 80ms++) */
#define ADXL345_THRESH_ACT_DEFAULT 0x15 // 1.3g (62.5 mg/LSB) #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_THRESH_INACT_DEFAULT 0x08 /* 0.5g (62.5 mg/LSB) */
#define ADXL345_TIME_INACT_DEFAULT 0x02 // 2 s (1 s/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_ACT_INACT_CTL_DEFAULT 0xFF /* all axis, ac-coupled */
#define ADXL345_THRESH_FF_DEFAULT 0x09 // 563 mg #define ADXL345_THRESH_FF_DEFAULT 0x09 /* 563 mg */
#define ADXL345_TIME_FF_DEFAULT 0x20 // 160 ms #define ADXL345_TIME_FF_DEFAULT 0x20 /* 60 ms */
#define ADXL345_TAP_AXES_DEFAULT 0x07 // all axis, no suppression #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_BW_RATE_DEFAULT (0x00 | ADXL345_SRATE_100) /* 100 Hz */
#define ADXL345_POWER_CTL_DEFAULT 0x28 // link bit set, no autosleep, start normal measuring /* link bit set, no autosleep, start normal measuring */
#define ADXL345_INT_ENABLE_DEFAULT 0x00 // no interrupts enabled #define ADXL345_POWER_CTL_DEFAULT 0x28
#define ADXL345_INT_MAP_DEFAULT 0x00 // all mapped to int_1 #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 /* 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 * 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 * 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 * 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 * 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. */ * 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 /* right-justify, 2g, 10-bit mode, int is active high */
#define ADXL345_DATA_FORMAT_DEFAULT (0x00 | ADXL345_RANGE_2G)
#define ADXL345_FIFO_CTL_DEFAULT 0x00 /* FIFO bypass mode */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Reference definitions, should not be changed */ /* Reference definitions, should not be changed */
@ -188,7 +136,7 @@ void accm_set_irq(uint8_t int1, uint8_t int2);
#define ADXL345_ADDR 0x53 #define ADXL345_ADDR 0x53
/* ADXL345 registers */ /* ADXL345 registers */
#define ADXL345_DEVID 0x00 // read only #define ADXL345_DEVID 0x00
/* registers 0x01 to 0x1C are reserved, do not access */ /* registers 0x01 to 0x1C are reserved, do not access */
#define ADXL345_THRESH_TAP 0x1D #define ADXL345_THRESH_TAP 0x1D
#define ADXL345_OFSX 0x1E #define ADXL345_OFSX 0x1E
@ -204,24 +152,24 @@ void accm_set_irq(uint8_t int1, uint8_t int2);
#define ADXL345_THRESH_FF 0x28 #define ADXL345_THRESH_FF 0x28
#define ADXL345_TIME_FF 0x29 #define ADXL345_TIME_FF 0x29
#define ADXL345_TAP_AXES 0x2A #define ADXL345_TAP_AXES 0x2A
#define ADXL345_ACT_TAP_STATUS 0x2B // read only #define ADXL345_ACT_TAP_STATUS 0x2B
#define ADXL345_BW_RATE 0x2C #define ADXL345_BW_RATE 0x2C
#define ADXL345_POWER_CTL 0x2D #define ADXL345_POWER_CTL 0x2D
#define ADXL345_INT_ENABLE 0x2E #define ADXL345_INT_ENABLE 0x2E
#define ADXL345_INT_MAP 0x2F #define ADXL345_INT_MAP 0x2F
#define ADXL345_INT_SOURCE 0x30 // read only #define ADXL345_INT_SOURCE 0x30
#define ADXL345_DATA_FORMAT 0x31 #define ADXL345_DATA_FORMAT 0x31
#define ADXL345_DATAX0 0x32 // read only, LSByte X, two's complement #define ADXL345_DATAX0 0x32 /* read only, LSByte X, two's complement */
#define ADXL345_DATAX1 0x33 // read only, MSByte X #define ADXL345_DATAX1 0x33 /* read only, MSByte X */
#define ADXL345_DATAY0 0x34 // read only, LSByte Y #define ADXL345_DATAY0 0x34 /* read only, LSByte Y */
#define ADXL345_DATAY1 0x35 // read only, MSByte X #define ADXL345_DATAY1 0x35 /* read only, MSByte X */
#define ADXL345_DATAZ0 0x36 // read only, LSByte Z #define ADXL345_DATAZ0 0x36 /* read only, LSByte Z */
#define ADXL345_DATAZ1 0x37 // read only, MSByte X #define ADXL345_DATAZ1 0x37 /* read only, MSByte X */
#define ADXL345_FIFO_CTL 0x38 #define ADXL345_FIFO_CTL 0x38
#define ADXL345_FIFO_STATUS 0x39 // read only #define ADXL345_FIFO_STATUS 0x39 /* read only */
/* ADXL345 interrupts */ /* ADXL345 interrupts */
#define ADXL345_INT_DISABLE 0X00 // used for disabling interrupts #define ADXL345_INT_DISABLE 0X00 /* used for disabling interrupts */
#define ADXL345_INT_OVERRUN 0X01 #define ADXL345_INT_OVERRUN 0X01
#define ADXL345_INT_WATERMARK 0X02 #define ADXL345_INT_WATERMARK 0X02
#define ADXL345_INT_FREEFALL 0X04 #define ADXL345_INT_FREEFALL 0X04
@ -237,8 +185,8 @@ void accm_set_irq(uint8_t int1, uint8_t int2);
#define ADXL345_REN P1REN #define ADXL345_REN P1REN
#define ADXL345_SEL P1SEL #define ADXL345_SEL P1SEL
#define ADXL345_SEL2 P1SEL2 #define ADXL345_SEL2 P1SEL2
#define ADXL345_INT1_PIN (1<<6) // P1.6 #define ADXL345_INT1_PIN (1<<6) /* P1.6 */
#define ADXL345_INT2_PIN (1<<7) // P1.7 #define ADXL345_INT2_PIN (1<<7) /* P1.7 */
#define ADXL345_IES P1IES #define ADXL345_IES P1IES
#define ADXL345_IE P1IE #define ADXL345_IE P1IE
#define ADXL345_IFG P1IFG #define ADXL345_IFG P1IFG
@ -251,43 +199,40 @@ void accm_set_irq(uint8_t int1, uint8_t int2);
#define ADXL345_RANGE_16G 0x03 #define ADXL345_RANGE_16G 0x03
/* The adxl345 has programmable sample rates, but unexpected results may occur if the wrong /* The adxl345 has programmable sample rates, but unexpected results may occur
rate and I2C bus speed is used (see datasheet p 17). Sample rates in Hz. This * if the wrong rate and I2C bus speed is used (see datasheet p 17). Sample
setting does not change the internal sampling rate, just how often it is piped * rates in Hz. This setting does not change the internal sampling rate, just
to the output registers (ie the interrupt features use the full sample rate * how often it is piped to the output registers (ie the interrupt features use
internally). * the full sample rate internally).
* Example use:
Example use: * adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER)
adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) | ADXL345_SRATE_50)); * | 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) /* XXX NB don't use at all as I2C data rate<= 400kHz */
#define ADXL345_SRATE_800 0x0D // when I2C data rate == 400 kHz #define ADXL345_SRATE_3200 0x0F
#define ADXL345_SRATE_400 0x0C // when I2C data rate == 400 kHz /* XXX NB don't use at all as I2C data rate<= 400kHz */
#define ADXL345_SRATE_200 0x0B // when I2C data rate >= 100 kHz #define ADXL345_SRATE_1600 0x0E
#define ADXL345_SRATE_100 0x0A // when I2C data rate >= 100 kHz #define ADXL345_SRATE_800 0x0D /* when I2C data rate == 400 kHz */
#define ADXL345_SRATE_50 0x09 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_400 0x0C /* when I2C data rate == 400 kHz */
#define ADXL345_SRATE_25 0x08 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_200 0x0B /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_12_5 0x07 // 12.5 Hz, when I2C data rate >= 100 kHz #define ADXL345_SRATE_100 0x0A /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_6_25 0x06 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_50 0x09 /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_3_13 0x05 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_25 0x08 /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_1_56 0x04 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_12_5 0x07 /* 12.5 Hz, when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_0_78 0x03 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_6_25 0x06 /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_0_39 0x02 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_3_13 0x05 /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_0_20 0x01 // when I2C data rate >= 100 kHz #define ADXL345_SRATE_1_56 0x04 /* when I2C data rate >= 100 kHz */
#define ADXL345_SRATE_0_10 0x00 // 0.10 Hz, 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 */ /* Callback pointers for the interrupts */
extern void (*accm_int1_cb)(uint8_t reg); extern void (*accm_int1_cb)(uint8_t reg);
extern void (*accm_int2_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_INT1 0x01
#define ACCM_INT2 0x02 #define ACCM_INT2 0x02
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#endif /* ifndef ADXL345_H_ */ #endif /* ifndef ADXL345_H_ */