1 /* 2 * Author: Jon Trulson <jtrulson@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