1 /*
2  * Author: Brendan Le Foll<brendan.le.foll@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  * Permission is hereby granted, free of charge, to any person obtaining
9  * a copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Software, and to
13  * permit persons to whom the Software is furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be
17  * included in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27 #pragma once
28 
29 #include <string.h>
30 #include <mraa/i2c.hpp>
31 #include <math.h>
32 
33 namespace upm {
34 
35 /* LSM303 Address definitions */
36 #define LSM303_MAG 0x1E // assuming SA0 grounded
37 #define LSM303_ACC 0x18 // assuming SA0 grounded
38 
39 /* LSM303 Register definitions */
40 #define CTRL_REG1_A 0x20
41 #define CTRL_REG2_A 0x21
42 #define CTRL_REG3_A 0x22
43 #define CTRL_REG4_A 0x23
44 #define CTRL_REG5_A 0x24
45 
46 #define CRA_REG_M 0x00
47 #define CRB_REG_M 0x01
48 
49 #define MR_REG_M 0x02
50 #define OUT_X_H_M 0x03
51 
52 #define OUT_X_L_A 0x28
53 #define OUT_X_H_A 0x29
54 #define OUT_Y_L_A 0x2A
55 #define OUT_Y_H_A 0x2B
56 #define OUT_Z_L_A 0x2C
57 #define OUT_Z_H_A 0x2D
58 
59 #define X 0
60 #define Y 1
61 #define Z 2
62 
63 /**
64  * @brief LSM303 Accelerometer/Compass library
65  * @defgroup lsm303 libupm-lsm303
66  * @ingroup seeed adafruit i2c accelerometer compass
67  */
68 
69 /**
70  * @library lsm303
71  * @sensor lsm303
72  * @comname LSM303 Accelerometer & Compass
73  * @altname Grove 6-Axis Accelerometer & Compass
74  * @type accelerometer compass
75  * @man seeed adafruit
76  * @web http://www.seeedstudio.com/wiki/Grove_-_6-Axis_Accelerometer%26Compass
77  * @con i2c
78  *
79  * @brief API for the LSM303 Accelerometer & Compass
80  *
81  * This module defines the LSM303DLH 3-axis magnetometer/3-axis accelerometer.
82  * This module was tested with the Seeed Studio* Grove 6-Axis Accelerometer & Compass
83  * module used over I2C. The magnometer and acceleromter are accessed
84  * at two seperate I2C addresses.
85  *
86  * @image html lsm303.jpeg
87  * @snippet lsm303.cxx Interesting
88  */
89 class LSM303 {
90     public:
91          /**
92          * Instantiates an LSM303 object
93          *
94          * @param i2c bus
95          * @param addr Magnetometer
96          * @param addr Accelerometer
97          */
98         LSM303 (int bus,
99                 int addrMag=LSM303_MAG,
100                 int addrAcc=LSM303_ACC,
101                 int accScale=8);
102 
103         /**
104          * LSM303 object destructor
105          * where is no more need for this here - I2c connection will be stopped
106          * automatically when m_i2c variable will go out of scope
107          * ~LSM303 ();
108          **/
109 
110         /**
111          * Gets the current heading; headings <0 indicate an error has occurred
112          *
113          * @return float
114          */
115         float getHeading();
116 
117         /**
118          * Gets the coordinates in the XYZ order
119          */
120         mraa::Result getCoordinates();
121 
122         /**
123          * Gets accelerometer values
124          * Should be called before other "get" functions for acceleration
125          */
126         mraa::Result getAcceleration();
127 
128         /**
129          * Gets raw coordinate data; it is updated when getCoordinates() is called
130          */
131         int16_t* getRawCoorData();
132 
133         /**
134          * Gets the X component of the coordinates data
135          */
136         int16_t getCoorX();
137 
138         /**
139          * Gets the Y component of the coordinates data
140          */
141         int16_t getCoorY();
142 
143         /**
144          * Gets the Z component of the coordinates data
145          */
146         int16_t getCoorZ();
147 
148         /**
149          * Gets raw accelerometer data; it is updated when getAcceleration() is called
150          */
151         int16_t* getRawAccelData();
152 
153         /**
154          * Gets the X component of the acceleration data
155          */
156         int16_t getAccelX();
157 
158         /**
159          * Gets the Y component of the acceleration data
160          */
161         int16_t getAccelY();
162 
163         /**
164          * Gets the Z component of the acceleration data
165          */
166         int16_t getAccelZ();
167 
168     private:
169         int readThenWrite(uint8_t reg);
170         mraa::Result setRegisterSafe(uint8_t slave, uint8_t sregister, uint8_t data);
171 
172         mraa::I2c m_i2c;
173         int m_addrMag;
174     int m_addrAcc;
175         uint8_t buf[6];
176         int16_t coor[3];
177         int16_t accel[3];
178 };
179 
180 }
181