An i2c version of mbed LIS302 Accelerometer Library by sford, cstyles, wreynolds. The return data is raw yet. It seems from -0x55 to 0x55 though I think it returns -0x7F to 0x7F. Humm... Why?

LIS302i2c.cpp

Committer:
kazushi2008
Date:
2010-10-10
Revision:
0:4ef465f255d0

File content as of revision 0:4ef465f255d0:

/* mbed LIS302 Accelerometer Library
 * Copyright (c) 2008-2010, sford, cstyles, wreynolds
 * modified for i2c version by Kazushi Mukaiyama 2010
 *
 * 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.
 */

#include "LIS302i2c.h"
#include "mbed.h"

#define LIS302_WHOAMI               0x0F
#define LIS302_CTRL_REG1            0x20
#define LIS302_CTRL_REG2            0x21
#define LIS302_CTRL_REG3            0x22
#define LIS302_HP_FILTER_RST        0x23
#define LIS302_STATUS_REG           0x27
#define LIS302_OUTX                 0x29
#define LIS302_OUTY                 0x2B
#define LIS302_OUTZ                 0x2D
#define LIS302_ALL_AXIS             0x28
#define LIS302_FF_WU_CFG1           0x30
#define LIS302_FF_WU_SRC_1          0x31
#define LIS302_FF_WU_THS_1          0x32
#define LIS302_FF_WU_DURATION_1     0x33
#define LIS302_FF_WU_CFG_2          0x34
#define LIS302_FF_WU_SRC_2          0x35
#define LIS302_FF_WU_THS_2          0x36
#define LIS302_FF_WU_DURATION_2     0x37
#define LIS302_CLICK_CFG            0x38
#define LIS302_CLICK_SRC            0x39
#define LIS302_CLICK_THSY_X         0x3B
#define LIS302_CLICK_THSZ           0x3C
#define LIS302_READ                 0x80
#define LIS302_WRITE                0x00

#define LIS302_STATUS_X_AVAILABLE 0x1
#define LIS302_STATUS_Y_AVAILABLE 0x2
#define LIS302_STATUS_Z_AVAILABLE 0x4

#define FACTOR_2g 55.6
#define FACTOR_8g 13.9

LIS302i2c::LIS302i2c(int addr, PinName sda, PinName scl)
    : _i2c(sda, scl) {

    _addr = addr<<1;

    // Set up the i2c interface
    //_i2c.frequency(1000000);

    // Write to CTRL_REG1
    _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG1);
    _cmd[1] = 0x47;
    _i2c.write(_addr, _cmd, 2);

    // Write to CTRL_REG2
    _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG2);
    _cmd[1] = 0x40;
    _i2c.write(_addr, _cmd, 2);

    // Write to CTRL_REG3
    _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG3);
    _cmd[1] = 0x00;  // This is default anyway
    _i2c.write(_addr, _cmd, 2);

    //range(0);
    //calibrate();
}

void LIS302i2c::update()
{
    while(!(status() & LIS302_STATUS_X_AVAILABLE));
    
    _cmd[0] = (LIS302_READ | LIS302_ALL_AXIS);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 6);
    
    x = (signed char)_cmd[1]/127.0;
    y = (signed char)_cmd[3]/127.0;
    z = (signed char)_cmd[5]/127.0;
}

float LIS302i2c::getX() {
    // wait for a new sample
    while(!(status() & LIS302_STATUS_X_AVAILABLE));

    _cmd[0] = (LIS302_READ | LIS302_OUTX);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 1);
    signed char raw = _cmd[0];
    
    return raw/127.0;
    //float gradient = (2.0/(_maxx-_minx));
    //return (gradient*(float)(raw)/_factor)+((-gradient*_maxx)+1);
}

float LIS302i2c::getY() {
    // wait for a new sample
    while(!(status() & LIS302_STATUS_Y_AVAILABLE));

    _cmd[0] = (LIS302_READ | LIS302_OUTY);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 1);
    signed char raw = _cmd[0];

    return raw/127.0;
    //float gradient = (2.0/(_maxy-_miny));
    //return (gradient*(float)(raw)/_factor)+((-gradient*_maxy)+1);
}

float LIS302i2c::getZ() {
    // wait for a new sample
    while(!(status() & LIS302_STATUS_Z_AVAILABLE));

    _cmd[0] = (LIS302_READ | LIS302_OUTZ);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 1);
    signed char raw = _cmd[0];

    return raw/127.0;
    //float gradient = (2.0/(_maxz-_minz));
    //return (gradient*(float)(raw)/_factor)+((-gradient*_maxz)+1);
}

void LIS302i2c::range(int g) {

    // fetch the current CRTL_REG1
    _cmd[0] = (LIS302_READ | LIS302_CTRL_REG1);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 1);
    char value = _cmd[0];

    // set the range bit, and the calculation factor
    if(g) {
        value |= 0x20; // 8g
        _factor = FACTOR_8g;
    } else {
        value &= ~0x20; // 2g
        _factor = FACTOR_2g;
    }

    _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG1);
    _cmd[1] = value;
    _i2c.write(_addr, _cmd, 2);
}

void LIS302i2c::calibrate(float maxx, float minx, float maxy, float miny, float maxz, float minz) {
    _maxx = maxx;
    _minx = minx;
    _maxy = maxy;
    _miny = miny;
    _maxz = maxz;
    _minz = minz;
}

char LIS302i2c::whoami() {
    _cmd[0] = (LIS302_READ | LIS302_WHOAMI);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 1);
    char value = _cmd[0];
    return value;
}

char LIS302i2c::status() {
    _cmd[0] = 0xA7;
    _i2c.write(_addr, _cmd, 1);
    _cmd[0] = (LIS302_READ | LIS302_STATUS_REG);
    _i2c.write(_addr, _cmd, 1);
    _i2c.read(_addr, _cmd, 1);
    char value = _cmd[0];
    return value;
}