Parcourir la source

bmi160: Initial implementation

The Bosch BMI160 is a 3-axis Accelerometer and Gyroscope.
Additionally it supports an external Magnetometer, accessed through
the BMI160's register interface.  This driver was developed with a
BMI160 "Shuttle" board, which included a BMM150 Magnetometer.

The device is driven by either 1.8v or 3.3vdc.  This driver
incorporates the Bosch BMI160 driver code at
https://github.com/BoschSensortec/BMI160_driver .

While not all of the functionality of this device is supported
initially, the inclusion of the Bosch driver in the source code
makes it possible to support whatever features are required that
the driver bosch driver itself can support.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Abhishek Malik <abhishek.malik@intel.com>
Jon Trulson il y a 9 ans
Parent
révision
e062b9b85c

+ 1
- 0
examples/c++/CMakeLists.txt Voir le fichier

@@ -252,6 +252,7 @@ add_example (cwlsxxa)
252 252
 add_example (teams)
253 253
 add_example (apa102)
254 254
 add_example (tex00)
255
+add_example (bmi160)
255 256
 
256 257
 # These are special cases where you specify example binary, source file and module(s)
257 258
 include_directories (${PROJECT_SOURCE_DIR}/src)

+ 82
- 0
examples/c++/bmi160.cxx Voir le fichier

@@ -0,0 +1,82 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 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 <iostream>
27
+#include <signal.h>
28
+#include "bmi160.h"
29
+
30
+using namespace std;
31
+
32
+int shouldRun = true;
33
+
34
+void sig_handler(int signo)
35
+{
36
+  if (signo == SIGINT)
37
+    shouldRun = false;
38
+}
39
+
40
+
41
+int main(int argc, char **argv)
42
+{
43
+  signal(SIGINT, sig_handler);
44
+//! [Interesting]
45
+
46
+  // Instantiate a BMI160 instance using default i2c bus and address
47
+  upm::BMI160 *sensor = new upm::BMI160();
48
+
49
+  while (shouldRun)
50
+    {
51
+      // update our values from the sensor
52
+      sensor->update();
53
+
54
+      float dataX, dataY, dataZ;
55
+
56
+      sensor->getAccelerometer(&dataX, &dataY, &dataZ);
57
+      cout << "Accelerometer: ";
58
+      cout << "AX: " << dataX << " AY: " << dataY << " AZ: "
59
+           << dataZ << endl;
60
+
61
+      sensor->getGyroscope(&dataX, &dataY, &dataZ);
62
+      cout << "Gryoscope:     ";
63
+      cout << "GX: " << dataX << " GY: " << dataY << " GZ: "
64
+           << dataZ << endl;
65
+
66
+      sensor->getMagnetometer(&dataX, &dataY, &dataZ);
67
+      cout << "Magnetometer:  ";
68
+      cout << "MX: " << dataX << " MY: " << dataY << " MZ: "
69
+           << dataZ << endl;
70
+
71
+      cout << endl;
72
+
73
+      usleep(500000);
74
+    }
75
+//! [Interesting]
76
+
77
+  cout << "Exiting..." << endl;
78
+
79
+  delete sensor;
80
+
81
+  return 0;
82
+}

+ 78
- 0
examples/java/BMI160_Example.java Voir le fichier

@@ -0,0 +1,78 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 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
+import upm_bmi160.BMI160;
26
+
27
+public class BMI160_Example
28
+{
29
+    public static void main(String[] args) throws InterruptedException
30
+    {
31
+// ! [Interesting]
32
+        System.out.println("Initializing...");
33
+
34
+        // Instantiate a BMI160 instance using default i2c bus and address
35
+        BMI160 sensor = new BMI160();
36
+
37
+        while (true)
38
+            {
39
+                // update our values from the sensor
40
+                sensor.update();
41
+
42
+                float dataA[] = sensor.getAccelerometer();
43
+
44
+                System.out.println("Accelerometer: "
45
+                                   + "AX: "
46
+                                   + dataA[0]
47
+                                   + " AY: "
48
+                                   + dataA[1]
49
+                                   + " AZ: "
50
+                                   + dataA[2]);
51
+
52
+                float dataG[] = sensor.getGyroscope();
53
+
54
+                System.out.println("Gryoscope:     "
55
+                                   + "GX: "
56
+                                   + dataG[0]
57
+                                   + " GY: "
58
+                                   + dataG[1]
59
+                                   + " GZ: "
60
+                                   + dataG[2]);
61
+
62
+                float dataM[] = sensor.getMagnetometer();
63
+
64
+                System.out.println("Magnetometer:  "
65
+                                   + "MX: "
66
+                                   + dataM[0]
67
+                                   + " MY: "
68
+                                   + dataM[1]
69
+                                   + " MZ: "
70
+                                   + dataM[2]);
71
+
72
+                System.out.println();
73
+                Thread.sleep(500);
74
+            }
75
+
76
+// ! [Interesting]
77
+    }
78
+}

