mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
lsm303d: Initial implementation, C, C++ wraps C
Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
parent
fe4e97f5dc
commit
5cc4e2120a
87
examples/c++/lsm303d.cxx
Normal file
87
examples/c++/lsm303d.cxx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "lsm303d.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int shouldRun = true;
|
||||||
|
|
||||||
|
void sig_handler(int signo)
|
||||||
|
{
|
||||||
|
if (signo == SIGINT)
|
||||||
|
shouldRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
signal(SIGINT, sig_handler);
|
||||||
|
//! [Interesting]
|
||||||
|
|
||||||
|
// Instantiate an LSM303D using default I2C parameters
|
||||||
|
upm::LSM303D sensor;
|
||||||
|
|
||||||
|
// now output data every 250 milliseconds
|
||||||
|
while (shouldRun)
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
sensor.update();
|
||||||
|
|
||||||
|
sensor.getAccelerometer(&x, &y, &z);
|
||||||
|
cout << "Accelerometer x: " << x
|
||||||
|
<< " y: " << y
|
||||||
|
<< " z: " << z
|
||||||
|
<< " g"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
sensor.getMagnetometer(&x, &y, &z);
|
||||||
|
cout << "Magnetometer x: " << x
|
||||||
|
<< " y: " << y
|
||||||
|
<< " z: " << z
|
||||||
|
<< " uT"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
cout << "Temperature: "
|
||||||
|
<< sensor.getTemperature()
|
||||||
|
<< " C"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
usleep(250000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! [Interesting]
|
||||||
|
|
||||||
|
cout << "Exiting..." << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
89
examples/c/lsm303d.c
Normal file
89
examples/c/lsm303d.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "upm_utilities.h"
|
||||||
|
#include "lsm303d.h"
|
||||||
|
|
||||||
|
bool shouldRun = true;
|
||||||
|
|
||||||
|
void sig_handler(int signo)
|
||||||
|
{
|
||||||
|
if (signo == SIGINT)
|
||||||
|
shouldRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
signal(SIGINT, sig_handler);
|
||||||
|
//! [Interesting]
|
||||||
|
|
||||||
|
// Instantiate a LSM303D instance using default i2c bus and addresses
|
||||||
|
lsm303d_context sensor = lsm303d_init(LSM303D_DEFAULT_I2C_BUS,
|
||||||
|
LSM303D_DEFAULT_I2C_ADDR);
|
||||||
|
|
||||||
|
if (!sensor)
|
||||||
|
{
|
||||||
|
printf("lsm303d_init() failed.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now output data every 250 milliseconds
|
||||||
|
while (shouldRun)
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
if (lsm303d_update(sensor))
|
||||||
|
{
|
||||||
|
printf("lsm303d_update() failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsm303d_get_accelerometer(sensor, &x, &y, &z);
|
||||||
|
printf("Accelerometer x: %f y: %f z: %f g\n",
|
||||||
|
x, y, z);
|
||||||
|
|
||||||
|
lsm303d_get_magnetometer(sensor, &x, &y, &z);
|
||||||
|
printf("Magnetometer x: %f y: %f z: %f uT\n",
|
||||||
|
x, y, z);
|
||||||
|
|
||||||
|
printf("Temperature: %f C\n\n", lsm303d_get_temperature(sensor));
|
||||||
|
|
||||||
|
upm_delay_ms(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exiting...\n");
|
||||||
|
|
||||||
|
lsm303d_close(sensor);
|
||||||
|
|
||||||
|
//! [Interesting]
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -170,6 +170,7 @@ add_example(BMG160_Example bmg160)
|
|||||||
add_example(BMA250E_Example bma250e)
|
add_example(BMA250E_Example bma250e)
|
||||||
add_example(BMM150_Example bmm150)
|
add_example(BMM150_Example bmm150)
|
||||||
add_example(LSM303AGR_Example lsm303agr)
|
add_example(LSM303AGR_Example lsm303agr)
|
||||||
|
add_example(LSM303D_Example lsm303d)
|
||||||
|
|
||||||
add_example_with_path(Jhd1313m1_lcdSample jhd1313m1 jhd1313m1)
|
add_example_with_path(Jhd1313m1_lcdSample jhd1313m1 jhd1313m1)
|
||||||
add_example_with_path(Jhd1313m1Sample jhd1313m1 jhd1313m1)
|
add_example_with_path(Jhd1313m1Sample jhd1313m1 jhd1313m1)
|
||||||
|
65
examples/java/LSM303D_Example.java
Normal file
65
examples/java/LSM303D_Example.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import upm_lsm303d.LSM303D;
|
||||||
|
|
||||||
|
public class LSM303D_Example
|
||||||
|
{
|
||||||
|
public static void main(String[] args) throws InterruptedException
|
||||||
|
{
|
||||||
|
// ! [Interesting]
|
||||||
|
|
||||||
|
// Instantiate a LSM303D instance using default i2c bus and address
|
||||||
|
LSM303D sensor = new LSM303D();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// update our values from the sensor
|
||||||
|
sensor.update();
|
||||||
|
|
||||||
|
upm_lsm303d.floatVector data = sensor.getAccelerometer();
|
||||||
|
|
||||||
|
System.out.println("Accelerometer x: " + data.get(0)
|
||||||
|
+ " y: " + data.get(1)
|
||||||
|
+ " z: " + data.get(2)
|
||||||
|
+ " g");
|
||||||
|
|
||||||
|
data = sensor.getMagnetometer();
|
||||||
|
System.out.println("Magnetometer x: " + data.get(0)
|
||||||
|
+ " y: " + data.get(1)
|
||||||
|
+ " z: " + data.get(2)
|
||||||
|
+ " uT");
|
||||||
|
|
||||||
|
System.out.println("Temperature: "
|
||||||
|
+ sensor.getTemperature());
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ! [Interesting]
|
||||||
|
}
|
||||||
|
}
|
67
examples/javascript/lsm303d.js
Normal file
67
examples/javascript/lsm303d.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var sensorObj = require('jsupm_lsm303d');
|
||||||
|
|
||||||
|
// Instantiate a LSM303D instance using default i2c bus and address
|
||||||
|
var sensor = new sensorObj.LSM303D();
|
||||||
|
|
||||||
|
// now output data every 250 milliseconds
|
||||||
|
setInterval(function()
|
||||||
|
{
|
||||||
|
// update our values from the sensor
|
||||||
|
sensor.update();
|
||||||
|
|
||||||
|
var data = sensor.getAccelerometer();
|
||||||
|
console.log("Accelerometer x: "
|
||||||
|
+ data.get(0)
|
||||||
|
+ " y: " + data.get(1)
|
||||||
|
+ " z: " + data.get(2)
|
||||||
|
+ " g");
|
||||||
|
|
||||||
|
data = sensor.getMagnetometer();
|
||||||
|
console.log("Magnetometer x: "
|
||||||
|
+ data.get(0)
|
||||||
|
+ " y: " + data.get(1)
|
||||||
|
+ " z: " + data.get(2)
|
||||||
|
+ " uT");
|
||||||
|
|
||||||
|
console.log("Temperature: "
|
||||||
|
+ sensor.getTemperature());
|
||||||
|
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
}, 250);
|
||||||
|
|
||||||
|
// exit on ^C
|
||||||
|
process.on('SIGINT', function()
|
||||||
|
{
|
||||||
|
sensor = null;
|
||||||
|
sensorObj.cleanUp();
|
||||||
|
sensorObj = null;
|
||||||
|
console.log("Exiting.");
|
||||||
|
process.exit(0);
|
||||||
|
});
|
71
examples/python/lsm303d.py
Executable file
71
examples/python/lsm303d.py
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
# Copyright (c) 2017 Intel Corporation.
|
||||||
|
#
|
||||||
|
# The MIT License
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import time, sys, signal, atexit
|
||||||
|
from upm import pyupm_lsm303d as sensorObj
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Instantiate a BMP250E instance using default i2c bus and address
|
||||||
|
sensor = sensorObj.LSM303D()
|
||||||
|
|
||||||
|
## Exit handlers ##
|
||||||
|
# This function stops python from printing a stacktrace when you
|
||||||
|
# hit control-C
|
||||||
|
def SIGINTHandler(signum, frame):
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
# This function lets you run code on exit
|
||||||
|
def exitHandler():
|
||||||
|
print("Exiting")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Register exit handlers
|
||||||
|
atexit.register(exitHandler)
|
||||||
|
signal.signal(signal.SIGINT, SIGINTHandler)
|
||||||
|
|
||||||
|
# now output data every 250 milliseconds
|
||||||
|
while (1):
|
||||||
|
sensor.update()
|
||||||
|
|
||||||
|
data = sensor.getAccelerometer()
|
||||||
|
print("Accelerometer x:", data[0], end=' ')
|
||||||
|
print(" y:", data[1], end=' ')
|
||||||
|
print(" z:", data[2], end=' ')
|
||||||
|
print(" g")
|
||||||
|
|
||||||
|
data = sensor.getMagnetometer()
|
||||||
|
print("Magnetometer x:", data[0], end=' ')
|
||||||
|
print(" y:", data[1], end=' ')
|
||||||
|
print(" z:", data[2], end=' ')
|
||||||
|
print(" uT")
|
||||||
|
|
||||||
|
print("Temperature: ", sensor.getTemperature())
|
||||||
|
|
||||||
|
print()
|
||||||
|
time.sleep(.250)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
8
src/lsm303d/CMakeLists.txt
Normal file
8
src/lsm303d/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
upm_mixed_module_init (NAME lsm303d
|
||||||
|
DESCRIPTION "3-Axis eCompass module"
|
||||||
|
C_HDR lsm303d.h lsm303d_defs.h
|
||||||
|
C_SRC lsm303d.c
|
||||||
|
CPP_HDR lsm303d.hpp
|
||||||
|
CPP_SRC lsm303d.cxx
|
||||||
|
CPP_WRAPS_C
|
||||||
|
REQUIRES mraa)
|
24
src/lsm303d/javaupm_lsm303d.i
Normal file
24
src/lsm303d/javaupm_lsm303d.i
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
%module javaupm_lsm303d
|
||||||
|
%include "../upm.i"
|
||||||
|
%include "typemaps.i"
|
||||||
|
%include "../upm_vectortypes.i"
|
||||||
|
|
||||||
|
%ignore getMagnetometer(float *, float *, float *);
|
||||||
|
%ignore getAccelerometer(float *, float *, float *);
|
||||||
|
|
||||||
|
%include "lsm303d_defs.h"
|
||||||
|
%include "lsm303d.hpp"
|
||||||
|
%{
|
||||||
|
#include "lsm303d.hpp"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%pragma(java) jniclasscode=%{
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("javaupm_lsm303d");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.err.println("Native code library failed to load. \n" + e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
9
src/lsm303d/jsupm_lsm303d.i
Normal file
9
src/lsm303d/jsupm_lsm303d.i
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
%module jsupm_lsm303d
|
||||||
|
%include "../upm.i"
|
||||||
|
%include "../upm_vectortypes.i"
|
||||||
|
|
||||||
|
%include "lsm303d_defs.h"
|
||||||
|
%include "lsm303d.hpp"
|
||||||
|
%{
|
||||||
|
#include "lsm303d.hpp"
|
||||||
|
%}
|
417
src/lsm303d/lsm303d.c
Normal file
417
src/lsm303d/lsm303d.c
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "upm_utilities.h"
|
||||||
|
|
||||||
|
#include "lsm303d.h"
|
||||||
|
|
||||||
|
|
||||||
|
// some useful macros to save on typing and text wrapping
|
||||||
|
#undef _SHIFT
|
||||||
|
#define _SHIFT(x) (_LSM303D_##x##_SHIFT)
|
||||||
|
|
||||||
|
#undef _MASK
|
||||||
|
#define _MASK(x) (_LSM303D_##x##_MASK)
|
||||||
|
|
||||||
|
#undef _SHIFTMASK
|
||||||
|
#define _SHIFTMASK(x) (_MASK(x) << _SHIFT(x))
|
||||||
|
|
||||||
|
|
||||||
|
// init
|
||||||
|
lsm303d_context lsm303d_init(int bus, int addr)
|
||||||
|
{
|
||||||
|
lsm303d_context dev =
|
||||||
|
(lsm303d_context)malloc(sizeof(struct _lsm303d_context));
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// zero out context
|
||||||
|
memset((void *)dev, 0, sizeof(struct _lsm303d_context));
|
||||||
|
|
||||||
|
// make sure MRAA is initialized
|
||||||
|
if (mraa_init() != MRAA_SUCCESS)
|
||||||
|
{
|
||||||
|
printf("%s: mraa_init() failed.\n", __FUNCTION__);
|
||||||
|
lsm303d_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dev->i2c = mraa_i2c_init(bus)))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_init() failed.\n", __FUNCTION__);
|
||||||
|
lsm303d_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mraa_i2c_address(dev->i2c, addr))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_address() failed.\n", __FUNCTION__);
|
||||||
|
lsm303d_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the chip id
|
||||||
|
uint8_t chipID = lsm303d_read_reg(dev, LSM303D_REG_WHO_AM_I);
|
||||||
|
|
||||||
|
if (chipID != LSM303D_CHIPID)
|
||||||
|
{
|
||||||
|
printf("%s: invalid chip id: %02x. Expected %02x\n",
|
||||||
|
__FUNCTION__, chipID, LSM303D_CHIPID);
|
||||||
|
lsm303d_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call devinit with a default high resolution mode
|
||||||
|
if (lsm303d_devinit(dev, LSM303D_M_RES_HIGH))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_devinit() failed.\n", __FUNCTION__);
|
||||||
|
lsm303d_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303d_close(lsm303d_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (dev->i2c)
|
||||||
|
mraa_i2c_stop(dev->i2c);
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_devinit(const lsm303d_context dev,
|
||||||
|
LSM303D_M_RES_T res)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// enable all axes and BDU
|
||||||
|
uint8_t reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL1);
|
||||||
|
|
||||||
|
reg |= LSM303D_CTRL1_AXEN
|
||||||
|
| LSM303D_CTRL1_AYEN
|
||||||
|
| LSM303D_CTRL1_AZEN
|
||||||
|
| LSM303D_CTRL1_BDU;
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL1, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable temperature measurement and set mag resolution
|
||||||
|
reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL5);
|
||||||
|
reg &= ~_SHIFTMASK(CTRL5_MRES);
|
||||||
|
reg |= LSM303D_CTRL5_TEMP_EN
|
||||||
|
| (res << _SHIFT(CTRL5_MRES));
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL5, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set magnetometer to continuous mode
|
||||||
|
reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL7);
|
||||||
|
reg &= ~_SHIFTMASK(CTRL7_MD);
|
||||||
|
reg |= (LSM303D_MD_CONTINUOUS << _SHIFT(CTRL7_MD));
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL7, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set ACC ODR to 100Hz by default
|
||||||
|
if (lsm303d_set_acc_odr(dev, LSM303D_AODR_100HZ))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_set_acc_odr() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set MAG ODR to 12.5Hz by default
|
||||||
|
if (lsm303d_set_mag_odr(dev, LSM303D_MODR_12_5HZ))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_set_acc_odr() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to 2G acc sensitivity
|
||||||
|
if (lsm303d_set_acc_full_scale(dev, LSM303D_AFS_2G))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_set_acc_full_scale() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to 2 Gauss mag sensitivity
|
||||||
|
if (lsm303d_set_mag_full_scale(dev, LSM303D_MFS_2))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_set_acc_full_scale() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_delay_ms(10);
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_set_acc_full_scale(const lsm303d_context dev,
|
||||||
|
LSM303D_AFS_T fs)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
uint8_t reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL2);
|
||||||
|
|
||||||
|
reg &= ~_SHIFTMASK(CTRL2_AFS);
|
||||||
|
reg |= (fs << _SHIFT(CTRL2_AFS));
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL2, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
upm_delay_ms(50);
|
||||||
|
|
||||||
|
// set our scaling factor depending on current FS
|
||||||
|
switch(fs)
|
||||||
|
{
|
||||||
|
case LSM303D_AFS_2G:
|
||||||
|
dev->accScale = 0.061;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_AFS_4G:
|
||||||
|
dev->accScale = 0.122;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_AFS_6G:
|
||||||
|
dev->accScale = 0.183;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_AFS_8G:
|
||||||
|
dev->accScale = 0.320;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_AFS_16G:
|
||||||
|
dev->accScale = 0.732;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_set_mag_full_scale(const lsm303d_context dev,
|
||||||
|
LSM303D_MFS_T fs)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
uint8_t reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL6);
|
||||||
|
|
||||||
|
reg &= ~_SHIFTMASK(CTRL6_MFS);
|
||||||
|
reg |= (fs << _SHIFT(CTRL6_MFS));
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL6, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
upm_delay_ms(50);
|
||||||
|
|
||||||
|
// set our scaling factor depending on current FS
|
||||||
|
switch(fs)
|
||||||
|
{
|
||||||
|
case LSM303D_MFS_2:
|
||||||
|
dev->magScale = 0.080;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_MFS_4:
|
||||||
|
dev->magScale = 0.160;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_MFS_8:
|
||||||
|
dev->magScale = 0.320;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303D_MFS_12:
|
||||||
|
dev->magScale = 0.479;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_update(const lsm303d_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
const int maxLen = 6;
|
||||||
|
uint8_t buf[maxLen];
|
||||||
|
|
||||||
|
// get the temperature first, only 2 bytes
|
||||||
|
if (lsm303d_read_regs(dev, LSM303D_REG_TEMP_OUT_L, buf, 2) != 2)
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_read_regs(temp) failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->temperature = (float)( (int16_t)(buf[0] | (buf[1] << 8)) << 4);
|
||||||
|
|
||||||
|
// next, acc data
|
||||||
|
if (lsm303d_read_regs(dev, LSM303D_REG_OUT_X_L_A, buf,
|
||||||
|
maxLen) != maxLen)
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_read_regs(acc) failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->accX = (float)((int16_t)(buf[0] | (buf[1] << 8)));
|
||||||
|
dev->accY = (float)((int16_t)(buf[2] | (buf[3] << 8)));
|
||||||
|
dev->accZ = (float)((int16_t)(buf[4] | (buf[5] << 8)));
|
||||||
|
|
||||||
|
// now mag data
|
||||||
|
if (lsm303d_read_regs(dev, LSM303D_REG_OUT_X_L_M, buf,
|
||||||
|
maxLen) != maxLen)
|
||||||
|
{
|
||||||
|
printf("%s: lsm303d_read_regs(mag) failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->magX = (float)((int16_t)(buf[0] | (buf[1] << 8)));
|
||||||
|
dev->magY = (float)((int16_t)(buf[2] | (buf[3] << 8)));
|
||||||
|
dev->magZ = (float)((int16_t)(buf[4] | (buf[5] << 8)));
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303d_read_reg(const lsm303d_context dev, uint8_t reg)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
int rv = mraa_i2c_read_byte_data(dev->i2c, reg);
|
||||||
|
if (rv < 0)
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_read_byte_data() failed\n", __FUNCTION__);
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint8_t)rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lsm303d_read_regs(const lsm303d_context dev, uint8_t reg,
|
||||||
|
uint8_t *buffer, int len)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
reg |= 0x80; // enable auto-increment
|
||||||
|
if (mraa_i2c_read_bytes_data(dev->i2c, reg, buffer, len) != len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_write_reg(const lsm303d_context dev,
|
||||||
|
uint8_t reg, uint8_t val)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (mraa_i2c_write_byte_data(dev->i2c, val, reg))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_write_byte_data() failed.\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
float lsm303d_get_temperature(const lsm303d_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// It's not clear how to compute this from the datasheet, but this
|
||||||
|
// seems to give a reasonably accurate result.
|
||||||
|
return (dev->temperature / 128.0) + 25.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303d_get_magnetometer(const lsm303d_context dev,
|
||||||
|
float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// Output is in milli-Gauss - we convert and return it in uT (SI
|
||||||
|
// micro-teslas) instead.
|
||||||
|
if (x)
|
||||||
|
*x = (dev->magX * dev->magScale) / 10.0;
|
||||||
|
if (y)
|
||||||
|
*y = (dev->magY * dev->magScale) / 10.0;
|
||||||
|
if (z)
|
||||||
|
*z = (dev->magZ * dev->magScale) / 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303d_get_accelerometer(const lsm303d_context dev,
|
||||||
|
float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
*x = (dev->accX * dev->accScale) / 1000.0;
|
||||||
|
if (y)
|
||||||
|
*y = (dev->accY * dev->accScale) / 1000.0;
|
||||||
|
if (z)
|
||||||
|
*z = (dev->accZ * dev->accScale) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_set_acc_odr(const lsm303d_context dev,
|
||||||
|
LSM303D_AODR_T odr)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
uint8_t reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL1);
|
||||||
|
reg &= ~_SHIFTMASK(CTRL1_AODR);
|
||||||
|
reg |= (odr << _SHIFT(CTRL1_AODR));
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL1, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303d_set_mag_odr(const lsm303d_context dev,
|
||||||
|
LSM303D_MODR_T odr)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
uint8_t reg = lsm303d_read_reg(dev, LSM303D_REG_CTRL5);
|
||||||
|
reg &= ~_SHIFTMASK(CTRL5_MODR);
|
||||||
|
reg |= (odr << _SHIFT(CTRL5_MODR));
|
||||||
|
|
||||||
|
if (lsm303d_write_reg(dev, LSM303D_REG_CTRL5, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
142
src/lsm303d/lsm303d.cxx
Normal file
142
src/lsm303d/lsm303d.cxx
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lsm303d.hpp"
|
||||||
|
|
||||||
|
using namespace upm;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
LSM303D::LSM303D(int bus, int addr) :
|
||||||
|
m_lsm303d(lsm303d_init(bus, addr))
|
||||||
|
{
|
||||||
|
if (!m_lsm303d)
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_init() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
LSM303D::~LSM303D()
|
||||||
|
{
|
||||||
|
lsm303d_close(m_lsm303d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::init(LSM303D_M_RES_T res)
|
||||||
|
{
|
||||||
|
if (lsm303d_devinit(m_lsm303d, res))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_devinit() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::update()
|
||||||
|
{
|
||||||
|
if (lsm303d_update(m_lsm303d))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_update() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303D::readReg(uint8_t reg)
|
||||||
|
{
|
||||||
|
return lsm303d_read_reg(m_lsm303d, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LSM303D::readRegs(uint8_t reg, uint8_t *buffer, int len)
|
||||||
|
{
|
||||||
|
int rv = lsm303d_read_regs(m_lsm303d, reg, buffer, len);
|
||||||
|
if (rv < 0)
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_read_regs() failed");
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::writeReg(uint8_t reg, uint8_t val)
|
||||||
|
{
|
||||||
|
if (lsm303d_write_reg(m_lsm303d, reg, val))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_write_reg() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::getMagnetometer(float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
lsm303d_get_magnetometer(m_lsm303d, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> LSM303D::getMagnetometer()
|
||||||
|
{
|
||||||
|
float v[3];
|
||||||
|
|
||||||
|
getMagnetometer(&v[0], &v[1], &v[2]);
|
||||||
|
return std::vector<float>(v, v+3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::getAccelerometer(float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
lsm303d_get_accelerometer(m_lsm303d, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> LSM303D::getAccelerometer()
|
||||||
|
{
|
||||||
|
float v[3];
|
||||||
|
|
||||||
|
getAccelerometer(&v[0], &v[1], &v[2]);
|
||||||
|
return std::vector<float>(v, v+3);
|
||||||
|
}
|
||||||
|
|
||||||
|
float LSM303D::getTemperature()
|
||||||
|
{
|
||||||
|
return lsm303d_get_temperature(m_lsm303d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::setAccelerometerFullScale(LSM303D_AFS_T fs)
|
||||||
|
{
|
||||||
|
if (lsm303d_set_acc_full_scale(m_lsm303d, fs))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_set_acc_full_scale() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::setMagnetometerFullScale(LSM303D_MFS_T fs)
|
||||||
|
{
|
||||||
|
if (lsm303d_set_mag_full_scale(m_lsm303d, fs))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_set_mag_full_scale() failed");
|
||||||
|
}
|
||||||
|
void LSM303D::setAccelerometerODR(LSM303D_AODR_T odr)
|
||||||
|
{
|
||||||
|
if (lsm303d_set_acc_odr(m_lsm303d, odr))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_set_acc_odr() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303D::setMagnetometerODR(LSM303D_MODR_T odr)
|
||||||
|
{
|
||||||
|
if (lsm303d_set_mag_odr(m_lsm303d, odr))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303d_set_mag_odr() failed");
|
||||||
|
}
|
238
src/lsm303d/lsm303d.h
Normal file
238
src/lsm303d/lsm303d.h
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <mraa/i2c.h>
|
||||||
|
#include <mraa/gpio.h>
|
||||||
|
|
||||||
|
#include "upm.h"
|
||||||
|
|
||||||
|
#include "lsm303d_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file lsm303d.h
|
||||||
|
* @library lsm303d
|
||||||
|
* @brief C API for the lsm303d driver
|
||||||
|
*
|
||||||
|
* @include lsm303d.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device context
|
||||||
|
*/
|
||||||
|
typedef struct _lsm303d_context {
|
||||||
|
mraa_i2c_context i2c;
|
||||||
|
|
||||||
|
// uncompensated temperature in C
|
||||||
|
float temperature;
|
||||||
|
|
||||||
|
// accelerometer scaling
|
||||||
|
float accScale;
|
||||||
|
|
||||||
|
// magnetometer scaling
|
||||||
|
float magScale;
|
||||||
|
|
||||||
|
// uncompensated acc data
|
||||||
|
float accX;
|
||||||
|
float accY;
|
||||||
|
float accZ;
|
||||||
|
|
||||||
|
// uncompensated mag data
|
||||||
|
float magX;
|
||||||
|
float magY;
|
||||||
|
float magZ;
|
||||||
|
} *lsm303d_context;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303D initialization
|
||||||
|
*
|
||||||
|
* This driver only supports I2C.
|
||||||
|
*
|
||||||
|
* Due to the fact that this chip is currently obsolete, we only
|
||||||
|
* support minimum functionality.
|
||||||
|
*
|
||||||
|
* @param bus I2C bus to use
|
||||||
|
* @param addr The I2C address of the device
|
||||||
|
* @return The device context, or NULL if an error occurred
|
||||||
|
*/
|
||||||
|
lsm303d_context lsm303d_init(int bus, int addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303D Destructor
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
*/
|
||||||
|
void lsm303d_close(lsm303d_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the internal stored values from sensor data
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_update(const lsm303d_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return magnetometer data in micro-Teslas (uT). update() must
|
||||||
|
* have been called prior to calling this function.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param x Pointer to a floating point value that will have the
|
||||||
|
* current x component placed into it
|
||||||
|
* @param y Pointer to a floating point value that will have the
|
||||||
|
* current y component placed into it
|
||||||
|
* @param z Pointer to a floating point value that will have the
|
||||||
|
* current z component placed into it
|
||||||
|
*/
|
||||||
|
void lsm303d_get_magnetometer(const lsm303d_context dev,
|
||||||
|
float *x, float *y, float *z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accelerometer data in gravities. update() must have
|
||||||
|
* been called prior to calling this function.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param x Pointer to a floating point value that will have the
|
||||||
|
* current x component placed into it
|
||||||
|
* @param y Pointer to a floating point value that will have the
|
||||||
|
* current y component placed into it
|
||||||
|
* @param z Pointer to a floating point value that will have the
|
||||||
|
* current z component placed into it
|
||||||
|
*/
|
||||||
|
void lsm303d_get_accelerometer(const lsm303d_context dev,
|
||||||
|
float *x, float *y, float *z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return temperature data in degrees Celsius.. update() must
|
||||||
|
* have been called prior to calling this function.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return Temperature in degrees Celsius
|
||||||
|
*/
|
||||||
|
float lsm303d_get_temperature(const lsm303d_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the full scale (sensitivity) value for the accelerometer.
|
||||||
|
* This device supports 2G, 4G, 6G, 8G, and 16G full scale modes.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param fs One of the LSM303D_AFS_T values
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_set_acc_full_scale(const lsm303d_context dev,
|
||||||
|
LSM303D_AFS_T fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the full scale (sensitivity) value for the magnetometer.
|
||||||
|
* This device supports 2, 4, 8, and 16 Gauss.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param fs One of the LSM303D_MFS_T values
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_set_mag_full_scale(const lsm303d_context dev,
|
||||||
|
LSM303D_MFS_T fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the device and start operation. This function is
|
||||||
|
* called from the constructor so it will not typically need to be
|
||||||
|
* called by a user unless the device is reset. It will
|
||||||
|
* initialize the accelerometer and magnetometer (if enabled) to
|
||||||
|
* certain default running modes.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param res One of the LSM303D_M_RES_T values. This value sets
|
||||||
|
* the resolution of the magnetometer. At init time, this value
|
||||||
|
* is set to LSM303D_M_RES_HIGH.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_devinit(const lsm303d_context dev,
|
||||||
|
LSM303D_M_RES_T res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer (acc) output data rate (odr)
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param odr One of the LSM303D_AODR_T values. The default
|
||||||
|
* set at initialization time is LSM303D_AODR_100HZ.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_set_acc_odr(const lsm303d_context dev,
|
||||||
|
LSM303D_AODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the magnetometer (mag) output data rate (odr)
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param odr One of the LSM303D_MODR_T values. The default
|
||||||
|
* set at initialization time is LSM303D_MODR_12_5HZ.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_set_mag_odr(const lsm303d_context dev,
|
||||||
|
LSM303D_MODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a register.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param reg The register to read
|
||||||
|
* @return The value of the register
|
||||||
|
*/
|
||||||
|
uint8_t lsm303d_read_reg(const lsm303d_context dev, uint8_t reg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read contiguous registers into a buffer
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param buffer The buffer to store the results
|
||||||
|
* @param len The number of registers to read
|
||||||
|
* @return The number of bytes read, or -1 on error
|
||||||
|
*/
|
||||||
|
int lsm303d_read_regs(const lsm303d_context dev, uint8_t reg,
|
||||||
|
uint8_t *buffer, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to a register
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param reg The register to write to
|
||||||
|
* @param val The value to write
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303d_write_reg(const lsm303d_context dev,
|
||||||
|
uint8_t reg, uint8_t val);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
242
src/lsm303d/lsm303d.hpp
Normal file
242
src/lsm303d/lsm303d.hpp
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mraa/gpio.hpp>
|
||||||
|
#include "lsm303d.h"
|
||||||
|
|
||||||
|
namespace upm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ST Microelectronics Ultra-compact high-performance
|
||||||
|
* eCompass module
|
||||||
|
* @defgroup lsm303d libupm-lsm303d
|
||||||
|
* @ingroup i2c gpio stmicro compass accelerometer
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @library lsm303d
|
||||||
|
* @sensor lsm303d
|
||||||
|
* @comname Ultra-compact high-performance eCompass module
|
||||||
|
* @type compass
|
||||||
|
* @man stmicro
|
||||||
|
* @con i2c gpio
|
||||||
|
* @web http://www.st.com/en/mems-and-sensors/lsm303d.html
|
||||||
|
*
|
||||||
|
* @brief API for the LSM303D 3-Axis Geomagnetic Sensor
|
||||||
|
*
|
||||||
|
* The LSM303D is an ultra-low-power high-performance
|
||||||
|
* system-in-package featuring a 3D digital linear acceleration
|
||||||
|
* sensor and a 3D digital magnetic sensor. The LSM303D has
|
||||||
|
* linear acceleration full scales of 2g/4g/8g/16g and a
|
||||||
|
* magnetic field dynamic range of 50 Gauss.
|
||||||
|
*
|
||||||
|
* Not all functionality of this chip has been implemented in this
|
||||||
|
* driver, however all the pieces are present to add any desired
|
||||||
|
* functionality. This driver supports only I2C operation.
|
||||||
|
*
|
||||||
|
* This device requires 3.3v operation.
|
||||||
|
*
|
||||||
|
* @snippet lsm303d.cxx Interesting
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LSM303D {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* LSM303D constructor
|
||||||
|
*
|
||||||
|
* This driver only supports I2C.
|
||||||
|
*
|
||||||
|
* Due to the fact that this chip is currently obsolete, we only
|
||||||
|
* support minimum functionality.
|
||||||
|
*
|
||||||
|
* @param bus I2C bus to use
|
||||||
|
* @param addr The I2C address of the device
|
||||||
|
* @return The device context, or NULL if an error occurred
|
||||||
|
* @throws std::runtime_error on failure.
|
||||||
|
*/
|
||||||
|
LSM303D(int bus=LSM303D_DEFAULT_I2C_BUS,
|
||||||
|
int addr=LSM303D_DEFAULT_I2C_ADDR);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303D Destructor
|
||||||
|
*/
|
||||||
|
~LSM303D();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the internal stored values from sensor data. This
|
||||||
|
* method must be called before querying the acceleration,
|
||||||
|
* magnetometer, or temperature.
|
||||||
|
*
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return magnetometer data in micro-Teslas (uT). update() must
|
||||||
|
* have been called prior to calling this method.
|
||||||
|
*
|
||||||
|
* @param x Pointer to a floating point value that will have the
|
||||||
|
* current x component placed into it
|
||||||
|
* @param y Pointer to a floating point value that will have the
|
||||||
|
* current y component placed into it
|
||||||
|
* @param z Pointer to a floating point value that will have the
|
||||||
|
* current z component placed into it
|
||||||
|
*/
|
||||||
|
void getMagnetometer(float *x, float *y, float *z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return magnetometer data in micro-Teslas (uT) in the form
|
||||||
|
* of a floating point vector. update() must have been called
|
||||||
|
* prior to calling this method.
|
||||||
|
*
|
||||||
|
* @return A floating point vector containing x, y, and z in
|
||||||
|
* that order
|
||||||
|
*/
|
||||||
|
std::vector<float> getMagnetometer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return acceleration data in gravities. update() must have
|
||||||
|
* been called prior to calling this method.
|
||||||
|
*
|
||||||
|
* @param x Pointer to a floating point value that will have the
|
||||||
|
* current x component placed into it
|
||||||
|
* @param y Pointer to a floating point value that will have the
|
||||||
|
* current y component placed into it
|
||||||
|
* @param z Pointer to a floating point value that will have the
|
||||||
|
* current z component placed into it
|
||||||
|
*/
|
||||||
|
void getAccelerometer(float *x, float *y, float *z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return acceleration data in gravities in the form of a
|
||||||
|
* floating point vector. update() must have been called
|
||||||
|
* prior to calling this method.
|
||||||
|
*
|
||||||
|
* @return A floating point vector containing x, y, and z in
|
||||||
|
* that order
|
||||||
|
*/
|
||||||
|
std::vector<float> getAccelerometer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return temperature data in degrees Celsius. NOTE: This is
|
||||||
|
* not the ambient room temperature. update() must have been
|
||||||
|
* called prior to calling this method.
|
||||||
|
*
|
||||||
|
* @return Temperature in degrees Celsius
|
||||||
|
*/
|
||||||
|
float getTemperature();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the device and start operation. This function
|
||||||
|
* is called from the constructor so it will not typically
|
||||||
|
* need to be called by a user unless the device is reset. It
|
||||||
|
* will initialize the accelerometer and magnetometer (if
|
||||||
|
* enabled) to certain default running modes.
|
||||||
|
*
|
||||||
|
* @param res One of the LSM303D_M_RES_T values. This value
|
||||||
|
* sets the resolution of the magnetometer. At init time,
|
||||||
|
* this value is set to LSM303D_M_RES_HIGH.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void init(LSM303D_M_RES_T res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the full scale (sensitivity) value for the
|
||||||
|
* accelerometer. This device supports 2G, 4G, 6G, 8G, and
|
||||||
|
* 16G full scale modes.
|
||||||
|
*
|
||||||
|
* @param fs One of the LSM303D_AFS_T values
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setAccelerometerFullScale(LSM303D_AFS_T fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the full scale (sensitivity) value for the
|
||||||
|
* magnetometer. This device supports 2, 4, 8, and
|
||||||
|
* 16 Gauss full scale modes.
|
||||||
|
*
|
||||||
|
* @param fs One of the LSM303D_MFS_T values
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setMagnetometerFullScale(LSM303D_MFS_T fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer output data rate (ODR)
|
||||||
|
*
|
||||||
|
* @param odr One of the LSM303D_AODR_T values. The default
|
||||||
|
* set at initialization time is LSM303D_AODR_100HZ.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setAccelerometerODR(LSM303D_AODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the magnetometer output data rate (ODR)
|
||||||
|
*
|
||||||
|
* @param odr One of the LSM303D_MODR_T values.
|
||||||
|
* The default set at initialization time is
|
||||||
|
* LSM303D_MODR_12_5HZ.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setMagnetometerODR(LSM303D_MODR_T odr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// our underlying device context
|
||||||
|
lsm303d_context m_lsm303d;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a register
|
||||||
|
*
|
||||||
|
* @param reg The register to read
|
||||||
|
* @return The value of the register
|
||||||
|
*/
|
||||||
|
uint8_t readReg(uint8_t reg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read contiguous registers into a buffer
|
||||||
|
*
|
||||||
|
* @param buffer The buffer to store the results
|
||||||
|
* @param len The number of registers to read
|
||||||
|
* @return The number of bytes read
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
int readRegs(uint8_t reg, uint8_t *buffer, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to a register
|
||||||
|
*
|
||||||
|
* @param reg The register to write to
|
||||||
|
* @param val The value to write
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void writeReg(uint8_t reg, uint8_t val);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
301
src/lsm303d/lsm303d_defs.h
Normal file
301
src/lsm303d/lsm303d_defs.h
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||||||
|
* Copyright (c) 2017 Intel Corporation.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define LSM303D_DEFAULT_I2C_BUS 0
|
||||||
|
#define LSM303D_DEFAULT_I2C_ADDR 0x1e
|
||||||
|
|
||||||
|
// from the WHO_AM_I_* register
|
||||||
|
#define LSM303D_CHIPID 0x49
|
||||||
|
|
||||||
|
|
||||||
|
// Due to the fact that this chip is currently obsolete, we only
|
||||||
|
// support minimum functionality. This register map is not
|
||||||
|
// complete. While all registers are specified, bitfields and
|
||||||
|
// enumerants are only specified for certain registers of
|
||||||
|
// interest. Feel free to add what you need.
|
||||||
|
|
||||||
|
// NOTE: Reserved registers must not be written into or permanent
|
||||||
|
// damage to the device can result. Reading from them may return
|
||||||
|
// indeterminate values. Registers containing reserved bitfields
|
||||||
|
// must be written as 0.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303D registers
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
|
||||||
|
// 0x00-0x04 reserved
|
||||||
|
|
||||||
|
LSM303D_REG_TEMP_OUT_L = 0x05,
|
||||||
|
LSM303D_REG_TEMP_OUT_H = 0x06,
|
||||||
|
|
||||||
|
LSM303D_REG_STATUS_M = 0x07,
|
||||||
|
|
||||||
|
LSM303D_REG_OUT_X_L_M = 0x08,
|
||||||
|
LSM303D_REG_OUT_X_H_M = 0x09,
|
||||||
|
LSM303D_REG_OUT_Y_L_M = 0x0a,
|
||||||
|
LSM303D_REG_OUT_Y_H_M = 0x0b,
|
||||||
|
LSM303D_REG_OUT_Z_L_M = 0x0c,
|
||||||
|
LSM303D_REG_OUT_Z_H_M = 0x0d,
|
||||||
|
|
||||||
|
// 0x0e reserved
|
||||||
|
|
||||||
|
LSM303D_REG_WHO_AM_I = 0x0f,
|
||||||
|
|
||||||
|
// 0x10-0x11 reserved
|
||||||
|
|
||||||
|
LSM303D_REG_INT_CTRL_M = 0x12,
|
||||||
|
LSM303D_REG_INT_SRC_M = 0x13,
|
||||||
|
LSM303D_REG_INT_THS_L_M = 0x14,
|
||||||
|
LSM303D_REG_INT_THS_H_M = 0x15,
|
||||||
|
|
||||||
|
LSM303D_REG_OFFSET_X_L_M = 0x16,
|
||||||
|
LSM303D_REG_OFFSET_X_H_M = 0x17,
|
||||||
|
LSM303D_REG_OFFSET_Y_L_M = 0x18,
|
||||||
|
LSM303D_REG_OFFSET_Y_H_M = 0x19,
|
||||||
|
LSM303D_REG_OFFSET_Z_L_M = 0x1a,
|
||||||
|
LSM303D_REG_OFFSET_Z_H_M = 0x1b,
|
||||||
|
|
||||||
|
LSM303D_REG_REFERENCE_X = 0x1c,
|
||||||
|
LSM303D_REG_REFERENCE_Y = 0x1d,
|
||||||
|
LSM303D_REG_REFERENCE_Z = 0x1e,
|
||||||
|
|
||||||
|
LSM303D_REG_CTRL0 = 0x1f,
|
||||||
|
LSM303D_REG_CTRL1 = 0x20,
|
||||||
|
LSM303D_REG_CTRL2 = 0x21,
|
||||||
|
LSM303D_REG_CTRL3 = 0x22,
|
||||||
|
LSM303D_REG_CTRL4 = 0x23,
|
||||||
|
LSM303D_REG_CTRL5 = 0x24,
|
||||||
|
LSM303D_REG_CTRL6 = 0x25,
|
||||||
|
LSM303D_REG_CTRL7 = 0x26,
|
||||||
|
|
||||||
|
LSM303D_REG_STATUS_A = 0x27,
|
||||||
|
|
||||||
|
LSM303D_REG_OUT_X_L_A = 0x28,
|
||||||
|
LSM303D_REG_OUT_X_H_A = 0x29,
|
||||||
|
LSM303D_REG_OUT_Y_L_A = 0x2a,
|
||||||
|
LSM303D_REG_OUT_Y_H_A = 0x2b,
|
||||||
|
LSM303D_REG_OUT_Z_L_A = 0x2c,
|
||||||
|
LSM303D_REG_OUT_Z_H_A = 0x2d,
|
||||||
|
|
||||||
|
LSM303D_REG_FIFO_CTRL = 0x2e,
|
||||||
|
LSM303D_REG_FIFO_SRC = 0x2f,
|
||||||
|
|
||||||
|
LSM303D_REG_IG_CFG1 = 0x30,
|
||||||
|
LSM303D_REG_IG_SRC1 = 0x31,
|
||||||
|
LSM303D_REG_IG_THS1 = 0x32,
|
||||||
|
LSM303D_REG_IG_DUR1 = 0x33,
|
||||||
|
LSM303D_REG_IG_CFG2 = 0x34,
|
||||||
|
LSM303D_REG_IG_SRC2 = 0x35,
|
||||||
|
LSM303D_REG_IG_THS2 = 0x36,
|
||||||
|
LSM303D_REG_IG_DUR2 = 0x37,
|
||||||
|
|
||||||
|
LSM303D_REG_CLICK_CFG = 0x38,
|
||||||
|
LSM303D_REG_CLICK_SRC = 0x39,
|
||||||
|
LSM303D_REG_CLICK_THS = 0x3a,
|
||||||
|
|
||||||
|
LSM303D_REG_TIME_LIMIT = 0x3b,
|
||||||
|
LSM303D_REG_TIME_LATENCY = 0x3c,
|
||||||
|
LSM303D_REG_TIME_WINDOW = 0x3d,
|
||||||
|
|
||||||
|
LSM303D_REG_ACT_THS = 0x3e,
|
||||||
|
LSM303D_REG_ACT_DUR = 0x3f,
|
||||||
|
} LSM303D_REGS_T;
|
||||||
|
|
||||||
|
// Accelerometer registers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL1 bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_CTRL1_AXEN = 0x01, // axis enables
|
||||||
|
LSM303D_CTRL1_AYEN = 0x02,
|
||||||
|
LSM303D_CTRL1_AZEN = 0x04,
|
||||||
|
|
||||||
|
LSM303D_CTRL1_BDU = 0x08,
|
||||||
|
|
||||||
|
LSM303D_CTRL1_AODR0 = 0x10,
|
||||||
|
LSM303D_CTRL1_AODR1 = 0x20,
|
||||||
|
LSM303D_CTRL1_AODR2 = 0x40,
|
||||||
|
LSM303D_CTRL1_AODR3 = 0x80,
|
||||||
|
_LSM303D_CTRL1_AODR_MASK = 15,
|
||||||
|
_LSM303D_CTRL1_AODR_SHIFT = 4,
|
||||||
|
} LSM303D_CTRL1_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL1_AODR values (and power mode)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_AODR_POWER_DOWN = 0,
|
||||||
|
LSM303D_AODR_3_125HZ = 1, // 3.125Hz
|
||||||
|
LSM303D_AODR_6_25HZ = 2,
|
||||||
|
LSM303D_AODR_12_5HZ = 3,
|
||||||
|
LSM303D_AODR_25HZ = 4,
|
||||||
|
LSM303D_AODR_50HZ = 5,
|
||||||
|
LSM303D_AODR_100HZ = 6,
|
||||||
|
LSM303D_AODR_200HZ = 7,
|
||||||
|
LSM303D_AODR_400HZ = 8,
|
||||||
|
LSM303D_AODR_800HZ = 9,
|
||||||
|
LSM303D_AODR_1600HZ = 10,
|
||||||
|
} LSM303D_AODR_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL2 bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_CTRL2_SIM = 0x01,
|
||||||
|
LSM303D_CTRL2_AST = 0x02,
|
||||||
|
|
||||||
|
// 0x04 reserved
|
||||||
|
|
||||||
|
LSM303D_CTRL2_AFS0 = 0x08, // full scale
|
||||||
|
LSM303D_CTRL2_AFS1 = 0x10,
|
||||||
|
LSM303D_CTRL2_AFS2 = 0x20,
|
||||||
|
_LSM303D_CTRL2_AFS_MASK = 7,
|
||||||
|
_LSM303D_CTRL2_AFS_SHIFT = 3,
|
||||||
|
|
||||||
|
LSM303D_CTRL2_ABW0 = 0x40,
|
||||||
|
LSM303D_CTRL2_ABW1 = 0x80,
|
||||||
|
_LSM303D_CTRL2_ABW_MASK = 3,
|
||||||
|
_LSM303D_CTRL2_ABW_SHIFT = 6,
|
||||||
|
} LSM303D_CTRL2_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL2_AFS values (full scale)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_AFS_2G = 0, // 2G
|
||||||
|
LSM303D_AFS_4G = 1,
|
||||||
|
LSM303D_AFS_6G = 2,
|
||||||
|
LSM303D_AFS_8G = 3,
|
||||||
|
LSM303D_AFS_16G = 4,
|
||||||
|
} LSM303D_AFS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL5 bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_CTRL5_LIR1 = 0x01,
|
||||||
|
LSM303D_CTRL5_LIR2 = 0x02,
|
||||||
|
|
||||||
|
LSM303D_CTRL5_MODR0 = 0x04, // mag odr
|
||||||
|
LSM303D_CTRL5_MODR1 = 0x08,
|
||||||
|
LSM303D_CTRL5_MODR2 = 0x10,
|
||||||
|
_LSM303D_CTRL5_MODR_MASK = 7,
|
||||||
|
_LSM303D_CTRL5_MODR_SHIFT = 2,
|
||||||
|
|
||||||
|
LSM303D_CTRL5_M_RES0 = 0x20, // resolution
|
||||||
|
LSM303D_CTRL5_M_RES1 = 0x40,
|
||||||
|
_LSM303D_CTRL5_MRES_MASK = 3,
|
||||||
|
_LSM303D_CTRL5_MRES_SHIFT = 6,
|
||||||
|
|
||||||
|
LSM303D_CTRL5_TEMP_EN = 0x80,
|
||||||
|
} LSM303D_CTRL5_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL5_MODR values (mag output data rate)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_MODR_3_125HZ = 0, // 3.125Hz
|
||||||
|
LSM303D_MODR_6_25HZ = 1,
|
||||||
|
LSM303D_MODR_12_5HZ = 2,
|
||||||
|
LSM303D_MODR_25HZ = 3,
|
||||||
|
LSM303D_MODR_50HZ = 4,
|
||||||
|
LSM303D_MODR_100HZ = 5,
|
||||||
|
} LSM303D_MODR_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL5_M_RES values (resolution)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_M_RES_LOW = 0,
|
||||||
|
LSM303D_M_RES_HIGH = 3,
|
||||||
|
} LSM303D_M_RES_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL6 bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
// 0x01-0x10 reserved
|
||||||
|
|
||||||
|
LSM303D_CTRL6_MFS0 = 0x20,
|
||||||
|
LSM303D_CTRL6_MFS1 = 0x40,
|
||||||
|
_LSM303D_CTRL6_MFS_MASK = 3,
|
||||||
|
_LSM303D_CTRL6_MFS_SHIFT = 5,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303D_CTRL6_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL6_MFS values (mag full scale)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_MFS_2 = 0, // 2 Gauss
|
||||||
|
LSM303D_MFS_4 = 1,
|
||||||
|
LSM303D_MFS_8 = 2,
|
||||||
|
LSM303D_MFS_12 = 3,
|
||||||
|
} LSM303D_MFS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL7 bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_CTRL7_MD0 = 0x01,
|
||||||
|
LSM303D_CTRL7_MD1 = 0x02,
|
||||||
|
_LSM303D_CTRL7_MD_MASK = 3,
|
||||||
|
_LSM303D_CTRL7_MD_SHIFT = 0,
|
||||||
|
|
||||||
|
LSM303D_CTRL7_MLP = 0x04,
|
||||||
|
|
||||||
|
// 0x08 reserved
|
||||||
|
|
||||||
|
LSM303D_CTRL7_T_ONLY = 0x10,
|
||||||
|
LSM303D_CTRL7_AFDS = 0x20,
|
||||||
|
|
||||||
|
LSM303D_CTRL7_AHPM0 = 0x40,
|
||||||
|
LSM303D_CTRL7_AHPM1 = 0x80,
|
||||||
|
_LSM303D_CTRL7_AHPM_MASK = 3,
|
||||||
|
_LSM303D_CTRL7_AHPM_SHIFT = 6,
|
||||||
|
} LSM303D_CTRL7_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL7_MD values (power mode)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303D_MD_CONTINUOUS = 0,
|
||||||
|
LSM303D_MD_SINGLE = 1,
|
||||||
|
LSM303D_MD_POWER_DOWN = 3, // 2 is pwr down too
|
||||||
|
} LSM303D_MD_T;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
17
src/lsm303d/pyupm_lsm303d.i
Normal file
17
src/lsm303d/pyupm_lsm303d.i
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Include doxygen-generated documentation
|
||||||
|
%include "pyupm_doxy2swig.i"
|
||||||
|
%module pyupm_lsm303d
|
||||||
|
%include "../upm.i"
|
||||||
|
%include "../upm_vectortypes.i"
|
||||||
|
|
||||||
|
%feature("autodoc", "3");
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
%include "lsm303d_doc.i"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%include "lsm303d_defs.h"
|
||||||
|
%include "lsm303d.hpp"
|
||||||
|
%{
|
||||||
|
#include "lsm303d.hpp"
|
||||||
|
%}
|
Loading…
x
Reference in New Issue
Block a user