diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 1bda4f58..6c23738b 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -151,6 +151,7 @@ add_executable (xbee-example xbee.cxx) add_executable (urm37-example urm37.cxx) add_executable (urm37-uart-example urm37-uart.cxx) add_executable (adxrs610-example adxrs610.cxx) +add_executable (bma220-example bma220.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -266,6 +267,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/micsv89) include_directories (${PROJECT_SOURCE_DIR}/src/xbee) include_directories (${PROJECT_SOURCE_DIR}/src/urm37) include_directories (${PROJECT_SOURCE_DIR}/src/adxrs610) +include_directories (${PROJECT_SOURCE_DIR}/src/bma220) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -418,3 +420,4 @@ target_link_libraries (xbee-example xbee ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (urm37-example urm37 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (urm37-uart-example urm37 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (adxrs610-example adxrs610 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (bma220-example bma220 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/bma220.cxx b/examples/c++/bma220.cxx new file mode 100644 index 00000000..a41b81ad --- /dev/null +++ b/examples/c++/bma220.cxx @@ -0,0 +1,70 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * 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 "bma220.h" + +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 BMA220 using default parameters (bus 0, addr 0x0a) + upm::BMA220 *sensor = new upm::BMA220(); + + // Output data every half second until interrupted + while (shouldRun) + { + sensor->update(); + + float x, y, z; + + sensor->getAccelerometer(&x, &y, &z); + cout << "Accelerometer: "; + cout << "AX: " << x << " AY: " << y << " AZ: " << z << endl; + + usleep(500000); + } + +//! [Interesting] + + cout << "Exiting..." << endl; + + delete sensor; + + return 0; +} diff --git a/examples/javascript/bma220.js b/examples/javascript/bma220.js new file mode 100644 index 00000000..bc267def --- /dev/null +++ b/examples/javascript/bma220.js @@ -0,0 +1,59 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ + +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * 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_bma220'); + +// Instantiate an BMA220 using default parameters (bus 0, addr 0x0a) +var sensor = new sensorObj.BMA220(); + +var x = new sensorObj.new_floatp(); +var y = new sensorObj.new_floatp(); +var z = new sensorObj.new_floatp(); + +// Output data every half second until interrupted +setInterval(function() +{ + sensor.update(); + + sensor.getAccelerometer(x, y, z); + console.log("Accelerometer: AX: " + sensorObj.floatp_value(x) + + " AY: " + sensorObj.floatp_value(y) + + " AZ: " + sensorObj.floatp_value(z)); + +}, 500); + +// exit on ^C +process.on('SIGINT', function() +{ + sensor = null; + sensorObj.cleanUp(); + sensorObj = null; + console.log("Exiting."); + process.exit(0); +}); + diff --git a/examples/python/bma220.py b/examples/python/bma220.py new file mode 100644 index 00000000..9db6cdfd --- /dev/null +++ b/examples/python/bma220.py @@ -0,0 +1,55 @@ +#!/usr/bin/python +# Author: Jon Trulson +# Copyright (c) 2015 Intel Corporation. +# +# 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 time, sys, signal, atexit +import pyupm_bma220 as sensorObj + +# Instantiate an BMA220 using default parameters (bus 0, addr 0x0a) +sensor = sensorObj.BMA220() + +## 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) + +x = sensorObj.new_floatp() +y = sensorObj.new_floatp() +z = sensorObj.new_floatp() + +while (1): + sensor.update() + sensor.getAccelerometer(x, y, z) + print "Accelerometer: AX:", sensorObj.floatp_value(x), + print " AY:", sensorObj.floatp_value(y), + print " AZ:", sensorObj.floatp_value(z) + + time.sleep(.5) diff --git a/src/bma220/CMakeLists.txt b/src/bma220/CMakeLists.txt new file mode 100644 index 00000000..fcea4bbe --- /dev/null +++ b/src/bma220/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "bma220") +set (libdescription "accelerometer sensor based on bma220") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/bma220/bma220.cxx b/src/bma220/bma220.cxx new file mode 100644 index 00000000..74c78238 --- /dev/null +++ b/src/bma220/bma220.cxx @@ -0,0 +1,523 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * 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 "bma220.h" + +using namespace upm; +using namespace std; + + +BMA220::BMA220(int bus, uint8_t addr) : + m_i2c(bus), m_gpioIntr(0) +{ + m_addr = addr; + + m_accelX = 0.0; + m_accelY = 0.0; + m_accelZ = 0.0; + + m_accelScale = 0.0; + + mraa::Result rv; + if ( (rv = m_i2c.address(m_addr)) != mraa::SUCCESS) + { + throw std::runtime_error(string(__FUNCTION__) + + ": I2c.address() failed"); + return; + } + + // Init the accelerometer + enableAxes(true, true, true); + + // set scaling rate + if (!setAccelerometerScale(FSL_RANGE_2G)) + { + throw std::runtime_error(string(__FUNCTION__) + + ": Unable to set accel scale"); + return; + } +} + +BMA220::~BMA220() +{ + uninstallISR(); +} + +void BMA220::update() +{ + updateAccelerometer(); +} + +void BMA220::updateAccelerometer() +{ + int x, y, z; + char buf = 0; + + buf = (char)readReg(REG_ACC_X); + x = int(buf) / 4; + + buf = (char)readReg(REG_ACC_Y); + y = int(buf) / 4; + + buf = (char)readReg(REG_ACC_Z); + z = int(buf) / 4; + + m_accelX = float(x); + m_accelY = float(y); + m_accelZ = float(z); +} + +uint8_t BMA220::readReg(uint8_t reg) +{ + return m_i2c.readReg(reg); +} + +bool BMA220::writeReg(uint8_t reg, uint8_t val) +{ + mraa::Result rv; + if ((rv = m_i2c.writeReg(reg, val)) != mraa::SUCCESS) + { + throw std::runtime_error(std::string(__FUNCTION__) + + ": I2c.writeReg() failed"); + return false; + } + + return true; +} + +bool BMA220::setAccelerometerScale(FSL_RANGE_T scale) +{ + uint8_t reg = readReg(REG_SBIST_FSL_CONFIG); + + reg &= ~(_REG_SBIST_FSL_RANGE_MASK << _REG_SBIST_FSL_RANGE_SHIFT); + + reg |= (scale << _REG_SBIST_FSL_RANGE_SHIFT); + + if (!writeReg(REG_SBIST_FSL_CONFIG, reg)) + { + return false; + } + + // store scaling factor + + switch (scale) + { + case FSL_RANGE_2G: + m_accelScale = 16.0; + break; + + case FSL_RANGE_4G: + m_accelScale = 8.0; + break; + + case FSL_RANGE_8G: + m_accelScale = 4.0; + break; + + case FSL_RANGE_16G: + m_accelScale = 2.0; + break; + + default: // should never occur, but... + m_accelScale = 0.0; // set a safe, though incorrect value + throw std::logic_error(string(__FUNCTION__) + + ": internal error, unsupported scale"); + break; + } + + return true; +} + +void BMA220::getAccelerometer(float *x, float *y, float *z) +{ + if (x) + *x = m_accelX / m_accelScale; + + if (y) + *y = m_accelY / m_accelScale; + + if (z) + *z = m_accelZ / m_accelScale; +} + +#ifdef JAVACALLBACK +float *BMA220::getAccelerometer() +{ + float *v = new float[3]; + getAccelerometer(&v[0], &v[1], &v[2]); + return v; +} +#endif + +uint8_t BMA220::getChipID() +{ + return readReg(REG_CHIPID); +} + +uint8_t BMA220::getChipRevision() +{ + return readReg(REG_REVISIONID); +} + +bool BMA220::setFilterConfig(FILTER_CONFIG_T filter) +{ + uint8_t reg = readReg(REG_FILTER_CONFIG); + + reg &= ~(_FILTER_CONFIG_FILTER_MASK << _FILTER_CONFIG_FILTER_SHIFT); + + reg |= (filter << _FILTER_CONFIG_FILTER_SHIFT); + + return writeReg(REG_FILTER_CONFIG, reg); +} + +bool BMA220::setSerialHighBW(bool high) +{ + uint8_t reg = readReg(REG_FILTER_CONFIG); + + if (high) + reg |= FILTER_CONFIG_SERIAL_HIGH_BW; + else + reg &= ~FILTER_CONFIG_SERIAL_HIGH_BW; + + return writeReg(REG_FILTER_CONFIG, reg); +} + +bool BMA220::enableAxes(bool xEn, bool yEn, bool zEn) +{ + uint8_t reg = readReg(REG_ENABLE_CONFIG3); + + if (xEn) + reg |= ENABLE_CONFIG3_X_CHAN; + else + reg &= ~ENABLE_CONFIG3_X_CHAN; + + if (yEn) + reg |= ENABLE_CONFIG3_Y_CHAN; + else + reg &= ~ENABLE_CONFIG3_Y_CHAN; + + if (zEn) + reg |= ENABLE_CONFIG3_Z_CHAN; + else + reg &= ~ENABLE_CONFIG3_Z_CHAN; + + return writeReg(REG_ENABLE_CONFIG3, reg); +} + +uint8_t BMA220::suspend() +{ + return readReg(REG_SUSPEND); +} + +uint8_t BMA220::softReset() +{ + return readReg(REG_SOFTRESET); +} + +bool BMA220::sleep(bool enable) +{ + uint8_t reg = readReg(REG_ENABLE_CONFIG3); + + if (enable) + reg |= ENABLE_CONFIG3_SLEEP_EN; + else + reg &= ~ENABLE_CONFIG3_SLEEP_EN; + + return writeReg(REG_ENABLE_CONFIG3, reg); +} + +bool BMA220::setSleepDuration(SLEEP_DUR_T dur) +{ + uint8_t reg = readReg(REG_ENABLE_CONFIG3); + + reg &= ~(_ENABLE_CONFIG3_SLEEP_DUR_MASK << _ENABLE_CONFIG3_SLEEP_DUR_SHIFT); + + reg |= (dur << _ENABLE_CONFIG3_SLEEP_DUR_SHIFT); + + return writeReg(REG_ENABLE_CONFIG3, reg); +} + +bool BMA220::setLowGThreshold(uint8_t thresh) +{ + uint8_t reg = readReg(REG_THRESHOLD); + + thresh &= 0x0f; + + reg &= ~(_THRESHOLD_LOW_MASK << _THRESHOLD_LOW_SHIFT); + + reg |= (thresh << _THRESHOLD_LOW_SHIFT); + + return writeReg(REG_THRESHOLD, reg); +} + +bool BMA220::setHighGThreshold(uint8_t thresh) +{ + uint8_t reg = readReg(REG_THRESHOLD); + + thresh &= 0x0f; + + reg &= ~(_THRESHOLD_HIGH_MASK << _THRESHOLD_HIGH_SHIFT); + + reg |= (thresh << _THRESHOLD_HIGH_SHIFT); + + return writeReg(REG_THRESHOLD, reg); +} + +bool BMA220::setLowGHysteresis(uint8_t hyst) +{ + uint8_t reg = readReg(REG_L_HYST_DUR); + + hyst &= _L_HYST_DUR_LOW_HY_MASK; + + reg &= ~(_L_HYST_DUR_LOW_HY_MASK << _L_HYST_DUR_LOW_HY_SHIFT); + + reg |= (hyst << _L_HYST_DUR_LOW_HY_SHIFT); + + return writeReg(REG_L_HYST_DUR, reg); +} + +bool BMA220::setLowGDuration(uint8_t dur) +{ + uint8_t reg = readReg(REG_L_HYST_DUR); + + dur &= _L_HYST_DUR_LOW_DUR_MASK; + + reg &= ~(_L_HYST_DUR_LOW_DUR_MASK << _L_HYST_DUR_LOW_DUR_SHIFT); + + reg |= (dur << _L_HYST_DUR_LOW_DUR_SHIFT); + + return writeReg(REG_L_HYST_DUR, reg); +} + +bool BMA220::setHighGHysteresis(uint8_t hyst) +{ + uint8_t reg = readReg(REG_H_HYST_DUR); + + hyst &= _H_HYST_DUR_HIGH_HY_MASK; + + reg &= ~(_H_HYST_DUR_HIGH_HY_MASK << _H_HYST_DUR_HIGH_HY_SHIFT); + + reg |= (hyst << _H_HYST_DUR_HIGH_HY_SHIFT); + + return writeReg(REG_H_HYST_DUR, reg); +} + +bool BMA220::setHighGDuration(uint8_t dur) +{ + uint8_t reg = readReg(REG_H_HYST_DUR); + + dur &= _H_HYST_DUR_HIGH_DUR_MASK; + + reg &= ~(_H_HYST_DUR_HIGH_DUR_MASK << _H_HYST_DUR_HIGH_DUR_SHIFT); + + reg |= (dur << _H_HYST_DUR_HIGH_DUR_SHIFT); + + return writeReg(REG_H_HYST_DUR, reg); +} + +bool BMA220::setTapDuration(uint8_t dur) +{ + uint8_t reg = readReg(REG_TAP_CONFIG); + + dur &= _TAP_CONFIG_DUR_MASK; + + reg &= ~(_TAP_CONFIG_DUR_MASK << _TAP_CONFIG_DUR_SHIFT); + + reg |= (dur << _TAP_CONFIG_DUR_SHIFT); + + return writeReg(REG_TAP_CONFIG, reg); +} + +bool BMA220::setTapThreshold(uint8_t thresh) +{ + uint8_t reg = readReg(REG_TAP_CONFIG); + + thresh &= _TAP_CONFIG_THRESH_MASK; + + reg &= ~(_TAP_CONFIG_THRESH_MASK << _TAP_CONFIG_THRESH_SHIFT); + + reg |= (thresh << _TAP_CONFIG_THRESH_SHIFT); + + return writeReg(REG_TAP_CONFIG, reg); +} + +bool BMA220::enableTapFilter(bool filt) +{ + uint8_t reg = readReg(REG_TAP_CONFIG); + + if (filt) + reg |= TAP_CONFIG_FILTER; + else + reg &= ~TAP_CONFIG_FILTER; + + return writeReg(REG_TAP_CONFIG, reg); +} + +bool BMA220::setSlopeDuration(uint8_t dur) +{ + uint8_t reg = readReg(REG_SLOPE_CONFIG); + + dur &= _SLOPE_CONFIG_DUR_MASK; + + reg &= ~(_SLOPE_CONFIG_DUR_MASK << _SLOPE_CONFIG_DUR_SHIFT); + + reg |= (dur << _SLOPE_CONFIG_DUR_SHIFT); + + return writeReg(REG_SLOPE_CONFIG, reg); +} + +bool BMA220::setSlopeThreshold(uint8_t thresh) +{ + uint8_t reg = readReg(REG_SLOPE_CONFIG); + + thresh &= _SLOPE_CONFIG_THRESH_MASK; + + reg &= ~(_SLOPE_CONFIG_THRESH_MASK << _SLOPE_CONFIG_THRESH_SHIFT); + + reg |= (thresh << _SLOPE_CONFIG_THRESH_SHIFT); + + return writeReg(REG_SLOPE_CONFIG, reg); +} + +bool BMA220::enableSlopeFilter(bool filt) +{ + uint8_t reg = readReg(REG_SLOPE_CONFIG); + + if (filt) + reg |= SLOPE_CONFIG_FILTER; + else + reg &= ~SLOPE_CONFIG_FILTER; + + return writeReg(REG_SLOPE_CONFIG, reg); +} + +uint8_t BMA220::getInterruptStatus1() +{ + return (readReg(REG_INT_STATUS1) & 0x8f); +} + +BMA220::CONFIG_ORIENT_T BMA220::getOrient() +{ + uint8_t reg = readReg(REG_INT_STATUS2); + + reg &= (_INT_STATUS1_ORIENT_MASK << _INT_STATUS1_ORIENT_SHIFT); + + reg >>= _INT_STATUS1_ORIENT_SHIFT; + + return (CONFIG_ORIENT_T)reg; +} + +uint8_t BMA220::getInterruptStatus2() +{ + return (readReg(REG_INT_STATUS2) & 0x1f); +} + +bool BMA220::setInterruptEnables1(uint8_t bits) +{ + return writeReg(REG_ENABLE_CONFIG, bits); +} + +uint8_t BMA220::getInterruptEnables1() +{ + return readReg(REG_ENABLE_CONFIG); +} + +bool BMA220::setInterruptEnables2(uint8_t bits) +{ + uint8_t reg = readReg(REG_ENABLE_CONFIG2); + + // only the first 4 bits... + bits &= 0x0f; + reg &= 0x0f; + + reg |= bits; + + return writeReg(REG_ENABLE_CONFIG2, reg); +} + +uint8_t BMA220::getInterruptEnables2() +{ + return (readReg(REG_ENABLE_CONFIG2) & 0x0f); +} + +bool BMA220::setInterruptLatch(CONFIG2_LAT_T lat) +{ + uint8_t reg = readReg(REG_ENABLE_CONFIG2); + + reg &= ~(_ENABLE_CONFIG2_LAT_INT_MASK << _ENABLE_CONFIG2_LAT_INT_SHIFT); + + reg |= (lat << _ENABLE_CONFIG2_LAT_INT_SHIFT); + + return writeReg(REG_ENABLE_CONFIG2, reg); +} + +bool BMA220::resetInterrupts() +{ + // This resets the interrupt controller, and should be called + // whenever the interrupt configuration changes + uint8_t reg = readReg(REG_ENABLE_CONFIG2); + + reg |= ENABLE_CONFIG2_RESET_INT; + + return writeReg(REG_ENABLE_CONFIG2, reg); +} + +#ifdef SWIGJAVA +void BMA220::installISR(int gpio, mraa::Edge level, + IsrCallback *cb) +{ + installISR(gpio, level, generic_callback_isr, cb); +} +#endif + +void BMA220::installISR(int gpio, mraa::Edge level, + void (*isr)(void *), void *arg) +{ + // delete any existing ISR and GPIO context + uninstallISR(); + + // create gpio context + m_gpioIntr = new mraa::Gpio(gpio); + + m_gpioIntr->dir(mraa::DIR_IN); + m_gpioIntr->isr(level, isr, arg); +} + +void BMA220::uninstallISR() +{ + if (m_gpioIntr) + { + m_gpioIntr->isrExit(); + delete m_gpioIntr; + + m_gpioIntr = 0; + } +} + diff --git a/src/bma220/bma220.h b/src/bma220/bma220.h new file mode 100644 index 00000000..aac45028 --- /dev/null +++ b/src/bma220/bma220.h @@ -0,0 +1,834 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * 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 + +#if defined(SWIGJAVA) || defined(JAVACALLBACK) +#include "../IsrCallback.h" +#endif + +#define BMA220_I2C_BUS 0 +#define BMA220_DEFAULT_ADDR 0x0a + +namespace upm { + + /** + * @brief BMA220 Accelerometer library + * @defgroup bma220 libupm-bma220 + * @ingroup i2c gpio accelerometer + */ + + /** + * @library bma220 + * @sensor bma220 + * @comname BMA220 3-axis Accelerometer + * @type accelerometer + * @man dfrobot + * @con i2c gpio + * @web http://www.dfrobot.com/index.php?route=product/product&product_id=1085 + * + * @brief API for the BMA220 3-axis Accelerometer + * + * The BMA220 is a low cost, very small 3-axis accelerometer with 6 + * bits of resolution. It can also detect orientation and tap events. + * + * The BMA220 has a linear acceleration full scale of + * 2g/4g/8g/16g. + * + * While not all of the functionality of this device is supported + * initially, methods and register definitions are provided that + * should allow an end user to implement whatever features are + * required. + * + * This driver was developed on a DFRobot BMA (Tiny). + * + * @snippet bma220.cxx Interesting + */ + + class BMA220 { + public: + + // NOTE: reserved registers must not be written into or read from. + // Reserved bitfields must always be 0. The registers aren't + // named in the datasheet, so I made up some hopefully useful + // names for them. The whole I2C register map design is a little + // strange, IMO. + + /** + * BMA220 Accelerometer registers + */ + typedef enum { + REG_CHIPID = 0x00, + REG_REVISIONID = 0x02, + + // 2 lsb bits of ACC regs are always 0, yeilding 6 bits resolution + REG_ACC_X = 0x04, // acceleration data + REG_ACC_Y = 0x06, + REG_ACC_Z = 0x08, + + REG_H_HYST_DUR = 0x0a, // high hysteresis/dur + REG_THRESHOLD = 0x0c, // high/low threshold + REG_L_HYST_DUR = 0x0e, // low hysteresis/dur + + REG_TAP_CONFIG = 0x10, + + REG_SLOPE_CONFIG = 0x12, + REG_TAP_CONFIG2 = 0x14, + + REG_INT_STATUS1 = 0x16, + REG_INT_STATUS2 = 0x18, + + REG_ENABLE_CONFIG = 0x1a, + REG_ENABLE_CONFIG2 = 0x1c, + REG_ENABLE_CONFIG3 = 0x1e, + + REG_FILTER_CONFIG = 0x20, + + REG_SBIST_FSL_CONFIG = 0x22, // self test and full scale range + + // 0x24 - 0x2c reserved + + REG_I2C_WATCHDOG = 0x2e, // + SPI 3-wire mode + + REG_SUSPEND = 0x30, + REG_SOFTRESET = 0x32 + } REG_T; + + + /** + * REG_H_HYST_DUR bits + */ + typedef enum { + H_HYST_DUR_HIGH_DUR0 = 0x01, + H_HYST_DUR_HIGH_DUR1 = 0x02, + H_HYST_DUR_HIGH_DUR2 = 0x04, + H_HYST_DUR_HIGH_DUR3 = 0x08, + H_HYST_DUR_HIGH_DUR4 = 0x10, + H_HYST_DUR_HIGH_DUR5 = 0x20, + _H_HYST_DUR_HIGH_DUR_MASK = 63, + _H_HYST_DUR_HIGH_DUR_SHIFT = 0, + + H_HYST_DUR_HIGH_HY1 = 0x40, + H_HYST_DUR_HIGH_HY2 = 0x80, + _H_HYST_DUR_HIGH_HY_MASK = 3, + _H_HYST_DUR_HIGH_HY_SHIFT = 6 + } H_HYST_DUR_HIGH_BITS_T; + + /** + * REG_THRESHOLD bits + */ + typedef enum { + THRESHOLD_HIGH0 = 0x01, + THRESHOLD_HIGH1 = 0x02, + THRESHOLD_HIGH2 = 0x04, + THRESHOLD_HIGH3 = 0x08, + _THRESHOLD_HIGH_MASK = 15, + _THRESHOLD_HIGH_SHIFT = 0, + + THRESHOLD_LOW0 = 0x10, + THRESHOLD_LOW1 = 0x20, + THRESHOLD_LOW2 = 0x40, + THRESHOLD_LOW3 = 0x80, + _THRESHOLD_LOW_MASK = 15, + _THRESHOLD_LOW_SHIFT = 4 + } THRESHOLD_BITS_T; + + /** + * REG_L_HYST_DUR bits + */ + typedef enum { + L_HYST_DUR_LOW_DUR0 = 0x01, + L_HYST_DUR_LOW_DUR1 = 0x02, + L_HYST_DUR_LOW_DUR2 = 0x04, + L_HYST_DUR_LOW_DUR3 = 0x08, + L_HYST_DUR_LOW_DUR4 = 0x10, + L_HYST_DUR_LOW_DUR5 = 0x20, + _L_HYST_DUR_LOW_DUR_MASK = 63, + _L_HYST_DUR_LOW_DUR_SHIFT = 0, + + L_HYST_DUR_LOW_HY1 = 0x40, + L_HYST_DUR_LOW_HY2 = 0x80, + _L_HYST_DUR_LOW_HY_MASK = 3, + _L_HYST_DUR_LOW_HY_SHIFT = 6 + } L_HYST_DUR_LOW_BITS_T; + + /** + * REG_TAP_CONFIG bits + */ + typedef enum { + TAP_CONFIG_DUR0 = 0x01, + TAP_CONFIG_DUR1 = 0x02, + TAP_CONFIG_DUR2 = 0x04, + _TAP_CONFIG_DUR_MASK = 7, + _TAP_CONFIG_DUR_SHIFT = 0, + + TAP_CONFIG_THRESH0 = 0x08, + TAP_CONFIG_THRESH1 = 0x10, + TAP_CONFIG_THRESH2 = 0x20, + TAP_CONFIG_THRESH3 = 0x40, + _TAP_CONFIG_THRESH_MASK = 15, + _TAP_CONFIG_THRESH_SHIFT = 3, + + TAP_CONFIG_FILTER = 0x80 + } TAP_CONFIG_BITS_T; + + /** + * REG_SLOPE_CONFIG bits + */ + typedef enum { + SLOPE_CONFIG_DUR0 = 0x01, + SLOPE_CONFIG_DUR1 = 0x02, + _SLOPE_CONFIG_DUR_MASK = 3, + _SLOPE_CONFIG_DUR_SHIFT = 0, + + SLOPE_CONFIG_THRESH0 = 0x04, + SLOPE_CONFIG_THRESH1 = 0x08, + SLOPE_CONFIG_THRESH2 = 0x10, + SLOPE_CONFIG_THRESH3 = 0x20, + _SLOPE_CONFIG_THRESH_MASK = 15, + _SLOPE_CONFIG_THRESH_SHIFT = 2, + + SLOPE_CONFIG_FILTER = 0x40, + SLOPE_CONFIG_ORIENT_EX = 0x80 // exchange x and z axis for orient + } SLOPE_CONFIG_BITS_T; + + /** + * REG_TAP_CONFIG2 bits + */ + typedef enum { + TAP_CONFIG2_SAMP0 = 0x01, + TAP_CONFIG2_SAMP1 = 0x02, + _TAP_CONFIG2_SAMP_MASK = 3, + _TAP_CONFIG2_SAMP_SHIFT = 0, + + TAP_CONFIG2_ORIENT_BLOCK0 = 0x04, + TAP_CONFIG2_ORIENT_BLOCK1 = 0x08, + _TAP_CONFIG2_ORIENT_BLOCK_MASK = 3, + _TAP_CONFIG2_ORIENT_BLOCK_SHIFT = 2, + + TAP_CONFIG2_TIP_EN = 0x10 + + // 0x20-0x80 reserved + } TAP_CONFIG2_BITS_T; + + /** + * TAP_CONFIG2_SAMP values + */ + typedef enum { + TAP_SAMP_2 = 0, // 2 data samples after wakeup + TAP_SAMP_4 = 1, + TAP_SAMP_8 = 2, + TAP_SAMP_16 = 3 + } TAP_SAMP_T; + + /** + * TAP_CONFIG2_ORIENT_BLOCK values + * + */ + typedef enum { + TAP_ORIENT_BLOCK_0 = 0, // orient blocking disabled + TAP_ORIENT_BLOCK_2 = 1, // |z|>0.9g OR |x|+|y| < 0.2g OR m<0.2g + TAP_ORIENT_BLOCK_3 = 2, // |z|>0.9g OR |x|+|y| < 0.3g OR m<0.3g + TAP_ORIENT_BLOCK_4 = 3, // |z|>0.9g OR |x|+|y| < 0.4g OR m<0.4g + } TAP_ORIENT_BLOCK_T; + + /** + * REG_INT_STATUS1 bits + */ + typedef enum { + INT_STATUS1_SIGN = 0x01, + INT_STATUS1_FIRST_Z = 0x02, + INT_STATUS1_FIRST_Y = 0x04, + INT_STATUS1_FIRST_X = 0x08, + + INT_STATUS1_ORIENT0 = 0x10, + INT_STATUS1_ORIENT1 = 0x20, + INT_STATUS1_ORIENT2 = 0x40, + _INT_STATUS1_ORIENT_MASK = 7, + _INT_STATUS1_ORIENT_SHIFT = 4, + + INT_STATUS1_ORIENT_INT = 0x80 // orient intr was generated + } INT_STATUS1_BITS_T; + + /** + * INT_STATUS1_ORIENT values + * + * These are values reported by the device if orientation + * detection is enabled. + */ + typedef enum { + CONFIG_ORI_UP_PORT_UPRIGHT = 0, // up portrait + CONFIG_ORI_UP_PORT_UPSIDE_DOWN = 1, + CONFIG_ORI_UP_LAND_LEFT = 2, // landscape + CONFIG_ORI_UP_LAND_RIGHT = 3, + CONFIG_ORI_DN_PORT_UPRIGHT = 4, // down portrait + CONFIG_ORI_DN_PORT_UPSIDE_DOWN = 5, + CONFIG_ORI_DN_LAND_LEFT = 6, // landscape + CONFIG_ORI_DN_LAND_RIGHT = 7 + } CONFIG_ORIENT_T; + + /** + * REG_INT_STATUS2 bits + */ + typedef enum { + INT_STATUS2_SLOPE = 0x01, + INT_STATUS2_DATA = 0x02, + INT_STATUS2_HIGH = 0x04, + INT_STATUS2_LOW = 0x08, + INT_STATUS2_TAP = 0x10 + + // 0x20-0x80 reserved + } INT_STATUS2_BITS_T; + + /** + * REG_ENABLE_CONFIG bits + */ + typedef enum { + ENABLE_CONFIG_TT_Z = 0x01, + ENABLE_CONFIG_TT_Y = 0x02, + ENABLE_CONFIG_TT_X = 0x04, + ENABLE_CONFIG_SLOPE_Z = 0x08, + ENABLE_CONFIG_SLOPE_Y = 0x10, + ENABLE_CONFIG_SLOPE_X = 0x20, + ENABLE_CONFIG_ORIENT = 0x40, + ENABLE_CONFIG_DATA = 0x80 + } ENABLE_CONFIG_BITS_T; + + /** + * REG_ENABLE_CONFIG2 bits + */ + typedef enum { + ENABLE_CONFIG2_HIGH_Z = 0x01, + ENABLE_CONFIG2_HIGH_Y = 0x02, + ENABLE_CONFIG2_HIGH_X = 0x04, + + ENABLE_CONFIG2_LOW = 0x08, + + ENABLE_CONFIG2_LAT_INT0 = 0x10, // interrupt latching + ENABLE_CONFIG2_LAT_INT1 = 0x20, + ENABLE_CONFIG2_LAT_INT2 = 0x40, + _ENABLE_CONFIG2_LAT_INT_MASK = 7, + _ENABLE_CONFIG2_LAT_INT_SHIFT = 4, + + ENABLE_CONFIG2_RESET_INT = 0x80 // reset interrupts + } ENABLE_CONFIG2_BITS_T; + + /** + * ENABLE_CONFIG2_LAT values + * + * These are values that define the interrupt latching behavior + */ + typedef enum { + CONFIG2_LAT_UNLATCH = 0, // unlatched intrs + CONFIG2_LAT_0_25 = 1, // latch intr for 0.25s + CONFIG2_LAT_0_5 = 2, // latch intr for 0.5s + CONFIG2_LAT_1 = 3, // latch intr for 1s + CONFIG2_LAT_2 = 4, // latch intr for 2s + CONFIG2_LAT_4 = 5, // latch intr for 4s + CONFIG2_LAT_8 = 6, // latch intr for 8s + CONFIG2_LAT_PERM = 7 // latch permanently + } CONFIG2_LAT_T; + + /** + * REG_ENABLE_CONFIG3 bits + */ + typedef enum { + ENABLE_CONFIG3_Z_CHAN = 0x01, + ENABLE_CONFIG3_Y_CHAN = 0x02, + ENABLE_CONFIG3_X_CHAN = 0x04, + + ENABLE_CONFIG3_SLEEP_DUR0 = 0x08, + ENABLE_CONFIG3_SLEEP_DUR1 = 0x10, + ENABLE_CONFIG3_SLEEP_DUR2 = 0x20, + _ENABLE_CONFIG3_SLEEP_DUR_MASK = 7, + _ENABLE_CONFIG3_SLEEP_DUR_SHIFT = 3, + + ENABLE_CONFIG3_SLEEP_EN = 0x40 + + // 0x80 reserved + } ENABLE_CONFIG3_BITS_T; + + /** + * ENABLE_CONFIG3_SLEEP_DUR values + * + * These are values that define the length of time the device + * sleeps before sampling when in sleep mode. + */ + typedef enum { + SLEEP_DUR_2MS = 0, // 2 ms + SLEEP_DUR_10MS = 1, + SLEEP_DUR_25MS = 2, + SLEEP_DUR_50MS = 3, + SLEEP_DUR_100MS = 4, + SLEEP_DUR_500MS = 5, + SLEEP_DUR_1S = 6, // 1 second + SLEEP_DUR_2S = 7 + } SLEEP_DUR_T; + + /** + * REG_FILTER_CONFIG bits + */ + typedef enum { + FILTER_CONFIG_FILTER0 = 0x01, + FILTER_CONFIG_FILTER1 = 0x02, + FILTER_CONFIG_FILTER2 = 0x04, + FILTER_CONFIG_FILTER3 = 0x08, + _FILTER_CONFIG_FILTER_MASK = 15, + _FILTER_CONFIG_FILTER_SHIFT = 0, + + // 0x10-0x40 reserved + + FILTER_CONFIG_SERIAL_HIGH_BW = 0x80 + } FILTER_CONFIG_BITS_T; + + /** + * FILTER_CONFIG_FILTER values + * + * These are values that define the digital filtering frequency + */ + typedef enum { + FILTER_CONFIG_1KHZ = 0, // 1Khz + FILTER_CONFIG_500HZ = 1, + FILTER_CONFIG_250HZ = 2, + FILTER_CONFIG_125HZ = 3, + FILTER_CONFIG_64HZ = 4, + FILTER_CONFIG_32HZ = 5 + } FILTER_CONFIG_T; + + /** + * REG_SBIST_FSL_CONFIG bits + */ + typedef enum { + REG_SBIST_FSL_RANGE0 = 0x01, // full scale range + REG_SBIST_FSL_RANGE1 = 0x02, + _REG_SBIST_FSL_RANGE_MASK = 3, + _REG_SBIST_FSL_RANGE_SHIFT = 0, + + REG_SBIST_FSL_SBIST0 = 0x04, // self test enables + REG_SBIST_FSL_SBIST1 = 0x08, + _REG_SBIST_FSL_SBIST_MASK = 3, + _REG_SBIST_FSL_SBIST_SHIFT = 2, + + REG_SBIST_FSL_SBIST_SIGN = 0x10 // signedness of self test + + // 0x20-0x80 reserved + } SBIST_FSL_CONFIG_BITS_T; + + /** + * REG_SBIST_FSL_RANGE values + * + * These are values that define the Full Scale configuration + */ + typedef enum { + FSL_RANGE_2G = 0, // 2G FSL + FSL_RANGE_4G = 1, + FSL_RANGE_8G = 2, + FSL_RANGE_16G = 3 + } FSL_RANGE_T; + + /** + * REG_SBIST_FSL_SBIST values + * + * These are values that enable self test mode + */ + typedef enum { + SBIST_OFF = 0, // self test off + SBIST_X = 1, // self test X + SBIST_Y = 2, + SBIST_Z = 3 + } SBIST_T; + + /** + * REG_I2C_WATCHDOG bits + */ + typedef enum { + I2C_WATCHDOG_SPI3 = 0x01, // SPI 3wire mode (SPI not supported) + + I2C_WATCHDOG_TO_SEL = 0x02, + I2C_WATCHDOG_TO_EN = 0x04 + + // 0x08-0x80 reserved + } I2C_WATCHDOG_BITS_T; + + + /** + * BMA220 constructor + * + * @param bus i2c bus to use + * @param address the address for this device + */ + BMA220(int bus=BMA220_I2C_BUS, uint8_t addr=BMA220_DEFAULT_ADDR); + + /** + * BMA220 Destructor + */ + ~BMA220(); + + /** + * update the accelerometer values + */ + void update(); + + /** + * read a register + * + * @param dev the device to access (XM or G) + * @param reg the register to read + * @return the value of the register + */ + uint8_t readReg(uint8_t reg); + + /** + * write to a register + * + * @param dev the device to access (XM or G) + * @param reg the register to write to + * @param val the value to write + * @return true if successful, false otherwise + */ + bool writeReg(uint8_t reg, uint8_t val); + + /** + * return the chip ID + * + * @return the chip ID (usually 0xdd) + */ + uint8_t getChipID(); + + /** + * return the chip revision + * + * @return the chip revision (usually 0x00) + */ + uint8_t getChipRevision(); + + /** + * set the scaling mode of the accelerometer (2g/4g/8g/16g) + * + * @param scale one of the FSL_RANGE_T values + * @return true if successful, false otherwise + */ + bool setAccelerometerScale(FSL_RANGE_T scale); + + /** + * get the accelerometer values in gravities + * + * @param x the returned x value, if arg is non-NULL + * @param y the returned y value, if arg is non-NULL + * @param z the returned z value, if arg is non-NULL + */ + void getAccelerometer(float *x, float *y, float *z); + +#if defined(SWIGJAVA) || defined(JAVACALLBACK) + /** + * get the accelerometer values in gravities + * + * @return Array containing X, Y, Z acceleration values + */ + float *getAccelerometer(); +#endif + + /** + * set the filtering configuration + * + * @param filter one of the FILTER_CONFIG_T values + * @return true if successful + */ + bool setFilterConfig(FILTER_CONFIG_T filter); + + /** + * enable or disable high bandwidth serial access (1Khz). This + * essentially disables filtering and makes the raw unfiltered + * data available in the axis registers. + * + * @param high true to enable high bw access, false otherwise + * @return true if successful + */ + bool setSerialHighBW(bool high); + + /** + * enable or disable axis channels + * + * @param xEn true to enable the axis, false otherwise + * @param yEn true to enable the axis, false otherwise + * @param zEn true to enable the axis, false otherwise + * @return true if successful + */ + bool enableAxes(bool xEn, bool yEn, bool zEn); + + /** + * place the device into, or take the device out of suspend mode + * + * @return 0x00 if the device was in active mode, 0xff if the + * device was in suspend mode + */ + uint8_t suspend(); + + /** + * place the device into, or take the device out of soft reset mode + * + * @return 0x00 if the device was in active mode, 0xff if the + * device was in soft reset mode + */ + uint8_t softReset(); + + /** + * place the device into, or take the device out of low power + * mode. See the datasheet for information on how low power mode + * is implemented on this device. + * + * @param enable true to set low power mode, false otherwise + * @return true if successful + */ + bool sleep(bool enable); + + /** + * when in low power (sleep) mode, specify how often the device + * wakes up to acquire samples. + * + * @param dur one of the SLEEP_DUR_T values + * @return true if successful + */ + bool setSleepDuration(SLEEP_DUR_T dur); + + /** + * specify the threshold for low G detection + * + * @param thresh see the datasheet + * @return true if successful + */ + bool setLowGThreshold(uint8_t thresh); + + /** + * specify the threshold for high G detection + * + * @param thresh see the datasheet + * @return true if successful + */ + bool setHighGThreshold(uint8_t thresh); + + /** + * specify the hysteresis for low G detection + * + * @param hyst 2 bit hysteresis value + * @return true if successful + */ + bool setLowGHysteresis(uint8_t hyst); + + /** + * specify the sample duration for low G detection + * + * @param dur the number of samples (depends on bandwidth) + * @return true if successful + */ + bool setLowGDuration(uint8_t dur); + + /** + * specify the hysteresis for high G detection + * + * @param hyst 2 bit hysteresis value + * @return true if successful + */ + bool setHighGHysteresis(uint8_t hyst); + + /** + * specify the sample duration for high G detection + * + * @param dur the number of samples (depends on bandwidth) + * @return true if successful + */ + bool setHighGDuration(uint8_t dur); + + /** + * specify the sample duration for tap detection + * + * @param dur the number of samples (depends on bandwidth) + * @return true if successful + */ + bool setTapDuration(uint8_t dur); + + /** + * specify the threshold for tap detection + * + * @param thresh see the datasheet + * @return true if successful + */ + bool setTapThreshold(uint8_t thresh); + + /** + * unable to disable tap filtering + * + * @param filt true to enable, false otherwise + * @return true if successful + */ + bool enableTapFilter(bool filt); + + /** + * specify the sample duration for slope detection + * + * @param dur the number of samples (depends on bandwidth) + * @return true if successful + */ + bool setSlopeDuration(uint8_t dur); + + /** + * specify the threshold for slope detection + * + * @param thresh see the datasheet + * @return true if successful + */ + bool setSlopeThreshold(uint8_t thresh); + + /** + * enable or disable slope filtering + * + * @param filt true to enable filtering, false otherwise + * @return true if successful + */ + bool enableSlopeFilter(bool filt); + + /** + * return a bitmask of the interrupt status 1 register + * + * @return bitmask of INT_STATUS1_BITS_T bits (minus the orient value) + */ + uint8_t getInterruptStatus1(); + + /** + * return the orient value from the interrupt status 1 register + * + * @return one of the CONFIG_ORIENT_T values + */ + CONFIG_ORIENT_T getOrient(); + + /** + * return a bitmask of the interrupt status 2 register + * + * @return bitmask of INT_STATUS2_BITS_T bits + */ + uint8_t getInterruptStatus2(); + + /** + * enable interrupts for events in interrupt config register 1 + * + * @param bits bitmask of ENABLE_CONFIG_BITS_T values + * @return true if successful + */ + bool setInterruptEnables1(uint8_t bits); + + /** + * return the enabled interrupts for events in interrupt config register 1 + * + * @return bitmask of ENABLE_CONFIG_BITS_T values + */ + uint8_t getInterruptEnables1(); + + /** + * enable interrupts for events in interrupt config register 2 + * + * @param bits bitmask of ENABLE_CONFIG2_BITS_T values + * @return true if successful + */ + bool setInterruptEnables2(uint8_t bits); + + /** + * return the enabled interrupts for events in interrupt config register 2 + * + * @return bitmask of ENABLE_CONFIG2_BITS_T values + */ + uint8_t getInterruptEnables2(); + + /** + * configure interrupt latching behavior + * + * @param lat one of the CONFIG2_LAT_T values + * @return true if successful + */ + bool setInterruptLatch(CONFIG2_LAT_T lat); + + /** + * reset the interrupt controller. This should be called after + * any changes are made to interrupt configuration, or to reset + * interrupts if latched interrupts have been enabled and an + * interrupt has occurred.. + * + * @return true if successful + */ + bool resetInterrupts(); + +#if defined(SWIGJAVA) || defined(JAVACALLBACK) + void installISR(int gpio, mraa::Edge level, IsrCallback *cb); +#else + /** + * install an interrupt handler. + * + * @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 + */ + void installISR(int gpio, mraa::Edge level, + void (*isr)(void *), void *arg); +#endif + + /** + * uninstall a previously installed interrupt handler + * + */ + void uninstallISR(); + + protected: + mraa::I2c m_i2c; + mraa::Gpio *m_gpioIntr; + uint8_t m_addr; + + // uncompensated accelerometer values + float m_accelX; + float m_accelY; + float m_accelZ; + + // accelerometer full scale + float m_accelScale; + + private: + /** + * update the accelerometer values + */ + void updateAccelerometer(); + // Adding a private function definition for java bindings +#if defined(SWIGJAVA) || defined(JAVACALLBACK) + void installISR(int gpio, mraa::Edge level, + void (*isr)(void *), void *arg); +#endif + + }; +} + + diff --git a/src/bma220/javaupm_bma220.i b/src/bma220/javaupm_bma220.i new file mode 100644 index 00000000..37707405 --- /dev/null +++ b/src/bma220/javaupm_bma220.i @@ -0,0 +1,36 @@ +%module(directors="1") javaupm_bma220 +%include "../upm.i" +%include "cpointer.i" +%include "typemaps.i" +%include "arrays_java.i"; +%include "../java_buffer.i" + +%feature("director") IsrCallback; + +%ignore generic_callback_isr; +%include "../IsrCallback.h" + +%apply int {mraa::Edge}; +%apply float *INOUT { float *x, float *y, float *z }; + +%typemap(jni) float* "jfloatArray" +%typemap(jstype) float* "float[]" +%typemap(jtype) float* "float[]" + +%typemap(javaout) float* { + return $jnicall; +} + +%typemap(out) float *getAccelerometer { + $result = JCALL1(NewFloatArray, jenv, 3); + JCALL4(SetFloatArrayRegion, jenv, $result, 0, 3, $1); + delete [] $1; +} + +%ignore getAccelerometer(float *, float *, float *); + +%{ + #include "bma220.h" +%} + +%include "bma220.h" diff --git a/src/bma220/jsupm_bma220.i b/src/bma220/jsupm_bma220.i new file mode 100644 index 00000000..fa25b7f6 --- /dev/null +++ b/src/bma220/jsupm_bma220.i @@ -0,0 +1,11 @@ +%module jsupm_bma220 +%include "../upm.i" +%include "cpointer.i" + +%pointer_functions(float, floatp); + +%include "bma220.h" +%{ + #include "bma220.h" +%} + diff --git a/src/bma220/pyupm_bma220.i b/src/bma220/pyupm_bma220.i new file mode 100644 index 00000000..44b56df3 --- /dev/null +++ b/src/bma220/pyupm_bma220.i @@ -0,0 +1,15 @@ +%module pyupm_bma220 +%include "../upm.i" +%include "cpointer.i" + +%include "stdint.i" + +%feature("autodoc", "3"); + +%pointer_functions(float, floatp); + +%include "bma220.h" +%{ + #include "bma220.h" +%} +