+ 1
- 0
examples/java/CMakeLists.txt Voir le fichier

@@ -109,6 +109,7 @@ add_example(CWLSXXA_Example cwlsxxa)
109 109
 add_example(TEAMS_Example teams)
110 110
 add_example(APA102Sample apa102)
111 111
 add_example(TEX00_Example tex00)
112
+add_example(BMI160_Example bmi160)
112 113
 
113 114
 add_example_with_path(Jhd1313m1_lcdSample lcd/upm_i2clcd.jar)
114 115
 add_example_with_path(Jhd1313m1Sample lcd/upm_i2clcd.jar)

+ 71
- 0
examples/javascript/bmi160.js Voir le fichier

@@ -0,0 +1,71 @@
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) 2016 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
+
29
+var sensorObj = require('jsupm_bmi160');
30
+
31
+// Instantiate a BMI160 instance using default i2c bus and address
32
+var sensor = new sensorObj.BMI160();
33
+
34
+var x = new sensorObj.new_floatp();
35
+var y = new sensorObj.new_floatp();
36
+var z = new sensorObj.new_floatp();
37
+
38
+// Output data every half second until interrupted
39
+setInterval(function()
40
+{
41
+    // update our values from the sensor
42
+    sensor.update();
43
+
44
+    sensor.getAccelerometer(x, y, z);
45
+    console.log("Accelerometer: AX: " + sensorObj.floatp_value(x) +
46
+                " AY: " + sensorObj.floatp_value(y) +
47
+                " AZ: " + sensorObj.floatp_value(z));
48
+
49
+    sensor.getGyroscope(x, y, z);
50
+    console.log("Gyroscope:     GX: " + sensorObj.floatp_value(x) +
51
+                " AY: " + sensorObj.floatp_value(y) +
52
+                " AZ: " + sensorObj.floatp_value(z));
53
+
54
+    sensor.getMagnetometer(x, y, z);
55
+    console.log("Magnetometer:  MX: " + sensorObj.floatp_value(x) +
56
+                " MY: " + sensorObj.floatp_value(y) +
57
+                " MZ: " + sensorObj.floatp_value(z));
58
+
59
+    console.log();
60
+
61
+}, 500);
62
+
63
+// exit on ^C
64
+process.on('SIGINT', function()
65
+{
66
+    sensor = null;
67
+    sensorObj.cleanUp();
68
+    sensorObj = null;
69
+    console.log("Exiting.");
70
+    process.exit(0);
71
+});

+ 66
- 0
examples/python/bmi160.py Voir le fichier

@@ -0,0 +1,66 @@
1
+#!/usr/bin/python
2
+# Author: Jon Trulson <jtrulson@ics.com>
3
+# Copyright (c) 2016 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_bmi160 as sensorObj
26
+
27
+# Instantiate a BMI160 instance using default i2c bus and address
28
+sensor = sensorObj.BMI160()
29
+
30
+## Exit handlers ##
31
+# This function stops python from printing a stacktrace when you hit control-C
32
+def SIGINTHandler(signum, frame):
33
+	raise SystemExit
34
+
35
+# This function lets you run code on exit
36
+def exitHandler():
37
+	print "Exiting"
38
+	sys.exit(0)
39
+
40
+# Register exit handlers
41
+atexit.register(exitHandler)
42
+signal.signal(signal.SIGINT, SIGINTHandler)
43
+
44
+x = sensorObj.new_floatp()
45
+y = sensorObj.new_floatp()
46
+z = sensorObj.new_floatp()
47
+
48
+while (1):
49
+        sensor.update()
50
+        sensor.getAccelerometer(x, y, z)
51
+        print "Accelerometer: AX: ", sensorObj.floatp_value(x),
52
+        print " AY: ", sensorObj.floatp_value(y),
53
+        print " AZ: ", sensorObj.floatp_value(z)
54
+
55
+        sensor.getGyroscope(x, y, z)
56
+        print "Gyroscope:     GX: ", sensorObj.floatp_value(x),
57
+        print " GY: ", sensorObj.floatp_value(y),
58
+        print " GZ: ", sensorObj.floatp_value(z)
59
+
60
+        sensor.getMagnetometer(x, y, z)
61
+        print "Magnetometer:  MX: ", sensorObj.floatp_value(x),
62
+        print " MY: ", sensorObj.floatp_value(y),
63
+        print " MZ: ", sensorObj.floatp_value(z)
64
+
65
+        print
66
+	time.sleep(.5)

