Home | History | Annotate | Download | only in hp20x
      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 HP20X_I2C_BUS 0
     31 #define HP20X_DEFAULT_I2C_ADDR 0x76
     32 
     33 namespace upm {
     34 
     35   /**
     36    * @brief HP20X I2C Barometer (High-Accuracy) library
     37    * @defgroup hp20x libupm-hp20x
     38    * @ingroup seeed i2c pressure
     39    */
     40 
     41   /**
     42    * @library hp20x
     43    * @sensor hp20x
     44    * @comname Grove Barometer (High-Accuracy)
     45    * @altname HP20X Barometer (High-Accuracy)
     46    * @type pressure
     47    * @man seeed
     48    * @web http://www.seeedstudio.com/depot/Grove-Barometer-HighAccuracy-p-1865.html
     49    * @con i2c
     50    *
     51    * @brief API for the HP20X-based Grove Barometer (High-Accuracy)
     52    *
     53    * This is a high-accuracy barometer providing pressure, altitude,
     54    * and temperature data. It can be calibrated for a given altitude
     55    * offset, and a wide range of interrupt generating capabilities are
     56    * supported. As usual, see the HP20X datasheet for more details.
     57    *
     58    * This module was developed using a Grove Barometer (High-Accuracy)
     59    * based on an HP206C chip.
     60    *
     61    * @image html hp20x.jpg
     62    * @snippet hp20x.cxx Interesting
     63    */
     64   class HP20X {
     65   public:
     66 
     67     /**
     68      * HP20X commands
     69      */
     70     typedef enum {
     71       CMD_SOFT_RST              = 0x06,
     72 
     73       CMD_ADC_CVT               = 0x40, // mask - ANDed with DSR and CHNL bits
     74 
     75       CMD_READ_PT               = 0x10, // read pressure/temp
     76       CMD_READ_AT               = 0x11, // read alt/temp
     77 
     78       CMD_READ_P                = 0x30, // read pressure only
     79       CMD_READ_A                = 0x31, // read alt only
     80       CMD_READ_T                = 0x32, // read temp only
     81 
     82       CMD_ANA_CAL               = 0x28, // recalibrate internal analog blocks
     83 
     84       CMD_READ_REG              = 0x80, // mask - ANDed with reg addr
     85       CMD_WRITE_REG             = 0xc0  // mask - ANDed with reg addr
     86     } HP20X_CMD_T;
     87 
     88     /**
     89      * CHNL bits
     90      */
     91     typedef enum {
     92       CHNL_PT                   = 0x00, // pressure and temperature
     93       CHNL_T                    = 0x02, // temperature
     94 
     95       CHNL_SHIFT                = 0 // don't use, indicates position in REG
     96     } CHNL_BITS_T;
     97 
     98     /**
     99      * DSR bits
    100      */
    101     typedef enum {
    102       DSR_4096                  = 0x00, // decimation rate of digital filter
    103       DSR_2048                  = 0x01,
    104       DSR_1024                  = 0x02,
    105       DSR_512                   = 0x03,
    106       DSR_256                   = 0x04,
    107       DSR_128                   = 0x05,
    108 
    109       DSR_SHIFT                 = 2 // don't use, indicates position in REG
    110     } DSR_BITS_T;
    111 
    112 
    113     /**
    114      * HP20X registers
    115      */
    116     typedef enum {
    117       REG_ALT_OFF_LSB           = 0x00,
    118       REG_ALT_OFF_MSB           = 0x01,
    119 
    120       REG_PA_H_TH_LSB           = 0x02, // Pres/Alt high threshold
    121       REG_PA_H_TH_MSB           = 0x03,
    122 
    123       REG_PA_M_TH_LSB           = 0x04, // Pres/Alt medium threshold
    124       REG_PA_M_TH_MSB           = 0x05,
    125 
    126       REG_PA_L_TH_LSB           = 0x06, // Pres/Alt low threshold
    127       REG_PA_L_TH_MSB           = 0x07,
    128 
    129       REG_T_H_TH                = 0x08, // temperature high threshold
    130       REG_T_M_TH                = 0x09,
    131       REG_T_L_TH                = 0x0a,
    132 
    133       REG_INT_EN                = 0x0b, // interrupt enables
    134       REG_INT_CFG               = 0x0c, // interrupt configuration
    135       REG_INT_SRC               = 0x0d, // interrupt sources
    136 
    137       REG_PARA                  = 0x0e  // parameters config
    138     } HP20X_REG_T;
    139 
    140     /**
    141      * INT_EN bits
    142      */
    143     typedef enum {
    144       INT_EN_T_WIN_EN           = 0x01,
    145       INT_EN_PA_WIN_EN          = 0x02,
    146 
    147       INT_EN_T_TRAV_EN          = 0x04,
    148       INT_EN_PA_TRAV_EN         = 0x08,
    149 
    150       INT_EN_T_RDY_EN           = 0x10,
    151       INT_EN_PA_RDY_EN          = 0x20
    152       // 0x40, 0x80 reserved
    153     } INT_EN_BITS_T;
    154 
    155     /**
    156      * INT_CFG bits
    157      */
    158     typedef enum {
    159       INT_CFG_T_WIN_CFG          = 0x01,
    160       INT_CFG_PA_WIN_CFG         = 0x02,
    161 
    162       INT_CFG_T_TRAV_CFG         = 0x04,
    163       INT_CFG_PA_TRAV_CFG        = 0x08,
    164 
    165       INT_CFG_T_RDY_CFG          = 0x10,
    166       INT_CFG_PA_RDY_CFG         = 0x20,
    167 
    168       INT_CFG_PA_MODE            = 0x40
    169       // 0x80 reserved
    170     } INT_CFG_BITS_T;
    171 
    172     /**
    173      * INT_SRC bits
    174      */
    175     typedef enum {
    176       INT_SRC_T_WIN              = 0x01,
    177       INT_SRC_PA_WIN             = 0x02,
    178 
    179       INT_SRC_T_TRAV             = 0x04,
    180       INT_SRC_PA_TRAV            = 0x08,
    181 
    182       INT_SRC_T_RDY              = 0x10,
    183       INT_SRC_PA_RDY             = 0x20,
    184 
    185       INT_SRC_DEV_RDY            = 0x40, // device is ready
    186 
    187       INT_SRC_TH_ERR             = 0x80 // threshold error
    188     } INT_SRC_BITS_T;
    189 
    190     /**
    191      * PARA bits
    192      */
    193     typedef enum {
    194       // 0x01-0x40 reserved
    195       PARA_CMPS_EN               = 0x80 // compensation enable
    196     } PARA_BITS_T;
    197 
    198     /**
    199      * HP20X constructor
    200      *
    201      * @param bus I2C bus to use
    202      * @param address Address for this device
    203      */
    204     HP20X(int bus=HP20X_I2C_BUS, uint8_t address=HP20X_DEFAULT_I2C_ADDR);
    205 
    206     /**
    207      * HP20X destructor
    208      */
    209     ~HP20X();
    210 
    211     /**
    212      * Sets up initial values and starts operation
    213      *
    214      * @param dsr Data sampling rate; one of the DSR_BITS_T values
    215      * @return True if successful
    216      */
    217     bool init(DSR_BITS_T dsr=DSR_4096);
    218 
    219     /**
    220      * Sends a command to the device
    221      *
    222      * @param cmd Command to send; usually, one of the HP20X_CMD_T values
    223      * @return True if successful
    224      */
    225     bool writeCmd(uint8_t cmd);
    226 
    227     /**
    228      * Writes a value to a register
    229      *
    230      * @param reg Register to write to; one of the HP20X_REG_T values
    231      * @param data Value to write
    232      * @return True if successful
    233      */
    234     bool writeReg(HP20X_REG_T reg, uint8_t data);
    235 
    236     /**
    237      * Reads a register and returns its value
    238      *
    239      * @param reg Register to read; one of the HP20X_REG_T values
    240      * @return Value of a specified register
    241      */
    242     uint8_t readReg(HP20X_REG_T reg);
    243 
    244     /**
    245      * Reads 3 bytes of data in response to a conversion request, and
    246      * converts it to an integer
    247      *
    248      * @return Value read back (temperature, pressure, etc.)
    249      */
    250     int readData();
    251 
    252     /**
    253      * Checks to see if the DR_RDY bit is set, indicating the device
    254      * can accept commands
    255      *
    256      * @return True if the device is ready, false otherwise
    257      */
    258     bool isReady();
    259 
    260     /**
    261      * Checks to see if the device is ready, and sleeps/retries if not.
    262      * Returns once the device indicates it's ready.
    263      *
    264      * @return True if the device is ready; false if retries are exhausted
    265      */
    266     bool waitforDeviceReady();
    267 
    268     /**
    269      * Returns the temperature in Celsius
    270      *
    271      * @return Temperature
    272      */
    273     float getTemperature();
    274 
    275     /**
    276      * Returns the pressure in millibars
    277      *
    278      * @return Pressure
    279      */
    280     float getPressure();
    281 
    282     /**
    283      * Returns the computed altitude in meters
    284      *
    285      * @return Altitude
    286      */
    287     float getAltitude();
    288 
    289     /**
    290      * Enables or disables the on-chip compensator. This allows the
    291      * chip to filter and clean up the output data.
    292      *
    293      * @param enable True to enable, false otherwise
    294      */
    295     void compensationEnable(bool enable);
    296 
    297     /**
    298      * Sets up the interrupt enable register. This register defines
    299      * which events can cause a hardware interrupt pin to be pulled high
    300      * (active).
    301      *
    302      * @param bits One or more of the INT_EN_BITS_T bits
    303      * @return True if successful, false otherwise
    304      */
    305     bool setInterruptEnable(uint8_t bits);
    306 
    307     /**
    308      * Sets up the interrupt configuration register. This register
    309      * defines which events can cause an interrupt to be indicated.
    310      *
    311      * @param bits One or more of the INT_EN_BITS_T bits
    312      * @return True if successful, false otherwise
    313      */
    314     bool setInterruptConfig(uint8_t bits);
    315 
    316     /**
    317      * Gets the interrupt source register. This register indicates
    318      * which interrupts have been triggered. In addition, it
    319      * indicates when certain operations have been completed.
    320      *
    321      * @return One of more of the INT_SRC_BITS_T values
    322      */
    323     uint8_t getInterruptSource();
    324 
    325     /**
    326      * Sets the data sampling rate. Higher rates are more precise, but
    327      * take more time per measurement.
    328      *
    329      * @param dsr One of the DSR_BITS_T values
    330      */
    331     void setDSR(DSR_BITS_T dsr);
    332 
    333 
    334     /**
    335      * Starts an internal recalibration of analog blocks. This is
    336      * faster than a soft reset.
    337      */
    338     void recalibrateInternal();
    339 
    340     /**
    341      * Executes a soft reset. All register values are reset to power-on
    342      * defaults. This function returns when the reset is
    343      * complete and the device reports it is ready.
    344      */
    345     void softReset();
    346 
    347     /**
    348      * Sets the altitude offset for your region. See the datasheet for
    349      * more details. Setting this correctly for your region is
    350      * required for accurate altitude data.
    351      *
    352      * @param off Offset
    353      */
    354     void setAltitudeOffset(int16_t off);
    355 
    356     /**
    357      * Sets pressure/altitude thresholds for interrupt generation
    358      *
    359      * @param low Low threshold to generate an interrupt
    360      * @param med Medium threshold to generate an interrupt
    361      * @param high High threshold to generate an interrupt
    362      */
    363     void setPAThreshholds(int16_t low, int16_t med, int16_t high);
    364 
    365     /**
    366      * Sets temperature thresholds for interrupt generation
    367      *
    368      * @param low Low threshold to generate an interrupt
    369      * @param med Medium threshold to generate an interrupt
    370      * @param high High threshold to generate an interrupt
    371      */
    372     void setTemperatureThreshholds(int8_t low, int8_t med, int8_t high);
    373 
    374 
    375   protected:
    376     mraa::I2c m_i2c;
    377 
    378   private:
    379     uint8_t m_addr;
    380     uint8_t m_dsr;
    381 
    382   };
    383 }
    384 
    385 
    386