hybridgroup/cylon-i2c

View on GitHub
lib/lsm9ds0xm.js

Summary

Maintainability
D
2 days
Test Coverage
/*
 * LSM9DS0XM I2C accelerometer driver
 * http://cylonjs.com
 *
 * Copyright (c) 2014-2015 The Hybrid Group
 * Licensed under the Apache 2.0 license.
*/

"use strict";

var Cylon = require("cylon");

var I2CDriver = require("./i2c-driver");

/**
 * A LSM9DS0XM Driver
 *
 * @constructor lsm9ds0xm
 */
var LSM9DS0XM = module.exports = function LSM9DS0XM() {
  LSM9DS0XM.__super__.constructor.apply(this, arguments);
  this.address = this.address || 0x1d;

  this.commands = {
    getAccel: this.getAccel,
    getMag: this.getMag
  };
};

Cylon.Utils.subclass(LSM9DS0XM, I2CDriver);

LSM9DS0XM.OUT_TEMP_L_XM = 0x05;
LSM9DS0XM.OUT_TEMP_H_XM = 0x06;
LSM9DS0XM.STATUS_REG_M = 0x07;
LSM9DS0XM.OUT_X_L_M = 0x08;
LSM9DS0XM.OUT_X_H_M = 0x09;
LSM9DS0XM.OUT_Y_L_M = 0x0A;
LSM9DS0XM.OUT_Y_H_M = 0x0B;
LSM9DS0XM.OUT_Z_L_M = 0x0C;
LSM9DS0XM.OUT_Z_H_M = 0x0D;
LSM9DS0XM.WHO_AM_I_XM = 0x0F;
LSM9DS0XM.INT_CTRL_REG_M = 0x12;
LSM9DS0XM.INT_SRC_REG_M = 0x13;
LSM9DS0XM.INT_THS_L_M = 0x14;
LSM9DS0XM.INT_THS_H_M = 0x15;
LSM9DS0XM.OFFSET_X_L_M = 0x16;
LSM9DS0XM.OFFSET_X_H_M = 0x17;
LSM9DS0XM.OFFSET_Y_L_M = 0x18;
LSM9DS0XM.OFFSET_Y_H_M = 0x19;
LSM9DS0XM.OFFSET_Z_L_M = 0x1A;
LSM9DS0XM.OFFSET_Z_H_M = 0x1B;
LSM9DS0XM.REFERENCE_X = 0x1C;
LSM9DS0XM.REFERENCE_Y = 0x1D;
LSM9DS0XM.REFERENCE_Z = 0x1E;
LSM9DS0XM.CTRL_REG0_XM = 0x1F;
LSM9DS0XM.CTRL_REG1_XM = 0x20;
LSM9DS0XM.CTRL_REG2_XM = 0x21;
LSM9DS0XM.CTRL_REG3_XM = 0x22;
LSM9DS0XM.CTRL_REG4_XM = 0x23;
LSM9DS0XM.CTRL_REG5_XM = 0x24;
LSM9DS0XM.CTRL_REG6_XM = 0x25;
LSM9DS0XM.CTRL_REG7_XM = 0x26;
LSM9DS0XM.STATUS_REG_A = 0x27;
LSM9DS0XM.OUT_X_L_A = 0x28;
LSM9DS0XM.OUT_X_H_A = 0x29;
LSM9DS0XM.OUT_Y_L_A = 0x2A;
LSM9DS0XM.OUT_Y_H_A = 0x2B;
LSM9DS0XM.OUT_Z_L_A = 0x2C;
LSM9DS0XM.OUT_Z_H_A = 0x2D;
LSM9DS0XM.FIFO_CTRL_REG = 0x2E;
LSM9DS0XM.FIFO_SRC_REG = 0x2F;
LSM9DS0XM.INT_GEN_1_REG = 0x30;
LSM9DS0XM.INT_GEN_1_SRC = 0x31;
LSM9DS0XM.INT_GEN_1_THS = 0x32;
LSM9DS0XM.INT_GEN_1_DURATION = 0x33;
LSM9DS0XM.INT_GEN_2_REG = 0x34;
LSM9DS0XM.INT_GEN_2_SRC = 0x35;
LSM9DS0XM.INT_GEN_2_THS = 0x36;
LSM9DS0XM.INT_GEN_2_DURATION = 0x37;
LSM9DS0XM.CLICK_CFG = 0x38;
LSM9DS0XM.CLICK_SRC = 0x39;
LSM9DS0XM.CLICK_THS = 0x3A;
LSM9DS0XM.TIME_LIMIT = 0x3B;
LSM9DS0XM.TIME_LATENCY = 0x3C;
LSM9DS0XM.TIME_WINDOW = 0x3D;
LSM9DS0XM.ACT_THS = 0x3E;
LSM9DS0XM.ACT_DUR = 0x3F;

