SCA3000 triple axis digital interface accelerometer

SCA3000.cpp

Committer:
aberk
Date:
2011-06-09
Revision:
1:f5f2e79304fb
Parent:
0:fe041345c169

File content as of revision 1:f5f2e79304fb:

/**
 * @author Aaron Berk
 *
 * @section LICENSE
 *
 * 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
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * @section DESCRIPTION
 *
 * SCA3000, triple axis, digital interface, accelerometer.
 *
 * Datasheet:
 *
 * http://www.sparkfun.com/datasheets/Sensors/Accelerometer/SCA3000-D01.pdf
 */

/**
 * Includes
 */
#include "SCA3000.h"

SCA3000::SCA3000(PinName mosi,
                 PinName miso,
                 PinName sck,
                 PinName cs,
                 PinName nr) : spi_(mosi, miso, sck), nCS_(cs), nR_(nr) {

    //1MHz rate.
    spi_.frequency(1000000);
    //8-bit frame, POL = 0, PHA = 0.
    spi_.format(8,0);
    //Chip select is active low [so set it high initially].
    nCS_ = 1;
    //Pulse reset.
    nR_ = 0;
    wait(0.1);
    nR_ = 1;

    int status = 0;
    //Check whether the device successfully reset by reading
    //the CSME bit of the STATUS register.
    //0 => no error
    //1 => error
    status = oneByteRead(SCA3000_STATUS_REG);
    //CSME bit = 1... uh oh...
    if (status & 0x2) {
    
    }

}

int SCA3000::getRevId(void) {

    return oneByteRead(SCA3000_REVID_REG);

}

float SCA3000::getAcceleration(int axis) {

    return getCounts(axis) * 0.75;

}

int SCA3000::getCounts(int axis){

    int acceleration = 0;
    int axis_lsb     = 0;
    int axis_msb     = 0;

    switch (axis) {

        case SCA3000_X_AXIS:

            axis_lsb = oneByteRead(SCA3000_X_LSB);
            axis_msb = oneByteRead(SCA3000_X_MSB);
            
            break;

        case SCA3000_Y_AXIS:

            axis_lsb = oneByteRead(SCA3000_Y_LSB);
            axis_msb = oneByteRead(SCA3000_Y_MSB);
            
            break;

        case SCA3000_Z_AXIS:

            axis_lsb = oneByteRead(SCA3000_Z_LSB);
            axis_msb = oneByteRead(SCA3000_Z_MSB);
            
            break;

            //An invalid axis value has been passed.
        default:
        
            break;

    }

    int counts = ( axis_msb << 8 | axis_lsb );
    
    //If this looks like nonsense it's because
    //the datasheet is completely wrong.
    if(counts & 0x8000){
        counts = (counts >> 3) & 0x1FFF;
        counts = (~counts & 0x1FFF) + 1;
        acceleration = counts * -1;
    }
    else{
        counts = (counts >> 3) & 0xFFF;
        acceleration = counts;
    }
    
    return acceleration;
    
}

int SCA3000::oneByteRead(int address) {

    //Register address sits in the first 6 bits of the transmission.
    int tx = ((address << 2) | SCA3000_SPI_READ);
    int rx = 0;

    nCS_ = 0;
    //Send address to read from.
    spi_.write(tx);
    //Read back contents of address.
    rx = spi_.write(0x00);
    nCS_ = 1;

    return rx;

}

void SCA3000::oneByteWrite(int address, char data) {

    //Register address sits in the first 6 bits of the transmission.
    int tx = ((address << 2) | SCA3000_SPI_WRITE);

    nCS_ = 0;
    //Send address to write to.
    spi_.write(tx);
    //Send data to be written.
    spi_.write(data);
    nCS_ = 1;

}