mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
lsm303agr: Initial implementation, C, FTI, C++ wraps C
Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
parent
12c59a6aca
commit
1f5f466691
87
examples/c++/lsm303agr.cxx
Normal file
87
examples/c++/lsm303agr.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 "lsm303agr.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 LSM303AGR using default I2C parameters
|
||||||
|
upm::LSM303AGR 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;
|
||||||
|
}
|
90
examples/c/lsm303agr.c
Normal file
90
examples/c/lsm303agr.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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 "lsm303agr.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 LSM303AGR instance using default i2c bus and addresses
|
||||||
|
lsm303agr_context sensor = lsm303agr_init(LSM303AGR_DEFAULT_I2C_BUS,
|
||||||
|
LSM303AGR_DEFAULT_ACC_ADDR,
|
||||||
|
LSM303AGR_DEFAULT_MAG_ADDR);
|
||||||
|
|
||||||
|
if (!sensor)
|
||||||
|
{
|
||||||
|
printf("lsm303agr_init() failed.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now output data every 250 milliseconds
|
||||||
|
while (shouldRun)
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
if (lsm303agr_update(sensor))
|
||||||
|
{
|
||||||
|
printf("lsm303agr_update() failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsm303agr_get_accelerometer(sensor, &x, &y, &z);
|
||||||
|
printf("Accelerometer x: %f y: %f z: %f g\n",
|
||||||
|
x, y, z);
|
||||||
|
|
||||||
|
lsm303agr_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", lsm303agr_get_temperature(sensor));
|
||||||
|
|
||||||
|
upm_delay_ms(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exiting...\n");
|
||||||
|
|
||||||
|
lsm303agr_close(sensor);
|
||||||
|
|
||||||
|
//! [Interesting]
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -169,6 +169,7 @@ add_example(P9813Sample p9813)
|
|||||||
add_example(BMG160_Example bmg160)
|
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_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/LSM303AGR_Example.java
Normal file
65
examples/java/LSM303AGR_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_lsm303agr.LSM303AGR;
|
||||||
|
|
||||||
|
public class LSM303AGR_Example
|
||||||
|
{
|
||||||
|
public static void main(String[] args) throws InterruptedException
|
||||||
|
{
|
||||||
|
// ! [Interesting]
|
||||||
|
|
||||||
|
// Instantiate a LSM303AGR instance using default i2c bus and address
|
||||||
|
LSM303AGR sensor = new LSM303AGR();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// update our values from the sensor
|
||||||
|
sensor.update();
|
||||||
|
|
||||||
|
upm_lsm303agr.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/lsm303agr.js
Normal file
67
examples/javascript/lsm303agr.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_lsm303agr');
|
||||||
|
|
||||||
|
// Instantiate a LSM303AGR instance using default i2c bus and address
|
||||||
|
var sensor = new sensorObj.LSM303AGR();
|
||||||
|
|
||||||
|
// 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/lsm303agr.py
Executable file
71
examples/python/lsm303agr.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_lsm303agr as sensorObj
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Instantiate a BMP250E instance using default i2c bus and address
|
||||||
|
sensor = sensorObj.LSM303AGR()
|
||||||
|
|
||||||
|
## 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()
|
9
src/lsm303agr/CMakeLists.txt
Normal file
9
src/lsm303agr/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
upm_mixed_module_init (NAME lsm303agr
|
||||||
|
DESCRIPTION "3-Axis eCompass module"
|
||||||
|
C_HDR lsm303agr.h lsm303agr_defs.h
|
||||||
|
C_SRC lsm303agr.c
|
||||||
|
CPP_HDR lsm303agr.hpp
|
||||||
|
CPP_SRC lsm303agr.cxx
|
||||||
|
FTI_SRC lsm303agr_fti.c
|
||||||
|
CPP_WRAPS_C
|
||||||
|
REQUIRES mraa)
|
24
src/lsm303agr/javaupm_lsm303agr.i
Normal file
24
src/lsm303agr/javaupm_lsm303agr.i
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
%module javaupm_lsm303agr
|
||||||
|
%include "../upm.i"
|
||||||
|
%include "typemaps.i"
|
||||||
|
%include "../upm_vectortypes.i"
|
||||||
|
|
||||||
|
%ignore getMagnetometer(float *, float *, float *);
|
||||||
|
%ignore getAccelerometer(float *, float *, float *);
|
||||||
|
|
||||||
|
%include "lsm303agr_defs.h"
|
||||||
|
%include "lsm303agr.hpp"
|
||||||
|
%{
|
||||||
|
#include "lsm303agr.hpp"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%pragma(java) jniclasscode=%{
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("javaupm_lsm303agr");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.err.println("Native code library failed to load. \n" + e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
9
src/lsm303agr/jsupm_lsm303agr.i
Normal file
9
src/lsm303agr/jsupm_lsm303agr.i
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
%module jsupm_lsm303agr
|
||||||
|
%include "../upm.i"
|
||||||
|
%include "../upm_vectortypes.i"
|
||||||
|
|
||||||
|
%include "lsm303agr_defs.h"
|
||||||
|
%include "lsm303agr.hpp"
|
||||||
|
%{
|
||||||
|
#include "lsm303agr.hpp"
|
||||||
|
%}
|
781
src/lsm303agr/lsm303agr.c
Normal file
781
src/lsm303agr/lsm303agr.c
Normal file
@ -0,0 +1,781 @@
|
|||||||
|
/*
|
||||||
|
* 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 "lsm303agr.h"
|
||||||
|
|
||||||
|
// init
|
||||||
|
lsm303agr_context lsm303agr_init(int bus, int acc_addr, int mag_addr)
|
||||||
|
{
|
||||||
|
if (acc_addr <= 0 && mag_addr <= 0)
|
||||||
|
{
|
||||||
|
printf("%s: At least one device must be enabled\n", __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsm303agr_context dev =
|
||||||
|
(lsm303agr_context)malloc(sizeof(struct _lsm303agr_context));
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// zero out context
|
||||||
|
memset((void *)dev, 0, sizeof(struct _lsm303agr_context));
|
||||||
|
|
||||||
|
// make sure MRAA is initialized
|
||||||
|
if (mraa_init() != MRAA_SUCCESS)
|
||||||
|
{
|
||||||
|
printf("%s: mraa_init() failed.\n", __FUNCTION__);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acc_addr > 0)
|
||||||
|
{
|
||||||
|
if (!(dev->i2cACC = mraa_i2c_init(bus)))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_init(acc) failed.\n", __FUNCTION__);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mraa_i2c_address(dev->i2cACC, acc_addr))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_address(acc) failed.\n", __FUNCTION__);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the chip id
|
||||||
|
uint8_t chipID = lsm303agr_read_reg(dev, LSM303AGR_REG_WHO_AM_I_A);
|
||||||
|
|
||||||
|
if (chipID != LSM303AGR_CHIPID_ACC)
|
||||||
|
{
|
||||||
|
printf("%s: invalid accelerometer chip id: %02x. Expected %02x\n",
|
||||||
|
__FUNCTION__, chipID, LSM303AGR_CHIPID_ACC);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// technically we could use a single i2c context since it is bus
|
||||||
|
// specific, but then we would need to call i2c_address() every
|
||||||
|
// time we wanted to talk to a specific device. In addition, we
|
||||||
|
// can use the i2c context pointer to determine if a subsystem
|
||||||
|
// (acc or mag) is actually enabled throughout this driver.
|
||||||
|
if (mag_addr > 0)
|
||||||
|
{
|
||||||
|
if (!(dev->i2cMAG = mraa_i2c_init(bus)))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_init(mag) failed.\n", __FUNCTION__);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mraa_i2c_address(dev->i2cMAG, mag_addr))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_address(mag) failed.\n", __FUNCTION__);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the chip id
|
||||||
|
uint8_t chipID = lsm303agr_read_reg(dev, LSM303AGR_REG_WHO_AM_I_M);
|
||||||
|
|
||||||
|
if (chipID != LSM303AGR_CHIPID_MAG)
|
||||||
|
{
|
||||||
|
printf("%s: invalid accelerometer chip id: %02x. Expected %02x\n",
|
||||||
|
__FUNCTION__, chipID, LSM303AGR_CHIPID_MAG);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// call devinit with a default high resolution mode
|
||||||
|
if (lsm303agr_devinit(dev, LSM303AGR_POWER_HIGH_RESOLUTION))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_devinit() failed.\n", __FUNCTION__);
|
||||||
|
lsm303agr_close(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303agr_close(lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
lsm303agr_uninstall_isr(dev, LSM303AGR_INTERRUPT_ACC_1);
|
||||||
|
lsm303agr_uninstall_isr(dev, LSM303AGR_INTERRUPT_ACC_2);
|
||||||
|
lsm303agr_uninstall_isr(dev, LSM303AGR_INTERRUPT_MAG);
|
||||||
|
|
||||||
|
if (dev->i2cACC)
|
||||||
|
mraa_i2c_stop(dev->i2cACC);
|
||||||
|
if (dev->i2cMAG)
|
||||||
|
mraa_i2c_stop(dev->i2cMAG);
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_devinit(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_POWER_MODE_T mode)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// magnetometer
|
||||||
|
if (dev->i2cMAG)
|
||||||
|
{
|
||||||
|
// enable temp compensation and continuous mode
|
||||||
|
uint8_t reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CFG_REG_A_M);
|
||||||
|
|
||||||
|
reg &= ~_LSM303AGR_SHIFTMASK(CFG_REG_A_M_MD);
|
||||||
|
reg |= LSM303AGR_CFG_REG_A_M_COMP_TEMP_EN;
|
||||||
|
reg |= (LSM303AGR_CFG_A_M_MD_CONTINUOUS
|
||||||
|
<< _LSM303AGR_SHIFT(CFG_REG_A_M_MD));
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CFG_REG_A_M, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set MAG ODR to 10Hz by default
|
||||||
|
if (lsm303agr_set_mag_odr(dev, LSM303AGR_CFG_A_M_ODR_10HZ))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_set_mag_odr() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_delay_ms(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// accelerometer
|
||||||
|
if (dev->i2cACC)
|
||||||
|
{
|
||||||
|
// enable all axes
|
||||||
|
uint8_t reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CTRL_REG1_A);
|
||||||
|
|
||||||
|
reg |= LSM303AGR_CTRL_REG1_A_XEN
|
||||||
|
| LSM303AGR_CTRL_REG1_A_YEN
|
||||||
|
| LSM303AGR_CTRL_REG1_A_ZEN;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CTRL_REG1_A, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable BDU
|
||||||
|
reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CTRL_REG4_A);
|
||||||
|
reg |= LSM303AGR_CTRL_REG4_A_BDU;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CTRL_REG4_A, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable temperature measurement
|
||||||
|
reg = lsm303agr_read_reg(dev, LSM303AGR_REG_TEMP_CFG_REG_A);
|
||||||
|
reg &= ~_LSM303AGR_SHIFTMASK(TEMP_CFG_REG_A_TEMP_EN);
|
||||||
|
reg |= (LSM303AGR_TEMP_EN_ON
|
||||||
|
<< _LSM303AGR_SHIFT(TEMP_CFG_REG_A_TEMP_EN));
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_TEMP_CFG_REG_A, reg))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_write_reg() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set ACC ODR to 100Hz by default
|
||||||
|
if (lsm303agr_set_acc_odr(dev, LSM303AGR_A_ODR_100HZ))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_set_acc_odr() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to 2G sensitivity
|
||||||
|
if (lsm303agr_set_full_scale(dev, LSM303AGR_A_FS_2G))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_set_full_scale() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_delay_ms(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lsm303agr_set_power_mode(dev, mode))
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_set_power_mode() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_power_mode(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_POWER_MODE_T mode)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// magnetometer
|
||||||
|
if (dev->i2cMAG)
|
||||||
|
{
|
||||||
|
uint8_t reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CFG_REG_A_M);
|
||||||
|
|
||||||
|
// only low power or hires supported here
|
||||||
|
if (mode == LSM303AGR_POWER_LOW_POWER)
|
||||||
|
reg |= LSM303AGR_CFG_REG_A_M_LP;
|
||||||
|
else
|
||||||
|
reg &= ~LSM303AGR_CFG_REG_A_M_LP;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CFG_REG_A_M, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// accelerometer
|
||||||
|
if (dev->i2cACC)
|
||||||
|
{
|
||||||
|
uint8_t reg1 = lsm303agr_read_reg(dev, LSM303AGR_REG_CTRL_REG1_A);
|
||||||
|
uint8_t reg4 = lsm303agr_read_reg(dev, LSM303AGR_REG_CTRL_REG4_A);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case LSM303AGR_POWER_LOW_POWER:
|
||||||
|
reg1 |= LSM303AGR_CTRL_REG1_A_LPEN;
|
||||||
|
reg4 &= ~LSM303AGR_CTRL_REG4_A_HR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_POWER_NORMAL:
|
||||||
|
reg1 &= ~LSM303AGR_CTRL_REG1_A_LPEN;
|
||||||
|
reg4 &= ~LSM303AGR_CTRL_REG4_A_HR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_POWER_HIGH_RESOLUTION:
|
||||||
|
reg1 &= ~LSM303AGR_CTRL_REG1_A_LPEN;
|
||||||
|
reg4 |= LSM303AGR_CTRL_REG4_A_HR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CTRL_REG1_A, reg1))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CTRL_REG4_A, reg4))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// settle
|
||||||
|
upm_delay_ms(10);
|
||||||
|
|
||||||
|
dev->powerMode = mode;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_full_scale(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_A_FS_T fs)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// this only affects the accelerometer
|
||||||
|
if (dev->i2cACC)
|
||||||
|
{
|
||||||
|
uint8_t reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CTRL_REG4_A);
|
||||||
|
|
||||||
|
reg &= ~_LSM303AGR_SHIFTMASK(CTRL_REG4_A_FS);
|
||||||
|
reg |= (fs << _LSM303AGR_SHIFT(CTRL_REG4_A_FS));
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CTRL_REG4_A, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
upm_delay_ms(50);
|
||||||
|
|
||||||
|
// set our scaling factor depending on current power mode and
|
||||||
|
// FS
|
||||||
|
switch(dev->powerMode)
|
||||||
|
{
|
||||||
|
case LSM303AGR_POWER_LOW_POWER:
|
||||||
|
// 8b resolution
|
||||||
|
dev->accDivisor = 256.0;
|
||||||
|
|
||||||
|
switch (fs)
|
||||||
|
{
|
||||||
|
case LSM303AGR_A_FS_2G:
|
||||||
|
dev->accScale = 15.63;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_4G:
|
||||||
|
dev->accScale = 31.26;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_8G:
|
||||||
|
dev->accScale = 62.52;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_16G:
|
||||||
|
dev->accScale = 187.58;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_POWER_NORMAL:
|
||||||
|
// 10b resolution
|
||||||
|
dev->accDivisor = 64.0;
|
||||||
|
|
||||||
|
switch (fs)
|
||||||
|
{
|
||||||
|
case LSM303AGR_A_FS_2G:
|
||||||
|
dev->accScale = 3.9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_4G:
|
||||||
|
dev->accScale = 7.82;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_8G:
|
||||||
|
dev->accScale = 15.63;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_16G:
|
||||||
|
dev->accScale = 46.9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_POWER_HIGH_RESOLUTION:
|
||||||
|
// 12b resolution
|
||||||
|
dev->accDivisor = 16.0;
|
||||||
|
|
||||||
|
switch (fs)
|
||||||
|
{
|
||||||
|
case LSM303AGR_A_FS_2G:
|
||||||
|
dev->accScale = 0.98;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_4G:
|
||||||
|
dev->accScale = 1.95;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_8G:
|
||||||
|
dev->accScale = 3.9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_A_FS_16G:
|
||||||
|
dev->accScale = 11.72;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_update(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
const int maxLen = 6;
|
||||||
|
uint8_t buf[maxLen];
|
||||||
|
|
||||||
|
if (dev->i2cACC)
|
||||||
|
{
|
||||||
|
// get the temperature first, only 2 bytes
|
||||||
|
if (lsm303agr_read_regs(dev, LSM303AGR_REG_OUT_TEMP_L_A, buf, 2) != 2)
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_read_regs(temp) failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->temperature = (float)((int16_t)(buf[0] | (buf[1] << 8)));
|
||||||
|
|
||||||
|
// next, acc data
|
||||||
|
if (lsm303agr_read_regs(dev, LSM303AGR_REG_OUT_X_L_A, buf,
|
||||||
|
maxLen) != maxLen)
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->i2cMAG)
|
||||||
|
{
|
||||||
|
// now mag data
|
||||||
|
if (lsm303agr_read_regs(dev,LSM303AGR_REG_OUTX_L_REG_M, buf,
|
||||||
|
maxLen) != maxLen)
|
||||||
|
{
|
||||||
|
printf("%s: lsm303agr_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 lsm303agr_read_reg(const lsm303agr_context dev, uint8_t reg)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
mraa_i2c_context i2c = NULL;
|
||||||
|
if (reg <= LSM303AGR_MAX_ACC_ADDR)
|
||||||
|
i2c = dev->i2cACC;
|
||||||
|
else
|
||||||
|
i2c = dev->i2cMAG;
|
||||||
|
|
||||||
|
if (i2c)
|
||||||
|
{
|
||||||
|
int rv = mraa_i2c_read_byte_data(i2c, reg);
|
||||||
|
if (rv < 0)
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_read_byte_data() failed\n", __FUNCTION__);
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
return (uint8_t)rv;
|
||||||
|
}
|
||||||
|
else // shouldn't happen, but...
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lsm303agr_read_regs(const lsm303agr_context dev, uint8_t reg,
|
||||||
|
uint8_t *buffer, int len)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
mraa_i2c_context i2c = NULL;
|
||||||
|
if (reg <= LSM303AGR_MAX_ACC_ADDR)
|
||||||
|
i2c = dev->i2cACC;
|
||||||
|
else
|
||||||
|
i2c = dev->i2cMAG;
|
||||||
|
|
||||||
|
if (i2c)
|
||||||
|
{
|
||||||
|
reg |= 0x80; // enable auto-increment
|
||||||
|
if (mraa_i2c_read_bytes_data(i2c, reg, buffer, len) != len)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_write_reg(const lsm303agr_context dev,
|
||||||
|
uint8_t reg, uint8_t val)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
mraa_i2c_context i2c = NULL;
|
||||||
|
if (reg <= LSM303AGR_MAX_ACC_ADDR)
|
||||||
|
i2c = dev->i2cACC;
|
||||||
|
else
|
||||||
|
i2c = dev->i2cMAG;
|
||||||
|
|
||||||
|
if (i2c)
|
||||||
|
{
|
||||||
|
if (mraa_i2c_write_byte_data(i2c, val, reg))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_i2c_write_byte_data() failed.\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return UPM_ERROR_NO_RESOURCES;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
float lsm303agr_get_temperature(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// DS says 8 bits. It is not clear in the DS how to compute this,
|
||||||
|
// but the following seems to produce a reasonably correct
|
||||||
|
// temperature.
|
||||||
|
return (dev->temperature / 256.0) + 25.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303agr_get_magnetometer(const lsm303agr_context dev,
|
||||||
|
float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// 1.5 comes from the datasheet. Output is in milli-Gauss - we
|
||||||
|
// convert and return it in uT (SI micro-teslas) instead.
|
||||||
|
if (x)
|
||||||
|
*x = (dev->magX * 1.5) / 10.0;
|
||||||
|
if (y)
|
||||||
|
*y = (dev->magY * 1.5) / 10.0;
|
||||||
|
if (z)
|
||||||
|
*z = (dev->magZ * 1.5) / 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303agr_get_accelerometer(const lsm303agr_context dev,
|
||||||
|
float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
*x = ((dev->accX / dev->accDivisor) * dev->accScale) / 1000.0;
|
||||||
|
if (y)
|
||||||
|
*y = ((dev->accY / dev->accDivisor) * dev->accScale) / 1000.0;
|
||||||
|
if (z)
|
||||||
|
*z = ((dev->accZ / dev->accDivisor) * dev->accScale) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_acc_odr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_A_ODR_T odr)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return UPM_ERROR_NO_RESOURCES;
|
||||||
|
|
||||||
|
uint8_t reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CTRL_REG1_A);
|
||||||
|
reg &= ~_LSM303AGR_SHIFTMASK(CTRL_REG1_A_ODR);
|
||||||
|
reg |= (odr << _LSM303AGR_SHIFT(CTRL_REG1_A_ODR));
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CTRL_REG1_A, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_mag_odr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_CFG_A_M_ODR_T odr)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cMAG)
|
||||||
|
return UPM_ERROR_NO_RESOURCES;
|
||||||
|
|
||||||
|
uint8_t reg = lsm303agr_read_reg(dev, LSM303AGR_REG_CFG_REG_A_M);
|
||||||
|
reg &= ~_LSM303AGR_SHIFTMASK(CFG_REG_A_M_ODR);
|
||||||
|
reg |= (odr << _LSM303AGR_SHIFT(CFG_REG_A_M_ODR));
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_CFG_REG_A_M, reg))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303agr_get_acc_int1_config(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lsm303agr_read_reg(dev, LSM303AGR_REG_INT1_CFG_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_acc_int1_config(const lsm303agr_context dev,
|
||||||
|
uint8_t bits)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return UPM_ERROR_NO_RESOURCES;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_INT1_CFG_A, bits))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303agr_get_acc_int2_config(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lsm303agr_read_reg(dev, LSM303AGR_REG_INT2_CFG_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_acc_int2_config(const lsm303agr_context dev,
|
||||||
|
uint8_t bits)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return UPM_ERROR_NO_RESOURCES;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_INT2_CFG_A, bits))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303agr_get_mag_int_config(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cMAG)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lsm303agr_read_reg(dev, LSM303AGR_REG_INT_CTRL_REG_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_set_mag_int_config(const lsm303agr_context dev,
|
||||||
|
uint8_t bits)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cMAG)
|
||||||
|
return UPM_ERROR_NO_RESOURCES;
|
||||||
|
|
||||||
|
if (lsm303agr_write_reg(dev, LSM303AGR_REG_INT_CTRL_REG_M, bits))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303agr_get_acc_int1_src(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lsm303agr_read_reg(dev, LSM303AGR_REG_INT1_SRC_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303agr_get_acc_int2_src(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cACC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lsm303agr_read_reg(dev, LSM303AGR_REG_INT2_SRC_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lsm303agr_get_mag_int_src(const lsm303agr_context dev)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
if (!dev->i2cMAG)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lsm303agr_read_reg(dev, LSM303AGR_REG_INT_SRC_REG_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t lsm303agr_install_isr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_INTERRUPT_PINS_T intr, int gpio,
|
||||||
|
mraa_gpio_edge_t level,
|
||||||
|
void (*isr)(void *), void *arg)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
// delete any existing ISR and GPIO context for this interrupt
|
||||||
|
lsm303agr_uninstall_isr(dev, intr);
|
||||||
|
|
||||||
|
mraa_gpio_context gpio_isr = NULL;
|
||||||
|
|
||||||
|
// create gpio context
|
||||||
|
if (!(gpio_isr = mraa_gpio_init(gpio)))
|
||||||
|
{
|
||||||
|
printf("%s: mraa_gpio_init() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
mraa_gpio_dir(gpio_isr, MRAA_GPIO_IN);
|
||||||
|
|
||||||
|
if (mraa_gpio_isr(gpio_isr, level, isr, arg))
|
||||||
|
{
|
||||||
|
mraa_gpio_close(gpio_isr);
|
||||||
|
printf("%s: mraa_gpio_isr() failed.\n", __FUNCTION__);
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (intr)
|
||||||
|
{
|
||||||
|
case LSM303AGR_INTERRUPT_ACC_1:
|
||||||
|
dev->gpioACC1 = gpio_isr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_INTERRUPT_ACC_2:
|
||||||
|
dev->gpioACC2 = gpio_isr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_INTERRUPT_MAG:
|
||||||
|
dev->gpioMAG = gpio_isr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm303agr_uninstall_isr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_INTERRUPT_PINS_T intr)
|
||||||
|
{
|
||||||
|
assert(dev != NULL);
|
||||||
|
|
||||||
|
switch (intr)
|
||||||
|
{
|
||||||
|
case LSM303AGR_INTERRUPT_ACC_1:
|
||||||
|
if (dev->gpioACC1)
|
||||||
|
{
|
||||||
|
mraa_gpio_isr_exit(dev->gpioACC1);
|
||||||
|
mraa_gpio_close(dev->gpioACC1);
|
||||||
|
dev->gpioACC1 = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_INTERRUPT_ACC_2:
|
||||||
|
if (dev->gpioACC2)
|
||||||
|
{
|
||||||
|
mraa_gpio_isr_exit(dev->gpioACC2);
|
||||||
|
mraa_gpio_close(dev->gpioACC2);
|
||||||
|
dev->gpioACC2 = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSM303AGR_INTERRUPT_MAG:
|
||||||
|
if (dev->gpioMAG)
|
||||||
|
{
|
||||||
|
mraa_gpio_isr_exit(dev->gpioMAG);
|
||||||
|
mraa_gpio_close(dev->gpioMAG);
|
||||||
|
dev->gpioMAG = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
210
src/lsm303agr/lsm303agr.cxx
Normal file
210
src/lsm303agr/lsm303agr.cxx
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* 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 "lsm303agr.hpp"
|
||||||
|
|
||||||
|
using namespace upm;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
LSM303AGR::LSM303AGR(int bus, int acc_addr, int mag_addr) :
|
||||||
|
m_lsm303agr(lsm303agr_init(bus, acc_addr, mag_addr))
|
||||||
|
{
|
||||||
|
if (!m_lsm303agr)
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_init() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
LSM303AGR::~LSM303AGR()
|
||||||
|
{
|
||||||
|
lsm303agr_close(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::init(LSM303AGR_POWER_MODE_T usage)
|
||||||
|
{
|
||||||
|
if (lsm303agr_devinit(m_lsm303agr, usage))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_devinit() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::update()
|
||||||
|
{
|
||||||
|
if (lsm303agr_update(m_lsm303agr))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_update() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::readReg(uint8_t reg)
|
||||||
|
{
|
||||||
|
return lsm303agr_read_reg(m_lsm303agr, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LSM303AGR::readRegs(uint8_t reg, uint8_t *buffer, int len)
|
||||||
|
{
|
||||||
|
int rv = lsm303agr_read_regs(m_lsm303agr, reg, buffer, len);
|
||||||
|
if (rv < 0)
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_read_regs() failed");
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::writeReg(uint8_t reg, uint8_t val)
|
||||||
|
{
|
||||||
|
if (lsm303agr_write_reg(m_lsm303agr, reg, val))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_write_reg() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::getMagnetometer(float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
lsm303agr_get_magnetometer(m_lsm303agr, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> LSM303AGR::getMagnetometer()
|
||||||
|
{
|
||||||
|
float v[3];
|
||||||
|
|
||||||
|
getMagnetometer(&v[0], &v[1], &v[2]);
|
||||||
|
return std::vector<float>(v, v+3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::getAccelerometer(float *x, float *y, float *z)
|
||||||
|
{
|
||||||
|
lsm303agr_get_accelerometer(m_lsm303agr, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> LSM303AGR::getAccelerometer()
|
||||||
|
{
|
||||||
|
float v[3];
|
||||||
|
|
||||||
|
getAccelerometer(&v[0], &v[1], &v[2]);
|
||||||
|
return std::vector<float>(v, v+3);
|
||||||
|
}
|
||||||
|
|
||||||
|
float LSM303AGR::getTemperature()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_temperature(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setFullScale(LSM303AGR_A_FS_T fs)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_full_scale(m_lsm303agr, fs))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_full_scale() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setPowerMode(LSM303AGR_POWER_MODE_T mode)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_power_mode(m_lsm303agr, mode))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_power_mode() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setAccelerometerODR(LSM303AGR_A_ODR_T odr)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_acc_odr(m_lsm303agr, odr))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_acc_odr() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setMagnetometerODR(LSM303AGR_CFG_A_M_ODR_T odr)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_mag_odr(m_lsm303agr, odr))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_mag_odr() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::getAccelerometerInt1Config()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_acc_int1_config(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::getAccelerometerInt2Config()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_acc_int2_config(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setAccelerometerInt1Config(uint8_t bits)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_acc_int1_config(m_lsm303agr, bits))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_acc_int1_config() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setAccelerometerInt2Config(uint8_t bits)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_acc_int2_config(m_lsm303agr, bits))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_acc_int2_config() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::getMagnetometerIntConfig()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_mag_int_config(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::setMagnetometerIntConfig(uint8_t bits)
|
||||||
|
{
|
||||||
|
if (lsm303agr_set_mag_int_config(m_lsm303agr, bits))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_set_mag_int_config() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::getAccelerometerInt1Src()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_acc_int1_src(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::getAccelerometerInt2Src()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_acc_int2_src(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LSM303AGR::getMagnetometerIntSrc()
|
||||||
|
{
|
||||||
|
return lsm303agr_get_mag_int_src(m_lsm303agr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LSM303AGR::installISR(LSM303AGR_INTERRUPT_PINS_T intr, int gpio,
|
||||||
|
mraa::Edge level,
|
||||||
|
void (*isr)(void *), void *arg)
|
||||||
|
{
|
||||||
|
if (lsm303agr_install_isr(m_lsm303agr, intr, gpio, (mraa_gpio_edge_t)level,
|
||||||
|
isr, arg))
|
||||||
|
throw std::runtime_error(string(__FUNCTION__)
|
||||||
|
+ ": lsm303agr_install_isr() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM303AGR::uninstallISR(LSM303AGR_INTERRUPT_PINS_T intr)
|
||||||
|
{
|
||||||
|
lsm303agr_uninstall_isr(m_lsm303agr, intr);
|
||||||
|
}
|
382
src/lsm303agr/lsm303agr.h
Normal file
382
src/lsm303agr/lsm303agr.h
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
/*
|
||||||
|
* 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 "lsm303agr_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file lsm303agr.h
|
||||||
|
* @library lsm303agr
|
||||||
|
* @brief C API for the lsm303agr driver
|
||||||
|
*
|
||||||
|
* @include lsm303agr.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device context
|
||||||
|
*/
|
||||||
|
typedef struct _lsm303agr_context {
|
||||||
|
mraa_i2c_context i2cACC; // accelerometer
|
||||||
|
mraa_i2c_context i2cMAG; // magnetometer
|
||||||
|
mraa_gpio_context gpioACC1; // acc intr
|
||||||
|
mraa_gpio_context gpioACC2; // acc intr
|
||||||
|
mraa_gpio_context gpioMAG; // mag intr
|
||||||
|
|
||||||
|
// currently set power mode
|
||||||
|
LSM303AGR_POWER_MODE_T powerMode;
|
||||||
|
|
||||||
|
// uncompensated temperature in C
|
||||||
|
float temperature;
|
||||||
|
|
||||||
|
// accelerometer scaling, depends on full scale sensitivity and
|
||||||
|
// power mode
|
||||||
|
float accScale;
|
||||||
|
float accDivisor;
|
||||||
|
|
||||||
|
// uncompensated acc data
|
||||||
|
float accX;
|
||||||
|
float accY;
|
||||||
|
float accZ;
|
||||||
|
|
||||||
|
// uncompensated mag data
|
||||||
|
float magX;
|
||||||
|
float magY;
|
||||||
|
float magZ;
|
||||||
|
} *lsm303agr_context;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303AGR initialization
|
||||||
|
*
|
||||||
|
* This driver can only support I2C. SPI requires support for
|
||||||
|
* 3-wire SPI which we cannot currently handle. Only the basic
|
||||||
|
* capabilities of the device are supported, however there is a
|
||||||
|
* full register map defined (lsm303agr_defs.h), and with access
|
||||||
|
* to the bus read/write functions, any desired additional
|
||||||
|
* functionality can be implemented.
|
||||||
|
*
|
||||||
|
* @param bus I2C bus to use
|
||||||
|
* @param acc_addr The I2C address of the accelerometer. Use -1
|
||||||
|
* if you do not wish to use the accelerometer.
|
||||||
|
* @param mag_addr The I2C address of the magnetometer. Use -1
|
||||||
|
* if you do not wish to use the magnetometer.
|
||||||
|
* @return The device context, or NULL if an error occurred
|
||||||
|
*/
|
||||||
|
lsm303agr_context lsm303agr_init(int bus, int acc_addr, int mag_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303AGR Destructor
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
*/
|
||||||
|
void lsm303agr_close(lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the internal stored values from sensor data
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_update(const lsm303agr_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 lsm303agr_get_magnetometer(const lsm303agr_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 lsm303agr_get_accelerometer(const lsm303agr_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 lsm303agr_get_temperature(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the full scale (sensitivity) value for the accelerometer.
|
||||||
|
* This device supports 2G, 4G, 8G, and 16G full scale modes.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param fs One of the LSM303AGR_A_FS_T values
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_full_scale(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_A_FS_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.
|
||||||
|
*
|
||||||
|
* For the accelerometer, the full scale will be set to 2G, mode
|
||||||
|
* continuous, all axes enabled, BDU enabled, temperature
|
||||||
|
* measurement enabled, and an output data rate (ODR) of 100Hz
|
||||||
|
* with the power mode set at high resolution.
|
||||||
|
*
|
||||||
|
* For the magnetometer, temperature compensation will be enabled,
|
||||||
|
* mode continuous, and an output data rate of 10Hz with the power
|
||||||
|
* mode set at high resolution.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param usage One of the LSM303AGR_POWER_MODE_T values. This
|
||||||
|
* parameter is passed to a call to lsm303agr_set_power_mode() and
|
||||||
|
* will set the appropriate mode for both the accelerometer and
|
||||||
|
* magnetometer. The default set by the constructor is
|
||||||
|
* LSM303AGR_POWER_HIGH_RESOLUTION.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_devinit(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_POWER_MODE_T mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an operating power mode. There are 3 modes available: low
|
||||||
|
* power, normal, and high resolution.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param usage One of the LSM303AGR_POWER_MODE_T values. The
|
||||||
|
* default set at initialization time is
|
||||||
|
* LSM303AGR_POWER_HIGH_RESOLUTION.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_power_mode(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_POWER_MODE_T mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer (acc) output data rate (odr)
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param usage One of the LSM303AGR_A_ODR_T values. The default
|
||||||
|
* set at initialization time is LSM303AGR_A_ODR_100HZ.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_acc_odr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_A_ODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the magnetometer (mag) output data rate (odr)
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param usage One of the LSM303AGR_CFG_A_M_ODR_T values. The default
|
||||||
|
* set at initialization time is LSM303AGR_CFG_A_M_ODR_10HZ.
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_mag_odr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_CFG_A_M_ODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer (acc) interrupt 1 config register.
|
||||||
|
* This register allows you to enable various interrupt
|
||||||
|
* conditions. See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_get_acc_int1_config(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer (acc) interrupt 2 config register.
|
||||||
|
* This register allows you to enable various interrupt
|
||||||
|
* conditions. See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_get_acc_int2_config(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer (acc) interrupt 1 config register. See
|
||||||
|
* the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param bits A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_acc_int1_config(const lsm303agr_context dev,
|
||||||
|
uint8_t bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer (acc) interrupt 2 config register. See
|
||||||
|
* the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param bits A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_acc_int2_config(const lsm303agr_context dev,
|
||||||
|
uint8_t bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the magnetometer (mag) interrupt config register. See
|
||||||
|
* the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return A bitmask of LSM303AGR_INT_CTRL_REG_M_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_get_mag_int_config(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the magnetometer (mag) interrupt config register. See
|
||||||
|
* the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param bits A bitmask of LSM303AGR_INT_CTRL_REG_M_BITS_T bits
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_set_mag_int_config(const lsm303agr_context dev,
|
||||||
|
uint8_t bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer (acc) interrupt 1 source register.
|
||||||
|
* This register indicates which interrupts have been triggered.
|
||||||
|
* See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return a bitmask of LSM303AGR_INT_SRC_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_get_acc_int1_src(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer (acc) interrupt 2 source register.
|
||||||
|
* This register indicates which interrupts have been triggered.
|
||||||
|
* See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return a bitmask of LSM303AGR_INT_SRC_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_get_acc_int2_src(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the magnetometer (mag) interrupt source register.
|
||||||
|
* This register indicates which interrupts have been triggered.
|
||||||
|
* See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return a bitmask of LSM303AGR_INT_SRC_REG_M_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_get_mag_int_src(const lsm303agr_context dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install an interrupt handler
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param intr One of the LSM303AGR_INTERRUPT_PINS_T values
|
||||||
|
* specifying which interrupt pin you are installing
|
||||||
|
* @param gpio GPIO pin to use as interrupt pin
|
||||||
|
* @param level The interrupt trigger level (one of the
|
||||||
|
* mraa_gpio_edge_t values). Make sure that you have configured
|
||||||
|
* the interrupt pin properly for whatever level you choose.
|
||||||
|
* @param isr The interrupt handler, accepting a void * argument
|
||||||
|
* @param arg The argument to pass the the interrupt handler
|
||||||
|
* @return UPM result
|
||||||
|
*/
|
||||||
|
upm_result_t lsm303agr_install_isr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_INTERRUPT_PINS_T intr,
|
||||||
|
int gpio, mraa_gpio_edge_t level,
|
||||||
|
void (*isr)(void *), void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall a previously installed interrupt handler
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param intr One of the LSM303AGR_INTERRUPT_PINS_T values
|
||||||
|
* specifying which interrupt pin you are removing
|
||||||
|
*/
|
||||||
|
void lsm303agr_uninstall_isr(const lsm303agr_context dev,
|
||||||
|
LSM303AGR_INTERRUPT_PINS_T intr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a register.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param reg The register to read
|
||||||
|
* @return The value of the register
|
||||||
|
*/
|
||||||
|
uint8_t lsm303agr_read_reg(const lsm303agr_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 lsm303agr_read_regs(const lsm303agr_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 lsm303agr_write_reg(const lsm303agr_context dev,
|
||||||
|
uint8_t reg, uint8_t val);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
379
src/lsm303agr/lsm303agr.hpp
Normal file
379
src/lsm303agr/lsm303agr.hpp
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
/*
|
||||||
|
* 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 "lsm303agr.h"
|
||||||
|
|
||||||
|
namespace upm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ST Microelectronics Ultra-compact high-performance
|
||||||
|
* eCompass module
|
||||||
|
* @defgroup lsm303agr libupm-lsm303agr
|
||||||
|
* @ingroup i2c gpio stmicro compass accelerometer
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @library lsm303agr
|
||||||
|
* @sensor lsm303agr
|
||||||
|
* @comname Ultra-compact high-performance eCompass module
|
||||||
|
* @type compass
|
||||||
|
* @man stmicro
|
||||||
|
* @con i2c gpio
|
||||||
|
* @web http://www.st.com/en/mems-and-sensors/lsm303agr.html
|
||||||
|
*
|
||||||
|
* @brief API for the LSM303AGR 3-Axis Geomagnetic Sensor
|
||||||
|
*
|
||||||
|
* The LSM303AGR is an ultra-low-power high-performance
|
||||||
|
* system-in-package featuring a 3D digital linear acceleration
|
||||||
|
* sensor and a 3D digital magnetic sensor. The LSM303AGR 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 lsm303agr.cxx Interesting
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LSM303AGR {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* LSM303AGR constructor
|
||||||
|
*
|
||||||
|
* This driver can only support I2C. SPI requires support for
|
||||||
|
* 3-wire SPI which we cannot currently handle. Only the
|
||||||
|
* basic capabilities of the device are supported, however
|
||||||
|
* there is a full register map defined (lsm303agr_defs.h),
|
||||||
|
* and with access to the bus read/write functions, any
|
||||||
|
* desired additional functionality can be implemented.
|
||||||
|
*
|
||||||
|
* @param bus I2C bus to use
|
||||||
|
* @param acc_addr The I2C address of the accelerometer. Use -1
|
||||||
|
* if you do not wish to use the accelerometer.
|
||||||
|
* @param mag_addr The I2C address of the magnetometer. Use -1
|
||||||
|
* if you do not wish to use the magnetometer.
|
||||||
|
* @return The device context, or NULL if an error occurred
|
||||||
|
* @throws std::runtime_error on failure.
|
||||||
|
*/
|
||||||
|
LSM303AGR(int bus=LSM303AGR_DEFAULT_I2C_BUS,
|
||||||
|
int acc_addr=LSM303AGR_DEFAULT_ACC_ADDR,
|
||||||
|
int mag_addr=LSM303AGR_DEFAULT_MAG_ADDR);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303AGR Destructor
|
||||||
|
*/
|
||||||
|
~LSM303AGR();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* For the accelerometer, the full scale will be set to 2G,
|
||||||
|
* mode continuous, all axes enabled, BDU enabled, temperature
|
||||||
|
* measurement enabled, and an output data rate (ODR) of 100Hz
|
||||||
|
* with the power mode set at high resolution.
|
||||||
|
*
|
||||||
|
* For the magnetometer, temperature compensation will be
|
||||||
|
* enabled, mode continuous, and an output data rate of 10Hz
|
||||||
|
* with the power mode set at high resolution.
|
||||||
|
*
|
||||||
|
* @param usage One of the LSM303AGR_POWER_MODE_T values. The
|
||||||
|
* default is LSM303AGR_POWER_HIGH_RESOLUTION.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void init(LSM303AGR_POWER_MODE_T usage=LSM303AGR_POWER_HIGH_RESOLUTION);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the full scale (sensitivity) value for the accelerometer.
|
||||||
|
* This device supports 2G, 4G, 8G, and 16G full scale modes.
|
||||||
|
*
|
||||||
|
* @param fs One of the LSM303AGR_A_FS_T values
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setFullScale(LSM303AGR_A_FS_T fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an operating power mode. There are 3 modes available: low
|
||||||
|
* power, normal, and high resolution.
|
||||||
|
*
|
||||||
|
* @param usage One of the LSM303AGR_POWER_MODE_T values. The
|
||||||
|
* default set at initialization time is
|
||||||
|
* LSM303AGR_POWER_HIGH_RESOLUTION.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setPowerMode(LSM303AGR_POWER_MODE_T mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer output data rate (ODR)
|
||||||
|
*
|
||||||
|
* @param usage One of the LSM303AGR_A_ODR_T values. The default
|
||||||
|
* set at initialization time is LSM303AGR_A_ODR_100HZ.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setAccelerometerODR(LSM303AGR_A_ODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the magnetometer output data rate (ODR)
|
||||||
|
*
|
||||||
|
* @param usage One of the LSM303AGR_CFG_A_M_ODR_T values.
|
||||||
|
* The default set at initialization time is
|
||||||
|
* LSM303AGR_CFG_A_M_ODR_10HZ.
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setMagnetometerODR(LSM303AGR_CFG_A_M_ODR_T odr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer interrupt 1 config register.
|
||||||
|
* This register allows you to enable various interrupt
|
||||||
|
* conditions. See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @return A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t getAccelerometerInt1Config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer interrupt 2 config register.
|
||||||
|
* This register allows you to enable various interrupt
|
||||||
|
* conditions. See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @return A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t getAccelerometerInt2Config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer interrupt 1 config register. See the
|
||||||
|
* datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param bits A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setAccelerometerInt1Config(uint8_t bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accelerometer interrupt 2 config register. See the
|
||||||
|
* datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @param bits A bitmask of LSM303AGR_INT_CFG_A_BITS_T bits
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setAccelerometerInt2Config(uint8_t bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the magnetometer interrupt config register. See the
|
||||||
|
* datasheet for details.
|
||||||
|
*
|
||||||
|
* @return A bitmask of LSM303AGR_INT_CTRL_REG_M_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t getMagnetometerIntConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the magnetometer (mag) interrupt config register. See
|
||||||
|
* the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param bits A bitmask of LSM303AGR_INT_CTRL_REG_M_BITS_T bits
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void setMagnetometerIntConfig(uint8_t bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer interrupt 1 source register. This
|
||||||
|
* register indicates which interrupts have been triggered.
|
||||||
|
* See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @return a bitmask of LSM303AGR_INT_SRC_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t getAccelerometerInt1Src();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the accelerometer interrupt 2 source register. This
|
||||||
|
* register indicates which interrupts have been triggered.
|
||||||
|
* See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @return a bitmask of LSM303AGR_INT_SRC_A_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t getAccelerometerInt2Src();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the magnetometer (mag) interrupt source register.
|
||||||
|
* This register indicates which interrupts have been triggered.
|
||||||
|
* See the datasheet for details.
|
||||||
|
*
|
||||||
|
* @param dev The device context
|
||||||
|
* @return a bitmask of LSM303AGR_INT_SRC_REG_M_BITS_T bits
|
||||||
|
*/
|
||||||
|
uint8_t getMagnetometerIntSrc();
|
||||||
|
|
||||||
|
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
|
||||||
|
void installISR(LSM303AGR_INTERRUPT_PINS_T intr, int gpio,
|
||||||
|
mraa::Edge level,
|
||||||
|
jobject runnable)
|
||||||
|
{
|
||||||
|
installISR(intr, gpio, level, mraa_java_isr_callback, runnable);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* Install an interrupt handler
|
||||||
|
*
|
||||||
|
* @param intr One of the LSM303AGR_INTERRUPT_PINS_T values
|
||||||
|
* specifying which interrupt pin you are installing
|
||||||
|
* @param gpio GPIO pin to use as interrupt pin
|
||||||
|
* @param level The interrupt trigger level (one of mraa::Edge
|
||||||
|
* values). Make sure that you have configured the interrupt pin
|
||||||
|
* properly for whatever level you choose.
|
||||||
|
* @param isr The interrupt handler, accepting a void * argument
|
||||||
|
* @param arg The argument to pass the the interrupt handler
|
||||||
|
* @throws std::runtime_error on failure
|
||||||
|
*/
|
||||||
|
void installISR(LSM303AGR_INTERRUPT_PINS_T intr, int gpio,
|
||||||
|
mraa::Edge level,
|
||||||
|
void (*isr)(void *), void *arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall a previously installed interrupt handler
|
||||||
|
*
|
||||||
|
* @param intr One of the LSM303AGR_INTERRUPT_PINS_T values
|
||||||
|
* specifying which interrupt pin you are removing
|
||||||
|
*/
|
||||||
|
void uninstallISR(LSM303AGR_INTERRUPT_PINS_T intr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// our underlying device context
|
||||||
|
lsm303agr_context m_lsm303agr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
||||||
|
// Adding a private function definition for java bindings
|
||||||
|
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
|
||||||
|
void installISR(LSM303AGR_INTERRUPT_PINS_T intr, int gpio,
|
||||||
|
mraa::Edge level,
|
||||||
|
void (*isr)(void *), void *arg);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
686
src/lsm303agr/lsm303agr_defs.h
Normal file
686
src/lsm303agr/lsm303agr_defs.h
Normal file
@ -0,0 +1,686 @@
|
|||||||
|
/*
|
||||||
|
* 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 LSM303AGR_DEFAULT_I2C_BUS 0
|
||||||
|
#define LSM303AGR_DEFAULT_ACC_ADDR 0x19
|
||||||
|
#define LSM303AGR_DEFAULT_MAG_ADDR 0x1e
|
||||||
|
|
||||||
|
// from the WHO_AM_I_* registers
|
||||||
|
#define LSM303AGR_CHIPID_ACC 0x33
|
||||||
|
#define LSM303AGR_CHIPID_MAG 0x40
|
||||||
|
|
||||||
|
// This device has 2 I2C addresses - one for the accelerometer (ACC)
|
||||||
|
// and one for the magnetometer (MAG). But, it uses a single register
|
||||||
|
// map. The MAG registers start at 0x40, while the ACC registers
|
||||||
|
// start at 0 and go to 0x3f. We define the cutoff point here so the
|
||||||
|
// register access functions can "automatically" choose the correct
|
||||||
|
// i2c context (MAG or ACC) to use depending on what register is
|
||||||
|
// being accessed.
|
||||||
|
|
||||||
|
#define LSM303AGR_MAX_ACC_ADDR 0x3f
|
||||||
|
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303AGR registers
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
|
||||||
|
// accelerometer registers
|
||||||
|
|
||||||
|
// 0x00-0x06 reserved
|
||||||
|
|
||||||
|
LSM303AGR_REG_STATUS_REG_AUX_A = 0x07,
|
||||||
|
|
||||||
|
// 0x08-0x0b reserved
|
||||||
|
|
||||||
|
LSM303AGR_REG_OUT_TEMP_L_A = 0x0c,
|
||||||
|
LSM303AGR_REG_OUT_TEMP_H_A = 0x0d,
|
||||||
|
|
||||||
|
LSM303AGR_REG_INT_COUNTER_REG_A = 0x0e,
|
||||||
|
|
||||||
|
LSM303AGR_REG_WHO_AM_I_A = 0x0f,
|
||||||
|
|
||||||
|
// 0x10-0x1e reserved
|
||||||
|
|
||||||
|
LSM303AGR_REG_TEMP_CFG_REG_A = 0x1f,
|
||||||
|
|
||||||
|
LSM303AGR_REG_CTRL_REG1_A = 0x20,
|
||||||
|
LSM303AGR_REG_CTRL_REG2_A = 0x21,
|
||||||
|
LSM303AGR_REG_CTRL_REG3_A = 0x22,
|
||||||
|
LSM303AGR_REG_CTRL_REG4_A = 0x23,
|
||||||
|
LSM303AGR_REG_CTRL_REG5_A = 0x24,
|
||||||
|
LSM303AGR_REG_CTRL_REG6_A = 0x25,
|
||||||
|
|
||||||
|
LSM303AGR_REG_REFERENCE = 0x26,
|
||||||
|
|
||||||
|
LSM303AGR_REG_STATUS_REG_A = 0x27,
|
||||||
|
|
||||||
|
LSM303AGR_REG_OUT_X_L_A = 0x28,
|
||||||
|
LSM303AGR_REG_OUT_X_H_A = 0x29,
|
||||||
|
LSM303AGR_REG_OUT_Y_L_A = 0x2a,
|
||||||
|
LSM303AGR_REG_OUT_Y_H_A = 0x2b,
|
||||||
|
LSM303AGR_REG_OUT_Z_L_A = 0x2c,
|
||||||
|
LSM303AGR_REG_OUT_Z_H_A = 0x2d,
|
||||||
|
|
||||||
|
LSM303AGR_REG_FIFO_CTRL_REG_A = 0x2e,
|
||||||
|
LSM303AGR_REG_FIFO_SRC_REG_A = 0x2f,
|
||||||
|
|
||||||
|
LSM303AGR_REG_INT1_CFG_A = 0x30,
|
||||||
|
LSM303AGR_REG_INT1_SRC_A = 0x31,
|
||||||
|
LSM303AGR_REG_INT1_THS_A = 0x32,
|
||||||
|
LSM303AGR_REG_INT1_DUR_A = 0x33,
|
||||||
|
|
||||||
|
LSM303AGR_REG_INT2_CFG_A = 0x34,
|
||||||
|
LSM303AGR_REG_INT2_SRC_A = 0x35,
|
||||||
|
LSM303AGR_REG_INT2_THS_A = 0x36,
|
||||||
|
LSM303AGR_REG_INT2_DUR_A = 0x37,
|
||||||
|
|
||||||
|
LSM303AGR_REG_CLICK_CFG_A = 0x38,
|
||||||
|
LSM303AGR_REG_CLICK_SRC_A = 0x39,
|
||||||
|
LSM303AGR_REG_CLICK_THS_A = 0x3a,
|
||||||
|
|
||||||
|
LSM303AGR_REG_TIME_LIMIT = 0x3b,
|
||||||
|
LSM303AGR_REG_TIME_LATENCY_A = 0x3c,
|
||||||
|
LSM303AGR_REG_TIME_WINDOW_A = 0x3d,
|
||||||
|
|
||||||
|
LSM303AGR_REG_ACT_THS_A = 0x3e,
|
||||||
|
LSM303AGR_REG_ACT_DUR_A = 0x3f,
|
||||||
|
|
||||||
|
// magnetometer registers
|
||||||
|
|
||||||
|
// 0x40-0x44 reserved
|
||||||
|
|
||||||
|
LSM303AGR_REG_OFFSET_X_REG_L_M = 0x45,
|
||||||
|
LSM303AGR_REG_OFFSET_X_REG_H_M = 0x46,
|
||||||
|
LSM303AGR_REG_OFFSET_Y_REG_L_M = 0x47,
|
||||||
|
LSM303AGR_REG_OFFSET_Y_REG_H_M = 0x48,
|
||||||
|
LSM303AGR_REG_OFFSET_Z_REG_L_M = 0x49,
|
||||||
|
LSM303AGR_REG_OFFSET_Z_REG_H_M = 0x4a,
|
||||||
|
|
||||||
|
// 0x4b-0x4d reserved
|
||||||
|
|
||||||
|
LSM303AGR_REG_WHO_AM_I_M = 0x4f,
|
||||||
|
|
||||||
|
// 0x50-0x5f reserved
|
||||||
|
|
||||||
|
LSM303AGR_REG_CFG_REG_A_M = 0x60,
|
||||||
|
LSM303AGR_REG_CFG_REG_B_M = 0x61,
|
||||||
|
LSM303AGR_REG_CFG_REG_C_M = 0x62,
|
||||||
|
|
||||||
|
LSM303AGR_REG_INT_CTRL_REG_M = 0x63,
|
||||||
|
LSM303AGR_REG_INT_SRC_REG_M = 0x64,
|
||||||
|
LSM303AGR_REG_INT_THS_L_REG_M = 0x65,
|
||||||
|
LSM303AGR_REG_INT_THS_H_REG_M = 0x66,
|
||||||
|
|
||||||
|
LSM303AGR_REG_STATUS_REG_M = 0x67,
|
||||||
|
|
||||||
|
LSM303AGR_REG_OUTX_L_REG_M = 0x68,
|
||||||
|
LSM303AGR_REG_OUTX_H_REG_M = 0x69,
|
||||||
|
LSM303AGR_REG_OUTY_L_REG_M = 0x6a,
|
||||||
|
LSM303AGR_REG_OUTY_H_REG_M = 0x6b,
|
||||||
|
LSM303AGR_REG_OUTZ_L_REG_M = 0x6c,
|
||||||
|
LSM303AGR_REG_OUTZ_H_REG_M = 0x6d
|
||||||
|
|
||||||
|
// 0x6e-0x6f reserved
|
||||||
|
} LSM303AGR_REGS_T;
|
||||||
|
|
||||||
|
// Accelerometer registers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STATUS_REG_AUX_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
// 0x01-0x02 reserved
|
||||||
|
|
||||||
|
LSM303AGR_STATUS_REG_AUX_A_TDA = 0x04, // temp data avail
|
||||||
|
|
||||||
|
// 0x08-0x20 reserved
|
||||||
|
|
||||||
|
LSM303AGR_STATUS_REG_AUX_A_TOR = 0x40, // temp data overrun
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_STATUS_REG_AUX_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TEMP_CFG_REG_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
// 0x01-0x20 reserved
|
||||||
|
|
||||||
|
LSM303AGR_TEMP_CFG_REG_A_TEMP_EN0 = 0x40,
|
||||||
|
LSM303AGR_TEMP_CFG_REG_A_TEMP_EN1 = 0x80,
|
||||||
|
_LSM303AGR_TEMP_CFG_REG_A_TEMP_EN_MASK = 3,
|
||||||
|
_LSM303AGR_TEMP_CFG_REG_A_TEMP_EN_SHIFT = 6,
|
||||||
|
} LSM303AGR_TEMP_CFG_REG_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TEMP_CFG_REG_A_TEMP_EN values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_TEMP_EN_OFF = 0,
|
||||||
|
LSM303AGR_TEMP_EN_ON = 3,
|
||||||
|
} LSM303AGR_TEMP_EN_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG1_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CTRL_REG1_A_XEN = 0x01, // axis enables
|
||||||
|
LSM303AGR_CTRL_REG1_A_YEN = 0x02,
|
||||||
|
LSM303AGR_CTRL_REG1_A_ZEN = 0x04,
|
||||||
|
LSM303AGR_CTRL_REG1_A_LPEN = 0x08, // low power enable
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG1_A_ODR0 = 0x10, // output data rate
|
||||||
|
LSM303AGR_CTRL_REG1_A_ODR1 = 0x20,
|
||||||
|
LSM303AGR_CTRL_REG1_A_ODR2 = 0x40,
|
||||||
|
LSM303AGR_CTRL_REG1_A_ODR3 = 0x80,
|
||||||
|
_LSM303AGR_CTRL_REG1_A_ODR_MASK = 15,
|
||||||
|
_LSM303AGR_CTRL_REG1_A_ODR_SHIFT = 4,
|
||||||
|
} LSM303AGR_CTRL_REG1_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG1_A_ODR values (and power mode)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_A_ODR_POWER_DOWN = 0,
|
||||||
|
LSM303AGR_A_ODR_1HZ = 1, // 1Hz, HR/Normal/LP
|
||||||
|
LSM303AGR_A_ODR_10HZ = 2,
|
||||||
|
LSM303AGR_A_ODR_25HZ = 3,
|
||||||
|
LSM303AGR_A_ODR_50HZ = 4,
|
||||||
|
LSM303AGR_A_ODR_100HZ = 5,
|
||||||
|
LSM303AGR_A_ODR_200HZ = 6,
|
||||||
|
LSM303AGR_A_ODR_400HZ = 7,
|
||||||
|
LSM303AGR_A_ODR_1_620KHZ = 8, // 1.620kHz, low power
|
||||||
|
LSM303AGR_A_ODR_1_344KHZ = 9, // 1.344kHZ
|
||||||
|
// HR/Normal,
|
||||||
|
// 5.376kHZ low
|
||||||
|
// power
|
||||||
|
} LSM303AGR_A_ODR_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG2_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPIS1 = 0x01,
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPIS2 = 0x02,
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPCLICK = 0x04,
|
||||||
|
LSM303AGR_CTRL_REG2_A_FDS = 0x08,
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPCF1 = 0x10,
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPCF2 = 0x20,
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPM0 = 0x40,
|
||||||
|
LSM303AGR_CTRL_REG2_A_HPM1 = 0x80,
|
||||||
|
_LSM303AGR_CTRL_REG2_A_HPM_MASK = 3,
|
||||||
|
_LSM303AGR_CTRL_REG2_A_HPM_SHIFT = 6,
|
||||||
|
} LSM303AGR_CTRL_REG2_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG2_A_HPM values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_A_HPM_NORMAL = 0,
|
||||||
|
LSM303AGR_A_HPM_REF = 1,
|
||||||
|
LSM303AGR_A_HPM_NORMAL2 = 2,
|
||||||
|
LSM303AGR_A_HPM_AUTORESET = 3,
|
||||||
|
} LSM303AGR_A_HPM_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG3_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
// 0x01 reserved
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_OVERRUN = 0x02,
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_WTM = 0x04,
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_DRDY2 = 0x08,
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_DRDY1 = 0x10,
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_AOI2 = 0x20,
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_AOI1 = 0x40,
|
||||||
|
LSM303AGR_CTRL_REG3_A_I1_CLICK = 0x80,
|
||||||
|
} LSM303AGR_CTRL_REG3_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG4_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CTRL_REG4_A_SPI_ENABLE = 0x01, // 3-wire
|
||||||
|
// spi (no
|
||||||
|
// supported!)
|
||||||
|
LSM303AGR_CTRL_REG4_A_ST0 = 0x02,
|
||||||
|
LSM303AGR_CTRL_REG4_A_ST1 = 0x04,
|
||||||
|
_LSM303AGR_CTRL_REG4_A_ST_MASK = 3,
|
||||||
|
_LSM303AGR_CTRL_REG4_A_ST_SHIFT = 1,
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG4_A_HR = 0x08, // high res
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG4_A_FS0 = 0x10, // FS selection
|
||||||
|
LSM303AGR_CTRL_REG4_A_FS1 = 0x20,
|
||||||
|
_LSM303AGR_CTRL_REG4_A_FS_MASK = 3,
|
||||||
|
_LSM303AGR_CTRL_REG4_A_FS_SHIFT = 4,
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG4_A_BLE = 0x40,
|
||||||
|
LSM303AGR_CTRL_REG4_A_BDU = 0x80, // block update
|
||||||
|
} LSM303AGR_CTRL_REG4_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG4_A_ST values (self-test)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_A_ST_NORMAL = 0,
|
||||||
|
LSM303AGR_A_ST_0 = 1,
|
||||||
|
LSM303AGR_A_ST_1 = 2,
|
||||||
|
} LSM303AGR_A_ST_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG4_A_FS values (full-scale)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_A_FS_2G = 0, // 2G
|
||||||
|
LSM303AGR_A_FS_4G = 1,
|
||||||
|
LSM303AGR_A_FS_8G = 2,
|
||||||
|
LSM303AGR_A_FS_16G = 3, // 16G
|
||||||
|
} LSM303AGR_A_FS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG5_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CTRL_REG5_A_D4D_INT2 = 0x01,
|
||||||
|
LSM303AGR_CTRL_REG5_A_LIR_INT2 = 0x02,
|
||||||
|
LSM303AGR_CTRL_REG5_A_D4D_INT1 = 0x04,
|
||||||
|
LSM303AGR_CTRL_REG5_A_LIR_INT1 = 0x08,
|
||||||
|
|
||||||
|
// 0x10-0x20 reserved
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG5_A_FIFO_EN = 0x40,
|
||||||
|
LSM303AGR_CTRL_REG5_A_BOOT = 0x80,
|
||||||
|
} LSM303AGR_CTRL_REG5_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTRL_REG6_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
// 0x01 reserved
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG6_A_H_LACTIVE = 0x02,
|
||||||
|
|
||||||
|
// 0x04 reserved
|
||||||
|
|
||||||
|
LSM303AGR_CTRL_REG6_A_P2_ACT = 0x08,
|
||||||
|
LSM303AGR_CTRL_REG6_A_BOOT_I2 = 0x10,
|
||||||
|
LSM303AGR_CTRL_REG6_A_I2_INT2 = 0x20,
|
||||||
|
LSM303AGR_CTRL_REG6_A_I2_INT1 = 0x40,
|
||||||
|
LSM303AGR_CTRL_REG6_A_I2_CLICK_EN = 0x80,
|
||||||
|
} LSM303AGR_CTRL_REG6_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STATUS_REG_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_STATUS_REG_A_XDA = 0x01,
|
||||||
|
LSM303AGR_STATUS_REG_A_YDA = 0x02,
|
||||||
|
LSM303AGR_STATUS_REG_A_ZDA = 0x04,
|
||||||
|
LSM303AGR_STATUS_REG_A_ZYXDA = 0x08,
|
||||||
|
LSM303AGR_STATUS_REG_A_XOR = 0x10,
|
||||||
|
LSM303AGR_STATUS_REG_A_YOR = 0x20,
|
||||||
|
LSM303AGR_STATUS_REG_A_ZOR = 0x40,
|
||||||
|
LSM303AGR_STATUS_REG_A_ZYXOR = 0x80,
|
||||||
|
} LSM303AGR_STATUS_REG_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIFO_CTRL_REG_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FTH0 = 0x01, // fifo threshold
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FTH1 = 0x02,
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FTH2 = 0x04,
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FTH3 = 0x08,
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FTH4 = 0x10,
|
||||||
|
_LSM303AGR_FIFO_CTRL_REG_A_FTH_MASK = 31,
|
||||||
|
_LSM303AGR_FIFO_CTRL_REG_A_FTH_SHIF = 0,
|
||||||
|
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_TR = 0x20, // trigger select
|
||||||
|
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FM0 = 0x40, // fifo mode
|
||||||
|
LSM303AGR_FIFO_CTRL_REG_A_FM1 = 0x80,
|
||||||
|
_LSM303AGR_FIFO_CTRL_REG_A_FM_MASK = 3,
|
||||||
|
_LSM303AGR_FIFO_CTRL_REG_A_FM_SHIFT = 6,
|
||||||
|
} LSM303AGR_FIFO_CTRL_REG_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIFO_CTRL_REG_A_FM values (fifo mode)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_A_FM_BYPASS = 0,
|
||||||
|
LSM303AGR_A_FM_FIFO = 1,
|
||||||
|
LSM303AGR_A_FM_STREAM = 2,
|
||||||
|
LSM303AGR_A_FM_STREAM_TO_FIFO = 3,
|
||||||
|
} LSM303AGR_A_FM_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIFO_SRC_REG_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_FSS0 = 0x01, // fifo unread samples
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_FSS1 = 0x02,
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_FSS2 = 0x04,
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_FSS3 = 0x08,
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_FSS4 = 0x10,
|
||||||
|
_LSM303AGR_FIFO_SRC_REG_A_FSS_MASK = 31,
|
||||||
|
_LSM303AGR_FIFO_SRC_REG_A_FSS_SHIFT = 0,
|
||||||
|
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_EMPTY = 0x20,
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_OVRN_FIFO = 0x40,
|
||||||
|
LSM303AGR_FIFO_SRC_REG_A_WTM = 0x80,
|
||||||
|
} LSM303AGR_FIFO_SRC_REG_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT_CFG_A bits. This definition is used for INT1 and INT2.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INT_CFG_A_XLIE = 0x01,
|
||||||
|
LSM303AGR_INT_CFG_A_XHIE = 0x02,
|
||||||
|
LSM303AGR_INT_CFG_A_YLIE = 0x04,
|
||||||
|
LSM303AGR_INT_CFG_A_YHIE = 0x08,
|
||||||
|
LSM303AGR_INT_CFG_A_ZLIE = 0x10,
|
||||||
|
LSM303AGR_INT_CFG_A_ZHIE = 0x20,
|
||||||
|
LSM303AGR_INT_CFG_A_6D = 0x40,
|
||||||
|
LSM303AGR_INT_CFG_A_AOI = 0x80,
|
||||||
|
} LSM303AGR_INT_CFG_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT_SRC_A bits. This definition is used for INT1 and INT2.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INT_SRC_A_XL = 0x01,
|
||||||
|
LSM303AGR_INT_SRC_A_XH = 0x02,
|
||||||
|
LSM303AGR_INT_SRC_A_YL = 0x04,
|
||||||
|
LSM303AGR_INT_SRC_A_YH = 0x08,
|
||||||
|
LSM303AGR_INT_SRC_A_ZL = 0x10,
|
||||||
|
LSM303AGR_INT_SRC_A_ZH = 0x20,
|
||||||
|
LSM303AGR_INT_SRC_A_IA = 0x40,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_INT_SRC_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT_THS_A bits. This definition is used for INT1 and INT2.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INT_THS0 = 0x01,
|
||||||
|
LSM303AGR_INT_THS1 = 0x02,
|
||||||
|
LSM303AGR_INT_THS2 = 0x04,
|
||||||
|
LSM303AGR_INT_THS3 = 0x08,
|
||||||
|
LSM303AGR_INT_THS4 = 0x10,
|
||||||
|
LSM303AGR_INT_THS5 = 0x20,
|
||||||
|
LSM303AGR_INT_THS6 = 0x40,
|
||||||
|
_LSM303AGR_INT_THS_MASK = 127,
|
||||||
|
_LSM303AGR_INT_THS_SHIFT = 0,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_INT_THS_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT_DUR_A bits. This definition is used for INT1 and INT2.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INT_DUR0 = 0x01,
|
||||||
|
LSM303AGR_INT_DUR1 = 0x02,
|
||||||
|
LSM303AGR_INT_DUR2 = 0x04,
|
||||||
|
LSM303AGR_INT_DUR3 = 0x08,
|
||||||
|
LSM303AGR_INT_DUR4 = 0x10,
|
||||||
|
LSM303AGR_INT_DUR5 = 0x20,
|
||||||
|
LSM303AGR_INT_DUR6 = 0x40,
|
||||||
|
_LSM303AGR_INT_DUR_MASK = 127,
|
||||||
|
_LSM303AGR_INT_DUR_SHIFT = 0,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_INT_DUR_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLICK_CFG_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CLICK_CFG_A_XS = 0x01,
|
||||||
|
LSM303AGR_CLICK_CFG_A_XD = 0x02,
|
||||||
|
LSM303AGR_CLICK_CFG_A_YS = 0x04,
|
||||||
|
LSM303AGR_CLICK_CFG_A_YD = 0x08,
|
||||||
|
LSM303AGR_CLICK_CFG_A_ZS = 0x10,
|
||||||
|
LSM303AGR_CLICK_CFG_A_ZD = 0x20,
|
||||||
|
|
||||||
|
// 0x40-0x80 reserved
|
||||||
|
} LSM303AGR_CLICK_CFG_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLICK_SRC_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CLICK_SRC_A_X = 0x01,
|
||||||
|
LSM303AGR_CLICK_SRC_A_Y = 0x02,
|
||||||
|
LSM303AGR_CLICK_SRC_A_Z = 0x04,
|
||||||
|
LSM303AGR_CLICK_SRC_A_SIGN = 0x08,
|
||||||
|
LSM303AGR_CLICK_SRC_A_SCLICK = 0x10,
|
||||||
|
LSM303AGR_CLICK_SRC_A_DCLICK = 0x20,
|
||||||
|
LSM303AGR_CLICK_SRC_A_IA = 0x40,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_CLICK_SRC_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLICK_THS_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CLICK_A_THS0 = 0x01,
|
||||||
|
LSM303AGR_CLICK_A_THS1 = 0x02,
|
||||||
|
LSM303AGR_CLICK_A_THS2 = 0x04,
|
||||||
|
LSM303AGR_CLICK_A_THS3 = 0x08,
|
||||||
|
LSM303AGR_CLICK_A_THS4 = 0x10,
|
||||||
|
LSM303AGR_CLICK_A_THS5 = 0x20,
|
||||||
|
LSM303AGR_CLICK_A_THS6 = 0x40,
|
||||||
|
_LSM303AGR_CLICK_A_THS_MASK = 127,
|
||||||
|
_LSM303AGR_CLICK_A_THS_SHIFT = 0,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_CLICK_THS_A_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TIME_LIMIT_A bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI0 = 0x01,
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI1 = 0x02,
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI2 = 0x04,
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI3 = 0x08,
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI4 = 0x10,
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI5 = 0x20,
|
||||||
|
LSM303AGR_TIME_LIMIT_A_TLI6 = 0x40,
|
||||||
|
_LSM303AGR_TIME_LIMIT_A_TLI_MASK = 127,
|
||||||
|
_LSM303AGR_TIME_LIMIT_A_TLI_SHIFT = 0,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_TIME_LIMIT_A_BITS_T;
|
||||||
|
|
||||||
|
// Magnetometer registers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG_REG_A_M bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CFG_REG_A_M_MD0 = 0x01, // mode select
|
||||||
|
LSM303AGR_CFG_REG_A_M_MD1 = 0x02,
|
||||||
|
_LSM303AGR_CFG_REG_A_M_MD_MASK = 3,
|
||||||
|
_LSM303AGR_CFG_REG_A_M_MD_SHIFT = 0,
|
||||||
|
|
||||||
|
LSM303AGR_CFG_REG_A_M_ODR0 = 0x04, // output data rate
|
||||||
|
LSM303AGR_CFG_REG_A_M_ODR1 = 0x08,
|
||||||
|
_LSM303AGR_CFG_REG_A_M_ODR_MASK = 3,
|
||||||
|
_LSM303AGR_CFG_REG_A_M_ODR_SHIFT = 2,
|
||||||
|
|
||||||
|
LSM303AGR_CFG_REG_A_M_LP = 0x10, // low power/hi res
|
||||||
|
LSM303AGR_CFG_REG_A_M_SOFT_RESET = 0x20,
|
||||||
|
LSM303AGR_CFG_REG_A_M_REBOOT = 0x40,
|
||||||
|
LSM303AGR_CFG_REG_A_M_COMP_TEMP_EN = 0x80, // temp compensation
|
||||||
|
} LSM303AGR_CFG_REG_A_M_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG_REG_A_M_MD values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CFG_A_M_MD_CONTINUOUS = 0,
|
||||||
|
LSM303AGR_CFG_A_M_MD_SINGLE = 1,
|
||||||
|
LSM303AGR_CFG_A_M_MD_IDLE = 2,
|
||||||
|
} LSM303AGR_CFG_A_M_MD_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG_REG_A_M_ODR values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CFG_A_M_ODR_10HZ = 0,
|
||||||
|
LSM303AGR_CFG_A_M_ODR_20HZ = 1,
|
||||||
|
LSM303AGR_CFG_A_M_ODR_50HZ = 2,
|
||||||
|
LSM303AGR_CFG_A_M_ODR_100HZ = 3,
|
||||||
|
} LSM303AGR_CFG_A_M_ODR_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG_REG_B_M bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CFG_REG_B_M_LPF = 0x01,
|
||||||
|
LSM303AGR_CFG_REG_B_M_OFF_CANC = 0x02,
|
||||||
|
LSM303AGR_CFG_REG_B_M_SET_FREQ = 0x04,
|
||||||
|
LSM303AGR_CFG_REG_B_M_INT_ON_DATA_OFF = 0x08,
|
||||||
|
LSM303AGR_CFG_REG_B_M_OFF_CANC_ONE_SHOT = 0x10,
|
||||||
|
|
||||||
|
// 0x20-0x80 reserved
|
||||||
|
} LSM303AGR_CFG_REG_B_M_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG_REG_C_M bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_CFG_REG_C_M_INT_MAG = 0x01,
|
||||||
|
LSM303AGR_CFG_REG_C_M_SELF_TEST = 0x02,
|
||||||
|
|
||||||
|
// 0x04 reserved and MUST be 0 for correct operation
|
||||||
|
|
||||||
|
LSM303AGR_CFG_REG_C_M_BLE = 0x08,
|
||||||
|
LSM303AGR_CFG_REG_C_M_BDU = 0x10,
|
||||||
|
LSM303AGR_CFG_REG_C_M_I2C_DIS = 0x20, // don't do it...
|
||||||
|
LSM303AGR_CFG_REG_C_M_INT_MAG_PIN = 0x40,
|
||||||
|
|
||||||
|
// 0x80 reserved
|
||||||
|
} LSM303AGR_CFG_REG_C_M_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT_CTRL_REG_M bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INT_CTRL_REG_M_IEN = 0x01,
|
||||||
|
LSM303AGR_INT_CTRL_REG_M_IEL = 0x02,
|
||||||
|
LSM303AGR_INT_CTRL_REG_M_IEA = 0x04,
|
||||||
|
|
||||||
|
// 0x08-0x10 reserved and MUST be 0 for correct operation
|
||||||
|
|
||||||
|
LSM303AGR_INT_CTRL_REG_M_ZIEN = 0x20,
|
||||||
|
LSM303AGR_INT_CTRL_REG_M_YIEN = 0x40,
|
||||||
|
LSM303AGR_INT_CTRL_REG_M_XIEN = 0x80,
|
||||||
|
} LSM303AGR_INT_CTRL_REG_M_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT_SRC_REG_M bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INT_SRC_REG_M_MROI = 0x02,
|
||||||
|
LSM303AGR_INT_SRC_REG_M_N_TH_S_Z = 0x04,
|
||||||
|
LSM303AGR_INT_SRC_REG_M_N_TH_S_Y = 0x08,
|
||||||
|
LSM303AGR_INT_SRC_REG_M_N_TH_S_X = 0x10,
|
||||||
|
LSM303AGR_INT_SRC_REG_M_P_TH_S_Z = 0x20,
|
||||||
|
LSM303AGR_INT_SRC_REG_M_P_TH_S_Y = 0x40,
|
||||||
|
LSM303AGR_INT_SRC_REG_M_P_TH_S_X = 0x80,
|
||||||
|
} LSM303AGR_INT_SRC_REG_M_BITS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STATUS_REG_M bits
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_STATUS_REG_M_XDA = 0x01,
|
||||||
|
LSM303AGR_STATUS_REG_M_YDA = 0x02,
|
||||||
|
LSM303AGR_STATUS_REG_M_ZDA = 0x04,
|
||||||
|
LSM303AGR_STATUS_REG_M_ZYXDA = 0x08,
|
||||||
|
LSM303AGR_STATUS_REG_M_XOR = 0x10,
|
||||||
|
LSM303AGR_STATUS_REG_M_YOR = 0x20,
|
||||||
|
LSM303AGR_STATUS_REG_M_ZOR = 0x40,
|
||||||
|
LSM303AGR_STATUS_REG_M_ZYXOR = 0x80,
|
||||||
|
} LSM303AGR_STATUS_REG_M_BITS_T;
|
||||||
|
|
||||||
|
// The following enums are used for driver functionality.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERRUPT_PINS_T values. There are 3 interrupt pins available;
|
||||||
|
* two for the accelerometer, and one for the magnetometer.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_INTERRUPT_ACC_1 = 0, // ACC intr 1
|
||||||
|
LSM303AGR_INTERRUPT_ACC_2 = 1, // ACC intr 2
|
||||||
|
LSM303AGR_INTERRUPT_MAG = 2, // MAG intr
|
||||||
|
} LSM303AGR_INTERRUPT_PINS_T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LSM303AGR_POWER_MODE_T values. These set the basic operating
|
||||||
|
* power modes to one of low power, normal, and high resolution.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
LSM303AGR_POWER_LOW_POWER = 0,
|
||||||
|
LSM303AGR_POWER_NORMAL = 1,
|
||||||
|
LSM303AGR_POWER_HIGH_RESOLUTION = 2,
|
||||||
|
} LSM303AGR_POWER_MODE_T;
|
||||||
|
|
||||||
|
// some useful macros to save on typing and text wrapping
|
||||||
|
#define _LSM303AGR_SHIFT(x) \
|
||||||
|
(_LSM303AGR_##x##_SHIFT)
|
||||||
|
|
||||||
|
#define _LSM303AGR_MASK(x) \
|
||||||
|
(_LSM303AGR_##x##_MASK)
|
||||||
|
|
||||||
|
#define _LSM303AGR_SHIFTMASK(x) \
|
||||||
|
(_LSM303AGR_MASK(x) << _LSM303AGR_SHIFT(x))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
137
src/lsm303agr/lsm303agr_fti.c
Normal file
137
src/lsm303agr/lsm303agr_fti.c
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* 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 "lsm303agr.h"
|
||||||
|
#include "upm_fti.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file implements the Function Table Interface (FTI) for this sensor
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char upm_lsm303agr_name[] = "LSM303AGR";
|
||||||
|
const char upm_lsm303agr_description[] =
|
||||||
|
"3D Accelerometer and 3D Magnetometer";
|
||||||
|
const upm_protocol_t upm_lsm303agr_protocol[] = {UPM_I2C, UPM_GPIO};
|
||||||
|
const upm_sensor_t upm_lsm303agr_category[] = {UPM_MAGNETOMETER,
|
||||||
|
UPM_ACCELEROMETER};
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
const void* upm_lsm303agr_get_ft(upm_sensor_t sensor_type);
|
||||||
|
void* upm_lsm303agr_init_name();
|
||||||
|
void upm_lsm303agr_close(void *dev);
|
||||||
|
upm_result_t upm_lsm303agr_get_acc_value(void *dev, float *value,
|
||||||
|
upm_acceleration_u unit);
|
||||||
|
upm_result_t upm_lsm303agr_get_mag_value(void *dev, float *value);
|
||||||
|
|
||||||
|
const upm_sensor_descriptor_t upm_lsm303agr_get_descriptor()
|
||||||
|
{
|
||||||
|
upm_sensor_descriptor_t usd;
|
||||||
|
usd.name = upm_lsm303agr_name;
|
||||||
|
usd.description = upm_lsm303agr_description;
|
||||||
|
usd.protocol_size = 2;
|
||||||
|
usd.protocol = upm_lsm303agr_protocol;
|
||||||
|
usd.category_size = 2;
|
||||||
|
usd.category = upm_lsm303agr_category;
|
||||||
|
return usd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const upm_sensor_ft ft =
|
||||||
|
{
|
||||||
|
.upm_sensor_init_name = &upm_lsm303agr_init_name,
|
||||||
|
.upm_sensor_close = &upm_lsm303agr_close,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const upm_magnetometer_ft mft =
|
||||||
|
{
|
||||||
|
.upm_magnetometer_get_value = &upm_lsm303agr_get_mag_value
|
||||||
|
};
|
||||||
|
|
||||||
|
static const upm_acceleration_ft aft =
|
||||||
|
{
|
||||||
|
.upm_acceleration_get_value = &upm_lsm303agr_get_acc_value
|
||||||
|
};
|
||||||
|
|
||||||
|
const void* upm_lsm303agr_get_ft(upm_sensor_t sensor_type)
|
||||||
|
{
|
||||||
|
switch(sensor_type)
|
||||||
|
{
|
||||||
|
case UPM_SENSOR:
|
||||||
|
return &ft;
|
||||||
|
|
||||||
|
case UPM_MAGNETOMETER:
|
||||||
|
return &mft;
|
||||||
|
|
||||||
|
case UPM_ACCELEROMETER:
|
||||||
|
return &aft;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* upm_lsm303agr_init_name()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void upm_lsm303agr_close(void *dev)
|
||||||
|
{
|
||||||
|
lsm303agr_close((lsm303agr_context)dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t upm_lsm303agr_get_acc_value(void *dev, float *value,
|
||||||
|
upm_acceleration_u unit)
|
||||||
|
{
|
||||||
|
if (lsm303agr_update((lsm303agr_context)dev))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
lsm303agr_get_magnetometer(dev, &x, &y, &z);
|
||||||
|
|
||||||
|
value[0] = x;
|
||||||
|
value[1] = y;
|
||||||
|
value[2] = z;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
upm_result_t upm_lsm303agr_get_mag_value(void *dev, float *value)
|
||||||
|
{
|
||||||
|
if (lsm303agr_update((lsm303agr_context)dev))
|
||||||
|
return UPM_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
lsm303agr_get_accelerometer(dev, &x, &y, &z);
|
||||||
|
|
||||||
|
value[0] = x;
|
||||||
|
value[1] = y;
|
||||||
|
value[2] = z;
|
||||||
|
|
||||||
|
return UPM_SUCCESS;
|
||||||
|
}
|
17
src/lsm303agr/pyupm_lsm303agr.i
Normal file
17
src/lsm303agr/pyupm_lsm303agr.i
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Include doxygen-generated documentation
|
||||||
|
%include "pyupm_doxy2swig.i"
|
||||||
|
%module pyupm_lsm303agr
|
||||||
|
%include "../upm.i"
|
||||||
|
%include "../upm_vectortypes.i"
|
||||||
|
|
||||||
|
%feature("autodoc", "3");
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
%include "lsm303agr_doc.i"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%include "lsm303agr_defs.h"
|
||||||
|
%include "lsm303agr.hpp"
|
||||||
|
%{
|
||||||
|
#include "lsm303agr.hpp"
|
||||||
|
%}
|
Loading…
x
Reference in New Issue
Block a user