/**
 * Starts the driver
 *
 * @param {Function} callback triggered when the driver is started
 * @return {void}
 */
LSM9DS0XM.prototype.start = function(callback) {
  this._initAccel();
  this._initMag();
  callback();
};

/**
 * Gets the value of Accelerometer.
 *
 * @param {Function} callback callback to be invoked with data
 * @return {void}
 * @publish
 */
LSM9DS0XM.prototype.getAccel = function(callback) {
  var self = this;

  self.connection.i2cRead(self.address,
                          LSM9DS0XM.OUT_X_L_A,
                          6,
    function(err, d) {
      if (err) {
        callback(err, null);
      } else {
        var result = {};
        var data = new Buffer(d);
        result.x = data.readInt16LE(0);
        result.y = data.readInt16LE(2);
        result.z = data.readInt16LE(4);
        callback(null, result);
      }
    }
  );
};

/**
 * Gets the value of Magnetometer.
 *
 * @param {Function} callback callback to be invoked with data
 * @return {void}
 * @publish
 */
LSM9DS0XM.prototype.getMag = function(callback) {
  var self = this;

  self.connection.i2cRead(self.address,
                          LSM9DS0XM.OUT_X_L_M,
                          6,
    function(err, d) {
      if (err) {
        callback(err, null);
      } else {
        var result = {};
        var data = new Buffer(d);
        result.x = data.readInt16LE(0);
        result.y = data.readInt16LE(2);
        result.z = data.readInt16LE(4);
        callback(null, result);
      }
    }
  );
};

LSM9DS0XM.prototype._initAccel = function() {
  /* CTRL_REG0_XM (0x1F) (Default value: 0x00)
  Bits (7-0): BOOT FIFO_EN WTM_EN 0 0 HP_CLICK HPIS1 HPIS2
  BOOT - Reboot memory content (0: normal, 1: reboot)
  FIFO_EN - Fifo enable (0: disable, 1: enable)
  WTM_EN - FIFO watermark enable (0: disable, 1: enable)
  HP_CLICK - HPF enabled for click (0: filter bypassed, 1: enabled)
  HPIS1 - HPF enabled for interrupt generator 1 (0: bypassed, 1: enabled)
  HPIS2 - HPF enabled for interrupt generator 2 (0: bypassed, 1 enabled)   */
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG0_XM, 0x00);

  /* CTRL_REG1_XM (0x20) (Default value: 0x07)
  Bits (7-0): AODR3 AODR2 AODR1 AODR0 BDU AZEN AYEN AXEN
  AODR[3:0] - select the acceleration data rate:
    0000=power down, 0001=3.125Hz, 0010=6.25Hz, 0011=12.5Hz,
    0100=25Hz, 0101=50Hz, 0110=100Hz, 0111=200Hz, 1000=400Hz,
    1001=800Hz, 1010=1600Hz, (remaining combinations undefined).
  BDU - block data update for accel AND mag
    0: Continuous update
    1: Output registers aren't updated until MSB and LSB have been read.
  AZEN, AYEN, and AXEN - Acceleration x/y/z-axis enabled.
    0: Axis disabled, 1: Axis enabled                  */
  // 100Hz data rate, x/y/z all enabled
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG1_XM, 0x57);

  /* CTRL_REG2_XM (0x21) (Default value: 0x00)
  Bits (7-0): ABW1 ABW0 AFS2 AFS1 AFS0 AST1 AST0 SIM
  ABW[1:0] - Accelerometer anti-alias filter bandwidth
    00=773Hz, 01=194Hz, 10=362Hz, 11=50Hz
  AFS[2:0] - Accel full-scale selection
    000=+/-2g, 001=+/-4g, 010=+/-6g, 011=+/-8g, 100=+/-16g
  AST[1:0] - Accel self-test enable
    00=normal (no self-test), 01=positive st, 10=negative st, 11=not allowed
  SIM - SPI mode selection
    0=4-wire, 1=3-wire                           */
  this.connection.i2cWrite(this.address,
                           LSM9DS0XM.CTRL_REG2_XM,
                           0x00); // Set scale to 2g

  /* CTRL_REG3_XM is used to set interrupt generators on INT1_XM
  Bits (7-0): P1_BOOT P1_TAP P1_INT1 P1_INT2 P1_INTM P1_DRDYA P1_DRDYM P1_EMPTY
  */
  // Accelerometer data ready on INT1_XM (0x04)
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG3_XM, 0x04);
};

