Browse Source

h3lis331dl: Initial implementation

The driver implements support for the Grove 3-Axis Digital
Accelerometer(±400g), using the h3lis331dl chip.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
Jon Trulson 9 years ago
parent
commit
c8d0aee873

+ 3
- 0
examples/c++/CMakeLists.txt View File

@@ -119,6 +119,7 @@ add_executable (si114x-example si114x.cxx)
119 119
 add_executable (maxsonarez-example maxsonarez.cxx)
120 120
 add_executable (hm11-example hm11.cxx)
121 121
 add_executable (ht9170-example ht9170.cxx)
122
+add_executable (h3lis331dl-example h3lis331dl.cxx)
122 123
 
123 124
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
124 125
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -216,6 +217,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/si114x)
216 217
 include_directories (${PROJECT_SOURCE_DIR}/src/maxsonarez)
217 218
 include_directories (${PROJECT_SOURCE_DIR}/src/hm11)
218 219
 include_directories (${PROJECT_SOURCE_DIR}/src/ht9170)
220
+include_directories (${PROJECT_SOURCE_DIR}/src/h3lis331dl)
219 221
 
220 222
 target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
221 223
 target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@@ -336,3 +338,4 @@ target_link_libraries (si114x-example si114x ${CMAKE_THREAD_LIBS_INIT})
336 338
 target_link_libraries (maxsonarez-example maxsonarez ${CMAKE_THREAD_LIBS_INIT})
337 339
 target_link_libraries (hm11-example hm11 ${CMAKE_THREAD_LIBS_INIT})
338 340
 target_link_libraries (ht9170-example ht9170 ${CMAKE_THREAD_LIBS_INIT})
341
+target_link_libraries (h3lis331dl-example h3lis331dl ${CMAKE_THREAD_LIBS_INIT})

+ 80
- 0
examples/c++/h3lis331dl.cxx View File

@@ -0,0 +1,80 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <signal.h>
27
+#include <iostream>
28
+#include "h3lis331dl.h"
29
+
30
+using namespace std;
31
+using namespace upm;
32
+
33
+int shouldRun = true;
34
+
35
+void sig_handler(int signo)
36
+{
37
+  if (signo == SIGINT)
38
+    shouldRun = false;
39
+}
40
+
41
+int main(int argc, char **argv)
42
+{
43
+  signal(SIGINT, sig_handler);
44
+
45
+//! [Interesting]
46
+  // Instantiate an H3LIS331DL on I2C bus 0
47
+
48
+  upm::H3LIS331DL *accel = new upm::H3LIS331DL(H3LIS331DL_I2C_BUS, 
49
+                                               H3LIS331DL_DEFAULT_I2C_ADDR);
50
+
51
+  // Initialize the device with default values
52
+  accel->init();
53
+
54
+  while (shouldRun)
55
+    {
56
+      int x, y, z;
57
+      float ax, ay, az;
58
+
59
+      accel->update();
60
+
61
+      accel->getRawXYZ(&x, &y, &z);
62
+      accel->getAcceleration(&ax, &ay, &az);
63
+
64
+      cout << "Raw: X = " << x << " Y = " << y << " Z = " << z << endl;
65
+      
66
+      cout << "Acceleration: AX = " << ax << " AY = " << ay << " AZ = " << az
67
+           << endl;
68
+
69
+      cout << endl;
70
+
71
+      usleep(500000);
72
+    }
73
+
74
+//! [Interesting]
75
+
76
+  cout << "Exiting..." << endl;
77
+
78
+  delete accel;
79
+  return 0;
80
+}

+ 91
- 0
examples/javascript/h3lis331dl.js View File

