From 5c837f22cb647413937893d7734b2b411319060b Mon Sep 17 00:00:00 2001 From: Norbert Wesp Date: Tue, 14 Feb 2017 12:03:30 +0100 Subject: [PATCH] mag3110: Added upm support for sensor MAG3110 MAG3110 is a three-axis digital magnetometer. Signed-off-by: Norbert Wesp Signed-off-by: Mihai Tudor Panu --- doxy/samples.mapping.txt | 1 + examples/c++/CMakeLists.txt | 1 + examples/c++/mag3110.cxx | 76 +++++++++ examples/python/mag3110.py | 62 +++++++ src/mag3110/CMakeLists.txt | 5 + src/mag3110/javaupm_mag3110.i | 19 +++ src/mag3110/jsupm_mag3110.i | 8 + src/mag3110/mag3110.cpp | 269 ++++++++++++++++++++++++++++++ src/mag3110/mag3110.hpp | 296 ++++++++++++++++++++++++++++++++++ src/mag3110/pyupm_mag3110.i | 15 ++ 10 files changed, 752 insertions(+) create mode 100644 examples/c++/mag3110.cxx create mode 100644 examples/python/mag3110.py create mode 100644 src/mag3110/CMakeLists.txt create mode 100644 src/mag3110/javaupm_mag3110.i create mode 100644 src/mag3110/jsupm_mag3110.i create mode 100644 src/mag3110/mag3110.cpp create mode 100644 src/mag3110/mag3110.hpp create mode 100644 src/mag3110/pyupm_mag3110.i diff --git a/doxy/samples.mapping.txt b/doxy/samples.mapping.txt index 886e58e2..15702a99 100644 --- a/doxy/samples.mapping.txt +++ b/doxy/samples.mapping.txt @@ -77,3 +77,4 @@ p9813.cxx P9813Sample.java p9813.js p9813.py tcs37727.cxx tcs37727.py tmp006.cxx tmp006.py mma8x5x.cxx mma8x5x.py +mag3110.cxx mag3110.py diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index ddc4c137..92d92425 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -337,6 +337,7 @@ add_example (mmc35240) add_example (tcs37727) add_example (tmp006) add_example (mma8x5x) +add_example (mag3110) # These are special cases where you specify example binary, source file and module(s) include_directories (${PROJECT_SOURCE_DIR}/src) diff --git a/examples/c++/mag3110.cxx b/examples/c++/mag3110.cxx new file mode 100644 index 00000000..08e775c7 --- /dev/null +++ b/examples/c++/mag3110.cxx @@ -0,0 +1,76 @@ +/* Author: Norbert Wesp + * Copyright (c) 2017 Phytec Messtechnik GmbH. + * + * 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 +#include +#include + +#include "mag3110.hpp" + +using namespace upm; + +bool run = true; + +void sig_handler(int sig) +{ + if (sig == SIGINT) + run = false; +} + +int main(int argc, char **argv) +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + upm::mag3110_data_t data; + + cout << "Initializing test-application..." << endl; + + // Instantiate an MAG3110 instance on bus 1 + upm::MAG3110 *mySensor = new upm::MAG3110(1); + + // activate periodic measurements + mySensor->setActive(); + + // update and print available values every second + while (run) + { + mySensor->getData (&data, true); + cout << "x: " << data.x << endl + << "y: " << data.y << endl + << "z: " << data.z << endl + << "Status: " << data.status << endl + << "Die temperature: " << data.dtemp << endl; + + cout << endl; + + sleep(1); + } + + cout << "Exiting test-application..." << endl; + + delete mySensor; +//! [Interesting] + + return 0; +} \ No newline at end of file diff --git a/examples/python/mag3110.py b/examples/python/mag3110.py new file mode 100644 index 00000000..8e64d4b8 --- /dev/null +++ b/examples/python/mag3110.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# Author: Norbert Wesp +# Copyright (c) 2017 Phytec Messtechnik GmbH. +# +# based on: tcs3414cs.py +# +# 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_mag3110 as MAG3110 + +def main(): + # Instantiate the Three-Axis Digital Magnetometer Sensor on I2C on bus 1 + mySensor = MAG3110.MAG3110(1) + + ## Exit handlers ## + # This stops python from printing a stacktrace when you hit control-C + def SIGINTHandler(signum, frame): + raise SystemExit + + # This lets you run code on exit, + # including functions from mySensor + def exitHandler(): + print("Exiting") + sys.exit(0) + + # Register exit handlers + atexit.register(exitHandler) + signal.signal(signal.SIGINT, SIGINTHandler) + + data = MAG3110.mag3110_data_t() + + # activate periodic measurements + mySensor.setActive(); + + # Print out the x, y, z, status and die temperature value every 0.5 seconds + while(1): + mySensor.getData(data, True) + print(data.x, data.y, data.z, hex(data.status), data.dtemp) + + time.sleep(.5) + +if __name__ == '__main__': + main() diff --git a/src/mag3110/CMakeLists.txt b/src/mag3110/CMakeLists.txt new file mode 100644 index 00000000..a9f27b49 --- /dev/null +++ b/src/mag3110/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "mag3110") +set (libdescription "Three-Axis Digital Magnetometer") +set (module_src ${libname}.cpp) +set (module_hpp ${libname}.hpp) +upm_module_init() diff --git a/src/mag3110/javaupm_mag3110.i b/src/mag3110/javaupm_mag3110.i new file mode 100644 index 00000000..109de91f --- /dev/null +++ b/src/mag3110/javaupm_mag3110.i @@ -0,0 +1,19 @@ +%module javaupm_mag3110 +%include "../upm.i" + +%{ + #include "mag3110.hpp" +%} + +%include "mag3110.hpp" + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_mag3110"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} \ No newline at end of file diff --git a/src/mag3110/jsupm_mag3110.i b/src/mag3110/jsupm_mag3110.i new file mode 100644 index 00000000..2f74981e --- /dev/null +++ b/src/mag3110/jsupm_mag3110.i @@ -0,0 +1,8 @@ +%module jsupm_mag3110 +%include "../upm.i" + +%{ + #include "mag3110.hpp" +%} + +%include "mag3110.hpp" diff --git a/src/mag3110/mag3110.cpp b/src/mag3110/mag3110.cpp new file mode 100644 index 00000000..18db6d43 --- /dev/null +++ b/src/mag3110/mag3110.cpp @@ -0,0 +1,269 @@ +/* + * Author: Norbert Wesp + * Copyright (c) 2017 Phytec Messtechnik GmbH. + * + * based on: RIOT-driver mag3110 by Johann Fischer + * + * 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 +#include +#include + +#include +#include +#include + +#include "mag3110.hpp" + +using namespace upm; + +MAG3110::MAG3110 (int bus, uint8_t dros, int devAddr) : m_i2ControlCtx(bus) { + s_data->x = 0; + s_data->y = 0; + s_data->z = 0; + s_data->status = 0; + s_data->dtemp = 0; + + uint8_t reg; + + m_name = MAG3110_NAME; + + m_controlAddr = devAddr; + m_bus = bus; + + if (dros > MAG3110_DROS_0008_128) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": given DR-OS invalid"); + } + + mraa::Result ret = m_i2ControlCtx.address(m_controlAddr); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_address() failed"); + } + + if (checkID() != 0) { + /* sensor_id does not match! maybe wrong sensor chosen? */ + throw std::invalid_argument(std::string(__FUNCTION__) + + ": checkID() failed"); + } + + /* enable automatic magnetic sensor reset */ + reg = MAG3110_CTRL_REG2_AUTO_MRST_EN; + ret = m_i2ControlCtx.writeReg(MAG3110_CTRL_REG2, reg); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_byte_data() failed"); + } + + reg = MAG3110_CTRL_REG1_DROS(dros); + ret = m_i2ControlCtx.writeReg(MAG3110_CTRL_REG1, reg); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_byte_data() failed"); + } +} + +int +MAG3110::checkID(void) +{ + uint8_t id; + + id = m_i2ControlCtx.readReg(MAG3110_DEVICE_ID_REG); + + if (id != MAG3110_DEVICE_ID) { + return -1; + } + + return 0; +} + +int +MAG3110::setUserOffset(int16_t x, int16_t y, int16_t z) +{ + mraa::Result ret; + ret = m_i2ControlCtx.writeWordReg(MAG3110_OFF_X_MSB, (uint16_t)x); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_word_data() failed"); + return -1; + } + + ret = m_i2ControlCtx.writeWordReg(MAG3110_OFF_Y_MSB, (uint16_t)y); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_word_data() failed"); + return -1; + } + + ret = m_i2ControlCtx.writeWordReg(MAG3110_OFF_Z_MSB, (uint16_t)z); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_word_data() failed"); + return -1; + } + + return 0; +} + +int +MAG3110::setActive(void) +{ + uint8_t reg; + + reg = m_i2ControlCtx.readReg(MAG3110_CTRL_REG1); + + reg |= MAG3110_CTRL_REG1_AC; + + mraa::Result ret = m_i2ControlCtx.writeReg(MAG3110_CTRL_REG1, reg); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_byte_data() failed"); + return -1; + } + + return 0; +} + +int +MAG3110::setStandby(void) +{ + uint8_t reg; + + reg = m_i2ControlCtx.readReg(MAG3110_CTRL_REG1); + + reg &= ~MAG3110_CTRL_REG1_AC; + + mraa::Result ret = m_i2ControlCtx.writeReg(MAG3110_CTRL_REG1, reg); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write_byte_data() failed"); + return -1; + } + + return 0; +} + +int +MAG3110::isReady(void) +{ + uint8_t reg; + + reg = m_i2ControlCtx.readReg(MAG3110_DR_STATUS); + + return (int)(reg & MAG3110_DR_STATUS_ZYXDR); +} + +int +MAG3110::sampleData(void) +{ + uint8_t buf[7]; + uint8_t dtemp; + int re = 0; + + re = m_i2ControlCtx.readBytesReg(MAG3110_DR_STATUS, buf, 7); + if (re != 7) { + /* did not read enough bytes */ + return -1; + } + + s_data->status = buf[0]; + s_data->x = ((int16_t)buf[1] << 8) | buf[2]; + s_data->y = ((int16_t)buf[3] << 8) | buf[4]; + s_data->z = ((int16_t)buf[5] << 8) | buf[6]; + + dtemp = m_i2ControlCtx.readReg(MAG3110_DIE_TEMP); + + s_data->dtemp = dtemp; + + return 0; +} + +int16_t +MAG3110::getX(int bSampleData) +{ + if (bSampleData) { + if (sampleData() != 0) { + /* error in read values from reg */ + return -999; + } + } + + return s_data->x; +} + +int16_t +MAG3110::getY(int bSampleData) +{ + if (bSampleData) { + if (sampleData() != 0) { + /* error in read values from reg */ + return -999; + } + } + + return s_data->y; +} + +int16_t +MAG3110::getZ(int bSampleData) +{ + if (bSampleData) { + if (sampleData() != 0) { + /* error in read values from reg */ + return -999; + } + } + + return s_data->z; +} + +uint8_t +MAG3110::getStatus(void) +{ + return s_data->status; +} + +int8_t +MAG3110::getDieTemperature(void) +{ + return s_data->dtemp; +} + +int +MAG3110::getData(mag3110_data_t* data, int bSampleData) +{ + if (bSampleData) { + if (sampleData() != 0) { + /* error in read values from reg */ + return -1; + } + } + + data->x = s_data->x; + data->y = s_data->y; + data->z = s_data->z; + data->status = s_data->status; + data->dtemp = s_data->dtemp; + + return 0; +} diff --git a/src/mag3110/mag3110.hpp b/src/mag3110/mag3110.hpp new file mode 100644 index 00000000..fd9c3068 --- /dev/null +++ b/src/mag3110/mag3110.hpp @@ -0,0 +1,296 @@ +/* + * Author: Norbert Wesp + * Copyright (c) 2017 Phytec Messtechnik GmbH. + * + * based on: RIOT-driver mag3110 by Johann Fischer + * + * 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 +#include +#include +#include + +#define MAG3110_NAME "MAG3110" +#define MAG3110_I2C_ADDRESS 0x0E +#define MAG3110_DEVICE_ID 0xC4 +#define MAG3110_DEVICE_ID_REG 0x07 + +/* MAG3110 Register Map */ +#define MAG3110_DR_STATUS 0x00 /**< Data ready status per axis */ +#define MAG3110_OUT_X_MSB 0x01 /**< Bits [15:8] of X measurement */ +#define MAG3110_OUT_X_LSB 0x02 /**< Bits [7:0] of X measurement */ +#define MAG3110_OUT_Y_MSB 0x03 /**< Bits [15:8] of Y measurement */ +#define MAG3110_OUT_Y_LSB 0x04 /**< Bits [7:0] of Y measurement */ +#define MAG3110_OUT_Z_MSB 0x05 /**< Bits [15:8] of Z measurement */ +#define MAG3110_OUT_Z_LSB 0x06 /**< Bits [7:0] of Z measurement */ +#define MAG3110_SYSMOD 0x08 /**< FIFO Status Register */ +#define MAG3110_OFF_X_MSB 0x09 /**< Bits [15:8] of user X offset */ +#define MAG3110_OFF_X_LSB 0x0A /**< Bits [7:0] of user X offset */ +#define MAG3110_OFF_Y_MSB 0x0B /**< Bits [15:8] of user Y offset */ +#define MAG3110_OFF_Y_LSB 0x0C /**< Bits [7:0] of user Y offset */ +#define MAG3110_OFF_Z_MSB 0x0D /**< Bits [15:8] of user Z offset */ +#define MAG3110_OFF_Z_LSB 0x0E /**< Bits [7:0] of user Z offset */ +#define MAG3110_DIE_TEMP 0x0F /**< Temperature, signed 8 bits */ +#define MAG3110_CTRL_REG1 0x10 /**< Operation modes */ +#define MAG3110_CTRL_REG2 0x11 /**< Operation modes */ + +/* MAG3110 DR-STATUS Register */ +#define MAG3110_DR_STATUS_ZYXOW (1 << 7) +#define MAG3110_DR_STATUS_ZOW (1 << 6) +#define MAG3110_DR_STATUS_YOW (1 << 5) +#define MAG3110_DR_STATUS_XOW (1 << 4) +#define MAG3110_DR_STATUS_ZYXDR (1 << 3) +#define MAG3110_DR_STATUS_ZDR (1 << 2) +#define MAG3110_DR_STATUS_YDR (1 << 1) +#define MAG3110_DR_STATUS_XDR (1 << 0) + +/* MAG3110 SYSMOD Register */ +#define MAG3110_SYSMOD_STANDBY 0 +#define MAG3110_SYSMOD_ACTIVE_RAW 1 +#define MAG3110_SYSMOD_ACTIVE 2 + +/* MAG3110 Control Register 1 */ +#define MAG3110_CTRL_REG1_DROS_SHIFT 3 +#define MAG3110_CTRL_REG1_DROS_MASK 0xF8 +#define MAG3110_CTRL_REG1_DROS(x) (((uint8_t)(((uint8_t)(x))<<\ + MAG3110_CTRL_REG1_DROS_SHIFT))\ + &MAG3110_CTRL_REG1_DROS_MASK) +#define MAG3110_CTRL_REG1_FR (1 << 2) +#define MAG3110_CTRL_REG1_TM (1 << 1) +#define MAG3110_CTRL_REG1_AC (1 << 0) + +/* MAG3110 Control Register 2 */ +#define MAG3110_CTRL_REG2_AUTO_MRST_EN (1 << 7) +#define MAG3110_CTRL_REG2_RAW (1 << 5) +#define MAG3110_CTRL_REG2_MAG_RST (1 << 4) + +/* MAG3110 Output Rate (DR) and Over Sample (OS) Ratio for CTRL_REG1 */ +#define MAG3110_DROS_8000_16 0 /* DR 80 Hz, OS Ratio 16 */ +#define MAG3110_DROS_4000_32 1 /* DR 40 Hz, OS Ratio 32 */ +#define MAG3110_DROS_2000_64 2 /* DR 20 Hz, OS Ratio 64 */ +#define MAG3110_DROS_1000_128 3 /* DR 10 Hz, OS Ratio 128 */ +#define MAG3110_DROS_4000_16 4 /* DR 40 Hz, OS Ratio 16 */ +#define MAG3110_DROS_2000_32 5 /* DR 20 Hz, OS Ratio 32 */ +#define MAG3110_DROS_1000_64 6 /* DR 10 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0500_128 7 /* DR 5 Hz, OS Ratio 128 */ +#define MAG3110_DROS_2000_16 8 /* DR 20 Hz, OS Ratio 16 */ +#define MAG3110_DROS_1000_32 9 /* DR 10 Hz, OS Ratio 32 */ +#define MAG3110_DROS_0500_64 10 /* DR 5 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0250_128 11 /* DR 2.5 Hz, OS Ratio 128 */ +#define MAG3110_DROS_1000_16 12 /* DR 10 Hz, OS Ratio 16 */ +#define MAG3110_DROS_0500_32 13 /* DR 5 Hz, OS Ratio 32 */ +#define MAG3110_DROS_0250_64 14 /* DR 2.5 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0125_128 15 /* DR 1.25 Hz, OS Ratio 128 */ +#define MAG3110_DROS_0500_16 16 /* DR 5 Hz, OS Ratio 16 */ +#define MAG3110_DROS_0250_32 17 /* DR 2.5 Hz, OS Ratio 32 */ +#define MAG3110_DROS_0125_64 18 /* DR 1.25 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0063_128 19 /* DR 0.63 Hz, OS Ratio 128 */ +#define MAG3110_DROS_0250_16 20 /* DR 2.5 Hz, OS Ratio 16 */ +#define MAG3110_DROS_0125_32 21 /* DR 1.25 Hz, OS Ratio 32 */ +#define MAG3110_DROS_0063_64 22 /* DR 0.63 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0031_128 23 /* DR 0.31 Hz, OS Ratio 128 */ +#define MAG3110_DROS_0125_16 24 /* DR 1.25 Hz, OS Ratio 16 */ +#define MAG3110_DROS_0063_32 25 /* DR 0.63 Hz, OS Ratio 32 */ +#define MAG3110_DROS_0031_64 26 /* DR 0.31 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0016_128 27 /* DR 0.16 Hz, OS Ratio 128 */ +#define MAG3110_DROS_0063_16 28 /* DR 0.63 Hz, OS Ratio 16 */ +#define MAG3110_DROS_0031_32 29 /* DR 0.31 Hz, OS Ratio 32 */ +#define MAG3110_DROS_0016_64 30 /* DR 0.16 Hz, OS Ratio 64 */ +#define MAG3110_DROS_0008_128 31 /* DR 0.08 Hz, OS Ratio 128 */ +#define MAG3110_DROS_DEFAULT MAG3110_DROS_0125_128 + /* Default Setting for testing*/ + +namespace upm { + +typedef struct { + int16_t x; + int16_t y; + int16_t z; + uint8_t status; + int8_t dtemp; +} mag3110_data_t; + +/** + * @brief MAG3110 Three-Axis Digital Magnetometer + * @defgroup mag3110 libupm-mag3110 + * @ingroup freescale i2c accelerometer compass + */ + +/** + * @library mag3110 + * @sensor mag3110 + * @comname MAG3110 Three-Axis Digital Magnetometer + * @type accelerometer compass + * @man freescale + * @web http://www.nxp.com/assets/documents/data/en/data-sheets/MAG3110.pdf + * @con i2c + * + * @brief API for the MAG3110 Three-Axis Digital Magnetometer + * + * Description in web-link above: + * The MAG3110 is a small, low-power digital 3D magnetic sensor with a wide + * dynamic range to allow operation in PCBs with high extraneous magnetic + * fields. + * It measures the components of the local magnetic field, the sum of the + * geomagnetic field and the magnetic field created by components on the + * circuit board. + * It can be used in conjunction with a 3-axis accelerometer so that + * orientation-independent accurate compass heading information may be achieved + * It is capable of measuring local magnetic fields up to 10 Gauss with output + * data rates up to 80 Hz. + * + * @snippet mag3110.cxx Interesting + */ +class MAG3110 { + public: + /** + * + * Instantiates an MAG3110 object + * + * @param bus Number of the used bus + * @param dros Data rate and over sampling selection + * @param devAddr Address of the used I2C device + */ + MAG3110 (int bus, uint8_t dros=MAG3110_DROS_DEFAULT, + int devAddr=MAG3110_I2C_ADDRESS); + + /** + * Check device_id of sensor + * + * @return 0 on success + * -1 on error + */ + int checkID(void); + + /** + * Set user offset correction + * Offset correction register will be erased after accelerometer reset + * + * @param x Offset correction value for x-axis + * @param y Offset correction value for y-axis + * @param z Offset correction value for z-axis + * + * @return 0 on success + * -1 on error + */ + int setUserOffset(int16_t x, int16_t y, int16_t z); + + /** + * Set active mode, this enables periodic measurements + * + * @return 0 on success + * -1 on error + */ + int setActive(void); + + /** + * Set standby mode, this disables periodic measurements + * + * @return 0 on success + * -1 on error + */ + int setStandby(void); + + /** + * Check for new set of measurement data. + * + * @return >0 if x-, y- and z-axis new sample is ready + * 0 if measurement is in progress + */ + int isReady(void); + + /** + * Read magnetometer's data and saves them to variables + * + * Info: To get the actual values for the magnetic field someone + * has to divide the returned values from the magnetometer by 10 + * + * @return 0 on success + * -1 on error + */ + int sampleData(void); + + /** + * Get x-axis magnetic field strength + * + * @param bSampleData Flag to read sensor + * @return The x-axis magnetic field strength on success + * -999 on error + */ + int16_t getX(int bSampleData = 0); + + /** + * Get y-axis magnetic field strength + * + * @param bSampleData Flag to read sensor + * @return The y-axis magnetic field strength on success + * -999 on error + */ + int16_t getY(int bSampleData = 0); + + /** + * Get z-axis magnetic field strength + * + * @param bSampleData Flag to read sensor + * @return The z-axis magnetic field strength on success + * -999 on error + */ + int16_t getZ(int bSampleData = 0); + + /** + * Get value of status register + * + * @return Value of status register + */ + uint8_t getStatus(void); + + /** + * Get die temperature + * + * @return Die temperature + */ + int8_t getDieTemperature(void); + + /** + * Get sensor values + * + * @param data Sensor values + * @param bSampleData Flag to read sensor + * @return 0 on success + * -1 on error + */ + int getData(mag3110_data_t* data, int bSampleData = 0); + + private: + + std::string m_name; + + int m_controlAddr; + int m_bus; + mraa::I2c m_i2ControlCtx; + + mag3110_data_t s_data[1]; +}; + +} diff --git a/src/mag3110/pyupm_mag3110.i b/src/mag3110/pyupm_mag3110.i new file mode 100644 index 00000000..f1255454 --- /dev/null +++ b/src/mag3110/pyupm_mag3110.i @@ -0,0 +1,15 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_mag3110 +%include "../upm.i" + +%feature("autodoc", "3"); + +#ifdef DOXYGEN +%include "mag3110_doc.i" +#endif + +%include "mag3110.hpp" +%{ + #include "mag3110.hpp" +%}