Home | History | Annotate | Download | only in lsm303d
      1 /*
      2  * Author: Brendan Le Foll<brendan.le.foll (at) intel.com>
      3  * Copyright (c) 2014 Intel Corporation.
      4  *
      5  * Code based on LSM303DLH sample by Jim Lindblom SparkFun Electronics
      6  * and the CompensatedCompass.ino by Frankie Chu from SeedStudio
      7  *
      8  * Further modifications to port to the LSM303d by <bruce.j.beare (at) intel.com>
      9  *
     10  * Permission is hereby granted, free of charge, to any person obtaining
     11  * a copy of this software and associated documentation files (the
     12  * "Software"), to deal in the Software without restriction, including
     13  * without limitation the rights to use, copy, modify, merge, publish,
     14  * distribute, sublicense, and/or sell copies of the Software, and to
     15  * permit persons to whom the Software is furnished to do so, subject to
     16  * the following conditions:
     17  *
     18  * The above copyright notice and this permission notice shall be
     19  * included in all copies or substantial portions of the Software.
     20  *
     21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     25  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     26  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     27  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     28  */
     29 #pragma once
     30 
     31 #include <string.h>
     32 #include <mraa/i2c.hpp>
     33 #include <math.h>
     34 
     35 namespace upm {
     36 /**
     37  * @brief LSM303d Accelerometer/Compass library
     38  * @defgroup lsm303d libupm-lsm303d
     39  * @ingroup seeed adafruit i2c accelerometer compass
     40  */
     41 
     42 /**
     43  * @library lsm303d
     44  * @sensor lsm303d
     45  * @comname LSM303d Accelerometer & Compass
     46  * @altname Grove 6-Axis Accelerometer & Compass
     47  * @type accelerometer compass
     48  * @man seeed adafruit
     49  * @web http://www.seeedstudio.com/wiki/Grove_-_6-Axis_Accelerometer%26Compass
     50  * @con i2c
     51  *
     52  * @brief API for the LSM303d Accelerometer & Compass
     53  *
     54  * This module defines the LSM303d 3-axis magnetometer/3-axis accelerometer.
     55  * This module was tested with the Seeed Studio* Grove 6-Axis Accelerometer & Compass
     56  * version 2.0 module used over I2C. The magnometer and acceleromter are accessed
     57  * at two seperate I2C addresses.
     58  *
     59  * @image html lsm303d.jpeg
     60  * @snippet lsm303d.cxx Interesting
     61  */
     62 class LSM303d {
     63   public:
     64 
     65     /* Address definitions for the grove 6DOF v2.0 */
     66     typedef enum {
     67         LSM303d_ADDR = 0x1E
     68     } GROVE_6DOF_ADDRS_T;
     69 
     70     typedef enum {
     71         LM303D_SCALE_2G  = 2,
     72         LM303D_SCALE_4G  = 4,
     73         LM303D_SCALE_6G  = 6,
     74         LM303D_SCALE_8G  = 8,
     75         LM303D_SCALE_16G = 16
     76     } LSM303D_SCALE_T;
     77 
     78     typedef enum {
     79         X = 0,
     80         Y = 1,
     81         Z = 2
     82     } XYZ_T;
     83 
     84     /**
     85     * Instantiates an LSM303d object
     86     *
     87     * @param i2c bus
     88     * @param addr Magnetometer
     89     * @param addr Accelerometer
     90     */
     91    LSM303d (int bus,
     92            int addr=LSM303d_ADDR,
     93            int accScale=LM303D_SCALE_4G);
     94 
     95    /**
     96     * LSM303d object destructor
     97     * where is no more need for this here - I2c connection will be stopped
     98     * automatically when m_i2c variable will go out of scope
     99     * ~LSM303d ();
    100     **/
    101 
    102    /**
    103     * Gets the current heading; headings <0 indicate an error has occurred
    104     *
    105     * @return float
    106     */
    107    float getHeading();
    108 
    109    /**
    110     * Gets the coordinates in the XYZ order
    111     */
    112    mraa::Result getCoordinates();
    113 
    114    /**
    115     * Gets accelerometer values
    116     * Should be called before other "get" functions for acceleration
    117     */
    118    mraa::Result getAcceleration();
    119 
    120    /**
    121     * Gets raw coordinate data; it is updated when getCoordinates() is called
    122     */
    123    int16_t* getRawCoorData();
    124 
    125    /**
    126     * Gets the X component of the coordinates data
    127     */
    128    int16_t getCoorX();
    129 
    130    /**
    131     * Gets the Y component of the coordinates data
    132     */
    133    int16_t getCoorY();
    134 
    135    /**
    136     * Gets the Z component of the coordinates data
    137     */
    138    int16_t getCoorZ();
    139 
    140    /**
    141     * Gets raw accelerometer data; it is updated when getAcceleration() is called
    142     */
    143    int16_t* getRawAccelData();
    144 
    145    /**
    146     * Gets the X component of the acceleration data
    147     */
    148    int16_t getAccelX();
    149 
    150    /**
    151     * Gets the Y component of the acceleration data
    152     */
    153    int16_t getAccelY();
    154 
    155    /**
    156     * Gets the Z component of the acceleration data
    157     */
    158    int16_t getAccelZ();
    159 
    160   private:
    161 
    162     /* LSM303d Register definitions */
    163     typedef enum {
    164         STATUS_M     = 0x7,
    165         OUT_X_L_M    = 0x8,
    166         OUT_X_H_M    = 0x9,
    167         OUT_Y_L_M    = 0xA,
    168         OUT_Y_H_M    = 0xB,
    169         OUT_Z_L_M    = 0xC,
    170         OUT_Z_H_M    = 0xD,
    171 
    172         CTRL_REG0    = 0x1f,
    173         CTRL_REG1    = 0x20,
    174         CTRL_REG2    = 0x21,
    175         CTRL_REG3    = 0x22,
    176         CTRL_REG4    = 0x23,
    177         CTRL_REG5    = 0x24,
    178         CTRL_REG6    = 0x25,
    179         CTRL_REG7    = 0x26,
    180 
    181         STATUS_REGA  = 0x27,
    182 
    183         OUT_X_L_A    = 0x28,
    184         OUT_X_H_A    = 0x29,
    185         OUT_Y_L_A    = 0x2A,
    186         OUT_Y_H_A    = 0x2B,
    187         OUT_Z_L_A    = 0x2C,
    188         OUT_Z_H_A    = 0x2D,
    189 
    190         FIFO_CTRL    = 0x2E,
    191         FIFO_SRC     = 0x2F,
    192 
    193         IG_CFG1      = 0x30,
    194         IG_SRC1      = 0x31,
    195         IG_THS1      = 0x32,
    196         IG_DUR1      = 0x33,
    197 
    198         IG_CFG2      = 0x34,
    199         IG_SRC2      = 0x35,
    200         IG_THS2      = 0x36,
    201         IG_DUR2      = 0x37,
    202 
    203         CLICK_CFG    = 0x38,
    204         CLICK_SRC    = 0x39,
    205         CLICK_THS    = 0x3A,
    206 
    207         TIME_LIMIT   = 0x3B,
    208         TIME_LATEN   = 0x3C,
    209         TIME_WINDO   = 0x3D,
    210 
    211         ACT_THS      = 0x3E,
    212         ACT_DUR      = 0x3F,
    213     } LSM303d_REGS_T;
    214 
    215    int writeThenRead(uint8_t reg);
    216    mraa::Result setRegisterSafe(uint8_t slave, uint8_t sregister, uint8_t data);
    217 
    218    mraa::I2c m_i2c;
    219    int m_addr;
    220 
    221    uint8_t buf[6];
    222    int16_t coor[3];
    223    int16_t accel[3];
    224 };
    225 
    226 }
    227