LSM9DS0XM.prototype._initMag = function() {
  /* CTRL_REG5_XM enables temp sensor, sets mag resolution and data rate
  Bits (7-0): TEMP_EN M_RES1 M_RES0 M_ODR2 M_ODR1 M_ODR0 LIR2 LIR1
  TEMP_EN - Enable temperature sensor (0=disabled, 1=enabled)
  M_RES[1:0] - Magnetometer resolution select (0=low, 3=high)
  M_ODR[2:0] - Magnetometer data rate select
    000=3.125Hz, 001=6.25Hz, 010=12.5Hz, 011=25Hz, 100=50Hz, 101=100Hz
  LIR2 - Latch interrupt request on INT2_SRC (cleared by reading INT2_SRC)
    0=interrupt request not latched, 1=interrupt request latched
  LIR1 - Latch interrupt request on INT1_SRC (cleared by readging INT1_SRC)
    0=irq not latched, 1=irq latched                   */
  // Mag data rate - 100 Hz, enable temperature sensor
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG5_XM, 0x94);

  /* CTRL_REG6_XM sets the magnetometer full-scale
  Bits (7-0): 0 MFS1 MFS0 0 0 0 0 0
  MFS[1:0] - Magnetic full-scale selection
  00:+/-2Gauss, 01:+/-4Gs, 10:+/-8Gs, 11:+/-12Gs               */
  // Mag scale to +/- 2GS
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG6_XM, 0x00);

  /* CTRL_REG7_XM sets magnetic sensor mode, low power mode, and filters
  AHPM1 AHPM0 AFDS 0 0 MLP MD1 MD0
  AHPM[1:0] - HPF mode selection
    00=normal (resets reference registers), 01=reference signal for filtering,
    10=normal, 11=autoreset on interrupt event
  AFDS - Filtered acceleration data selection
    0=internal filter bypassed, 1=data from internal filter sent to FIFO
  MLP - Magnetic data low-power mode
    0=data rate is set by M_ODR bits in CTRL_REG5
    1=data rate is set to 3.125Hz
  MD[1:0] - Magnetic sensor mode selection (default 10)
    00=continuous-conversion, 01=single-conversion, 10 and 11=power-down */
  // Continuous conversion mode
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG7_XM, 0x00);

  /* CTRL_REG4_XM is used to set interrupt generators on INT2_XM
  Bits (7-0): P2_TAP P2_INT1 P2_INT2 P2_INTM P2_DRDYA P2_DRDYM P2_Overrun P2_WTM
  */
  // Magnetometer data ready on INT2_XM (0x08)
  this.connection.i2cWrite(this.address, LSM9DS0XM.CTRL_REG4_XM, 0x04);

  /* INT_CTRL_REG_M to set push-pull/open drain, and active-low/high
  Bits[7:0] - XMIEN YMIEN ZMIEN PP_OD IEA IEL 4D MIEN
  XMIEN, YMIEN, ZMIEN - Enable interrupt recognition on axis for mag data
  PP_OD - Push-pull/open-drain interrupt configuration (0=push-pull, 1=od)
  IEA - Interrupt polarity for accel and magneto
    0=active-low, 1=active-high
  IEL - Latch interrupt request for accel and magneto
    0=irq not latched, 1=irq latched
  4D - 4D enable. 4D detection is enabled when 6D bit in INT_GEN1_REG is set
  MIEN - Enable interrupt generation for magnetic data
    0=disable, 1=enable) */
  // Enable interrupts for mag, active-low, push-pull
  this.connection.i2cWrite(this.address, LSM9DS0XM.INT_CTRL_REG_M, 0x09);
};