+ 5
- 0
src/bmi160/CMakeLists.txt Voir le fichier

@@ -0,0 +1,5 @@
1
+set (libname "bmi160")
2
+set (libdescription "Bosch BMI160 Accelerometer, Gyroscope and BMM150 Magnetometer")
3
+set (module_src ${libname}.cxx bosch_bmi160.c)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 433
- 0
src/bmi160/bmi160.cxx Voir le fichier

@@ -0,0 +1,433 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 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 <iostream>
27
+#include <stdexcept>
28
+#include <string>
29
+
30
+// we have to do it the old skool way
31
+#include <mraa/i2c.h>
32
+
33
+#include "bmi160.h"
34
+
35
+extern "C" {
36
+#include "bosch_bmi160.h"
37
+}
38
+
39
+// We do not need this define anyway.  It conflicts with mraa::SUCCESS.
40
+#undef SUCCESS
41
+
42
+using namespace upm;
43
+using namespace std;
44
+
45
+static mraa_i2c_context i2cContext = NULL;
46
+
47
+// Our bmi160 info structure
48
+struct bmi160_t s_bmi160;
49
+
50
+// bus read and write functions for use with the bmi driver code
51
+s8 bmi160_i2c_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
52
+{
53
+  if (!i2cContext)
54
+    {
55
+      throw std::runtime_error(std::string(__FUNCTION__) +
56
+                               ": i2c context is NULL");
57
+    }
58
+
59
+  int retries = 10;
60
+
61
+  // There seems to be some occasional flakyness with reads when
62
+  // moving the sensor around
63
+  while (retries >= 0)
64
+    {
65
+      int rv = mraa_i2c_read_bytes_data(i2cContext, reg_addr, reg_data, cnt);
66
+
67
+      if (rv < 0)
68
+        {
69
+          usleep(100000);
70
+          retries--;
71
+        }
72
+      else
73
+        return 0;
74
+    }
75
+
76
+  throw std::runtime_error(std::string(__FUNCTION__) +
77
+                           ": mraa_i2c_read_bytes_data() failed");
78
+
79
+  return 0;
80
+}
81
+
82
+s8 bmi160_i2c_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
83
+{
84
+  if (!i2cContext)
85
+    {
86
+      throw std::runtime_error(std::string(__FUNCTION__) +
87
+                               ": i2c context is NULL");
88
+    }
89
+
90
+  // FIXME  fprintf(stderr, "%s: %02x: cnt %d\n", __FUNCTION__, reg_addr, cnt);
91
+  uint8_t buffer[cnt + 1];
92
+
93
+  buffer[0] = reg_addr;
94
+  for (int i=0; i<cnt; i++)
95
+    buffer[i+1] = reg_data[i];
96
+
97
+  mraa_result_t rv = mraa_i2c_write(i2cContext, buffer, cnt+1);
98
+
99
+  if (rv != MRAA_SUCCESS)
100
+    {
101
+      throw std::runtime_error(std::string(__FUNCTION__) +
102
+                               ": mraa_i2c_write() failed");
103
+    }
104
+
105
+  return 0;
106
+}
107
+
108
+// delay for some milliseconds
109
+void bmi160_delay_ms(u32 msek)
110
+{
111
+  usleep(msek * 1000);
112
+}
113
+
114
+
115
+BMI160::BMI160(int bus, uint8_t address)
116
+{
117
+  m_addr = address;
118
+
119
+  // We need to use the C MRAA interface to avoid issue with C++ <-> C
120
+  // calling convention issues, also we need a global
121
+  // mraa_i2c_context
122
+
123
+  if (!(i2cContext = mraa_i2c_init(bus)))
124
+    {
125
+      throw std::invalid_argument(std::string(__FUNCTION__) +
126
+                                  ": mraa_i2c_init() failed");
127
+    }
128
+
129
+  if (mraa_i2c_address(i2cContext, m_addr) != MRAA_SUCCESS)
130
+    {
131
+      throw std::runtime_error(std::string(__FUNCTION__) +
132
+                               ": mraa_i2c_address() failed");
133
+      return;
134
+    }
135
+
136
+  // init the driver interface functions
137
+  s_bmi160.bus_write = bmi160_i2c_bus_write;
138
+  s_bmi160.bus_read = bmi160_i2c_bus_read;
139
+  s_bmi160.delay_msec = bmi160_delay_ms;
140
+  s_bmi160.dev_addr = m_addr;
141
+
142
+  // Init our driver interface pointers
143
+  bmi160_init(&s_bmi160);
144
+
145
+  m_accelX = 0.0;
146
+  m_accelY = 0.0;
147
+  m_accelZ = 0.0;
148
+
149
+  m_gyroX = 0.0;
150
+  m_gyroY = 0.0;
151
+  m_gyroZ = 0.0;
152
+
153
+  m_magX = 0.0;
154
+  m_magY = 0.0;
155
+  m_magZ = 0.0;
156
+
157
+  m_accelScale = 1.0;
158
+  m_gyroScale = 1.0;
159
+
160
+  m_magEnabled = false;
161
+
162
+  if (!init())
163
+    {
164
+      throw std::runtime_error(std::string(__FUNCTION__) +
165
+                               ": init() failed");
166
+    }
167
+}
168
+
169
+BMI160::~BMI160()
170
+{
171
+  mraa_i2c_stop(i2cContext);
172
+  i2cContext = NULL;
173
+}
174
+
175
+bool BMI160::init()
176
+{
177
+  // This should be interesting...
178
+  const u32 C_BMI160_THIRTY_U8X = 30;
179
+
180
+  enableMagnetometer(true);
181
+
182
+  /*Set the accel mode as Normal write in the register 0x7E*/
183
+  bmi160_set_command_register(ACCEL_MODE_NORMAL);
184
+
185
+  /* bmi160_delay_ms in ms*/
186
+  bmi160_delay_ms(C_BMI160_THIRTY_U8X);
187
+
188
+  /*Set the gyro mode as Normal write in the register 0x7E*/
189
+  bmi160_set_command_register(GYRO_MODE_NORMAL);
190
+
191
+  /* bmi160_delay_ms in ms*/
192
+  bmi160_delay_ms(C_BMI160_THIRTY_U8X);
193
+
194
+  /* Set the accel bandwidth as OSRS4 */
195
+  bmi160_set_accel_bw(BMI160_ACCEL_OSR4_AVG1);
196
+  bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
197
+
198
+  /* Set the gryo bandwidth as Normal */
199
+  bmi160_set_gyro_bw(BMI160_GYRO_NORMAL_MODE);
200
+  bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
201
+
202
+  /* set gyro data rate as 200Hz*/
203
+  bmi160_set_gyro_output_data_rate(BMI160_GYRO_OUTPUT_DATA_RATE_200HZ);
204
+  bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
205
+
206
+  /* set accel data rate as 200Hz*/
207
+  bmi160_set_accel_output_data_rate(BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ,
208
+                                    BMI160_ACCEL_OSR4_AVG1);
209
+  bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
210
+
211
+  setAccelerometerScale(ACCEL_RANGE_2G);
212
+  setGyroscopeScale(GYRO_RANGE_125);
213
+
214
+  return true;
215
+}
216
+
217
+
218
+void BMI160::update()
219
+{
220
+  struct bmi160_gyro_t gyroxyz;
221
+  struct bmi160_accel_t accelxyz;
222
+  struct bmi160_mag_xyz_s32_t magxyz;
223
+
224
+  // read gyro data
225
+  bmi160_read_gyro_xyz(&gyroxyz);
226
+
227
+  // read accel data
228
+  bmi160_read_accel_xyz(&accelxyz);
229
+
230
+  // read mag data
231
+  if (m_magEnabled)
232
+    bmi160_bmm150_mag_compensate_xyz(&magxyz);
233
+
234
+  // read the sensor time
235
+  u32 v_sensor_time;
236
+  bmi160_get_sensor_time(&v_sensor_time);
237
+  m_sensorTime = (unsigned int)v_sensor_time;
238
+
239
+  m_accelX = float(accelxyz.x);
240
+  m_accelY = float(accelxyz.y);
241
+  m_accelZ = float(accelxyz.z);
242
+
243
+  m_gyroX = float(gyroxyz.x);
244
+  m_gyroY = float(gyroxyz.y);
245
+  m_gyroZ = float(gyroxyz.z);
246
+
247
+  if (m_magEnabled)
248
+    {
249
+      m_magX = float(magxyz.x);
250
+      m_magY = float(magxyz.y);
251
+      m_magZ = float(magxyz.z);
252
+    }
253
+}
254
+
255
+void BMI160::setAccelerometerScale(ACCEL_RANGE_T scale)
256
+{
257
+  s8 v_range = BMI160_ACCEL_RANGE_2G;
258
+  // store scaling factor
259
+
260
+  switch (scale)
261
+    {
262
+    case ACCEL_RANGE_2G:
263
+      v_range = BMI160_ACCEL_RANGE_2G;
264
+      m_accelScale = 16384.0;
265
+      break;
266
+
267
+    case ACCEL_RANGE_4G:
268
+      v_range = BMI160_ACCEL_RANGE_4G;
269
+      m_accelScale = 8192.0;
270
+      break;
271
+
272
+    case ACCEL_RANGE_8G:
273
+      v_range = BMI160_ACCEL_RANGE_8G;
274
+      m_accelScale = 4096.0;
275
+      break;
276
+
277
+    case ACCEL_RANGE_16G:
278
+      v_range = BMI160_ACCEL_RANGE_16G;
279
+      m_accelScale = 2048.0;
280
+      break;
281
+
282
+    default: // should never occur, but...
283
+      m_accelScale = 1.0;        // set a safe, though incorrect value
284
+      throw std::logic_error(string(__FUNCTION__) +
285
+                             ": internal error, unsupported scale");
286
+      break;
287
+    }
288
+
289
+  bmi160_set_accel_range(v_range);
290
+
291
+  return;
292
+}
293
+
294
+void BMI160::setGyroscopeScale(GYRO_RANGE_T scale)
295
+{
296
+  u8 v_range = BMI160_GYRO_RANGE_2000_DEG_SEC;
297
+
298
+  // store scaling factor
299
+
300
+  switch (scale)
301
+    {
302
+    case GYRO_RANGE_125:
303
+      v_range = BMI160_GYRO_RANGE_125_DEG_SEC;
304
+      m_gyroScale = 262.4;
305
+      break;
306
+
307
+    case GYRO_RANGE_250:
308
+      v_range = BMI160_GYRO_RANGE_250_DEG_SEC;
309
+      m_gyroScale = 131.2;
310
+      break;
311
+
312
+    case GYRO_RANGE_500:
313
+      v_range = BMI160_GYRO_RANGE_500_DEG_SEC;
314
+      m_gyroScale = 65.6;
315
+      break;
316
+
317
+    case GYRO_RANGE_1000:
318
+      v_range = BMI160_GYRO_RANGE_1000_DEG_SEC;
319
+      m_gyroScale = 32.8;
320
+      break;
321
+
322
+    case GYRO_RANGE_2000:
323
+      v_range = BMI160_GYRO_RANGE_2000_DEG_SEC;
324
+      m_gyroScale = 16.4;
325
+      break;
326
+
327
+    default: // should never occur, but...
328
+      m_gyroScale = 1.0;        // set a safe, though incorrect value
329
+      throw std::logic_error(string(__FUNCTION__) +
330
+                             ": internal error, unsupported scale");
331
+      break;
332
+    }
333
+
334
+  bmi160_set_gyro_range(v_range);
335
+
336
+  return;
337
+}
338
+
339
+void BMI160::getAccelerometer(float *x, float *y, float *z)
340
+{
341
+  if (x)
342
+    *x = m_accelX / m_accelScale;
343
+
344
+  if (y)
345
+    *y = m_accelY / m_accelScale;
346
+
347
+  if (z)
348
+    *z = m_accelZ / m_accelScale;
349
+}
350
+
351
+void BMI160::getGyroscope(float *x, float *y, float *z)
352
+{
353
+  if (x)
354
+    *x = m_gyroX / m_gyroScale;
355
+
356
+  if (y)
357
+    *y = m_gyroY / m_gyroScale;
358
+
359
+  if (z)
360
+    *z = m_gyroZ / m_gyroScale;
361
+}
362
+
363
+void BMI160::getMagnetometer(float *x, float *y, float *z)
364
+{
365
+  if (x)
366
+    *x = m_magX;
367
+
368
+  if (y)
369
+    *y = m_magY;
370
+
371
+  if (z)
372
+    *z = m_magZ;
373
+}
374
+
375
+float *BMI160::getAccelerometer()
376
+{
377
+  float *values = new float[3]; // x, y, and then z
378
+
379
+  getAccelerometer(&values[0], &values[1], &values[2]);
380
+
381
+  return values;
382
+}
383
+
384
+float *BMI160::getGyroscope()
385
+{
386
+  float *values = new float[3]; // x, y, and then z
387
+
388
+  getGyroscope(&values[0], &values[1], &values[2]);
389
+
390
+  return values;
391
+}
392
+
393
+float *BMI160::getMagnetometer()
394
+{
395
+  float *values = new float[3]; // x, y, and then z
396
+
397
+  getMagnetometer(&values[0], &values[1], &values[2]);
398
+
399
+  return values;
400
+}
401
+
402
+void BMI160::enableMagnetometer(bool enable)
403
+{
404
+  // butchered from support example
405
+  if (!enable)
406
+    {
407
+      bmi160_set_bmm150_mag_and_secondary_if_power_mode(MAG_SUSPEND_MODE);
408
+      bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
409
+      bmi160_set_if_mode(0x00);
410
+      bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
411
+
412
+      m_magEnabled = false;
413
+      m_magX = 0;
414
+      m_magY = 0;
415
+      m_magZ = 0;
416
+    }
417
+  else
418
+    {
419
+      u8 v_bmm_chip_id_u8 = BMI160_INIT_VALUE;
420
+      /* Init the magnetometer */
421
+      bmi160_bmm150_mag_interface_init(&v_bmm_chip_id_u8);
422
+
423
+      /* bmi160_delay_ms in ms*/
424
+      bmi160_delay_ms(BMI160_GEN_READ_WRITE_DELAY);
425
+
426
+      m_magEnabled = true;
427
+    }
428
+}
429
+
430
+unsigned int BMI160::getSensorTime()
431
+{
432
+  return m_sensorTime;
433
+}

