Home | History | Annotate | Download | only in h3lis331dl
      1 /*
      2  * Author: Jon Trulson <jtrulson (at) ics.com>
      3  * Copyright (c) 2015 Intel Corporation.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be
     14  * included in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 #pragma once
     25 
     26 #include <string>
     27 #include <mraa/common.hpp>
     28 #include <mraa/i2c.hpp>
     29 
     30 #define H3LIS331DL_I2C_BUS 0
     31 #define H3LIS331DL_DEFAULT_I2C_ADDR 0x18
     32 
     33 namespace upm {
     34 
     35   /**
     36    * @brief H3LIS331DL I2C Accelerometer (400g) library
     37    * @defgroup h3lis331dl libupm-h3lis331dl
     38    * @ingroup seeed i2c accelerometer
     39    */
     40 
     41   /**
     42    * @library h3lis331dl
     43    * @sensor h3lis331dl
     44    * @comname H3LIS331DL 3-Axis Digital Accelerometer
     45    * @altname Grove 3-Axis Digital Accelerometer (400g)
     46    * @type accelerometer
     47    * @man seeed
     48    * @web http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Accelerometer400g-p-1897.html
     49    * @con i2c
     50    *
     51    * @brief API for the H3LIS331DL-based Grove 3-Axis Digital Accelerometer (400g)
     52    *
     53    * This is a high-performance, high-range accelerometer for extreme applications.
     54    *
     55    * @image html h3lis331dl.jpg
     56    * @snippet h3lis331dl.cxx Interesting
     57    */
     58   class H3LIS331DL {
     59   public:
     60 
     61     /**
     62      * H3LIS331DL registers
     63      */
     64     typedef enum {
     65       // Reserved bytes must not be written into as they contain
     66       // factory calibration data. Changing those values may lead to
     67       // improper functioning of the device.
     68 
     69       // 0x00-0x0E reserved
     70 
     71       REG_WHOAMI                = 0x0f,
     72 
     73       // 0x10-0x1f reserved
     74 
     75       REG_REG1                  = 0x20,
     76       REG_REG2                  = 0x21,
     77       REG_REG3                  = 0x22,
     78       REG_REG4                  = 0x23,
     79       REG_REG5                  = 0x24,
     80 
     81       REG_HP_FILTER_RESET       = 0x25,
     82       REG_REFERENCE             = 0x26,
     83 
     84       REG_STATUS                = 0x27,
     85 
     86       REG_OUT_X_L               = 0x28,
     87       REG_OUT_X_H               = 0x29,
     88       REG_OUT_Y_L               = 0x2a,
     89       REG_OUT_Y_H               = 0x2b,
     90       REG_OUT_Z_L               = 0x2c,
     91       REG_OUT_Z_H               = 0x2d,
     92 
     93       // 0x2e, 0x2f reserved
     94 
     95       REG_INT1_CFG              = 0x30,
     96       REG_INT1_SRC              = 0x31,
     97       REG_INT1_THS              = 0x32,
     98       REG_INT1_DUR              = 0x33,
     99 
    100       REG_INT2_CFG              = 0x34,
    101       REG_INT2_SRC              = 0x35,
    102       REG_INT2_THS              = 0x36,
    103       REG_INT2_DUR              = 0x37,
    104 
    105       // 0x38-0x3f reserved
    106     } H3LIS331DL_REG_T;
    107 
    108     /**
    109      * REG1 bits
    110      */
    111     typedef enum {
    112       REG1_XEN                  = 0x01, // X-axis enable
    113       REG1_YEN                  = 0x02,
    114       REG1_ZEN                  = 0x04,
    115 
    116       REG1_DR0                  = 0x08, // data rate
    117       REG1_DR1                  = 0x10,
    118       REG1_DR_SHIFT             = 3,    // DR shift
    119 
    120       REG1_PM0                  = 0x20, // power mode
    121       REG1_PM1                  = 0x40,
    122       REG1_PM2                  = 0x80,
    123       REG1_PM_SHIFT             = 5
    124     } REG1_BITS_T;
    125 
    126     /**
    127      * REG1 DR (output rate) bits
    128      */
    129     typedef enum {
    130       DR_50_37                  = 0x0, // 50Hz output with 37Hz LPF cutoff
    131       DR_100_74                 = 0x1,
    132       DR_400_292                = 0x2,
    133       DR_1000_780               = 0x3
    134     } DR_BITS_T;
    135 
    136     /**
    137      * REG1 PM (power mode) bits
    138      */
    139     typedef enum {
    140       PM_POWERDWN               = 0x0,
    141       PM_NORMAL                 = 0x1,
    142       PM_LP05                   = 0x2, // .5 updates/sec
    143       PM_LP1                    = 0x3, // 1 update/sec
    144       PM_LP2                    = 0x4,
    145       PM_LP5                    = 0x5,
    146       PM_LP10                   = 0x6
    147     } PM_BITS_T;
    148 
    149     /**
    150      * REG2 bits
    151      */
    152     typedef enum {
    153       REG2_HPCF0                = 0x01,
    154       REG2_HPCF1                = 0x02,
    155       REG2_HPCF_SHIFT           = 0,
    156 
    157       REG2_HPEN1                = 0x04,
    158       REG2_HPEN2                = 0x08,
    159       REG2_FDS                  = 0x10,
    160 
    161       REG2_HPM0                 = 0x20,
    162       REG2_HPM1                 = 0x40,
    163       REG2_HPM_SHIFT            = 5,
    164 
    165       REG2_BOOT                 = 0x80
    166     } REG2_BITS_T;
    167 
    168     /**
    169      * REG2 HPCF (high-pass cutoff frequency) bits
    170      */
    171     typedef enum {
    172       HPCF_8                    = 0x0,
    173       HPCF_16                   = 0x1,
    174       HPCF_32                   = 0x2,
    175       HPCF_64                   = 0x3,
    176     } HPCF_BITS_T;
    177 
    178     /**
    179      * REG2 HPM (high-pass filter mode) bits
    180      */
    181     typedef enum {
    182       HPM_NORMAL0               = 0x0,
    183       HPM_REF                   = 0x1,
    184       HPM_NORMAL1               = 0x2
    185     } HPM_BITS_T;
    186 
    187     /**
    188      * REG3 bits
    189      */
    190     typedef enum {
    191       REG3_I1_CFG0              = 0x01,
    192       REG3_I1_CFG1              = 0x02,
    193       REG3_I1_CFG_SHIFT         = 0,
    194 
    195       REG3_LIR1                 = 0x04,
    196 
    197       REG3_I2_CFG0              = 0x08,
    198       REG3_I2_CFG1              = 0x10,
    199       REG3_I2_CFG_SHIFT         = 3,
    200 
    201       REG3_LIR2                 = 0x20,
    202       REG3_PP_OD                = 0x40,
    203       REG3_IHL                  = 0x80
    204     } REG3_BITS_T;
    205 
    206     /**
    207      * REG3 I1/I2 PAD control bits
    208      */
    209     typedef enum {
    210       I_SRC                     = 0x0, // INT source
    211       I_OR                      = 0x1, // INT1 OR INT2 source
    212       I_DR                      = 0x2, // Data Ready
    213       I_BOOTING                 = 0x3  // Boot is running
    214     } I_CFG_BITS_T;
    215 
    216     /**
    217      * REG4 bits
    218      */
    219     typedef enum {
    220       REG4_SIM                  = 0x01, // SPI 4 or 3 wire
    221 
    222       // bits 01,02,04 reserved
    223 
    224       REG4_FS0                  = 0x10,
    225       REG4_FS1                  = 0x20,
    226       REG4_FS_SHIFT             = 4,
    227 
    228       REG4_BLE                  = 0x40, // big/little-endian
    229       REG4_BDU                  = 0x80  // Block data update
    230     } REG4_BITS_T;
    231 
    232     /**
    233      * REG4 FS (full scale) bits
    234      */
    235     typedef enum {
    236       FS_100                    = 0x0, // 100g scale
    237       FS_200                    = 0x1, // 200g scale
    238       FS_400                    = 0x3  // 400g scale
    239     } FS_BITS_T;
    240 
    241     /**
    242      * REG5 TURNON (sleep to wake) bits
    243      */
    244     typedef enum {
    245       REG5_TURNON0              = 0x01, // turn-on mode for sleep-to-wake
    246       REG5_TURNON1              = 0x02
    247 
    248       // bits 04-80 reserved
    249     } REG5_BITS_T;
    250 
    251     /**
    252      * STATUS bits
    253      */
    254     typedef enum {
    255       STATUS_XDA                = 0x01, // X data available
    256       STATUS_YDA                = 0x02,
    257       STATUS_ZDA                = 0x04,
    258       STATUS_ZYXDA              = 0x08, // X, Y, and Z data available
    259       STATUS_XOR                = 0x10, // X overrun
    260       STATUS_YOR                = 0x20,
    261       STATUS_ZOR                = 0x40,
    262       STATUS_ZYXOR              = 0x80  // X, Y, and Z data overrun
    263     } STATUS_BITS_T;
    264 
    265     /**
    266      * INT1/INT2 CFG bits
    267      */
    268     typedef enum {
    269       INT_CFG_XLIE              = 0x01, // enable intr on low X event
    270       INT_CFG_XHIE              = 0x02, // enable intr on high X event
    271       INT_CFG_YLIE              = 0x04,
    272       INT_CFG_YHIE              = 0x08,
    273       INT_CFG_ZLIE              = 0x10,
    274       INT_CFG_ZHIE              = 0x20,
    275       // 0x40 reserved
    276       INT_CFG_AOI               = 0x80 // AND or OR combination or intrs
    277     } INT_CFG_BITS_T;
    278 
    279     /**
    280      * INT1/INT2 SRC bits
    281      */
    282     typedef enum {
    283       INT_SRC_XL                = 0x01, // X low intr event
    284       INT_SRC_XH                = 0x02, // X high intr event
    285       INT_SRC_YL                = 0x04,
    286       INT_SRC_YH                = 0x08,
    287       INT_SRC_ZL                = 0x10,
    288       INT_SRC_ZH                = 0x20,
    289       INT_SRC_IA                = 0x40  // Interrupt generated (active)
    290       // 0x80 reserved
    291     } INT_SRC_BITS_T;
    292 
    293     /**
    294      * H3LIS331DL constructor
    295      *
    296      * @param bus I2C bus to use
    297      * @param address Address for this device
    298      */
    299     H3LIS331DL(int bus, uint8_t address = H3LIS331DL_DEFAULT_I2C_ADDR);
    300 
    301     /**
    302      * H3LIS331DL destructor
    303      */
    304     ~H3LIS331DL();
    305 
    306     /**
    307      * Sets up initial values and starts operation
    308      *
    309      * @param odr Data rate: one of the DR_BITS_T values
    310      * @param pm Power mode: one of the PM_BITS_T values
    311      * @param fs FullScale: one of the FS_BITS_T values
    312      * @return True if successful
    313      */
    314     bool init(DR_BITS_T odr=DR_50_37, PM_BITS_T pm=PM_NORMAL,
    315               FS_BITS_T fs=FS_100);
    316 
    317     /**
    318      * Reads and returns the chip ID (WHO_AM_I register)
    319      *
    320      * @return True if successful
    321      */
    322     uint8_t getChipID();
    323 
    324     /**
    325      * Sets the output data rate
    326      *
    327      * @param One of the DR_BITS_T values
    328      * @return True if successful
    329      */
    330     bool setDataRate(DR_BITS_T odr);
    331 
    332     /**
    333      * Sets the power mode
    334      *
    335      * @param One of the PM_BITS_T values
    336      * @return True if successful
    337      */
    338     bool setPowerMode(PM_BITS_T pm);
    339 
    340     /**
    341      * Enables one or more of the 3 axes. The argument is a bitmask
    342      * composed of REG1_XEN, REG1_YEN, and/or REG1_ZEN corresponding to
    343      * the axes you want enabled.
    344      *
    345      * @param axisEnable Bitmask of axes to enable
    346      * (REG1_XEN | REG1_YEN | REG1_ZEN)
    347      * @return True if successful
    348      */
    349     bool enableAxis(uint8_t axisEnable);
    350 
    351     /**
    352      * Sets the scaling factor to 100g, 200g, or 400g
    353      *
    354      * @param fs One of the FS_BITS_T values
    355      * @return True if successful
    356      */
    357     bool setFullScale(FS_BITS_T fs);
    358 
    359     /**
    360      * Sets a high-pass cutoff filter
    361      *
    362      * @param val One of the HPCF_BITS_T values
    363      * @return True if successful
    364      */
    365     bool setHPCF(HPCF_BITS_T val);
    366 
    367     /**
    368      * Sets a high-pass filter mode
    369      *
    370      * @param val One of the HPM_BITS_T values
    371      * @return True if successful
    372      */
    373     bool setHPM(HPM_BITS_T val);
    374 
    375     /**
    376      * Boots the device. Booting the device causes internal flash
    377      * calibration values to be reloaded into the visible registers
    378      * in case they have been corrupted. This function
    379      * returns when the booting is complete.
    380      *
    381      * @return True if successful
    382      */
    383     bool boot();
    384 
    385     /**
    386      * Enables a high-pass filter for interrupt 1 source
    387      *
    388      * @param enable True to enable the filter, false otherwise
    389      * @return True if successful
    390      */
    391     bool enableHPF1(bool enable);
    392 
    393     /**
    394      * Enables a high-pass filter for interrupt 2 source
    395      *
    396      * @param enable True to enable the filter, false otherwise
    397      * @return True if successful
    398      */
    399     bool enableHPF2(bool enable);
    400 
    401     /**
    402      * Enables filtered data selection
    403      *
    404      * @param enable True to enable, false otherwise
    405      * @return True if successful
    406      */
    407     bool enableFDS(bool enable);
    408 
    409     /**
    410      * Sets interrupts to be active low instead of high
    411      *
    412      * @param enable True to enable, false otherwise
    413      * @return True if successful
    414      */
    415     bool setInterruptActiveLow(bool enable);
    416 
    417     /**
    418      * Sets an interrupt output mode to open drain rather than push/pull
    419      *
    420      * @param enable True to enable, false otherwise
    421      * @return True if successful
    422      */
    423     bool setInterruptOpenDrain(bool enable);
    424 
    425     /**
    426      * Enables interrupt 1 latch
    427      *
    428      * @param enable True to enable, false otherwise
    429      * @return True if successful
    430      */
    431     bool setInterrupt1Latch(bool enable);
    432 
    433     /**
    434      * Enables interrupt 2 latch
    435      *
    436      * @param enable True to enable, false otherwise
    437      * @return True if successful
    438      */
    439     bool setInterrupt2Latch(bool enable);
    440 
    441     /**
    442      * Sets the interrupt 1 pad configuration
    443      *
    444      * @param val One fo the I_CFG_BITS_T values
    445      * @return True if successful
    446      */
    447     bool setInterrupt1PadConfig(I_CFG_BITS_T val);
    448 
    449     /**
    450      * Sets the interrupt 2 pad configuration
    451      *
    452      * @param val One fo the I_CFG_BITS_T values
    453      * @return True if successful
    454      */
    455     bool setInterrupt2PadConfig(I_CFG_BITS_T val);
    456 
    457     /**
    458      * Enables block data update. When enabled, low/high output
    459      * registers are not updated until both low and high values have
    460      * been read.
    461      *
    462      * @param enable True to enable, false otherwise
    463      * @return True if successful
    464      */
    465     bool enableBDU(bool enable);
    466 
    467     /**
    468      * Enables big-endian output for 16b reads
    469      *
    470      * @param enable True to enable, false otherwise
    471      * @return True if successful
    472      */
    473     bool enableBLE(bool enable);
    474 
    475     /**
    476      * Enables sleep-to-wake functionality
    477      *
    478      * @param enable True to enable, false otherwise
    479      * @return True if successful
    480      */
    481     bool enableSleepToWake(bool enable);
    482 
    483     /**
    484      * Returns the contents of the REG_STATUS register
    485      *
    486      * @return Contents of the REG_STATUS register
    487      */
    488     uint8_t getStatus();
    489 
    490     /**
    491      * Sets up the interrupt 1 config register
    492      *
    493      * @param val Bitmask of desired INT_CFG_BITS_T bits
    494      * @return True if successful
    495      */
    496     bool setInterrupt1Config(uint8_t val);
    497 
    498     /**
    499      * Sets up the interrupt 2 config register
    500      *
    501      * @param val Bitmask of desired INT_CFG_BITS_T bits
    502      * @return True if successful
    503      */
    504     bool setInterrupt2Config(uint8_t val);
    505 
    506     /**
    507      * Sets up the interrupt 1 source register
    508      *
    509      * @param val Bitmask of desired INT_SRC_BITS_T bits
    510      * @return True if successful
    511      */
    512     bool setInterrupt1Source(uint8_t val);
    513 
    514     /**
    515      * Sets up the interrupt 2 source register
    516      *
    517      * @param val Bitmask of desired INT_SRC_BITS_T bits
    518      * @return True if successful
    519      */
    520     bool setInterrupt2Source(uint8_t val);
    521 
    522     /**
    523      * Sets up the interrupt 1 threshold register
    524      *
    525      * @param val Threshhold to set
    526      * @return True if successful
    527      */
    528     bool setInterrupt1Threshold(uint8_t val);
    529 
    530     /**
    531      * Sets up the interrupt 2 threshold register
    532      *
    533      * @param val Threshhold to set
    534      * @return True if successful
    535      */
    536     bool setInterrupt2Threshold(uint8_t val);
    537 
    538     /**
    539      * Sets up the interrupt 1 duration register
    540      *
    541      * @param val Duration to set
    542      * @return True if successful
    543      */
    544     bool setInterrupt1Duration(uint8_t val);
    545 
    546     /**
    547      * Sets up the interrupt 2 duration register
    548      *
    549      * @param val Duration to set
    550      * @return True if successful
    551      */
    552     bool setInterrupt2Duration(uint8_t val);
    553 
    554     /**
    555      * Reads the sensor and stores current values internally
    556      */
    557     void update();
    558 
    559     /**
    560      * Sets adjustment offsets for each of the axes. This can be used
    561      * for calibration. The values supplied here are subtracted
    562      * from the axis data read from the device.
    563      *
    564      * @param adjX Amount by which to correct the X-axis measurement
    565      * @param adjY Amount by which to correct the Y-axis measurement
    566      * @param adjZ Amount by which to correct the Z-axis measurement
    567      */
    568     void setAdjustmentOffsets(int adjX, int adjY, int adjZ);
    569 
    570     /**
    571      * Gets acceleration values for each of the axes
    572      *
    573      * @param aX Returned X-axis acceleration
    574      * @param aY Returned Y-axis acceleration
    575      * @param aZ Returned Z-axis acceleration
    576      */
    577     void getAcceleration(float *aX, float *aY, float *aZ);
    578 
    579     /**
    580      * Gets raw axis values
    581      *
    582      * @param x Returned raw X-axis value
    583      * @param y Returned raw Y-axis value
    584      * @param z Returned raw Z-axis value
    585      */
    586     void getRawXYZ(int *x, int *y, int *z);
    587 
    588     /**
    589      * Gets adjusted axis values
    590      *
    591      * @param x Returned X-axis value
    592      * @param y Returned Y-axis value
    593      * @param z Returned Z-axis value
    594      */
    595     void getXYZ(int *x, int *y, int *z);
    596 
    597 #ifdef SWIGJAVA
    598     /**
    599      * Gets acceleration values for each of the axes
    600      *
    601      * @return Array containing X, Y, Z acceleration values
    602      */
    603     float *getAcceleration();
    604 
    605     /**
    606      * Gets raw axis values
    607      *
    608      * @return Array containing X, Y, Z raw values
    609      */
    610     int *getRawXYZ();
    611 
    612     /**
    613      * Gets adjusted axis values
    614      *
    615      * @return Array containing X, Y, Z adjusted axis values
    616      */
    617     int *getXYZ();
    618 #endif
    619 
    620 
    621     /**
    622      * Provides public access to the MRAA I2C context of the class for
    623      * direct user access
    624      *
    625      * @return Reference to the class I2C context
    626      */
    627     mraa::I2c& i2cContext() { return m_i2c; };
    628 
    629 
    630   protected:
    631     int16_t m_rawX, m_rawY, m_rawZ;
    632     int16_t m_adjX, m_adjY, m_adjZ;
    633     mraa::I2c m_i2c;
    634 
    635   private:
    636     uint8_t m_addr;
    637   };
    638 }
    639 
    640 
    641