Jose Escalona / ADXL345

Dependents:   vmConfort_v6

Fork of ADXL345 by Tyler Weaver

Files at this revision

API Documentation at this revision

Comitter:
escalona
Date:
Wed Jan 16 11:10:19 2013 +0000
Parent:
10:d81793e01ec4
Commit message:
primer commit Juan

Changed in this revision

ADXL345.cpp Show annotated file Show diff for this revision Revisions of this file
ADXL345.h Show annotated file Show diff for this revision Revisions of this file
--- a/ADXL345.cpp	Tue Nov 06 17:36:40 2012 +0000
+++ b/ADXL345.cpp	Wed Jan 16 11:10:19 2013 +0000
@@ -1,25 +1,9 @@
 /**
- * @file ADXL345.cpp
- * @author Tyler Weaver
- * @author Peter Swanson
- * A personal note from me: Jesus Christ has changed my life so much it blows my mind. I say this because
- *                  today, religion is thought of as something that you do or believe and has about as
- *                  little impact on a person as their political stance. But for me, God gives me daily
- *                  strength and has filled my life with the satisfaction that I could never find in any
- *                  of the other things that I once looked for it in.
- * If your interested, heres verse that changed my life:
- *      Rom 8:1-3: "Therefore, there is now no condemnation for those who are in Christ Jesus,
- *                  because through Christ Jesus, the law of the Spirit who gives life has set
- *                  me free from the law of sin (which brings...) and death. For what the law
- *                  was powerless to do in that it was weakened by the flesh, God did by sending
- *                  His own Son in the likeness of sinful flesh to be a sin offering. And so He
- *                  condemned sin in the flesh in order that the righteous requirements of the
- *                  (God's) law might be fully met in us, who live not according to the flesh
- *                  but according to the Spirit."
+ * @author Aaron Berk
+ * 
+ * @section LICENSE
  *
- *  A special thanks to Ewout van Bekkum for all his patient help in developing this library!
- *
- * @section LICENSE
+ * Copyright (c) 2010 ARM Limited
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -41,166 +25,54 @@
  *
  * @section DESCRIPTION
  *
- * ADXL345, triple axis, I2C interface, accelerometer.
+ * ADXL345, triple axis, digital interface, accelerometer.
  *
  * Datasheet:
  *
  * http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf
- */
-
-/*
+ */  
+ 
+/**
  * Includes
  */
 #include "ADXL345.h"
 