+ 251
- 0
src/bmi160/bmi160.h Voir le fichier

@@ -0,0 +1,251 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 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 <stdint.h>
27
+
28
+#define BMI160_I2C_BUS 0
29
+#define BMI160_DEFAULT_I2C_ADDR 0x69
30
+
31
+namespace upm {
32
+
33
+  /**
34
+   * @brief BMI160 3-axis Accelerometer, Gyroscope and Magnetometer
35
+   * @defgroup bmi160 libupm-bmi160
36
+   * @ingroup i2c accelerometer compass
37
+   */
38
+
39
+
40
+  /**
41
+   * @library bmi160
42
+   * @sensor bmi160
43
+   * @comname UPM API for the BMI160 3-axis Accelerometer, Gyroscope
44
+   * and Magnetometer
45
+   * @type accelerometer compass
46
+   * @man mouser
47
+   * @con i2c
48
+   * @web http://www.mouser.com/ProductDetail/Bosch-Sensortec/0330SB2187/?qs=sGAEpiMZZMvi6wO7nhr1L9JELKA6cYRX60mAGNTn0fQ%3d
49
+   *
50
+   * @brief UPM API for the BMI160 3-axis Accelerometer, Gyroscope and
51
+   * Magnetometer
52
+   *
53
+   * The Bosch BMI160 is a 3-axis Accelerometer and Gyroscope.
54
+   * Additionally it supports an external Magnetometer, accessed
55
+   * through the BMI160's register interface.  This driver was
56
+   * developed with a BMI160 "Shuttle" board, which included a BMM150
57
+   * Magnetometer.
58
+   *
59
+   * The device is driven by either 1.8v or 3.3vdc.  This driver
60
+   * incorporates the Bosch BMI160 driver code at
61
+   * https://github.com/BoschSensortec/BMI160_driver .
62
+   *
63
+   * While not all of the functionality of this device is supported
64
+   * initially, the inclusion of the Bosch driver in the source code
65
+   * makes it possible to support whatever features are required that
66
+   * the driver can support.
67
+   *
68
+   * @snippet bmi160.cxx Interesting
69
+   */
70
+  class BMI160 {
71
+  public:
72
+
73
+    typedef enum {
74
+      ACCEL_RANGE_2G                      = 0, // 2 Gravities
75
+      ACCEL_RANGE_4G,
76
+      ACCEL_RANGE_8G,
77
+      ACCEL_RANGE_16G
78
+    } ACCEL_RANGE_T;
79
+
80
+    typedef enum {
81
+      GYRO_RANGE_125                      = 0, // 125 degrees/sec
82
+      GYRO_RANGE_250,
83
+      GYRO_RANGE_500,
84
+      GYRO_RANGE_1000,
85
+      GYRO_RANGE_2000
86
+    } GYRO_RANGE_T;
87
+
88
+    /**
89
+     * bmi160 constructor
90
+     *
91
+     * @param bus i2c bus to use
92
+     * @param address the address for this device
93
+     */
94
+    BMI160(int bus=BMI160_I2C_BUS, uint8_t address=BMI160_DEFAULT_I2C_ADDR);
95
+
96
+    /**
97
+     * BMI160 Destructor
98
+     */
99
+    ~BMI160();
100
+
101
+    /**
102
+     * Take a measurement and store the current sensor values
103
+     * internally.  This function must be called prior to retrieving
104
+     * any sensor values, for example getAccelerometer().
105
+     *
106
+     */
107
+    void update();
108
+
109
+    /**
110
+     * set the scaling mode of the accelerometer
111
+     *
112
+     * @param scale one of the ACCEL_RANGE_T values
113
+     */
114
+    void setAccelerometerScale(ACCEL_RANGE_T scale);
115
+
116
+    /**
117
+     * set the scaling mode of the gyroscope
118
+     *
119
+     * @param scale one of the GYRO_RANGE_T values
120
+     */
121
+    void setGyroscopeScale(GYRO_RANGE_T scale);
122
+
123
+    /**
124
+     * Get the Accelerometer values.  This function returns a pointer
125
+     * to 3 floating point values: X, Y, and Z, in that order.  The
126
+     * values returned are in gravities.  update() must have been
127
+     * called prior to calling this method.
128
+     *
129
+     * The caller is reponsible for freeing the returned pointer.
130
+     *
131
+     * @return Pointer to 3 floating point values: X, Y, and Z in
132
+     * gravities.
133
+     */
134
+    float *getAccelerometer();
135
+
136
+    /**
137
+     * Get the Accelerometer values.  The values returned are in
138
+     * gravities.  update() must have been called prior to calling
139
+     * this method.
140
+     *
141
+     * @param x A pointer into which the X value will be returned
142
+     * @param y A pointer into which the Y value will be returned
143
+     * @param z A pointer into which the Z value will be returned
144
+     */
145
+    void getAccelerometer(float *x, float *y, float *z);
146
+
147
+    /**
148
+     * Get the Gyroscope values.  This function returns a pointer to 3
149
+     * floating point values: X, Y, and Z, in that order.  The values
150
+     * values returned are in degrees per second.  update() must have
151
+     * been called prior to calling this method.
152
+     *
153
+     * The caller is reponsible for freeing the returned pointer.
154
+     *
155
+     * @return Pointer to 3 floating point values: X, Y, and Z in
156
+     * degrees per second.
157
+     */
158
+    float *getGyroscope();
159
+
160
+    /**
161
+     * Get the Gyroscope values.  The values returned are in degrees
162
+     * per second.  update() must have been called prior to calling
163
+     * this method.
164
+     *
165
+     * @param x A pointer into which the X value will be returned
166
+     * @param y A pointer into which the Y value will be returned
167
+     * @param z A pointer into which the Z value will be returned
168
+     */
169
+    void getGyroscope(float *x, float *y, float *z);
170
+
171
+    /**
172
+     * Get the Magnetometer values.  This function returns a pointer
173
+     * to 3 floating point values: X, Y, and Z, in that order.  The
174
+     * values values returned are in micro Teslas.  update() must have
175
+     * been called prior to calling this method.  If the Magnetometer
176
+     * has been disabled, the return values will always be 0, 0, and
177
+     * 0.
178
+     *
179
+     * The caller is reponsible for freeing the returned pointer.
180
+     *
181
+     * @return Pointer to 3 floating point values: X, Y, and Z in
182
+     * micro Teslas.
183
+     */
184
+    float *getMagnetometer();
185
+
186
+    /**
187
+     * Get the Magnetometer values.  The values returned are in micro
188
+     * Teslas.  update() must have been called prior to calling this
189
+     * method.
190
+     *
191
+     * @param x A pointer into which the X value will be returned
192
+     * @param y A pointer into which the Y value will be returned
193
+     * @param z A pointer into which the Z value will be returned
194
+     */
195
+    void getMagnetometer(float *x, float *y, float *z);
196
+
197
+    /**
198
+     * Enable or disable the Magnetometer.  By default, the
199
+     * magnetometer is enabled.
200
+     *
201
+     * @param enable true to enable the magnetometer, false to disable.
202
+     */
203
+    void enableMagnetometer(bool enable);
204
+
205
+    /**
206
+     * Return the sensor time.  This is a 24bit value that increments
207
+     * every 39us.  It will wrap around once the 24b resolution is
208
+     * exceeded.
209
+     *
210
+     * @return The current sensor time.
211
+     */
212
+    unsigned int getSensorTime();
213
+
214
+  protected:
215
+    // uncompensated accelerometer and gyroscope values
216
+    float m_accelX;
217
+    float m_accelY;
218
+    float m_accelZ;
219
+
220
+    float m_gyroX;
221
+    float m_gyroY;
222
+    float m_gyroZ;
223
+
224
+    float m_magX;
225
+    float m_magY;
226
+    float m_magZ;
227
+
228
+    unsigned int m_sensorTime;
229
+
230
+    // accelerometer and gyro scaling factors, depending on their Full
231
+    // Scale (Range) settings.
232
+    float m_accelScale;
233
+    float m_gyroScale;
234
+
235
+    // is the magnetometer enabled?
236
+    bool m_magEnabled;
237
+
238
+    /**
239
+     * set up initial values and start operation
240
+     *
241
+     * @return true if successful
242
+     */
243
+    virtual bool init();
244
+
245
+  private:
246
+    // due to the way we need to 'hook' into the bmi driver, the i2c
247
+    // context is a static variable defined in the .cxx implmentation.
248
+
249
+    uint8_t m_addr;
250
+  };
251
+}