@@ -0,0 +1,91 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+
4
+/*
5
+* Author: Jon Trulson <jtrulson@ics.com>
6
+* Copyright (c) 2015 Intel Corporation.
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
+
28
+var digitalAccelerometer = require('jsupm_h3lis331dl');
29
+
30
+// Instantiate an H3LIS331DL on I2C bus 0
31
+var myDigitalAccelerometer = new digitalAccelerometer.H3LIS331DL(
32
+    digitalAccelerometer.H3LIS331DL_I2C_BUS, 
33
+    digitalAccelerometer.H3LIS331DL_DEFAULT_I2C_ADDR);
34
+
35
+// Initialize the device with default values
36
+myDigitalAccelerometer.init();
37
+
38
+var x, y, z;
39
+x = digitalAccelerometer.new_intp();
40
+y = digitalAccelerometer.new_intp();
41
+z = digitalAccelerometer.new_intp();
42
+
43
+var ax, ay, az;
44
+ax = digitalAccelerometer.new_floatp();
45
+ay = digitalAccelerometer.new_floatp();
46
+az = digitalAccelerometer.new_floatp();
47
+
48
+var outputStr;
49
+
50
+var myInterval = setInterval(function()
51
+{
52
+	myDigitalAccelerometer.update();
53
+	myDigitalAccelerometer.getRawXYZ(x, y, z);
54
+	outputStr = "Raw: X = " + digitalAccelerometer.intp_value(x) +
55
+	" Y = " + digitalAccelerometer.intp_value(y) +
56
+	" Z = " + digitalAccelerometer.intp_value(z);
57
+	console.log(outputStr);
58
+
59
+	myDigitalAccelerometer.getAcceleration(ax, ay, az);
60
+	outputStr = "Acceleration: AX = " 
61
+		+ roundNum(digitalAccelerometer.floatp_value(ax), 6)
62
+		+ " AY = " + roundNum(digitalAccelerometer.floatp_value(ay), 6) 
63
+		+ " AZ = " + roundNum(digitalAccelerometer.floatp_value(az), 6);
64
+	console.log(outputStr);
65
+}, 500);
66
+
67
+// round off output to match C example, which has 6 decimal places
68
+function roundNum(num, decimalPlaces)
69
+{
70
+	var extraNum = (1 / (Math.pow(10, decimalPlaces) * 1000));
71
+	return (Math.round((num + extraNum) 
72
+		* (Math.pow(10, decimalPlaces))) / Math.pow(10, decimalPlaces));
73
+}
74
+
75
+// When exiting: clear interval and print message
76
+process.on('SIGINT', function()
77
+{
78
+	clearInterval(myInterval);
79
+
80
+	// clean up memory
81
+	digitalAccelerometer.delete_intp(x);
82
+	digitalAccelerometer.delete_intp(y);
83
+	digitalAccelerometer.delete_intp(z);
84
+
85
+	digitalAccelerometer.delete_floatp(ax);
86
+	digitalAccelerometer.delete_floatp(ay);
87
+	digitalAccelerometer.delete_floatp(az);
88
+
89
+	console.log("Exiting...");
90
+	process.exit(0);
91
+});

+ 76
- 0
examples/python/h3lis331dl.py View File

@@ -0,0 +1,76 @@
1
+#!/usr/bin/python
2
+# Author: Jon Trulson <jtrulson@ics.com>
3
+# Copyright (c) 2015 Intel Corporation.
4
+#
5
+# Permission is hereby granted, free of charge, to any person obtaining
6
+# a copy of this software and associated documentation files (the
7
+# "Software"), to deal in the Software without restriction, including
8
+# without limitation the rights to use, copy, modify, merge, publish,
9
+# distribute, sublicense, and/or sell copies of the Software, and to
10
+# permit persons to whom the Software is furnished to do so, subject to
11
+# the following conditions:
12
+#
13
+# The above copyright notice and this permission notice shall be
14
+# included in all copies or substantial portions of the Software.
15
+#
16
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+import time, sys, signal, atexit
25
+import pyupm_h3lis331dl as upmH3LIS331DL
26
+
27
+# Instantiate an H3LIS331DL on I2C bus 0
28
+myDigitalAccelerometer = upmH3LIS331DL.H3LIS331DL(
29
+        upmH3LIS331DL.H3LIS331DL_I2C_BUS, 
30
+        upmH3LIS331DL.H3LIS331DL_DEFAULT_I2C_ADDR);
31
+
32
+
33
+## Exit handlers ##
34
+# This function stops python from printing a stacktrace when you hit control-C
35
+def SIGINTHandler(signum, frame):
36
+	raise SystemExit
37
+
38
+# This function lets you run code on exit, including functions from myDigitalAccelerometer
39
+def exitHandler():
40
+	print "Exiting"
41
+	sys.exit(0)
42
+
43
+# Register exit handlers
44
+atexit.register(exitHandler)
45
+signal.signal(signal.SIGINT, SIGINTHandler)
46
+
47
+
48
+# Initialize the device with default values
49
+myDigitalAccelerometer.init()
50
+
51
+x = upmH3LIS331DL.new_intp()
52
+y = upmH3LIS331DL.new_intp()
53
+z = upmH3LIS331DL.new_intp()
54
+
55
+ax = upmH3LIS331DL.new_floatp()
56
+ay = upmH3LIS331DL.new_floatp()
57
+az = upmH3LIS331DL.new_floatp()
58
+
59
+while (1):
60
+	myDigitalAccelerometer.update()
61
+	myDigitalAccelerometer.getRawXYZ(x, y, z)
62
+	outputStr = ("Raw: X = {0}"
63
+	" Y = {1}" 
64
+	" Z = {2}").format(upmH3LIS331DL.intp_value(x),
65
+	upmH3LIS331DL.intp_value(y),
66
+	upmH3LIS331DL.intp_value(z))
67
+	print outputStr
68
+
69
+	myDigitalAccelerometer.getAcceleration(ax, ay, az)
70
+	outputStr = ("Acceleration: AX = {0}"
71
+	" AY = {1}"
72
+	" AZ = {2}").format(upmH3LIS331DL.floatp_value(ax),
73
+	upmH3LIS331DL.floatp_value(ay),
74
+	upmH3LIS331DL.floatp_value(az))
75
+	print outputStr
76
+	time.sleep(.5)

+ 5
- 0
src/h3lis331dl/CMakeLists.txt View File

@@ -0,0 +1,5 @@
1
+set (libname "h3lis331dl")
2
+set (libdescription "upm h3lis331dl I2c Accelerometer (400g)")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 569
- 0
src/h3lis331dl/h3lis331dl.cxx View File

@@ -0,0 +1,569 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <math.h>
27
+#include <iostream>
28
+#include <string>
29
+
30
+#include "h3lis331dl.h"
31
+
32
+using namespace upm;
33
+using namespace std;
34
+
35
+
36
+H3LIS331DL::H3LIS331DL(int bus, uint8_t address):
37
+  m_i2c(bus)
38
+{
39
+  m_addr = address;
40
+
41
+  mraa_result_t rv;
42
+  if ( (rv = m_i2c.address(m_addr)) != MRAA_SUCCESS)
43
+    {
44
+      cerr << "H3LIS331DL: Could not initialize i2c address. " << endl;
45
+      mraa_result_print(rv);
46
+      return;
47
+    }
48
+
49
+  m_rawX = m_rawY = m_rawZ = 0;
50
+  setAdjustmentOffsets(0, 0, 0);
51
+}
52
+
53
+H3LIS331DL::~H3LIS331DL()
54
+{
55
+}
56
+
57
+bool H3LIS331DL::init(DR_BITS_T odr, PM_BITS_T pm, FS_BITS_T fs)
58
+{
59
+  if (!setDataRate(odr))
60
+    return false;
61
+  if (!setPowerMode(pm))
62
+    return false;
63
+  if (!setFullScale(fs))
64
+    return false;
65
+
66
+  // now enable X, Y, and Z axes
67
+  if (enableAxis(REG1_XEN | REG1_YEN | REG1_ZEN))
68
+    return false;
69
+
70
+  return true;
71
+}
72
+
73
+uint8_t H3LIS331DL::getChipID()
74
+{
75
+  return m_i2c.readReg(REG_WHOAMI);
76
+}
77
+
78
+bool H3LIS331DL::setDataRate(DR_BITS_T odr)
79
+{
80
+  uint8_t reg1 = m_i2c.readReg(REG_REG1);
81
+
82
+  reg1 &= ~(REG1_DR0 | REG1_DR1);
83
+  reg1 |= (odr << REG1_DR_SHIFT);
84
+
85
+  if (m_i2c.writeReg(REG_REG1, reg1))
86
+    {
87
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
88
+      return false;
89
+    }
90
+
91
+  return true;
92
+}
93
+
94
+bool H3LIS331DL::setPowerMode(PM_BITS_T pm)
95
+{
96
+  uint8_t reg1 = m_i2c.readReg(REG_REG1);
97
+
98
+  reg1 &= ~(REG1_PM0 | REG1_PM1 | REG1_PM2);
99
+  reg1 |= (pm << REG1_PM_SHIFT);
100
+
101
+  if (m_i2c.writeReg(REG_REG1, reg1))
102
+    {
103
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
104
+      return false;
105
+    }
106
+
107
+  return true;
108
+}
109
+
110
+bool H3LIS331DL::enableAxis(uint8_t axisEnable)
111
+{
112
+  uint8_t reg1 = m_i2c.readReg(REG_REG1);
113
+
114
+  reg1 &= ~(REG1_XEN | REG1_YEN | REG1_ZEN);
115
+  reg1 |= (axisEnable & (REG1_XEN | REG1_YEN | REG1_ZEN));
116
+
117
+  if (m_i2c.writeReg(REG_REG1, reg1))
118
+    {
119
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
120
+      return false;
121
+    }
122
+
123
+  return true;
124
+}
125
+
126
+bool H3LIS331DL::setFullScale(FS_BITS_T fs)
127
+{
128
+  uint8_t reg4 = m_i2c.readReg(REG_REG4);
129
+
130
+  reg4 &= ~(REG4_FS0 | REG4_FS1);
131
+  reg4 |= (fs << REG4_FS_SHIFT);
132
+
133
+  if (m_i2c.writeReg(REG_REG4, reg4))
134
+    {
135
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
136
+      return false;
137
+    }
138
+
139
+  return true;
140
+}
141
+
142
+bool H3LIS331DL::setHPCF(HPCF_BITS_T val)
143
+{
144
+  uint8_t reg = m_i2c.readReg(REG_REG2);
145
+
146
+  reg &= ~(REG2_HPCF0 | REG2_HPCF1);
147
+  reg |= (val << REG2_HPCF_SHIFT);
148
+
149
+  if (m_i2c.writeReg(REG_REG2, reg))
150
+    {
151
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
152
+      return false;
153
+    }
154
+
155
+  return true;
156
+}
157
+
158
+bool H3LIS331DL::setHPM(HPM_BITS_T val)
159
+{
160
+  uint8_t reg = m_i2c.readReg(REG_REG2);
161
+
162
+  reg &= ~(REG2_HPM0 | REG2_HPM1);
163
+  reg |= (val << REG2_HPM_SHIFT);
164
+
165
+  if (m_i2c.writeReg(REG_REG2, reg))
166
+    {
167
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
168
+      return false;
169
+    }
170
+
171
+  return true;
172
+}
173
+
174
+bool H3LIS331DL::boot()
175
+{
176
+  uint8_t reg = m_i2c.readReg(REG_REG2);
177
+
178
+  reg |= REG2_BOOT;
179
+
180
+  if (m_i2c.writeReg(REG_REG2, reg))
181
+    {
182
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
183
+      return false;
184
+    }
185
+
186
+  // wait for the boot bit to clear
187
+  do {
188
+    reg = m_i2c.readReg(REG_REG2);
189
+    usleep(200000);
190
+  } while (reg & REG2_BOOT);
191
+
192
+  return true;
193
+}
194
+
195
+bool H3LIS331DL::enableHPF1(bool enable)
196
+{
197
+  uint8_t reg = m_i2c.readReg(REG_REG2);
198
+
199
+  if (enable)
200
+    reg |= REG2_HPEN1;
201
+  else
202
+    reg &= ~REG2_HPEN1;
203
+
204
+  if (m_i2c.writeReg(REG_REG2, reg))
205
+    {
206
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
207
+      return false;
208
+    }
209
+
210
+  return true;
211
+}
212
+
213
+bool H3LIS331DL::enableHPF2(bool enable)
214
+{
215
+  uint8_t reg = m_i2c.readReg(REG_REG2);
216
+
217
+  if (enable)
218
+    reg |= REG2_HPEN2;
219
+  else
220
+    reg &= ~REG2_HPEN2;
221
+
222
+  if (m_i2c.writeReg(REG_REG2, reg))
223
+    {
224
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
225
+      return false;
226
+    }
227
+
228
+  return true;
229
+}
230
+
231
+bool H3LIS331DL::enableFDS(bool enable)
232
+{
233
+  uint8_t reg = m_i2c.readReg(REG_REG2);
234
+
235
+  if (enable)
236
+    reg |= REG2_FDS;
237
+  else
238
+    reg &= ~REG2_FDS;
239
+
240
+  if (m_i2c.writeReg(REG_REG2, reg))
241
+    {
242
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
243
+      return false;
244
+    }
245
+
246
+  return true;
247
+}
248
+
249
+bool H3LIS331DL::setInterruptActiveLow(bool enable)
250
+{
251
+  uint8_t reg = m_i2c.readReg(REG_REG3);
252
+
253
+  if (enable)
254
+    reg |= REG3_IHL;
255
+  else
256
+    reg &= ~REG3_IHL;
257
+
258
+  if (m_i2c.writeReg(REG_REG3, reg))
259
+    {
260
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
261
+      return false;
262
+    }
263
+
264
+  return true;
265
+}
266
+
267
+bool H3LIS331DL::setInterruptOpenDrain(bool enable)
268
+{
269
+  uint8_t reg = m_i2c.readReg(REG_REG3);
270
+
271
+  if (enable)
272
+    reg |= REG3_PP_OD;
273
+  else
274
+    reg &= ~REG3_PP_OD;
275
+
276
+  if (m_i2c.writeReg(REG_REG3, reg))
277
+    {
278
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
279
+      return false;
280
+    }
281
+
282
+  return true;
283
+}
284
+
285
+bool H3LIS331DL::setInterrupt1Latch(bool enable)
286
+{
287
+  uint8_t reg = m_i2c.readReg(REG_REG3);
288
+
289
+  if (enable)
290
+    reg |= REG3_LIR1;
291
+  else
292
+    reg &= ~REG3_LIR1;
293
+
294
+  if (m_i2c.writeReg(REG_REG3, reg))
295
+    {
296
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
297
+      return false;
298
+    }
299
+
300
+  return true;
301
+}
302
+
303
+bool H3LIS331DL::setInterrupt2Latch(bool enable)
304
+{
305
+  uint8_t reg = m_i2c.readReg(REG_REG3);
306
+
307
+  if (enable)
308
+    reg |= REG3_LIR2;
309
+  else
310
+    reg &= ~REG3_LIR2;
311
+
312
+  if (m_i2c.writeReg(REG_REG3, reg))
313
+    {
314
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
315
+      return false;
316
+    }
317
+
318
+  return true;
319
+}
320
+
321
+bool H3LIS331DL::setInterrupt1PadConfig(I_CFG_BITS_T val)
322
+{
323
+  uint8_t reg = m_i2c.readReg(REG_REG3);
324
+
325
+  reg &= ~(REG3_I1_CFG0 | REG3_I1_CFG1);
326
+  reg |= (val << REG3_I1_CFG_SHIFT);
327
+
328
+  if (m_i2c.writeReg(REG_REG3, reg))
329
+    {
330
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
331
+      return false;
332
+    }
333
+
334
+  return true;
335
+}
336
+
337
+bool H3LIS331DL::setInterrupt2PadConfig(I_CFG_BITS_T val)
338
+{
339
+  uint8_t reg = m_i2c.readReg(REG_REG3);
340
+
341
+  reg &= ~(REG3_I2_CFG0 | REG3_I2_CFG1);
342
+  reg |= (val << REG3_I2_CFG_SHIFT);
343
+
344
+  if (m_i2c.writeReg(REG_REG3, reg))
345
+    {
346
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
347
+      return false;
348
+    }
349
+
350
+  return true;
351
+}
352
+
353
+
354
+bool H3LIS331DL::enableBDU(bool enable)
355
+{
356
+  uint8_t reg = m_i2c.readReg(REG_REG4);
357
+
358
+  if (enable)
359
+    reg |= REG4_BDU;
360
+  else
361
+    reg &= ~REG4_BDU;
362
+
363
+  if (m_i2c.writeReg(REG_REG4, reg))
364
+    {
365
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
366
+      return false;
367
+    }
368
+
369
+  return true;
370
+}
371
+
372
+bool H3LIS331DL::enableBLE(bool enable)
373
+{
374
+  uint8_t reg = m_i2c.readReg(REG_REG4);
375
+
376
+  if (enable)
377
+    reg |= REG4_BLE;
378
+  else
379
+    reg &= ~REG4_BLE;
380
+
381
+  if (m_i2c.writeReg(REG_REG4, reg))
382
+    {
383
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
384
+      return false;
385
+    }
386
+
387
+  return true;
388
+}
389
+
390
+bool H3LIS331DL::enableSleepToWake(bool enable)
391
+{
392
+  uint8_t reg = m_i2c.readReg(REG_REG5);
393
+
394
+  if (enable)
395
+    reg |= (REG5_TURNON0 | REG5_TURNON1);
396
+  else
397
+    reg &= ~(REG5_TURNON0 | REG5_TURNON1);
398
+
399
+  if (m_i2c.writeReg(REG_REG5, reg))
400
+    {
401
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
402
+      return false;
403
+    }
404
+
405
+  return true;
406
+}
407
+
408
+uint8_t H3LIS331DL::getStatus()
409
+{
410
+  return m_i2c.readReg(REG_STATUS);
411
+}
412
+
413
+bool H3LIS331DL::setInterrupt1Config(uint8_t val)
414
+{
415
+  uint8_t reg = m_i2c.readReg(REG_INT1_CFG);
416
+
417
+  // mask off reserved bit
418
+  reg = (val & ~0x40);
419
+
420
+  if (m_i2c.writeReg(REG_INT1_CFG, reg))
421
+    {
422
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
423
+      return false;
424
+    }
425
+
426
+  return true;
427
+}
428
+
429
+bool H3LIS331DL::setInterrupt1Source(uint8_t val)
430
+{
431
+  uint8_t reg = m_i2c.readReg(REG_INT1_SRC);
432
+
433
+  // mask off reserved bit
434
+  reg = (val & ~0x80);
435
+
436
+  if (m_i2c.writeReg(REG_INT1_SRC, reg))
437
+    {
438
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
439
+      return false;
440
+    }
441
+
442
+  return true;
443
+}
444
+
445
+bool H3LIS331DL::setInterrupt1Threshold(uint8_t val)
446
+{
447
+  if (m_i2c.writeReg(REG_INT1_THS, val))
448
+    {
449
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
450
+      return false;
451
+    }
452
+
453
+  return true;
454
+}
455
+
456
+bool H3LIS331DL::setInterrupt1Duration(uint8_t val)
457
+{
458
+  if (m_i2c.writeReg(REG_INT1_DUR, val))
459
+    {
460
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
461
+      return false;
462
+    }
463
+
464
+  return true;
465
+}
466
+
467
+bool H3LIS331DL::setInterrupt2Config(uint8_t val)
468
+{
469
+  uint8_t reg = m_i2c.readReg(REG_INT2_CFG);
470
+
471
+  // mask off reserved bit
472
+  reg = (val & ~0x40);
473
+
474
+  if (m_i2c.writeReg(REG_INT2_CFG, reg))
475
+    {
476
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
477
+      return false;
478
+    }
479
+
480
+  return true;
481
+}
482
+
483
+bool H3LIS331DL::setInterrupt2Source(uint8_t val)
484
+{
485
+  uint8_t reg = m_i2c.readReg(REG_INT2_SRC);
486
+
487
+  // mask off reserved bit
488
+  reg = (val & ~0x80);
489
+
490
+  if (m_i2c.writeReg(REG_INT2_SRC, reg))
491
+    {
492
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
493
+      return false;
494
+    }
495
+
496
+  return true;
497
+}
498
+
499
+bool H3LIS331DL::setInterrupt2Threshold(uint8_t val)
500
+{
501
+  if (m_i2c.writeReg(REG_INT2_THS, val))
502
+    {
503
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
504
+      return false;
505
+    }
506
+
507
+  return true;
508
+}
509
+
510
+bool H3LIS331DL::setInterrupt2Duration(uint8_t val)
511
+{
512
+  if (m_i2c.writeReg(REG_INT2_DUR, val))
513
+    {
514
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": writeReg failed" << endl;
515
+      return false;
516
+    }
517
+
518
+  return true;
519
+}
520
+
521
+void H3LIS331DL::update()
522
+{
523
+  uint8_t low, high;
524
+
525
+  // X
526
+  low = m_i2c.readReg(REG_OUT_X_L);
527
+  high = m_i2c.readReg(REG_OUT_X_H);
528
+  m_rawX = ((high << 8) | low);
529
+
530
+  // Y
531
+  low = m_i2c.readReg(REG_OUT_Y_L);
532
+  high = m_i2c.readReg(REG_OUT_Y_H);
533
+  m_rawY = ((high << 8) | low);
534
+
535
+  // Z
536
+  low = m_i2c.readReg(REG_OUT_Z_L);
537
+  high = m_i2c.readReg(REG_OUT_Z_H);
538
+  m_rawZ = ((high << 8) | low);
539
+}
540
+
541
+void H3LIS331DL::setAdjustmentOffsets(int adjX, int adjY, int adjZ)
542
+{
543
+  m_adjX = adjX;
544
+  m_adjY = adjY;
545
+  m_adjZ = adjZ;
546
+}
547
+
548
+void H3LIS331DL::getAcceleration(float *aX, float *aY, float *aZ)
549
+{
550
+  const float gains = 0.003;    // Seeed magic number?
551
+
552
+  *aX = float(m_rawX - m_adjX) * gains;
553
+  *aY = float(m_rawY - m_adjY) * gains;
554
+  *aZ = float(m_rawZ - m_adjZ) * gains;
555
+}
556
+
557
+void H3LIS331DL::getRawXYZ(int *x, int *y, int*z)
558
+{
559
+  *x = m_rawX;
560
+  *y = m_rawY;
561
+  *z = m_rawZ;
562
+}
563
+
564
+void H3LIS331DL::getXYZ(int *x, int *y, int*z)
565
+{
566
+  *x = (m_rawX - m_adjX);
567
+  *y = (m_rawY - m_adjY);
568
+  *z = (m_rawZ - m_adjZ);
569
+}

+ 613
- 0
src/h3lis331dl/h3lis331dl.h View File

@@ -0,0 +1,613 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+#pragma once
25
+
26
+#include <string>
27
+#include <mraa/i2c.hpp>
28
+
29
+#define H3LIS331DL_I2C_BUS 0
30
+#define H3LIS331DL_DEFAULT_I2C_ADDR 0x18
31
+
32
+namespace upm {
33
+  
34
+  /**
35
+   * @brief Grove 3-axis I2C Accelerometer (400G)
36
+   * @defgroup h3lis331dl libupm-h3lis331dl
37
+   * @ingroup seeed i2c accelerometer
38
+   */
39
+
40
+  /**
41
+   * @library h3lis331dl
42
+   * @sensor h3lis331dl
43
+   * @comname Grove 3-axis I2C Accelerometer (400G)
44
+   * @type accelerometer
45
+   * @man seeed
46
+   * @web http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Accelerometer400g-p-1897.html
47
+   * @con i2c
48
+   *
49
+   * @brief C++ API for the H3LIS331DL based Grove 3-axis I2C Accelerometer 
50
+   * (400G)
51
+   *
52
+   * @image html h3lis331dl.jpg
53
+   * @snippet h3lis331dl.cxx Interesting
54
+   */
55
+  class H3LIS331DL {
56
+  public:
57
+
58
+    /**
59
+     * H3LIS331DL registers
60
+     */
61
+    typedef enum {
62
+      // Reserved bytes must not be written into as they contain
63
+      // factory calibration data.  Changing those values may lead to
64
+      // improper functioning of the device.
65
+
66
+      // 0x00-0x0E reserved 
67
+
68
+      REG_WHOAMI                = 0x0f,
69
+
70
+      // 0x10-0x1f reserved
71
+
72
+      REG_REG1                  = 0x20,
73
+      REG_REG2                  = 0x21,
74
+      REG_REG3                  = 0x22,
75
+      REG_REG4                  = 0x23,
76
+      REG_REG5                  = 0x24,
77
+
78
+      REG_HP_FILTER_RESET       = 0x25,
79
+      REG_REFERENCE             = 0x26,
80
+
81
+      REG_STATUS                = 0x27,
82
+
83
+      REG_OUT_X_L               = 0x28,
84
+      REG_OUT_X_H               = 0x29,
85
+      REG_OUT_Y_L               = 0x2a,
86
+      REG_OUT_Y_H               = 0x2b,
87
+      REG_OUT_Z_L               = 0x2c,
88
+      REG_OUT_Z_H               = 0x2d,
89
+
90
+      // 0x2e, 0x2f reserved
91
+
92
+      REG_INT1_CFG              = 0x30,
93
+      REG_INT1_SRC              = 0x31,
94
+      REG_INT1_THS              = 0x32,
95
+      REG_INT1_DUR              = 0x33,
96
+
97
+      REG_INT2_CFG              = 0x34,
98
+      REG_INT2_SRC              = 0x35,
99
+      REG_INT2_THS              = 0x36,
100
+      REG_INT2_DUR              = 0x37,
101
+
102
+      // 0x38-0x3f reserved
103
+    } H3LIS331DL_REG_T;
104
+    
105
+    /**
106
+     * REG1 bits
107
+     */
108
+    typedef enum {
109
+      REG1_XEN                  = 0x01, // X axis enable
110
+      REG1_YEN                  = 0x02,
111
+      REG1_ZEN                  = 0x04,
112
+
113
+      REG1_DR0                  = 0x08, // data rate
114
+      REG1_DR1                  = 0x10,
115
+      REG1_DR_SHIFT             = 3,    // DR shift
116
+
117
+      REG1_PM0                  = 0x20, // power mode
118
+      REG1_PM1                  = 0x40,
119
+      REG1_PM2                  = 0x80,
120
+      REG1_PM_SHIFT             = 5
121
+    } REG1_BITS_T;
122
+
123
+    /**
124
+     * REG1 DR (output rate) bits
125
+     */
126
+    typedef enum {
127
+      DR_50_37                  = 0x0, // 50Hz output with 37Hz LPF cutoff
128
+      DR_100_74                 = 0x1,
129
+      DR_400_292                = 0x2,
130
+      DR_1000_780               = 0x3
131
+    } DR_BITS_T;
132
+
133
+    /**
134
+     * REG1 PM (Power mode) bits
135
+     */
136
+    typedef enum {
137
+      PM_POWERDWN               = 0x0,
138
+      PM_NORMAL                 = 0x1,
139
+      PM_LP05                   = 0x2, // .5 updates/sec
140
+      PM_LP1                    = 0x3, // 1 update/sec
141
+      PM_LP2                    = 0x4,
142
+      PM_LP5                    = 0x5,
143
+      PM_LP10                   = 0x6
144
+    } PM_BITS_T;
145
+
146
+    /**
147
+     * REG2 bits
148
+     */
149
+    typedef enum {
150
+      REG2_HPCF0                = 0x01,
151
+      REG2_HPCF1                = 0x02,
152
+      REG2_HPCF_SHIFT           = 0,
153
+
154
+      REG2_HPEN1                = 0x04,
155
+      REG2_HPEN2                = 0x08,
156
+      REG2_FDS                  = 0x10,
157
+
158
+      REG2_HPM0                 = 0x20,
159
+      REG2_HPM1                 = 0x40,
160
+      REG2_HPM_SHIFT            = 5,
161
+
162
+      REG2_BOOT                 = 0x80
163
+    } REG2_BITS_T;
164
+
165
+    /**
166
+     * REG2 HPCF (High Pass Cutoff Frequency) bits
167
+     */
168
+    typedef enum {
169
+      HPCF_8                    = 0x0,
170
+      HPCF_16                   = 0x1,
171
+      HPCF_32                   = 0x2,
172
+      HPCF_64                   = 0x3,
173
+    } HPCF_BITS_T;
174
+
175
+    /**
176
+     * REG2 HPM (High Pass Filter Mode) bits
177
+     */
178
+    typedef enum {
179
+      HPM_NORMAL0               = 0x0,
180
+      HPM_REF                   = 0x1,
181
+      HPM_NORMAL1               = 0x2
182
+    } HPM_BITS_T;
183
+
184
+    /**
185
+     * REG3 bits
186
+     */
187
+    typedef enum {
188
+      REG3_I1_CFG0              = 0x01,
189
+      REG3_I1_CFG1              = 0x02,
190
+      REG3_I1_CFG_SHIFT         = 0,
191
+
192
+      REG3_LIR1                 = 0x04,
193
+
194
+      REG3_I2_CFG0              = 0x08,
195
+      REG3_I2_CFG1              = 0x10,
196
+      REG3_I2_CFG_SHIFT         = 3,
197
+
198
+      REG3_LIR2                 = 0x20,
199
+      REG3_PP_OD                = 0x40,
200
+      REG3_IHL                  = 0x80
201
+    } REG3_BITS_T;
202
+
203
+    /**
204
+     * REG3 I1/I2 PAD control bits
205
+     */
206
+    typedef enum {
207
+      I_SRC                     = 0x0, // INT source
208
+      I_OR                      = 0x1, // INT1 OR INT2 source
209
+      I_DR                      = 0x2, // Data Ready
210
+      I_BOOTING                 = 0x3  // Boot is running
211
+    } I_CFG_BITS_T;
212
+    
213
+    /**
214
+     * REG4 bits
215
+     */
216
+    typedef enum {
217
+      REG4_SIM                  = 0x01, // SPI 4 or 3 wire
218
+
219
+      // bits 01,02,04 reserved
220
+
221
+      REG4_FS0                  = 0x10,
222
+      REG4_FS1                  = 0x20,
223
+      REG4_FS_SHIFT             = 4,
224
+
225
+      REG4_BLE                  = 0x40, // big/little endian
226
+      REG4_BDU                  = 0x80  // Block data update
227
+    } REG4_BITS_T;
228
+
229
+    /**
230
+     * REG4 FS (Full Scale) bits
231
+     */
232
+    typedef enum {
233
+      FS_100                    = 0x0, // 100g scale
234
+      FS_200                    = 0x1, // 200g scale
235
+      FS_400                    = 0x3  // 400g scale
236
+    } FS_BITS_T;
237
+
238
+    /**
239
+     * REG5 TURNON (sleep to wake) bits
240
+     */
241
+    typedef enum {
242
+      REG5_TURNON0              = 0x01, // turnon mode for sleep-to-wake
243
+      REG5_TURNON1              = 0x02
244
+ 
245
+      // bits 04-80 reserved
246
+    } REG5_BITS_T;
247
+
248
+    /**
249
+     * STATUS bits
250
+     */
251
+    typedef enum {
252
+      STATUS_XDA                = 0x01, // X data available
253
+      STATUS_YDA                = 0x02,
254
+      STATUS_ZDA                = 0x04,
255
+      STATUS_ZYXDA              = 0x08, // X, Y, and Z data available
256
+      STATUS_XOR                = 0x10, // X overrun
257
+      STATUS_YOR                = 0x20,
258
+      STATUS_ZOR                = 0x40,
259
+      STATUS_ZYXOR              = 0x80  // X, Y, and Z data overrun
260
+    } STATUS_BITS_T;
261
+
262
+    /**
263
+     * INT1/INT2 CFG bits
264
+     */
265
+    typedef enum {
266
+      INT_CFG_XLIE              = 0x01, // enable intr on low X event
267
+      INT_CFG_XHIE              = 0x02, // enable intr on high X event
268
+      INT_CFG_YLIE              = 0x04,
269
+      INT_CFG_YHIE              = 0x08,
270
+      INT_CFG_ZLIE              = 0x10,
271
+      INT_CFG_ZHIE              = 0x20,
272
+      // 0x40 reserved
273
+      INT_CFG_AOI               = 0x80 // AND or OR combination or intrs
274
+    } INT_CFG_BITS_T;
275
+
276
+    /**
277
+     * INT1/INT2 SRC bits
278
+     */
279
+    typedef enum {
280
+      INT_SRC_XL                = 0x01, // X low intr event
281
+      INT_SRC_XH                = 0x02, // X high intr event
282
+      INT_SRC_YL                = 0x04,
283
+      INT_SRC_YH                = 0x08,
284
+      INT_SRC_ZL                = 0x10,
285
+      INT_SRC_ZH                = 0x20,
286
+      INT_SRC_IA                = 0x40  // Interrupt generated (active)
287
+      // 0x80 reserved
288
+    } INT_SRC_BITS_T;
289
+    
290
+    /**
291
+     * h3lis331dl constructor
292
+     *
293
+     * @param bus i2c bus to use
294
+     * @param address the address for this device
295
+     */
296
+    H3LIS331DL(int bus, uint8_t address = H3LIS331DL_DEFAULT_I2C_ADDR);
297
+
298
+    /**
299
+     * H3LIS331DL Destructor
300
+     */
301
+    ~H3LIS331DL();
302
+    
303
+    /**
304
+     * set up initial values and start operation
305
+     *
306
+     * @param odr the data rate: one of the DR_BITS_T values
307
+     * @param pm the power mode: one of the PM_BITS_T values
308
+     * @param fs the FullScale: one of the FS_BITS_T values
309
+     * @return true if successful
310
+     */
311
+    bool init(DR_BITS_T odr=DR_50_37, PM_BITS_T pm=PM_NORMAL, 
312
+              FS_BITS_T fs=FS_100);
313
+
314
+    /**
315
+     * read and return the Chip ID (WHO_AM_I register)
316
+     *
317
+     * @return true if successful
318
+     */
319
+    uint8_t getChipID();
320
+
321
+    /**
322
+     * set the output data rate
323
+     *
324
+     * @param one of the DR_BITS_T values
325
+     * @return true if successful
326
+     */
327
+    bool setDataRate(DR_BITS_T odr);
328
+
329
+    /**
330
+     * set the power mode
331
+     *
332
+     * @param one of the PM_BITS_T values
333
+     * @return true if successful
334
+     */
335
+    bool setPowerMode(PM_BITS_T pm);
336
+
337
+    /**
338
+     * enable one or more of the 3 axes.  The arguement is a bitmsk
339
+     * composed of REG1_XEN, REG1_YEN and/or REG1_ZEN corresponding
340
+     * the axes you want enabled.
341
+     *
342
+     * @param axisEnable bitmask of axes to enable 
343
+     * (REG1_XEN | REG1_YEN | REG1_ZEN)
344
+     * @return true if successful
345
+     */
346
+    bool enableAxis(uint8_t axisEnable);
347
+
348
+    /**
349
+     * set the scaling factor to 100, 200, or 400G's
350
+     *
351
+     * @param fs one of the FS_BITS_T values
352
+     * @return true if successful
353
+     */
354
+    bool setFullScale(FS_BITS_T fs);
355
+
356
+    /**
357
+     * set high pass cutoff filter
358
+     *
359
+     * @param val one of the HPCF_BITS_T values
360
+     * @return true if successful
361
+     */
362
+    bool setHPCF(HPCF_BITS_T val);
363
+
364
+    /**
365
+     * set high pass filter mode
366
+     *
367
+     * @param val one of the HPM_BITS_T values
368
+     * @return true if successful
369
+     */
370
+    bool setHPM(HPM_BITS_T val);
371
+
372
+    /**
373
+     * boot the device.  Booting the device causes internal flash
374
+     * calibration values to be reloaded into the visible registers,
375
+     * in the event they have been corrupted.  This function will
376
+     * return when boot is complete.
377
+     *
378
+     * @return true if successful
379
+     */
380
+    bool boot();
381
+
382
+    /**
383
+     * enable high pass filter for interrupt 1 source
384
+     *
385
+     * @param enable true to enable the filter, false otherwise
386
+     * @return true if successful
387
+     */
388
+    bool enableHPF1(bool enable);
389
+
390
+    /**
391
+     * enable high pass filter for interrupt 2 source
392
+     *
393
+     * @param enable true to enable the filter, false otherwise
394
+     * @return true if successful
395
+     */
396
+    bool enableHPF2(bool enable);
397
+
398
+    /**
399
+     * enable filtered data selection
400
+     *
401
+     * @param enable true to enable, false otherwise
402
+     * @return true if successful
403
+     */
404
+    bool enableFDS(bool enable);
405
+
406
+    /**
407
+     * set interrupts to be active low instead of high
408
+     *
409
+     * @param enable true to enable, false otherwise
410
+     * @return true if successful
411
+     */
412
+    bool setInterruptActiveLow(bool enable);
413
+
414
+    /**
415
+     * set interrupt output mode to open drain rather than push/pull
416
+     *
417
+     * @param enable true to enable, false otherwise
418
+     * @return true if successful
419
+     */
420
+    bool setInterruptOpenDrain(bool enable);
421
+
422
+    /**
423
+     * set interrupt 1 latch enable
424
+     *
425
+     * @param enable true to enable, false otherwise
426
+     * @return true if successful
427
+     */
428
+    bool setInterrupt1Latch(bool enable);
429
+
430
+    /**
431
+     * set interrupt 2 latch enable
432
+     *
433
+     * @param enable true to enable, false otherwise
434
+     * @return true if successful
435
+     */
436
+    bool setInterrupt2Latch(bool enable);
437
+
438
+    /**
439
+     * set the interrupt 1 pad configuration
440
+     *
441
+     * @param val one fo the I_CFG_BITS_T values
442
+     * @return true if successful
443
+     */
444
+    bool setInterrupt1PadConfig(I_CFG_BITS_T val);
445
+
446
+    /**
447
+     * set the interrupt 2 pad configuration
448
+     *
449
+     * @param val one fo the I_CFG_BITS_T values
450
+     * @return true if successful
451
+     */
452
+    bool setInterrupt2PadConfig(I_CFG_BITS_T val);
453
+    
454
+    /**
455
+     * enable block data update.  When enabled, low/high output
456
+     * registers are not update until both low and high values have
457
+     * been read.
458
+     *
459
+     * @param enable true to enable, false otherwise
460
+     * @return true if successful
461
+     */
462
+    bool enableBDU(bool enable);
463
+
464
+    /**
465
+     * enable big endian output for 16b reads
466
+     *
467
+     * @param enable true to enable, false otherwise
468
+     * @return true if successful
469
+     */
470
+    bool enableBLE(bool enable);
471
+
472
+    /**
473
+     * enable sleep to wake functionality.  
474
+     *
475
+     * @param enable true to enable, false otherwise
476
+     * @return true if successful
477
+     */
478
+    bool enableSleepToWake(bool enable);
479
+
480
+    /**
481
+     * return the contents of the REG_STATUS register
482
+     *
483
+     * @return the contents of the REG_STATUS register
484
+     */
485
+    uint8_t getStatus();
486
+
487
+    /**
488
+     * setup the interrupt 1 config register
489
+     *
490
+     * @param val a bitmask of desired INT_CFG_BITS_T bits
491
+     * @return true if successful
492
+     */
493
+    bool setInterrupt1Config(uint8_t val);
494
+
495
+    /**
496
+     * setup the interrupt 2 config register
497
+     *
498
+     * @param val a bitmask of desired INT_CFG_BITS_T bits
499
+     * @return true if successful
500
+     */
501
+    bool setInterrupt2Config(uint8_t val);
502
+
503
+    /**
504
+     * setup the interrupt 1 source register
505
+     *
506
+     * @param val a bitmask of desired INT_SRC_BITS_T bits
507
+     * @return true if successful
508
+     */
509
+    bool setInterrupt1Source(uint8_t val);
510
+
511
+    /**
512
+     * setup the interrupt 2 source register
513
+     *
514
+     * @param val a bitmask of desired INT_SRC_BITS_T bits
515
+     * @return true if successful
516
+     */
517
+    bool setInterrupt2Source(uint8_t val);
518
+
519
+    /**
520
+     * setup the interrupt 1 threshold register
521
+     *
522
+     * @param val the threshhold to set
523
+     * @return true if successful
524
+     */
525
+    bool setInterrupt1Threshold(uint8_t val);
526
+
527
+    /**
528
+     * setup the interrupt 2 threshold register
529
+     *
530
+     * @param val the threshhold to set
531
+     * @return true if successful
532
+     */
533
+    bool setInterrupt2Threshold(uint8_t val);
534
+
535
+    /**
536
+     * setup the interrupt 1 duration register
537
+     *
538
+     * @param val the duration to set
539
+     * @return true if successful
540
+     */
541
+    bool setInterrupt1Duration(uint8_t val);
542
+
543
+    /**
544
+     * setup the interrupt 2 duration register
545
+     *
546
+     * @param val the duration to set
547
+     * @return true if successful
548
+     */
549
+    bool setInterrupt2Duration(uint8_t val);
550
+
551
+    /**
552
+     * read the sensor and store current values internally
553
+     */
554
+    void update();
555
+
556
+    /**
557
+     * set adjustment offsets for each of the axes.  This can be used
558
+     * for calibration.  The values supplied here will be subtracted
559
+     * from the axis data read from the device.
560
+     *
561
+     * @param adjX the amount by which to correct the X axis measurement
562
+     * @param adjY the amount by which to correct the Y axis measurement
563
+     * @param adjZ the amount by which to correct the Z axis measurement
564
+     */
565
+    void setAdjustmentOffsets(int adjX, int adjY, int adjZ);
566
+
567
+    /**
568
+     * get the acceleration values for each of the axes
569
+     *
570
+     * @param aX the returned X acceleration
571
+     * @param aY the returned Y acceleration
572
+     * @param aZ the returned Z acceleration
573
+     */
574
+    void getAcceleration(float *aX, float *aY, float *aZ);
575
+
576
+    /**
577
+     * get the raw axis values
578
+     *
579
+     * @param x the returned raw X value
580
+     * @param y the returned raw Y value
581
+     * @param z the returned raw Z value
582
+     */
583
+    void getRawXYZ(int *x, int *y, int *z);
584
+
585
+    /**
586
+     * get the adjusted axis values
587
+     *
588
+     * @param x the returned X value
589
+     * @param y the returned Y value
590
+     * @param z the returned Z value
591
+     */
592
+    void getXYZ(int *x, int *y, int *z);
593
+
594
+    /**
595
+     * provide public access to the class's MRAA i2C context for
596
+     * direct user access
597
+     *
598
+     * @return a reference to the class i2c context
599
+     */
600
+    mraa::I2c& i2cContext() { return m_i2c; };
601
+
602
+
603
+  protected:
604
+    int16_t m_rawX, m_rawY, m_rawZ;
605
+    int16_t m_adjX, m_adjY, m_adjZ;
606
+    mraa::I2c m_i2c;
607
+
608
+  private:
609
+    uint8_t m_addr;
610
+  };
611
+}
612
+
613
+

+ 13
- 0
src/h3lis331dl/jsupm_h3lis331dl.i View File

@@ -0,0 +1,13 @@
1
+%module jsupm_h3lis331dl
2
+%include "../upm.i"
3
+%include "cpointer.i"
4
+
5
+/* Send "int *" and "float *" to JavaScript as intp and floatp */
6
+%pointer_functions(int, intp);
7
+%pointer_functions(float, floatp);
8
+
9
+%{
10
+    #include "h3lis331dl.h"
11
+%}
12
+
13
+%include "h3lis331dl.h"

+ 18
- 0
src/h3lis331dl/pyupm_h3lis331dl.i View File

@@ -0,0 +1,18 @@
1
+%module pyupm_h3lis331dl
2
+%include "../upm.i"
3
+%include "cpointer.i"
4
+
5
+/* Send "int *" and "float *" to python as intp and floatp */
6
+%pointer_functions(int, intp);
7
+%pointer_functions(float, floatp);
8
+
9
+%feature("autodoc", "3");
10
+
11
+#ifdef DOXYGEN
12
+%include "h3lis331dl_doc.i"
13
+#endif
14
+
15
+%include "h3lis331dl.h"
16
+%{
17
+    #include "h3lis331dl.h"
18
+%}