Kazushi Mukaiyama / LS302i2c
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LIS302i2c.cpp Source File

LIS302i2c.cpp

00001 /* mbed LIS302 Accelerometer Library
00002  * Copyright (c) 2008-2010, sford, cstyles, wreynolds
00003  * modified for i2c version by Kazushi Mukaiyama 2010
00004  *
00005  * Permission is hereby granted, free of charge, to any person obtaining a copy
00006  * of this software and associated documentation files (the "Software"), to deal
00007  * in the Software without restriction, including without limitation the rights
00008  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009  * copies of the Software, and to permit persons to whom the Software is
00010  * furnished to do so, subject to the following conditions:
00011  *
00012  * The above copyright notice and this permission notice shall be included in
00013  * all copies or substantial portions of the Software.
00014  *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021  * THE SOFTWARE.
00022  */
00023 
00024 #include "LIS302i2c.h"
00025 #include "mbed.h"
00026 
00027 #define LIS302_WHOAMI               0x0F
00028 #define LIS302_CTRL_REG1            0x20
00029 #define LIS302_CTRL_REG2            0x21
00030 #define LIS302_CTRL_REG3            0x22
00031 #define LIS302_HP_FILTER_RST        0x23
00032 #define LIS302_STATUS_REG           0x27
00033 #define LIS302_OUTX                 0x29
00034 #define LIS302_OUTY                 0x2B
00035 #define LIS302_OUTZ                 0x2D
00036 #define LIS302_ALL_AXIS             0x28
00037 #define LIS302_FF_WU_CFG1           0x30
00038 #define LIS302_FF_WU_SRC_1          0x31
00039 #define LIS302_FF_WU_THS_1          0x32
00040 #define LIS302_FF_WU_DURATION_1     0x33
00041 #define LIS302_FF_WU_CFG_2          0x34
00042 #define LIS302_FF_WU_SRC_2          0x35
00043 #define LIS302_FF_WU_THS_2          0x36
00044 #define LIS302_FF_WU_DURATION_2     0x37
00045 #define LIS302_CLICK_CFG            0x38
00046 #define LIS302_CLICK_SRC            0x39
00047 #define LIS302_CLICK_THSY_X         0x3B
00048 #define LIS302_CLICK_THSZ           0x3C
00049 #define LIS302_READ                 0x80
00050 #define LIS302_WRITE                0x00
00051 
00052 #define LIS302_STATUS_X_AVAILABLE 0x1
00053 #define LIS302_STATUS_Y_AVAILABLE 0x2
00054 #define LIS302_STATUS_Z_AVAILABLE 0x4
00055 
00056 #define FACTOR_2g 55.6
00057 #define FACTOR_8g 13.9
00058 
00059 LIS302i2c::LIS302i2c(int addr, PinName sda, PinName scl)
00060     : _i2c(sda, scl) {
00061 
00062     _addr = addr<<1;
00063 
00064     // Set up the i2c interface
00065     //_i2c.frequency(1000000);
00066 
00067     // Write to CTRL_REG1
00068     _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG1);
00069     _cmd[1] = 0x47;
00070     _i2c.write(_addr, _cmd, 2);
00071 
00072     // Write to CTRL_REG2
00073     _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG2);
00074     _cmd[1] = 0x40;
00075     _i2c.write(_addr, _cmd, 2);
00076 
00077     // Write to CTRL_REG3
00078     _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG3);
00079     _cmd[1] = 0x00;  // This is default anyway
00080     _i2c.write(_addr, _cmd, 2);
00081 
00082     //range(0);
00083     //calibrate();
00084 }
00085 
00086 void LIS302i2c::update()
00087 {
00088     while(!(status() & LIS302_STATUS_X_AVAILABLE));
00089     
00090     _cmd[0] = (LIS302_READ | LIS302_ALL_AXIS);
00091     _i2c.write(_addr, _cmd, 1);
00092     _i2c.read(_addr, _cmd, 6);
00093     
00094     x = (signed char)_cmd[1]/127.0;
00095     y = (signed char)_cmd[3]/127.0;
00096     z = (signed char)_cmd[5]/127.0;
00097 }
00098 
00099 float LIS302i2c::getX() {
00100     // wait for a new sample
00101     while(!(status() & LIS302_STATUS_X_AVAILABLE));
00102 
00103     _cmd[0] = (LIS302_READ | LIS302_OUTX);
00104     _i2c.write(_addr, _cmd, 1);
00105     _i2c.read(_addr, _cmd, 1);
00106     signed char raw = _cmd[0];
00107     
00108     return raw/127.0;
00109     //float gradient = (2.0/(_maxx-_minx));
00110     //return (gradient*(float)(raw)/_factor)+((-gradient*_maxx)+1);
00111 }
00112 
00113 float LIS302i2c::getY() {
00114     // wait for a new sample
00115     while(!(status() & LIS302_STATUS_Y_AVAILABLE));
00116 
00117     _cmd[0] = (LIS302_READ | LIS302_OUTY);
00118     _i2c.write(_addr, _cmd, 1);
00119     _i2c.read(_addr, _cmd, 1);
00120     signed char raw = _cmd[0];
00121 
00122     return raw/127.0;
00123     //float gradient = (2.0/(_maxy-_miny));
00124     //return (gradient*(float)(raw)/_factor)+((-gradient*_maxy)+1);
00125 }
00126 
00127 float LIS302i2c::getZ() {
00128     // wait for a new sample
00129     while(!(status() & LIS302_STATUS_Z_AVAILABLE));
00130 
00131     _cmd[0] = (LIS302_READ | LIS302_OUTZ);
00132     _i2c.write(_addr, _cmd, 1);
00133     _i2c.read(_addr, _cmd, 1);
00134     signed char raw = _cmd[0];
00135 
00136     return raw/127.0;
00137     //float gradient = (2.0/(_maxz-_minz));
00138     //return (gradient*(float)(raw)/_factor)+((-gradient*_maxz)+1);
00139 }
00140 
00141 void LIS302i2c::range(int g) {
00142 
00143     // fetch the current CRTL_REG1
00144     _cmd[0] = (LIS302_READ | LIS302_CTRL_REG1);
00145     _i2c.write(_addr, _cmd, 1);
00146     _i2c.read(_addr, _cmd, 1);
00147     char value = _cmd[0];
00148 
00149     // set the range bit, and the calculation factor
00150     if(g) {
00151         value |= 0x20; // 8g
00152         _factor = FACTOR_8g;
00153     } else {
00154         value &= ~0x20; // 2g
00155         _factor = FACTOR_2g;
00156     }
00157 
00158     _cmd[0] = (LIS302_WRITE | LIS302_CTRL_REG1);
00159     _cmd[1] = value;
00160     _i2c.write(_addr, _cmd, 2);
00161 }
00162 
00163 void LIS302i2c::calibrate(float maxx, float minx, float maxy, float miny, float maxz, float minz) {
00164     _maxx = maxx;
00165     _minx = minx;
00166     _maxy = maxy;
00167     _miny = miny;
00168     _maxz = maxz;
00169     _minz = minz;
00170 }
00171 
00172 char LIS302i2c::whoami() {
00173     _cmd[0] = (LIS302_READ | LIS302_WHOAMI);
00174     _i2c.write(_addr, _cmd, 1);
00175     _i2c.read(_addr, _cmd, 1);
00176     char value = _cmd[0];
00177     return value;
00178 }
00179 
00180 char LIS302i2c::status() {
00181     _cmd[0] = 0xA7;
00182     _i2c.write(_addr, _cmd, 1);
00183     _cmd[0] = (LIS302_READ | LIS302_STATUS_REG);
00184     _i2c.write(_addr, _cmd, 1);
00185     _i2c.read(_addr, _cmd, 1);
00186     char value = _cmd[0];
00187     return value;
00188 }