+ 20467
- 0
src/bmi160/bosch_bmi160.c
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 12045
- 0
src/bmi160/bosch_bmi160.h
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 41
- 0
src/bmi160/javaupm_bmi160.i Voir le fichier

@@ -0,0 +1,41 @@
1
+%module javaupm_bmi160
2
+%include "../upm.i"
3
+%include "typemaps.i"
4
+%include "arrays_java.i"
5
+%include "../java_buffer.i"
6
+
7
+%{
8
+    #include "bmi160.h"
9
+%}
10
+
11
+
12
+%typemap(jni) float * "jfloatArray"
13
+%typemap(jstype) float * "float[]"
14
+%typemap(jtype) float * "float[]"
15
+
16
+%typemap(javaout) float * {
17
+    return $jnicall;
18
+}
19
+
20
+%typemap(out) float * {
21
+    $result = JCALL1(NewFloatArray, jenv, 3);
22
+    JCALL4(SetFloatArrayRegion, jenv, $result, 0, 3, $1);
23
+    delete [] $1;
24
+}
25
+
26
+%ignore getAccelerometer(float *, float *, float *);
27
+%ignore getGyroscope(float *, float *, float *);
28
+%ignore getMagnetometer(float *, float *, float *);
29
+
30
+%include "bmi160.h"
31
+
32
+%pragma(java) jniclasscode=%{
33
+    static {
34
+        try {
35
+            System.loadLibrary("javaupm_bmi160");
36
+        } catch (UnsatisfiedLinkError e) {
37
+            System.err.println("Native code library failed to load. \n" + e);
38
+            System.exit(1);
39
+        }
40
+    }
41
+%}

