mirror of
https://github.com/eclipse/upm.git
synced 2025-03-19 23:17:29 +03:00

Signed-off-by: Serban Waltter <serban.waltter@rinftech.com> Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
800 lines
18 KiB
C++
800 lines
18 KiB
C++
/*
|
|
* Author: Jon Trulson <jtrulson@ics.com>
|
|
* 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 <unistd.h>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <string.h>
|
|
#include <vector>
|
|
|
|
#include "lsm9ds0.hpp"
|
|
|
|
using namespace upm;
|
|
using namespace std;
|
|
|
|
|
|
LSM9DS0::LSM9DS0(int bus, bool raw, uint8_t gAddress, uint8_t xmAddress) :
|
|
m_i2cG(bus, raw), m_i2cXM(bus, raw), m_gpioG_INT(0), m_gpioG_DRDY(0),
|
|
m_gpioXM_GEN1(0), m_gpioXM_GEN2(0)
|
|
{
|
|
m_gAddr = gAddress;
|
|
m_xmAddr = xmAddress;
|
|
|
|
m_accelX = 0.0;
|
|
m_accelY = 0.0;
|
|
m_accelZ = 0.0;
|
|
|
|
m_gyroX = 0.0;
|
|
m_gyroY = 0.0;
|
|
m_gyroZ = 0.0;
|
|
|
|
m_magX = 0.0;
|
|
m_magY = 0.0;
|
|
m_magZ = 0.0;
|
|
|
|
m_temp = 0.0;
|
|
|
|
m_accelScale = 0.0;
|
|
m_gyroScale = 0.0;
|
|
m_magScale = 0.0;
|
|
|
|
mraa::Result rv;
|
|
if ( (rv = m_i2cG.address(m_gAddr)) != mraa::SUCCESS)
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Could not initialize Gyro i2c address");
|
|
return;
|
|
}
|
|
|
|
if ( (rv = m_i2cXM.address(m_xmAddr)) != mraa::SUCCESS)
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Could not initialize XM i2c address");
|
|
return;
|
|
}
|
|
}
|
|
|
|
LSM9DS0::~LSM9DS0()
|
|
{
|
|
uninstallISR(INTERRUPT_G_INT);
|
|
uninstallISR(INTERRUPT_G_DRDY);
|
|
uninstallISR(INTERRUPT_XM_GEN1);
|
|
uninstallISR(INTERRUPT_XM_GEN2);
|
|
}
|
|
|
|
bool LSM9DS0::init()
|
|
{
|
|
// Init the gyroscope
|
|
|
|
// power up
|
|
if (!setGyroscopePowerDown(false))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to wake up gyro");
|
|
return false;
|
|
}
|
|
|
|
// enable all axes
|
|
if (!setGyroscopeEnableAxes(CTRL_REG1_G_YEN |CTRL_REG1_G_XEN |
|
|
CTRL_REG1_G_ZEN))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to enable gyro axes");
|
|
return false;
|
|
}
|
|
|
|
// set gyro ODR
|
|
if (!setGyroscopeODR(G_ODR_95_25))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set gyro ODR");
|
|
return false;
|
|
}
|
|
|
|
// set gyro scale
|
|
if (!setGyroscopeScale(G_FS_245))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set gyro scale");
|
|
return false;
|
|
}
|
|
|
|
// Init the accelerometer
|
|
|
|
// power up and set ODR
|
|
if (!setAccelerometerODR(XM_AODR_100))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set accel ODR");
|
|
return false;
|
|
}
|
|
|
|
// enable all axes
|
|
if (!setAccelerometerEnableAxes(CTRL_REG1_XM_AXEN |CTRL_REG1_XM_AYEN |
|
|
CTRL_REG1_XM_AZEN))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to enable accel axes");
|
|
return false;
|
|
}
|
|
|
|
// set scaling rate
|
|
if (!setAccelerometerScale(XM_AFS_2))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set accel scale");
|
|
return false;
|
|
}
|
|
|
|
// temperature sensor
|
|
|
|
// enable the temperature sensor
|
|
if (!enableTemperatureSensor(true))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to enable temp sensor");
|
|
return false;
|
|
}
|
|
|
|
// Init the magnetometer
|
|
|
|
// set mode (this also powers it up if not XM_MD_POWERDOWN)
|
|
if (!setMagnetometerMode(XM_MD_CONTINUOUS))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set mag scale");
|
|
return false;
|
|
}
|
|
|
|
// turn LPM off
|
|
if (!setMagnetometerLPM(false))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to disable mag LPM");
|
|
return false;
|
|
}
|
|
|
|
// set resolution
|
|
if (!setMagnetometerResolution(XM_RES_LOW))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set mag res");
|
|
return false;
|
|
}
|
|
|
|
// set ODR
|
|
if (!setMagnetometerODR(XM_ODR_12_5))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set mag ODR");
|
|
return false;
|
|
}
|
|
|
|
// set scale
|
|
if (!setMagnetometerScale(XM_MFS_2))
|
|
{
|
|
throw std::runtime_error(string(__FUNCTION__) +
|
|
": Unable to set mag scale");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void LSM9DS0::update()
|
|
{
|
|
updateGyroscope();
|
|
updateAccelerometer();
|
|
updateMagnetometer();
|
|
updateTemperature();
|
|
}
|
|
|
|
void LSM9DS0::updateGyroscope()
|
|
{
|
|
uint8_t buffer[6];
|
|
|
|
memset(buffer, 0, 6);
|
|
readRegs(DEV_GYRO, REG_OUT_X_L_G, buffer, 6);
|
|
|
|
int16_t x, y, z;
|
|
|
|
x = ( (buffer[1] << 8) | buffer[0] );
|
|
y = ( (buffer[3] << 8) | buffer[2] );
|
|
z = ( (buffer[5] << 8) | buffer[4] );
|
|
|
|
m_gyroX = float(x);
|
|
m_gyroY = float(y);
|
|
m_gyroZ = float(z);
|
|
}
|
|
|
|
void LSM9DS0::updateAccelerometer()
|
|
{
|
|
uint8_t buffer[6];
|
|
|
|
memset(buffer, 0, 6);
|
|
readRegs(DEV_XM, REG_OUT_X_L_A, buffer, 6);
|
|
|
|
int16_t x, y, z;
|
|
|
|
x = ( (buffer[1] << 8) | buffer[0] );
|
|
y = ( (buffer[3] << 8) | buffer[2] );
|
|
z = ( (buffer[5] << 8) | buffer[4] );
|
|
|
|
m_accelX = float(x);
|
|
m_accelY = float(y);
|
|
m_accelZ = float(z);
|
|
}
|
|
|
|
void LSM9DS0::updateMagnetometer()
|
|
{
|
|
uint8_t buffer[6];
|
|
|
|
memset(buffer, 0, 6);
|
|
readRegs(DEV_XM, REG_OUT_X_L_M, buffer, 6);
|
|
|
|
int16_t x, y, z;
|
|
|
|
x = ( (buffer[1] << 8) | buffer[0] );
|
|
y = ( (buffer[3] << 8) | buffer[2] );
|
|
z = ( (buffer[5] << 8) | buffer[4] );
|
|
|
|
m_magX = float(x);
|
|
m_magY = float(y);
|
|
m_magZ = float(z);
|
|
}
|
|
|
|
void LSM9DS0::updateTemperature()
|
|
{
|
|
uint8_t buffer[2];
|
|
|
|
memset(buffer, 0, 2);
|
|
readRegs(DEV_XM, REG_OUT_TEMP_L_XM, buffer, 2);
|
|
|
|
// cerr << "HIGH: " << int(buffer[1]) << " LOW: " << int(buffer[0]) << endl;
|
|
|
|
// 12b signed
|
|
int16_t temp = ( (buffer[1] << 8) | (buffer[0] ) );
|
|
if (temp & 0x0800)
|
|
{
|
|
temp &= ~0x0800;
|
|
temp *= -1;
|
|
}
|
|
|
|
m_temp = float(temp);
|
|
}
|
|
|
|
uint8_t LSM9DS0::readReg(DEVICE_T dev, uint8_t reg)
|
|
{
|
|
mraa::I2c *device;
|
|
|
|
switch(dev)
|
|
{
|
|
case DEV_GYRO: device = &m_i2cG; break;
|
|
case DEV_XM: device = &m_i2cXM; break;
|
|
default:
|
|
throw std::logic_error(string(__FUNCTION__) +
|
|
": Internal error, invalid device specified");
|
|
return 0;
|
|
}
|
|
|
|
return device->readReg(reg);
|
|
}
|
|
|
|
void LSM9DS0::readRegs(DEVICE_T dev, uint8_t reg, uint8_t *buffer, int len)
|
|
{
|
|
mraa::I2c *device;
|
|
|
|
switch(dev)
|
|
{
|
|
case DEV_GYRO: device = &m_i2cG; break;
|
|
case DEV_XM: device = &m_i2cXM; break;
|
|
default:
|
|
throw std::logic_error(string(__FUNCTION__) +
|
|
": Internal error, invalid device specified");
|
|
return;
|
|
}
|
|
|
|
// We need to set the high bit of the register to enable
|
|
// auto-increment mode for reading multiple registers in one go.
|
|
device->readBytesReg(reg | m_autoIncrementMode, buffer, len);
|
|
}
|
|
|
|
bool LSM9DS0::writeReg(DEVICE_T dev, uint8_t reg, uint8_t val)
|
|
{
|
|
mraa::I2c *device;
|
|
|
|
switch(dev)
|
|
{
|
|
case DEV_GYRO: device = &m_i2cG; break;
|
|
case DEV_XM: device = &m_i2cXM; break;
|
|
default:
|
|
throw std::logic_error(string(__FUNCTION__) +
|
|
": Internal error, invalid device specified");
|
|
return false;
|
|
}
|
|
|
|
mraa::Result rv;
|
|
if ((rv = device->writeReg(reg, val)) != mraa::SUCCESS)
|
|
{
|
|
throw std::runtime_error(std::string(__FUNCTION__) +
|
|
": I2c.writeReg() failed");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LSM9DS0::setGyroscopePowerDown(bool enable)
|
|
{
|
|
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
|
|
|
|
if (enable)
|
|
reg &= ~CTRL_REG1_G_PD;
|
|
else
|
|
reg |= CTRL_REG1_G_PD;
|
|
|
|
return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setGyroscopeEnableAxes(uint8_t axes)
|
|
{
|
|
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
|
|
|
|
// filter out any non-axis related data from arg
|
|
axes &= (CTRL_REG1_G_YEN | CTRL_REG1_G_XEN | CTRL_REG1_G_ZEN);
|
|
|
|
// clear them in the register
|
|
reg &= ~(CTRL_REG1_G_YEN | CTRL_REG1_G_XEN | CTRL_REG1_G_ZEN);
|
|
|
|
// now add them
|
|
reg |= axes;
|
|
|
|
return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setGyroscopeODR(G_ODR_T odr)
|
|
{
|
|
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
|
|
|
|
reg &= ~(_CTRL_REG1_G_ODR_MASK << _CTRL_REG1_G_ODR_SHIFT);
|
|
|
|
reg |= (odr << _CTRL_REG1_G_ODR_SHIFT);
|
|
|
|
return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setGyroscopeScale(G_FS_T scale)
|
|
{
|
|
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG4_G);
|
|
|
|
reg &= ~(_CTRL_REG4_G_FS_MASK << _CTRL_REG4_G_FS_SHIFT);
|
|
|
|
reg |= (scale << _CTRL_REG4_G_FS_SHIFT);
|
|
|
|
if (!writeReg(DEV_GYRO, REG_CTRL_REG4_G, reg))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// store scaling factor (mDeg/s/LSB)
|
|
|
|
switch (scale)
|
|
{
|
|
case G_FS_245:
|
|
m_gyroScale = 8.75;
|
|
break;
|
|
|
|
case G_FS_500:
|
|
m_gyroScale = 17.5;
|
|
break;
|
|
|
|
case G_FS_2000:
|
|
m_gyroScale = 70.0;
|
|
break;
|
|
|
|
default: // should never occur, but...
|
|
m_gyroScale = 0.0; // set a safe, though incorrect value
|
|
throw std::logic_error(string(__FUNCTION__) +
|
|
": internal error, unsupported scale");
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LSM9DS0::setAccelerometerEnableAxes(uint8_t axes)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG1_XM);
|
|
|
|
// filter out any non-axis related data from arg
|
|
axes &= (CTRL_REG1_XM_AXEN | CTRL_REG1_XM_AYEN | CTRL_REG1_XM_AZEN);
|
|
|
|
// clear them in the register
|
|
reg &= ~(CTRL_REG1_XM_AXEN | CTRL_REG1_XM_AYEN | CTRL_REG1_XM_AZEN);
|
|
|
|
// now add them
|
|
reg |= axes;
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG1_XM, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setAccelerometerODR(XM_AODR_T odr)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG1_XM);
|
|
|
|
reg &= ~(_CTRL_REG1_XM_AODR_MASK << _CTRL_REG1_XM_AODR_SHIFT);
|
|
|
|
reg |= (odr << _CTRL_REG1_XM_AODR_SHIFT);
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG1_XM, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setAccelerometerScale(XM_AFS_T scale)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG2_XM);
|
|
|
|
reg &= ~(_CTRL_REG2_XM_AFS_MASK << _CTRL_REG2_XM_AFS_SHIFT);
|
|
|
|
reg |= (scale << _CTRL_REG2_XM_AFS_SHIFT);
|
|
|
|
if (!writeReg(DEV_XM, REG_CTRL_REG2_XM, reg))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// store scaling factor
|
|
|
|
switch (scale)
|
|
{
|
|
case XM_AFS_2:
|
|
m_accelScale = 0.061;
|
|
break;
|
|
|
|
case XM_AFS_4:
|
|
m_accelScale = 0.122 ;
|
|
break;
|
|
|
|
case XM_AFS_6:
|
|
m_accelScale = 0.183 ;
|
|
break;
|
|
|
|
case XM_AFS_8:
|
|
m_accelScale = 0.244 ;
|
|
break;
|
|
|
|
case XM_AFS_16:
|
|
m_accelScale = 0.732 ;
|
|
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;
|
|
}
|
|
|
|
bool LSM9DS0::setMagnetometerResolution(XM_RES_T res)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
|
|
|
|
reg &= ~(_CTRL_REG5_XM_RES_MASK << _CTRL_REG5_XM_RES_SHIFT);
|
|
|
|
reg |= (res << _CTRL_REG5_XM_RES_SHIFT);
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setMagnetometerODR(XM_ODR_T odr)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
|
|
|
|
reg &= ~(_CTRL_REG5_XM_ODR_MASK << _CTRL_REG5_XM_ODR_SHIFT);
|
|
|
|
reg |= (odr << _CTRL_REG5_XM_ODR_SHIFT);
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setMagnetometerMode(XM_MD_T mode)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG7_XM);
|
|
|
|
reg &= ~(_CTRL_REG7_XM_MD_MASK << _CTRL_REG7_XM_MD_SHIFT);
|
|
|
|
reg |= (mode << _CTRL_REG7_XM_MD_SHIFT);
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG7_XM, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setMagnetometerLPM(bool enable)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG7_XM);
|
|
|
|
if (enable)
|
|
reg |= CTRL_REG7_XM_MLP;
|
|
else
|
|
reg &= ~CTRL_REG7_XM_MLP;
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG7_XM, reg);
|
|
}
|
|
|
|
bool LSM9DS0::setMagnetometerScale(XM_MFS_T scale)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG6_XM);
|
|
|
|
reg &= ~(_CTRL_REG6_XM_MFS_MASK << _CTRL_REG6_XM_MFS_SHIFT);
|
|
|
|
reg |= (scale << _CTRL_REG6_XM_MFS_SHIFT);
|
|
|
|
if (!writeReg(DEV_XM, REG_CTRL_REG6_XM, reg))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// store scaling factor
|
|
|
|
switch (scale)
|
|
{
|
|
case XM_MFS_2:
|
|
m_magScale = 0.08;
|
|
break;
|
|
|
|
case XM_MFS_4:
|
|
m_magScale = 0.16;
|
|
break;
|
|
|
|
case XM_MFS_8:
|
|
m_magScale = 0.32;
|
|
break;
|
|
|
|
case XM_MFS_12:
|
|
m_magScale = 0.48;
|
|
break;
|
|
|
|
default: // should never occur, but...
|
|
m_magScale = 0.0; // set a safe, though incorrect value
|
|
throw std::logic_error(string(__FUNCTION__) +
|
|
": internal error, unsupported scale");
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void LSM9DS0::getAccelerometer(float *x, float *y, float *z)
|
|
{
|
|
if (x)
|
|
*x = (m_accelX * m_accelScale) / 1000.0;
|
|
|
|
if (y)
|
|
*y = (m_accelY * m_accelScale) / 1000.0;
|
|
|
|
if (z)
|
|
*z = (m_accelZ * m_accelScale) / 1000.0;
|
|
}
|
|
|
|
void LSM9DS0::getGyroscope(float *x, float *y, float *z)
|
|
{
|
|
if (x)
|
|
*x = (m_gyroX * m_gyroScale) / 1000.0;
|
|
|
|
if (y)
|
|
*y = (m_gyroY * m_gyroScale) / 1000.0;
|
|
|
|
if (z)
|
|
*z = (m_gyroZ * m_gyroScale) / 1000.0;
|
|
}
|
|
|
|
void LSM9DS0::getMagnetometer(float *x, float *y, float *z)
|
|
{
|
|
if (x)
|
|
*x = (m_magX * m_magScale) / 1000.0;
|
|
|
|
if (y)
|
|
*y = (m_magY * m_magScale) / 1000.0;
|
|
|
|
if (z)
|
|
*z = (m_magZ * m_magScale) / 1000.0;
|
|
}
|
|
|
|
std::vector<float> LSM9DS0::getAccelerometer()
|
|
{
|
|
std::vector<float> v(3);
|
|
getAccelerometer(&v[0], &v[1], &v[2]);
|
|
return v;
|
|
}
|
|
|
|
std::vector<float> LSM9DS0::getAcceleration()
|
|
{
|
|
std::vector<float> v(3);
|
|
getAccelerometer(&v[0], &v[1], &v[2]);
|
|
return v;
|
|
}
|
|
|
|
std::vector<float> LSM9DS0::getGyroscope()
|
|
{
|
|
std::vector<float> v(3);
|
|
getGyroscope(&v[0], &v[1], &v[2]);
|
|
return v;
|
|
}
|
|
|
|
std::vector<float> LSM9DS0::getMagnetometer()
|
|
{
|
|
update();
|
|
std::vector<float> v(3);
|
|
v[0] = (m_magX * m_magScale) / 1000.0;
|
|
v[1] = (m_magY * m_magScale) / 1000.0;
|
|
v[2] = (m_magZ * m_magScale) / 1000.0;
|
|
return v;
|
|
}
|
|
|
|
float LSM9DS0::getTemperature()
|
|
{
|
|
// This might be wrong... The datasheet does not provide enough info
|
|
// to calculate the temperature given a specific sensor reading. So
|
|
// - with 12b resolution, signed, and 8 degrees/per LSB, we come up
|
|
// with the following. Then scale up and we get a number that seems
|
|
// pretty close.
|
|
return (((m_temp / 2048.0) * 8.0) * 100.0);
|
|
}
|
|
|
|
bool LSM9DS0::enableTemperatureSensor(bool enable)
|
|
{
|
|
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
|
|
|
|
if (enable)
|
|
reg |= CTRL_REG5_XM_TEMP_EN;
|
|
else
|
|
reg &= ~CTRL_REG5_XM_TEMP_EN;
|
|
|
|
return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getGyroscopeStatus()
|
|
{
|
|
return readReg(DEV_GYRO, REG_STATUS_REG_G);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getMagnetometerStatus()
|
|
{
|
|
return readReg(DEV_XM, REG_STATUS_REG_M);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getAccelerometerStatus()
|
|
{
|
|
return readReg(DEV_XM, REG_STATUS_REG_A);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getGyroscopeInterruptConfig()
|
|
{
|
|
return readReg(DEV_GYRO, REG_INT1_CFG_G);
|
|
}
|
|
|
|
bool LSM9DS0::setGyroscopeInterruptConfig(uint8_t enables)
|
|
{
|
|
return writeReg(DEV_GYRO, REG_INT1_CFG_G, enables);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getGyroscopeInterruptSrc()
|
|
{
|
|
return readReg(DEV_GYRO, REG_INT1_SRC_G);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getMagnetometerInterruptControl()
|
|
{
|
|
return readReg(DEV_XM, REG_INT_CTRL_REG_M);
|
|
}
|
|
|
|
bool LSM9DS0::setMagnetometerInterruptControl(uint8_t enables)
|
|
{
|
|
return writeReg(DEV_XM, REG_INT_CTRL_REG_M, enables);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getMagnetometerInterruptSrc()
|
|
{
|
|
return readReg(DEV_XM, REG_INT_SRC_REG_M);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getInterruptGen1()
|
|
{
|
|
return readReg(DEV_XM, REG_INT_GEN_1_REG);
|
|
}
|
|
|
|
bool LSM9DS0::setInterruptGen1(uint8_t enables)
|
|
{
|
|
return writeReg(DEV_XM, REG_INT_GEN_1_REG, enables);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getInterruptGen1Src()
|
|
{
|
|
return readReg(DEV_XM, REG_INT_GEN_1_SRC);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getInterruptGen2()
|
|
{
|
|
return readReg(DEV_XM, REG_INT_GEN_2_REG);
|
|
}
|
|
|
|
bool LSM9DS0::setInterruptGen2(uint8_t enables)
|
|
{
|
|
return writeReg(DEV_XM, REG_INT_GEN_2_REG, enables);
|
|
}
|
|
|
|
uint8_t LSM9DS0::getInterruptGen2Src()
|
|
{
|
|
return readReg(DEV_XM, REG_INT_GEN_2_SRC);
|
|
}
|
|
|
|
|
|
void LSM9DS0::installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level,
|
|
void (*isr)(void *), void *arg)
|
|
{
|
|
// delete any existing ISR and GPIO context
|
|
uninstallISR(intr);
|
|
|
|
// greate gpio context
|
|
getPin(intr) = new mraa::Gpio(gpio);
|
|
|
|
getPin(intr)->dir(mraa::DIR_IN);
|
|
getPin(intr)->isr(level, isr, arg);
|
|
}
|
|
|
|
|
|
void LSM9DS0::uninstallISR(INTERRUPT_PINS_T intr)
|
|
{
|
|
if (getPin(intr))
|
|
{
|
|
getPin(intr)->isrExit();
|
|
delete getPin(intr);
|
|
|
|
getPin(intr) = 0;
|
|
}
|
|
}
|
|
|
|
mraa::Gpio*& LSM9DS0::getPin(INTERRUPT_PINS_T intr)
|
|
{
|
|
switch(intr)
|
|
{
|
|
case INTERRUPT_G_INT:
|
|
return m_gpioG_INT;
|
|
break;
|
|
case INTERRUPT_G_DRDY:
|
|
return m_gpioG_DRDY;
|
|
break;
|
|
case INTERRUPT_XM_GEN1:
|
|
return m_gpioXM_GEN1;
|
|
break;
|
|
case INTERRUPT_XM_GEN2:
|
|
return m_gpioXM_GEN2;
|
|
break;
|
|
default:
|
|
throw std::out_of_range(string(__FUNCTION__) +
|
|
": Invalid interrupt enum passed");
|
|
}
|
|
}
|