-//#include "mbed.h"
-
-ADXL345::ADXL345(PinName sda, PinName scl) : i2c_(*(new I2C(sda, scl)))
-{
-    myI2c = &i2c_;
-    init();
-}
-
-ADXL345::~ADXL345()
-{
-    delete myI2c;
-}
-
-void ADXL345::init()
-{
-    setDataRate(ADXL345_25HZ);
-    setPowerMode(0); // high power
-    setDataFormatControl(ADXL345_FULL_RES | ADXL345_2G); // full resolution, right justified, 2g range
-    setFifoControl(0x00); // bypass mode
-    setPowerControl(0x08); // start measurements
-    
-    int8_t calibration_offset[3] = {-5,-4,2}; // calibration offset values
-    for(char axis = 0x00; axis < 0x03; axis++)
-        setOffset(axis,calibration_offset[axis]);
-}
-
-char ADXL345::SingleByteRead(char address)
-{
-    char tx = address;
-    char output;
-    i2c_.write( ADXL345_WRITE , &tx, 1);  //tell it what you want to read
-    i2c_.read( ADXL345_READ , &output, 1);    //tell it where to store the data
-    return output;
-}
-
-
-/*
-***info on the i2c_.write***
-address     8-bit I2C slave address [ addr | 0 ]
-data        Pointer to the byte-array data to send
-length        Number of bytes to send
-repeated    Repeated start, true - do not send stop at end
-returns     0 on success (ack), or non-0 on failure (nack)
-*/
-
-int ADXL345::SingleByteWrite(char address, char data)
-{
-    int ack = 0;
-    char tx[2];
-    tx[0] = address;
-    tx[1] = data;
-    return   ack | i2c_.write( ADXL345_WRITE , tx, 2);
-}
-
+ADXL345::ADXL345(PinName mosi, 
+                 PinName miso, 
+                 PinName sck, 
+                 PinName cs) : spi_(mosi, miso, sck), nCS_(cs) {
 
-void ADXL345::multiByteRead(char address, char* output, int size)
-{
-    i2c_.write( ADXL345_WRITE, &address, 1);  //tell it where to read from
-    i2c_.read( ADXL345_READ , output, size);      //tell it where to store the data read
-}
-
-
-int ADXL345::multiByteWrite(char address, char* ptr_data, int size)
-{
-    int ack;
-
-    ack = i2c_.write( ADXL345_WRITE, &address, 1);  //tell it where to write to
-    return ack | i2c_.write( ADXL345_READ, ptr_data, size);  //tell it what data to write
-}
-
-
-void ADXL345::getXYZ(int16_t* readings)
-{
-    char buffer[6];
-    multiByteRead(ADXL345_DATAX0_REG, buffer, 6);
-
-    readings[0] = wordExtend(&buffer[0]);
-    readings[1] = wordExtend(&buffer[2]);
-    readings[2] = wordExtend(&buffer[4]);
-}
+    //1.5MHz, allowing us to use the fastest data rates without problems with the FIFO (must be less than 1.6MHz)
+    spi_.frequency(1500000);
+    spi_.format(8,3);
+    
+    nCS_ = 1;
 
-char ADXL345::getDeviceID()
-{
-    return SingleByteRead(ADXL345_DEVID_REG);
-}
-//
-int ADXL345::setPowerMode(char mode)
-{
-    //Get the current register contents, so we don't clobber the rate value.
-    char registerContents = (mode << 4) | SingleByteRead(ADXL345_BW_RATE_REG);
-
-    return SingleByteWrite(ADXL345_BW_RATE_REG, registerContents);
-}
-
-char ADXL345::getBwRateReg()
-{
-    return SingleByteRead(ADXL345_BW_RATE_REG);
-}
-
-int ADXL345::setBwRateReg(char reg)
-{
-    return SingleByteWrite(ADXL345_BW_RATE_REG, reg);
-}
-
-char ADXL345::getPowerControl()
-{
-    return SingleByteRead(ADXL345_POWER_CTL_REG);
-}
-
-int ADXL345::setPowerControl(char settings)
-{
-    return SingleByteWrite(ADXL345_POWER_CTL_REG, settings);
+    wait_us(500);
 
 }
 
-char ADXL345::getDataFormatControl(void)
-{
-    return SingleByteRead(ADXL345_DATA_FORMAT_REG);
-}
+int ADXL345::getDevId(void) {
 
-int ADXL345::setDataFormatControl(char settings)
-{
-    return SingleByteWrite(ADXL345_DATA_FORMAT_REG, settings);
+    return oneByteRead(ADXL345_DEVID_REG);
+
 }
 
-int ADXL345::setDataFormatControl(char settings, char mask, char *prev)
-{
-    char old = SingleByteRead(ADXL345_DATA_FORMAT_REG);
-    if(prev)
-        *prev = old;
-    return SingleByteWrite(ADXL345_DATA_FORMAT_REG, (old | (settings & mask)) & (settings | ~mask));
+int ADXL345::getTapThreshold(void) {
+
+    return oneByteRead(ADXL345_THRESH_TAP_REG);
+
 }
 
-int ADXL345::setDataRate(char rate)
-{
-    //Get the current register contents, so we don't clobber the power bit.
-    char registerContents = SingleByteRead(ADXL345_BW_RATE_REG);
+void ADXL345::setTapThreshold(int threshold) {
 
-    registerContents &= 0x10;
-    registerContents |= rate;
+    oneByteWrite(ADXL345_THRESH_TAP_REG, threshold);
 
-    return SingleByteWrite(ADXL345_BW_RATE_REG, registerContents);
 }
 
+int ADXL345::getOffset(int axis) {
 
-char ADXL345::getOffset(char axis)
-{
-    char address = 0;
+    int address = 0;
 
     if (axis == ADXL345_X) {
         address = ADXL345_OFSX_REG;
@@ -210,12 +82,13 @@
         address = ADXL345_OFSZ_REG;
     }
 
-    return SingleByteRead(address);
+    return oneByteRead(address);
+
 }
 
-int ADXL345::setOffset(char axis, char offset)
-{
-    char address = 0;
+void ADXL345::setOffset(int axis, char offset) {
+
+    int address = 0;
 
     if (axis == ADXL345_X) {
         address = ADXL345_OFSX_REG;
@@ -225,308 +98,338 @@
         address = ADXL345_OFSZ_REG;
     }
 
-    return SingleByteWrite(address, offset);
+    return oneByteWrite(address, offset);
+
+}
+
+int ADXL345::getTapDuration(void) {
+
+    return oneByteRead(ADXL345_DUR_REG)*625;
+
+}
+
+void ADXL345::setTapDuration(int duration_us) {
+
+    int tapDuration = duration_us / 625;
+
+    oneByteWrite(ADXL345_DUR_REG, tapDuration);
+
+}
+
+float ADXL345::getTapLatency(void) {
+
+    return oneByteRead(ADXL345_LATENT_REG)*1.25;
+
+}
+
+void ADXL345::setTapLatency(int latency_ms) {
+
+    int tapLatency = latency_ms / 1.25;
+
+    oneByteWrite(ADXL345_LATENT_REG, tapLatency);
+
+}
+
+float ADXL345::getWindowTime(void) {
+
+    return oneByteRead(ADXL345_WINDOW_REG)*1.25;
+
+}
+
+void ADXL345::setWindowTime(int window_ms) {
+
+    int windowTime = window_ms / 1.25;
+
+    oneByteWrite(ADXL345_WINDOW_REG, windowTime);
+
+}
+
+int ADXL345::getActivityThreshold(void) {
+
+    return oneByteRead(ADXL345_THRESH_ACT_REG);
+
+}
+
+void ADXL345::setActivityThreshold(int threshold) {
+
+    oneByteWrite(ADXL345_THRESH_ACT_REG, threshold);
+
+}
+
+int ADXL345::getInactivityThreshold(void) {
+
+    return oneByteRead(ADXL345_THRESH_INACT_REG);
+
+}
+
+void ADXL345::setInactivityThreshold(int threshold) {
+
+    return oneByteWrite(ADXL345_THRESH_INACT_REG, threshold);
+
+}
+
+int ADXL345::getTimeInactivity(void) {
+
+    return oneByteRead(ADXL345_TIME_INACT_REG);
+
+}
+
+void ADXL345::setTimeInactivity(int timeInactivity) {
+
+    oneByteWrite(ADXL345_TIME_INACT_REG, timeInactivity);
+
+}
+
+int ADXL345::getActivityInactivityControl(void) {
+
+    return oneByteRead(ADXL345_ACT_INACT_CTL_REG);
+
+}
+
+void ADXL345::setActivityInactivityControl(int settings) {
+
+    oneByteWrite(ADXL345_ACT_INACT_CTL_REG, settings);
+
+}
+
+int ADXL345::getFreefallThreshold(void) {
+
+    return oneByteRead(ADXL345_THRESH_FF_REG);
+
+}
+
+void ADXL345::setFreefallThreshold(int threshold) {
+
+    oneByteWrite(ADXL345_THRESH_FF_REG, threshold);
+
+}
+
+int ADXL345::getFreefallTime(void) {
+
+    return oneByteRead(ADXL345_TIME_FF_REG)*5;
+
+}
+
+void ADXL345::setFreefallTime(int freefallTime_ms) {
+
+    int freefallTime = freefallTime_ms / 5;
+
+    oneByteWrite(ADXL345_TIME_FF_REG, freefallTime);
+
+}
+
+int ADXL345::getTapAxisControl(void) {
+
+    return oneByteRead(ADXL345_TAP_AXES_REG);
+
+}
+
+void ADXL345::setTapAxisControl(int settings) {
+
+    oneByteWrite(ADXL345_TAP_AXES_REG, settings);
+
+}
+
+int ADXL345::getTapSource(void) {
+
+    return oneByteRead(ADXL345_ACT_TAP_STATUS_REG);
+
+}
+
+void ADXL345::setPowerMode(char mode) {
+
+    //Get the current register contents, so we don't clobber the rate value.
+    char registerContents = oneByteRead(ADXL345_BW_RATE_REG);
+
+    registerContents = (mode << 4) | registerContents;
+
+    oneByteWrite(ADXL345_BW_RATE_REG, registerContents);
+
+}
+
+int ADXL345::getPowerControl(void) {
+
+    return oneByteRead(ADXL345_POWER_CTL_REG);
+
+}
+
+void ADXL345::setPowerControl(int settings) {
+
+    oneByteWrite(ADXL345_POWER_CTL_REG, settings);
+
+}
+
+int ADXL345::getInterruptEnableControl(void) {
+
+    return oneByteRead(ADXL345_INT_ENABLE_REG);
+
+}
+
+void ADXL345::setInterruptEnableControl(int settings) {
+
+    oneByteWrite(ADXL345_INT_ENABLE_REG, settings);
+
+}
+
+int ADXL345::getInterruptMappingControl(void) {
+
+    return oneByteRead(ADXL345_INT_MAP_REG);
+
+}
+
+void ADXL345::setInterruptMappingControl(int settings) {
+
+    oneByteWrite(ADXL345_INT_MAP_REG, settings);
+
+}
+
+int ADXL345::getInterruptSource(void){
+
+    return oneByteRead(ADXL345_INT_SOURCE_REG);
+
+}
+
+int ADXL345::getDataFormatControl(void){
+
+    return oneByteRead(ADXL345_DATA_FORMAT_REG);
+
+}
+
+void ADXL345::setDataFormatControl(int settings){
+
+    oneByteWrite(ADXL345_DATA_FORMAT_REG, settings);
+
+}
+
+void ADXL345::setDataRate(int rate) {
+
+    //Get the current register contents, so we don't clobber the power bit.
+    char registerContents = oneByteRead(ADXL345_BW_RATE_REG);
+
+    registerContents &= 0x10;
+    registerContents |= rate;
+
+    oneByteWrite(ADXL345_BW_RATE_REG, registerContents);
+
+}
+
+int ADXL345::getAx(){
+
+    char buffer[2];
+    
+    multiByteRead(ADXL345_DATAX0_REG, buffer, 2);
+    
+    return ((int)buffer[1] << 8 | (int)buffer[0]);
 }
 
 
-char ADXL345::getFifoControl(void)
-{
-    return SingleByteRead(ADXL345_FIFO_CTL);
-}
-
-int ADXL345::setFifoControl(char settings)
-{
-    return SingleByteWrite(ADXL345_FIFO_STATUS, settings);
-}
+int ADXL345::getAy(){
 
-char ADXL345::getFifoStatus(void)
-{
-    return SingleByteRead(ADXL345_FIFO_STATUS);
-}
-
-char ADXL345::getTapThreshold(void)
-{
-    return SingleByteRead(ADXL345_THRESH_TAP_REG);
-}
-
-int ADXL345::setTapThreshold(char threshold)
-{
-    return SingleByteWrite(ADXL345_THRESH_TAP_REG, threshold);
-}
-
-float ADXL345::getTapDuration(void)
-{
-    return (float)SingleByteRead(ADXL345_DUR_REG)*625;
+    char buffer[2];
+    
+    multiByteRead(ADXL345_DATAY0_REG, buffer, 2);
+    
+    return ((int)buffer[1] << 8 | (int)buffer[0]);
 }
 
-int ADXL345::setTapDuration(short int duration_us)
-{
-    short int tapDuration = duration_us / 625;
-    char tapChar[2];
-    tapChar[0] = (tapDuration & 0x00FF);
-    tapChar[1] = (tapDuration >> 8) & 0x00FF;
-    return multiByteWrite(ADXL345_DUR_REG, tapChar, 2);
-}
-
-float ADXL345::getTapLatency(void)
-{
-    return (float)SingleByteRead(ADXL345_LATENT_REG)*1.25;
-}
+int ADXL345::getAz(){
 
-int ADXL345::setTapLatency(short int latency_ms)
-{
-    latency_ms = latency_ms / 1.25;
-    char latChar[2];
-    latChar[0] = (latency_ms & 0x00FF);
-    latChar[1] = (latency_ms << 8) & 0xFF00;
-    return multiByteWrite(ADXL345_LATENT_REG, latChar, 2);
-}
-
-float ADXL345::getWindowTime(void)
-{
-    return (float)SingleByteRead(ADXL345_WINDOW_REG)*1.25;
-}
-
-int ADXL345::setWindowTime(short int window_ms)
-{
-    window_ms = window_ms / 1.25;
-    char windowChar[2];
-    windowChar[0] = (window_ms & 0x00FF);
-    windowChar[1] = ((window_ms << 8) & 0xFF00);
-    return multiByteWrite(ADXL345_WINDOW_REG, windowChar, 2);
-}
-
-char ADXL345::getActivityThreshold(void)
-{
-    return SingleByteRead(ADXL345_THRESH_ACT_REG);
+    char buffer[2];
+    
+    multiByteRead(ADXL345_DATAZ0_REG, buffer, 2);
+    
+    return ((int)buffer[1] << 8 | (int)buffer[0]);
 }
 
-int ADXL345::setActivityThreshold(char threshold)
-{
-    return SingleByteWrite(ADXL345_THRESH_ACT_REG, threshold);
-}
+
 
-char ADXL345::getInactivityThreshold(void)
-{
-    return SingleByteRead(ADXL345_THRESH_INACT_REG);
-}
-
-//int FUNCTION(short int * ptr_Output)
-//short int FUNCTION ()
-
-int ADXL345::setInactivityThreshold(char threshold)
-{
-    return SingleByteWrite(ADXL345_THRESH_INACT_REG, threshold);
-}
+void ADXL345::getOutput(int* readings){
 
-char ADXL345::getTimeInactivity(void)
-{
-    return SingleByteRead(ADXL345_TIME_INACT_REG);
-}
+    char buffer[6];
+    
+    multiByteRead(ADXL345_DATAX0_REG, buffer, 6);
+    
+    readings[0] = (int)buffer[1] << 8 | (int)buffer[0];
+    readings[1] = (int)buffer[3] << 8 | (int)buffer[2];
+    readings[2] = (int)buffer[5] << 8 | (int)buffer[4];
 
-int ADXL345::setTimeInactivity(char timeInactivity)
-{
-    return SingleByteWrite(ADXL345_TIME_INACT_REG, timeInactivity);
-}
-
-char ADXL345::getActivityInactivityControl(void)
-{
-    return SingleByteRead(ADXL345_ACT_INACT_CTL_REG);
-}
-
-int ADXL345::setActivityInactivityControl(char settings)
-{
-    return SingleByteWrite(ADXL345_ACT_INACT_CTL_REG, settings);
 }
 
-char ADXL345::getFreefallThreshold(void)
-{
-    return SingleByteRead(ADXL345_THRESH_FF_REG);
-}
+int ADXL345::getFifoControl(void){
 
-int ADXL345::setFreefallThreshold(char threshold)
-{
-    return SingleByteWrite(ADXL345_THRESH_FF_REG, threshold);
-}
+    return oneByteRead(ADXL345_FIFO_CTL);
 
-char ADXL345::getFreefallTime(void)
-{
-    return SingleByteRead(ADXL345_TIME_FF_REG)*5;
 }
 
-int ADXL345::setFreefallTime(short int freefallTime_ms)
-{
-    freefallTime_ms = freefallTime_ms / 5;
-    char fallChar[2];
-    fallChar[0] = (freefallTime_ms & 0x00FF);
-    fallChar[1] = (freefallTime_ms << 8) & 0xFF00;
+void ADXL345::setFifoControl(int settings){
 
-    return multiByteWrite(ADXL345_TIME_FF_REG, fallChar, 2);
+    oneByteWrite(ADXL345_FIFO_CTL, settings);
+
 }
 
-char ADXL345::getTapAxisControl(void)
-{
-    return SingleByteRead(ADXL345_TAP_AXES_REG);
-}
+int ADXL345::getFifoStatus(void){
 
-int ADXL345::setTapAxisControl(char settings)
-{
-    return SingleByteWrite(ADXL345_TAP_AXES_REG, settings);
-}
+    return oneByteRead(ADXL345_FIFO_STATUS);
 
-char ADXL345::getTapSource(void)
-{
-    return SingleByteRead(ADXL345_ACT_TAP_STATUS_REG);
 }
 
-char ADXL345::getInterruptEnableControl(void)
-{
-    return SingleByteRead(ADXL345_INT_ENABLE_REG);
-}
+int ADXL345::oneByteRead(int address) {
+
+    int tx = (ADXL345_SPI_READ | (address & 0x3F));
+    int rx = 0;
 
-int ADXL345::setInterruptEnableControl(char settings)
-{
-    return SingleByteWrite(ADXL345_INT_ENABLE_REG, settings);
-}
+    nCS_ = 0;
+    //Send address to read from.
+    spi_.write(tx);
+    //Read back contents of address.
+    rx = spi_.write(0x00);
+    nCS_ = 1;
 
-char ADXL345::getInterruptMappingControl(void)
-{
-    return SingleByteRead(ADXL345_INT_MAP_REG);
-}
+    return rx;
 
-int ADXL345::setInterruptMappingControl(char settings)
-{
-    return SingleByteWrite(ADXL345_INT_MAP_REG, settings);
 }
 
-char ADXL345::getInterruptSource(void)
-{
-    return SingleByteRead(ADXL345_INT_SOURCE_REG);
-}
+void ADXL345::oneByteWrite(int address, char data) {
 
-void ADXL345::sample100avg(float period, int16_t buffer[][3], int16_t *avg, Timer* t)
-{
-    double start_time;
-
-    for(int sample = 0; sample < 100; sample++) {
-        start_time = t->read();
+    int tx = (ADXL345_SPI_WRITE | (address & 0x3F));
 
-        getXYZ(buffer[sample]);
-
-        wait(period - (start_time - t->read()));
-    }
+    nCS_ = 0;
+    //Send address to write to.
+    spi_.write(tx);
+    //Send data to be written.
+    spi_.write(data);
+    nCS_ = 1;
 
-    for(int axis = 0; axis < 3; axis++) {
-        double average = 0.0;
-        for(int sample = 0; sample < 100; sample++)
-            average += buffer[sample][axis];
-        average /= 100.0;
-        avg[axis] = static_cast<int16_t>(average);
-    }
 }
 
-void ADXL345::calibrate(Timer* t, bool store_output, Serial *pc)
-{
-    int16_t data[100][3]; // {x,y,z}, data
-    int16_t data_avg[3];
-    int8_t calibration_offset[3];
-
-    float period = 0.01; // period of sample rate
-
-    // wait 11.1ms
-    wait(0.0111);
+void ADXL345::multiByteRead(int startAddress, char* buffer, int size) {
 
-    pc->puts("Reading old register states... ");
-    // read current register states
-    char bw_rate = getBwRateReg();
-    char power_control = getPowerControl();
-    char data_format = getDataFormatControl();
-
-    pc->puts("Done!\r\nSetting new register states... ");
-    // initalize command sequence
-    setDataFormatControl((ADXL345_16G | ADXL345_FULL_RES));
-    setBwRateReg(ADXL345_100HZ); // 100Hz data rate
-    setPowerControl(0x08); // start measurement
+    int tx = (ADXL345_SPI_READ | ADXL345_MULTI_BYTE | (startAddress & 0x3F));
 
-    // wait 1.1ms
-    wait(0.0111);
-    pc->puts("Done!\r\nSampling... ");
-    //take 100 data points and average (100Hz)
-    sample100avg(period, data, data_avg, t);
-    pc->puts("Done!\r\nCalculating offset values... ");
-    // calculate calibration value
-    calibration_offset[0] = -1 * (data_avg[0] / 4); // x
-    calibration_offset[1] = -1 * (data_avg[1] / 4); // y
-    calibration_offset[2] = -1 * ((data_avg[2] - 256) / 4); // z
+    nCS_ = 0;
+    //Send address to start reading from.
+    spi_.write(tx);
 
-    if(store_output) {
-        pc->puts("Done!\r\nStoring output to file... ");
-        LocalFileSystem local("local");
-        FILE *fp = fopen("/local/OFF_CAL.csv", "w"); // write
-        fprintf(fp, "ADXL345 Calibration offsets\r\nx,%d\r\ny,%d\r\nz,%d\r\n\r\n", calibration_offset[0], calibration_offset[1], calibration_offset[2]);
-
-        fputs("Raw Data:\r\nX,Y,Z\r\n", fp);
-        for(int sample = 0; sample < 100; sample++)
-            fprintf(fp, "%d,%d,%d\r\n",data[sample][0],data[sample][1],data[sample][2]);
-        fclose(fp);
+    for (int i = 0; i < size; i++) {
+        buffer[i] = spi_.write(0x00);
     }
-    pc->puts("Done!\r\nSetting the offset registers... ");
-    // update offset registers
-    for(char axis = 0x00; axis < 0x03; axis++)
-        setOffset(axis,calibration_offset[axis]);
-    pc->puts("Done!\r\nReturning registers to original state... ");
-    // return control registers to original state
-    setDataFormatControl(data_format);
-    setBwRateReg(bw_rate);
-    setPowerControl(power_control);
-    pc->puts("Done!\r\n");
+
+    nCS_ = 1;
+
 }
 
-void ADXL345::calibrate(Timer* t, bool store_output)
-{
-    int16_t data[100][3]; // {x,y,z}, data
-    int16_t data_avg[3];
-    int8_t calibration_offset[3];
+void ADXL345::multiByteWrite(int startAddress, char* buffer, int size) {
 
-    float period = 0.01; // period of sample rate
+    int tx = (ADXL345_SPI_WRITE | ADXL345_MULTI_BYTE | (startAddress & 0x3F));
 
-    // wait 11.1ms
-    wait(0.0111);
-
-    // read current register states
-    char bw_rate = getBwRateReg();
-    char power_control = getPowerControl();
-    char data_format = getDataFormatControl();
-
-    // initalize command sequence
-    setDataFormatControl((ADXL345_16G | ADXL345_FULL_RES));
-    setBwRateReg(ADXL345_100HZ); // 100Hz data rate
-    setPowerControl(0x08); // start measurement
+    nCS_ = 0;
+    //Send address to start reading from.
+    spi_.write(tx);
 
-    // wait 1.1ms
-    wait(0.0111);
-    //take 100 data points and average (100Hz)
-    sample100avg(period, data, data_avg, t);
-    // calculate calibration value
-    calibration_offset[0] = -1 * (data_avg[0] / 4); // x
-    calibration_offset[1] = -1 * (data_avg[1] / 4); // y
-    calibration_offset[2] = -1 * ((data_avg[2] - 256) / 4); // z
-
-    if(store_output) {
-        LocalFileSystem local("local");
-        FILE *fp = fopen("/local/OFF_CAL.csv", "w"); // write
-        fprintf(fp, "ADXL345 Calibration offsets\r\nx,%d\r\ny,%d\r\nz,%d\r\n\r\n", calibration_offset[0], calibration_offset[1], calibration_offset[2]);
+    for (int i = 0; i < size; i++) {
+        buffer[i] = spi_.write(0x00);
+    }
 
-        fputs("Raw Data:\r\nX,Y,Z\r\n", fp);
-        for(int sample = 0; sample < 100; sample++)
-            fprintf(fp, "%d,%d,%d\r\n",data[sample][0],data[sample][1],data[sample][2]);
-        fclose(fp);
-    }
-    // update offset registers
-    for(char axis = 0x00; axis < 0x03; axis++)
-        setOffset(axis,calibration_offset[axis]);
-    // return control registers to original state
-    setDataFormatControl(data_format);
-    setBwRateReg(bw_rate);
-    setPowerControl(power_control);
+    nCS_ = 1;
+
 }
\ No newline at end of file
--- a/ADXL345.h	Tue Nov 06 17:36:40 2012 +0000
+++ b/ADXL345.h	Wed Jan 16 11:10:19 2013 +0000
@@ -1,12 +1,10 @@
 /**
- * @file ADXL345.h
- * @author Tyler Weaver
- * @author Uwe Gartmann
- * @author Used ITG3200 library developed Peter Swanson as template
- * A special thanks to Ewout van Bekkum for all his patient help in developing this library!
+ * @author Aaron Berk
  *
  * @section LICENSE
  *
+ * Copyright (c) 2010 ARM Limited
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
@@ -27,26 +25,22 @@
  *
  * @section DESCRIPTION
  *
- * ADXL345, triple axis, I2C interface, accelerometer.
- *
- * Modified for use with 9DOF sensor stick (no interupt pin access) on HARP project.
+ * ADXL345, triple axis, digital interface, accelerometer.
  *
  * Datasheet:
  *
  * http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf
- */
-
-
+ */  
 
 #ifndef ADXL345_H
 #define ADXL345_H
 
-/*
+/**
  * Includes
  */
 #include "mbed.h"
 
-/*
+/**
  * Defines
  */
 //Registers.
@@ -93,156 +87,53 @@
 #define ADXL345_12HZ5       0x07
 #define ADXL345_6HZ25       0x06
 
-// DATA_FORMAT register
-#define ADXL345_2G          0x00
-#define ADXL345_4G          0x01
-#define ADXL345_8G          0x02
-#define ADXL345_16G         0x03
-#define ADXL345_LJUST       0x04
-#define ADXL345_FULL_RES    0x08
-#define ADXL345_INT_LOW     0x10
-#define ADXL345_SELF_TEST   0x80
-
-// read or write bytes
-#define ADXL345_READ    0xA7
-#define ADXL345_WRITE   0xA6
-#define ADXL345_ADDRESS 0x53   //the ADXL345 7-bit address is 0x53 when ALT ADDRESS is low as it is on the sparkfun chip: when ALT ADDRESS is high the address is 0x1D
-
-/////////////when ALT ADDRESS pin is high:
-//#define ADXL345_READ    0x3B
-//#define ADXL345_WRITE   0x3A
-//#define ADXL345_ADDRESS 0x1D
+#define ADXL345_SPI_READ    0x80
+#define ADXL345_SPI_WRITE   0x00
+#define ADXL345_MULTI_BYTE  0x60
 
 #define ADXL345_X           0x00
 #define ADXL345_Y           0x01
 #define ADXL345_Z           0x02
 
-// modes
-#define MeasurementMode     0x08
-
 /**
- * ADXL345 triple axis accelerometer.
+ * ADXL345 triple axis, digital interface, accelerometer.
  */
-class ADXL345
-{
+class ADXL345 {
 
 public:
 
-    static const char RANGE_BITS = 0x3;
-    static const char RANGE_2G = 0x0;
-    static const char RANGE_4G = 0x1;
-    static const char RANGE_8G = 0x2;
-    static const char RANGE_16G = 0x3;
-
     /**
      * Constructor.
      *
-     * @param mosi mbed pin to use for SDA line of I2C interface.
-     * @param sck mbed pin to use for SCL line of I2C interface.
-     */
-    ADXL345(PinName sda, PinName scl);
-
-
-    /**
-     * Constructor that accepts external i2c interface object.
-     *
-     * @param i2c The I2C interface object to use.
+     * @param mosi mbed pin to use for MOSI line of SPI interface.
+     * @param miso mbed pin to use for MISO line of SPI interface.
+     * @param sck mbed pin to use for SCK line of SPI interface.
+     * @param cs mbed pin to use for not chip select line of SPI interface.
      */
-    ADXL345(I2C &i2c) : i2c_(i2c), myI2c(NULL) {init();}
-
-    /**
-     * Destructor that frees self-allocated I2C object.
-     */
-    ~ADXL345();
-
-    void init();
-
-    /**
-     * Get the output of all three axes.
-     *
-     * @param Pointer to a buffer to hold the accelerometer value for the
-     *        x-axis, y-axis and z-axis [in that order].
-     */
-    void getXYZ(int16_t* readings);
+    ADXL345(PinName mosi, PinName miso, PinName sck, PinName cs);
 
     /**
      * Read the device ID register on the device.
      *
      * @return The device ID code [0xE5]
      */
-    char getDeviceID(void);
-
-    /**
-    * Set the power mode.
-    *
-    * @param mode 0 -> Normal operation.
-    *             1 -> Reduced power operation.
-    */
-    int setPowerMode(char mode);
-
-    /**
-    * Get the BW_RATE register contents
-    *
-    * @returns The contents of BW_RATE register
-    */
-    char getBwRateReg();
-    
-    /**
-    * Set the BW_RATE register contents
-    *
-    * @param Byte to write to BW_RATE register
-    */
-    int setBwRateReg(char);
-
-    /**
-    * Set the power control settings.
-    *
-    * See datasheet for details.
-    *
-    * @param The control byte to write to the POWER_CTL register.
-    */
-    int setPowerControl(char settings);
+    int getDevId(void);
 
     /**
-    * Get the power control settings.
-    *
-    * See datasheet for details.
-    *
-    * @return The contents of the POWER_CTL register.
-    */
-    char getPowerControl(void);
-
-
-    /**
-     * Get the data format settings.
+     * Read the tap threshold on the device.
      *
-     * @return The contents of the DATA_FORMAT register.
+     * @return The tap threshold as an 8-bit number with a scale factor of
+     *         62.5mg/LSB.
      */
-
-    char getDataFormatControl(void);
+    int getTapThreshold(void);
 
     /**
-     * Set the data format settings.
-     *
-     * @param settings The control byte to write to the DATA_FORMAT register.
-     */
-    int setDataFormatControl(char settings);
-
-    /**
-     * Set the data format settings with only specified bits.
+     * Set the tap threshold.
      *
-     * @param settings The control byte to write to the DATA_FORMAT register.
-     * @param mask The mask bits that
+     * @param The tap threshold as an 8-bit number with a scale factor of
+     *        62.5mg/LSB.
      */
-    int setDataFormatControl(char settings, char mask, char *prev = NULL);
-
-    /**
-     * Set the data rate.
-     *
-     * @param rate The rate code (see #defines or datasheet).
-     */
-    int setDataRate(char rate);
-
+    void setTapThreshold(int threshold);
 
     /**
      * Get the current offset for a particular axis.
@@ -253,7 +144,7 @@
      * @return The current offset as an 8-bit 2's complement number with scale
      *         factor 15.6mg/LSB.
      */
-    char getOffset(char axis);
+    int getOffset(int axis);
 
     /**
      * Set the offset for a particular axis.
@@ -264,44 +155,7 @@
      * @param offset The offset as an 8-bit 2's complement number with scale
      *               factor 15.6mg/LSB.
      */
-    int setOffset(char axis, char offset);
-
-    /**
-     * Get the FIFO control settings.
-     *
-     * @return The contents of the FIFO_CTL register.
-     */
-    char getFifoControl(void);
-
-    /**
-     * Set the FIFO control settings.
-     *
-     * @param The control byte to write to the FIFO_CTL register.
-     */
-    int setFifoControl(char settings);
-
-    /**
-     * Get FIFO status.
-     *
-     * @return The contents of the FIFO_STATUS register.
-     */
-    char getFifoStatus(void);
-
-    /**
-     * Read the tap threshold on the device.
-     *
-     * @return The tap threshold as an 8-bit number with a scale factor of
-     *         62.5mg/LSB.
-     */
-    char getTapThreshold(void);
-
-    /**
-     * Set the tap threshold.
-     *
-     * @param The tap threshold as an 8-bit number with a scale factor of
-     *        62.5mg/LSB.
-     */
-    int setTapThreshold(char threshold);
+    void setOffset(int axis, char offset);
 
     /**
      * Get the tap duration required to trigger an event.
@@ -309,7 +163,7 @@
      * @return The max time that an event must be above the tap threshold to
      *         qualify as a tap event, in microseconds.
      */
-    float getTapDuration(void);
+    int getTapDuration(void);
 
     /**
      * Set the tap duration required to trigger an event.
@@ -320,7 +174,7 @@
      *                    625us/LSB. A value of 0 disables the single/double
      *                    tap functions.
      */
-    int setTapDuration(short int duration_us);
+    void setTapDuration(int duration_us);
 
     /**
      * Get the tap latency between the detection of a tap and the time window.
@@ -339,7 +193,7 @@
      *                   second tap event can be detected in milliseconds.
      *                   A value of 0 disables the double tap function.
      */
-    int setTapLatency(short int latency_ms);
+    void setTapLatency(int latency_ms);
 
     /**
      * Get the time of window between tap latency and a double tap.
@@ -356,7 +210,7 @@
      *                  time during which a second valid tap can begin,
      *                  in milliseconds.
      */
-    int setWindowTime(short int window_ms);
+    void setWindowTime(int window_ms);
 
     /**
      * Get the threshold value for detecting activity.
@@ -364,7 +218,7 @@
      * @return The threshold value for detecting activity as an 8-bit number.
      *         Scale factor is 62.5mg/LSB.
      */
-    char getActivityThreshold(void);
+    int getActivityThreshold(void);
 
     /**
      * Set the threshold value for detecting activity.
@@ -374,7 +228,7 @@
      *                  result in undesirable behavior if the activity
      *                  interrupt is enabled.
      */
-    int setActivityThreshold(char threshold);
+    void setActivityThreshold(int threshold);
 
     /**
      * Get the threshold value for detecting inactivity.
@@ -382,7 +236,7 @@
      * @return The threshold value for detecting inactivity as an 8-bit number.
      *         Scale factor is 62.5mg/LSB.
      */
-    char getInactivityThreshold(void);
+    int getInactivityThreshold(void);
 
     /**
      * Set the threshold value for detecting inactivity.
@@ -390,7 +244,7 @@
      * @param threshold The threshold value for detecting inactivity as an
      *                  8-bit number. Scale factor is 62.5mg/LSB.
      */
-    int setInactivityThreshold(char threshold);
+    void setInactivityThreshold(int threshold);
 
     /**
      * Get the time required for inactivity to be declared.
@@ -399,8 +253,8 @@
      *         inactivity threshold for inactivity to be declared, in
      *         seconds.
      */
-    char getTimeInactivity(void);
-
+    int getTimeInactivity(void);
+    
     /**
      * Set the time required for inactivity to be declared.
      *
@@ -410,8 +264,8 @@
      *                   interrupt when the output data is less than the
      *                   threshold inactivity.
      */
-    int setTimeInactivity(char timeInactivity);
-
+    void setTimeInactivity(int timeInactivity);
+    
     /**
      * Get the activity/inactivity control settings.
      *
@@ -429,8 +283,8 @@
      *
      * @return The contents of the ACT_INACT_CTL register.
      */
-    char getActivityInactivityControl(void);
-
+    int getActivityInactivityControl(void);
+    
     /**
      * Set the activity/inactivity control settings.
      *
@@ -448,26 +302,26 @@
      *
      * @param settings The control byte to write to the ACT_INACT_CTL register.
      */
-    int setActivityInactivityControl(char settings);
-
+    void setActivityInactivityControl(int settings);
+    
     /**
      * Get the threshold for free fall detection.
      *
      * @return The threshold value for free-fall detection, as an 8-bit number,
      *         with scale factor 62.5mg/LSB.
      */
-    char getFreefallThreshold(void);
-
+    int getFreefallThreshold(void);
+    
     /**
      * Set the threshold for free fall detection.
      *
      * @return The threshold value for free-fall detection, as an 8-bit number,
-     *         with scale factor 62.5mg/LSB. A value of 0 may result in
+     *         with scale factor 62.5mg/LSB. A value of 0 may result in 
      *         undesirable behavior if the free-fall interrupt is enabled.
      *         Values between 300 mg and 600 mg (0x05 to 0x09) are recommended.
      */
-    int setFreefallThreshold(char threshold);
-
+    void setFreefallThreshold(int threshold);
+    
     /**
      * Get the time required to generate a free fall interrupt.
      *
@@ -475,19 +329,19 @@
      *         the freefall threshold to generate a free-fall interrupt, in
      *         milliseconds.
      */
-    char getFreefallTime(void);
-
+    int getFreefallTime(void);
+    
     /**
      * Set the time required to generate a free fall interrupt.
      *
      * @return The minimum time that the value of all axes must be less than
      *         the freefall threshold to generate a free-fall interrupt, in
      *         milliseconds. A value of 0 may result in undesirable behavior
-     *         if the free-fall interrupt is enabled. Values between 100 ms
+     *         if the free-fall interrupt is enabled. Values between 100 ms 
      *         and 350 ms (0x14 to 0x46) are recommended.
      */
-    int setFreefallTime(short int freefallTime_ms);
-
+    void setFreefallTime(int freefallTime_ms);
+    
     /**
      * Get the axis tap settings.
      *
@@ -501,9 +355,9 @@
      * See datasheet for more details.
      *
      * @return The contents of the TAP_AXES register.
-     */
-    char getTapAxisControl(void);
-
+     */ 
+    int getTapAxisControl(void);
+    
     /**
      * Set the axis tap settings.
      *
@@ -518,141 +372,194 @@
      *
      * @param The control byte to write to the TAP_AXES register.
      */
-    int setTapAxisControl(char settings);
-
+    void setTapAxisControl(int settings);
+    
     /**
      * Get the source of a tap.
      *
      * @return The contents of the ACT_TAP_STATUS register.
      */
-    char getTapSource(void);
-
+    int getTapSource(void);
+    
+    /**
+     * Set the power mode.
+     *
+     * @param mode 0 -> Normal operation.
+     *             1 -> Reduced power operation.
+     */
+    void setPowerMode(char mode);
+    
+    /**
+     * Set the data rate.
+     *
+     * @param rate The rate code (see #defines or datasheet).
+     */
+    void setDataRate(int rate);
+    
     /**
-    * Get the interrupt enable settings.
-    *
-    * @return The contents of the INT_ENABLE register.
-    */
-
-    char getInterruptEnableControl(void);
-
+     * Get the power control settings.
+     *
+     * See datasheet for details.
+     *
+     * @return The contents of the POWER_CTL register.
+     */
+    int getPowerControl(void);
+    
+    /**
+     * Set the power control settings.
+     *
+     * See datasheet for details.
+     *
+     * @param The control byte to write to the POWER_CTL register.
+     */
+    void setPowerControl(int settings);
+    
+    /**
+     * Get the interrupt enable settings.
+     *
+     * @return The contents of the INT_ENABLE register.
+     */
+    int getInterruptEnableControl(void);
+    
     /**
      * Set the interrupt enable settings.
      *
      * @param settings The control byte to write to the INT_ENABLE register.
      */
-    int setInterruptEnableControl(char settings);
-
+    void setInterruptEnableControl(int settings);
+    
     /**
      * Get the interrupt mapping settings.
      *
      * @return The contents of the INT_MAP register.
      */
-    char getInterruptMappingControl(void);
-
+    int getInterruptMappingControl(void);
+    
     /**
      * Set the interrupt mapping settings.
      *
      * @param settings The control byte to write to the INT_MAP register.
      */
-    int setInterruptMappingControl(char settings);
-
+    void setInterruptMappingControl(int settings);
+    
     /**
      * Get the interrupt source.
      *
      * @return The contents of the INT_SOURCE register.
      */
-    char getInterruptSource(void);
-
+    int getInterruptSource(void);
+    
+    /**
+     * Get the data format settings.
+     *
+     * @return The contents of the DATA_FORMAT register.
+     */
+    int getDataFormatControl(void);
+    
+    /**
+     * Set the data format settings.
+     *
+     * @param settings The control byte to write to the DATA_FORMAT register.
+     */
+    void setDataFormatControl(int settings);
+    
     /**
-    * Calibrate using the calibrate routine, sets the offset registers
-    *
-    * 100 samples at 100Hz (1 second)
-    * Sensor should be in x=0g,y=0g,z=1g orientation and held still
-    *
-    * @param pointer to timer object (should already be started)
-    * @param store_output true -> stores offsets in local file system, false -> only offset registers are set
-    * @param serial output (pc) for debugging  
-    */
-    void calibrate(Timer*, bool, Serial*);
+     * Get the output of all three axes.
+     *
+     * @param Pointer to a buffer to hold the accelerometer value for the
+     *        x-axis, y-axis and z-axis [in that order].
+     */
+    void getOutput(int* readings);
+    
+    
+      /**
+     * Get acceleration of X axis.
+     *
+     *@return Accelerometer value for the x-axis.
+     */
+     int getAx();
+     
+     
+     /**
+     * Get acceleration of Y axis.
+     *
+     *@return Accelerometer value for the y-axis
+     */
+     int getAy();
+     
+     
+      /**
+     * Get acceleration of Z axis.
+     *
+     *@return Accelerometer value for the z-axis
+     */
+     int getAz();
+    
+    
+    
+    
+    
     /**
-    * Calibrate using the calibrate routine, sets the offset registers
-    *
-    * 100 samples at 100Hz (1 second)
-    * Sensor should be in x=0g,y=0g,z=1g orientation and held still
-    *
-    * @param pointer to timer object (should already be started)
-    * @param store_output true -> stores offsets in local file system, false -> only offset registers are set
-    */
-    void calibrate(Timer*, bool);
-
+     * Get the FIFO control settings.
+     *
+     * @return The contents of the FIFO_CTL register.
+     */
+    int getFifoControl(void);
+    
+    /**
+     * Set the FIFO control settings.
+     *
+     * @param The control byte to write to the FIFO_CTL register.
+     */
+    void setFifoControl(int settings);
+    
+    /**
+     * Get FIFO status.
+     *
+     * @return The contents of the FIFO_STATUS register.
+     */
+    int getFifoStatus(void);
+    
 private:
 
-    I2C &i2c_;
-
-    I2C *myI2c;
+    SPI        spi_;
+    DigitalOut nCS_;
 
     /**
      * Read one byte from a register on the device.
      *
-     * @param: - the address to be read from
+     * @param address Address of the register to read.
      *
-     * @return: the value of the data read
+     * @return The contents of the register address.
      */
-    char SingleByteRead(char address);
+    int oneByteRead(int address);
 
     /**
      * Write one byte to a register on the device.
      *
-     * @param:
-        - address of the register to write to.
-        - the value of the data to store
+     * @param address Address of the register to write to.
+     * @param data The data to write into the register.
      */
-    int SingleByteWrite(char address, char data);
-
-    /**
-     * Read several consecutive bytes on the device and store them in a given location.
-     *
-     * @param startAddress: The address of the first register to read from.
-     * @param ptr_output: a pointer to the location to store the data being read
-     * @param size: The number of bytes to read.
-     */
-    void multiByteRead(char startAddress, char* ptr_output, int size);
+    void oneByteWrite(int address, char data);
 
     /**
-     * Write several consecutive bytes  on the device.
+     * Read several consecutive bytes on the device.
      *
-     * @param startAddress: The address of the first register to write to.
-     * @param ptr_data: Pointer to a location which contains the data to write.
-     * @param size: The number of bytes to write.
-     */
-    int multiByteWrite(char startAddress, char* ptr_data, int size);
-    
-    /**
-     * Converts little-endian 2's complement byte pair to native byte order of
-     * the CPU and then sign extend it to the CPU's register size.
-     *
-     * Implemented here to make the compiler inline expand it.
+     * @param startAddress The address of the first register to read from.
+     * @param buffer Pointer to a buffer to store data read from the device.
+     * @param size The number of bytes to read.
      */
-    static int wordExtend(const char rx[2]) {
-        // Readings are expressed in 16bit 2's complement, so we must first
-        // concatenate two bytes to make a word and sign extend it to obtain
-        // correct negative values.
-        // ARMCC compiles char as unsigned, which means no sign extension is
-        // performed during bitwise operations to chars. But we should make sure
-        // that lower byte won't extend its sign past upper byte for other
-        // compilers if we want to keep it portable.
-        return int16_t(((unsigned char)rx[1] << 8) | (unsigned char)rx[0]);
-    }
-    
+    void multiByteRead(int startAddress, char* buffer, int size);
+
     /**
-    * Sample 100 times and average
-    *
-    * @param period of sample rate
-    * @param array to hold raw data, should be int16_t[100][3] (sample,axis)
-    * @param array to hold averages, should be 3 in length
-    * @param pointer to timer object
-    */
-    void sample100avg(float, int16_t[][3], int16_t*, Timer*);
+     * Write several consecutive bytes on the device.
+     *
+     * @param startAddress The address of the first register to write to.
+     * @param buffer Pointer to a buffer which contains the data to write.
+     * @param size The number of bytes to write.
+     */
+    void multiByteWrite(int startAddress, char* buffer, int size);
+
 };
 
 #endif /* ADXL345_H */