+ 10
- 0
src/bmi160/jsupm_bmi160.i Voir le fichier

@@ -0,0 +1,10 @@
1
+%module jsupm_bmi160
2
+%include "../upm.i"
3
+%include "cpointer.i"
4
+
5
+%pointer_functions(float, floatp);
6
+
7
+%include "bmi160.h"
8
+%{
9
+    #include "bmi160.h"
10
+%}

+ 55
- 0
src/bmi160/license.txt Voir le fichier

@@ -0,0 +1,55 @@
1
+/** \mainpage
2
+*
3
+****************************************************************************
4
+* Copyright (C) 2014 Bosch Sensortec GmbH
5
+*
6
+* File : bmi160.h
7
+*
8
+* Date : 2014/10/27
9
+*
10
+* Revision : 2.0.6 $
11
+*
12
+* Usage: Sensor Driver for BMI160 sensor
13
+*
14
+****************************************************************************
15
+*
16
+* \section License
17
+*
18
+* Redistribution and use in source and binary forms, with or without
19
+* modification, are permitted provided that the following conditions are met:
20
+*
21
+*   Redistributions of source code must retain the above copyright
22
+*   notice, this list of conditions and the following disclaimer.
23
+*
24
+*   Redistributions in binary form must reproduce the above copyright
25
+*   notice, this list of conditions and the following disclaimer in the
26
+*   documentation and/or other materials provided with the distribution.
27
+*
28
+*   Neither the name of the copyright holder nor the names of the
29
+*   contributors may be used to endorse or promote products derived from
30
+*   this software without specific prior written permission.
31
+*
32
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
33
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
34
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36
+* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
37
+* OR CONTRIBUTORS BE LIABLE FOR ANY
38
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39
+* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
40
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
41
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
45
+* ANY WAY OUT OF THE USE OF THIS
46
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
47
+*
48
+* The information provided is believed to be accurate and reliable.
49
+* The copyright holder assumes no responsibility
50
+* for the consequences of use
51
+* of such information nor for any infringement of patents or
52
+* other rights of third parties which may result from its use.
53
+* No license is granted by implication or otherwise under any patent or
54
+* patent rights of the copyright holder.
55
+**************************************************************************/

+ 16
- 0
src/bmi160/pyupm_bmi160.i Voir le fichier

@@ -0,0 +1,16 @@
1
+// Include doxygen-generated documentation
2
+%include "pyupm_doxy2swig.i"
3
+%module pyupm_bmi160
4
+%include "../upm.i"
5
+%include "cpointer.i"
6
+
7
+%include "stdint.i"
8
+
9
+%feature("autodoc", "3");
10
+
11
+%pointer_functions(float, floatp);
12
+
13
+%include "bmi160.h"
14
+%{
15
+    #include "bmi160.h"
16
+%}

+ 6
- 0
src/upm.h Voir le fichier

@@ -372,6 +372,12 @@
372 372
  * @ingroup byman
373 373
  */
374 374
 
375
+/**
376
+ * @brief Mouser
377
+ * @defgroup mouser Mouser
378
+ * @ingroup byman
379
+ */
380
+
375 381
 /**
376 382
  * @brief Omega
377 383
  * @defgroup omega Omega