mirror of
https://github.com/eclipse/upm.git
synced 2025-07-01 09:21:12 +03:00
bmpx8x: rewrite in C; FTI; C++ wraps C
This driver has been rewritten from scratch. See docs/apichanges.md for a list of API compatibility changes compared to the original driver. Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
@ -1,5 +1,10 @@
|
||||
set (libname "bmpx8x")
|
||||
set (libdescription "Bosch BMP & GY65 Atmospheric Pressure Sensor Library")
|
||||
set (module_src ${libname}.cxx)
|
||||
set (module_hpp ${libname}.hpp)
|
||||
upm_module_init(mraa interfaces)
|
||||
upm_mixed_module_init (NAME bmpx8x
|
||||
DESCRIPTION "Pressure and temperature sensor"
|
||||
C_HDR bmpx8x.h bmpx8x_defs.h
|
||||
C_SRC bmpx8x.c
|
||||
CPP_HDR bmpx8x.hpp
|
||||
CPP_SRC bmpx8x.cxx
|
||||
FTI_SRC bmpx8x_fti.c
|
||||
CPP_WRAPS_C
|
||||
REQUIRES mraa interfaces)
|
||||
target_link_libraries(${libnamec} m)
|
||||
|
360
src/bmpx8x/bmpx8x.c
Normal file
360
src/bmpx8x/bmpx8x.c
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* This driver was rewritten based on the original driver written by:
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "upm_utilities.h"
|
||||
#include "upm_math.h"
|
||||
|
||||
#include "bmpx8x.h"
|
||||
|
||||
// UT is uncompensated temperature
|
||||
static int32_t _bmpx8x_computeB5(const bmpx8x_context dev, int32_t UT)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
int32_t X1 = (UT - (int32_t)dev->ac6) * ((int32_t)dev->ac5) >> 15;
|
||||
int32_t X2 = ((int32_t)dev->mc << 11) / (X1+(int32_t)dev->md);
|
||||
|
||||
return X1 + X2;
|
||||
}
|
||||
|
||||
static upm_result_t _bmpx8x_read_calibration_data(const bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
const int dataLen = 22;
|
||||
uint8_t calData[dataLen];
|
||||
|
||||
if (bmpx8x_read_regs(dev, BMPX8X_CAL_AC1, calData, dataLen) != dataLen)
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
|
||||
dev->ac1 = (int16_t)( (calData[0] << 8) | calData[1] );
|
||||
dev->ac2 = (int16_t)( (calData[2] << 8) | calData[3] );
|
||||
dev->ac3 = (int16_t)( (calData[4] << 8) | calData[5] );
|
||||
dev->ac4 = (uint16_t)( (calData[6] << 8) | calData[7] );
|
||||
dev->ac5 = (uint16_t)( (calData[8] << 8) | calData[9] );
|
||||
dev->ac6 = (uint16_t)( (calData[10] << 8) | calData[11] );
|
||||
|
||||
dev->b1 = (int16_t)( (calData[12] << 8) | calData[13] );
|
||||
dev->b2 = (int16_t)( (calData[14] << 8) | calData[15] );
|
||||
|
||||
dev->mb = (int16_t)( (calData[16] << 8) | calData[17] );
|
||||
dev->mc = (int16_t)( (calData[18] << 8) | calData[19] );
|
||||
dev->md = (int16_t)( (calData[20] << 8) | calData[21] );
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
||||
|
||||
// init
|
||||
bmpx8x_context bmpx8x_init(int bus, int addr)
|
||||
{
|
||||
bmpx8x_context dev =
|
||||
(bmpx8x_context)malloc(sizeof(struct _bmpx8x_context));
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
// zero out context
|
||||
memset((void *)dev, 0, sizeof(struct _bmpx8x_context));
|
||||
|
||||
// make sure MRAA is initialized
|
||||
if (mraa_init() != MRAA_SUCCESS)
|
||||
{
|
||||
printf("%s: mraa_init() failed.\n", __FUNCTION__);
|
||||
bmpx8x_close(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(dev->i2c = mraa_i2c_init(bus)))
|
||||
{
|
||||
printf("%s: mraa_i2c_init() failed.\n", __FUNCTION__);
|
||||
bmpx8x_close(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mraa_i2c_address(dev->i2c, addr))
|
||||
{
|
||||
printf("%s: mraa_i2c_address() failed.\n", __FUNCTION__);
|
||||
bmpx8x_close(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// check the chip id
|
||||
|
||||
uint8_t chipID = bmpx8x_get_chip_id(dev);
|
||||
|
||||
if (chipID != BMPX8X_DEFAULT_CHIPID)
|
||||
{
|
||||
printf("%s: invalid chip id: %02x. Expected %02x\n",
|
||||
__FUNCTION__, chipID, BMPX8X_DEFAULT_CHIPID);
|
||||
bmpx8x_close(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// call devinit with a default ultrahigh resolution mode
|
||||
if (bmpx8x_devinit(dev, BMPX8X_OSS_ULTRAHIGHRES))
|
||||
{
|
||||
printf("%s: bmpx8x_devinit() failed.\n", __FUNCTION__);
|
||||
bmpx8x_close(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
void bmpx8x_close(bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
if (dev->i2c)
|
||||
mraa_i2c_stop(dev->i2c);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
upm_result_t bmpx8x_devinit(const bmpx8x_context dev,
|
||||
BMPX8X_OSS_T oss)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
// first read calibration data
|
||||
if (_bmpx8x_read_calibration_data(dev))
|
||||
{
|
||||
printf("%s: _bmpx8x_read_calibration_data() failed.\n", __FUNCTION__);
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
// now set our oversampling mode
|
||||
bmpx8x_set_oversampling(dev, oss);
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t bmpx8x_get_chip_id(const bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
return bmpx8x_read_reg(dev, BMPX8X_CHIP_ID);
|
||||
}
|
||||
|
||||
upm_result_t bmpx8x_reset(const bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
if (bmpx8x_write_reg(dev, BMPX8X_RESET, BMPX8X_RESET_BYTE))
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
|
||||
upm_delay(1);
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
||||
|
||||
void bmpx8x_set_oversampling(const bmpx8x_context dev,
|
||||
BMPX8X_OSS_T oss)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
dev->oversampling = oss;
|
||||
}
|
||||
|
||||
upm_result_t bmpx8x_update(const bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
const int maxLen = 3; // maximum number of bytes we will read
|
||||
uint8_t buffer[maxLen];
|
||||
|
||||
// first we need to read the temperature
|
||||
|
||||
// send the measurement command, and sleep the required time
|
||||
// before reading it
|
||||
|
||||
if (bmpx8x_write_reg(dev, BMPX8X_CTRL_MEAS, BMPX8X_CMD_READ_TEMP))
|
||||
{
|
||||
printf("%s: bmpx8x_write_reg(tempcmd) failed.\n", __FUNCTION__);
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
upm_delay_ms(5);
|
||||
|
||||
if (bmpx8x_read_regs(dev, BMPX8X_OUTDATA_MSB, buffer, maxLen) != maxLen)
|
||||
{
|
||||
printf("%s: bmpx8x_read_regs(temp) failed.\n", __FUNCTION__);
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
// we only need the first 2 bytes, uncompensated temperature
|
||||
int32_t UT = (int32_t)( (buffer[0] << 8) | buffer[1] );
|
||||
|
||||
// now read in the uncompensated pressure - the delay time depends
|
||||
// on the oversampling value
|
||||
|
||||
uint8_t reg = BMPX8X_CMD_READ_PRESSURE |
|
||||
(dev->oversampling << _BMPX8X_CTRL_MEAS_OSS_SHIFT);
|
||||
|
||||
if (bmpx8x_write_reg(dev, BMPX8X_CTRL_MEAS, reg))
|
||||
{
|
||||
printf("%s: bmpx8x_write_reg(prescmd) failed.\n", __FUNCTION__);
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
switch(dev->oversampling)
|
||||
{
|
||||
case BMPX8X_OSS_ULTRALOWPOWER:
|
||||
upm_delay_ms(5);
|
||||
break;
|
||||
|
||||
case BMPX8X_OSS_STANDARD:
|
||||
upm_delay_ms(8);
|
||||
break;
|
||||
|
||||
case BMPX8X_OSS_HIGHRES:
|
||||
upm_delay_ms(14);
|
||||
break;
|
||||
|
||||
case BMPX8X_OSS_ULTRAHIGHRES:
|
||||
upm_delay_ms(26);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bmpx8x_read_regs(dev, BMPX8X_OUTDATA_MSB, buffer, maxLen) != maxLen)
|
||||
{
|
||||
printf("%s: bmpx8x_read_regs(pres) failed.\n", __FUNCTION__);
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
// uncompensated pressure
|
||||
|
||||
int32_t UP = ( (buffer[0] << 16) | (buffer[1] << 8) | buffer[2] );
|
||||
UP >>= (8 - dev->oversampling);
|
||||
|
||||
// now, compensate and store
|
||||
int32_t B3, B5, B6, X1, X2, X3, p;
|
||||
uint32_t B4, B7;
|
||||
|
||||
// temperature
|
||||
B5 = _bmpx8x_computeB5(dev, UT);
|
||||
|
||||
dev->temperature = (float)( (B5 + 8) >> 4 );
|
||||
dev->temperature /= 10.0;
|
||||
|
||||
// pressure
|
||||
B6 = B5 - 4000;
|
||||
X1 = ((int32_t)dev->b2 * ( (B6 * B6)>>12 )) >> 11;
|
||||
X2 = ((int32_t)dev->ac2 * B6) >> 11;
|
||||
X3 = X1 + X2;
|
||||
B3 = ((((int32_t)dev->ac1*4 + X3) << dev->oversampling) + 2) / 4;
|
||||
|
||||
X1 = ((int32_t)dev->ac3 * B6) >> 13;
|
||||
X2 = ((int32_t)dev->b1 * ((B6 * B6) >> 12)) >> 16;
|
||||
X3 = ((X1 + X2) + 2) >> 2;
|
||||
B4 = ((uint32_t)dev->ac4 * (uint32_t)(X3 + 32768)) >> 15;
|
||||
B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> dev->oversampling );
|
||||
|
||||
if (B7 < 0x80000000)
|
||||
p = (B7 * 2) / B4;
|
||||
else
|
||||
p = (B7 / B4) * 2;
|
||||
|
||||
X1 = (p >> 8) * (p >> 8);
|
||||
X1 = (X1 * 3038) >> 16;
|
||||
X2 = (-7357 * p) >> 16;
|
||||
|
||||
dev->pressure = p + ((X1 + X2 + (int32_t)3791)>>4);
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
||||
|
||||
int bmpx8x_get_pressure(const bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
return dev->pressure;
|
||||
}
|
||||
|
||||
float bmpx8x_get_temperature(const bmpx8x_context dev)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
return dev->temperature;
|
||||
}
|
||||
|
||||
int bmpx8x_get_sealevel_pressure(const bmpx8x_context dev,
|
||||
float altitude)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
return ((float)dev->pressure / powf(1.0-altitude/44330.0, 5.255));
|
||||
}
|
||||
|
||||
float bmpx8x_get_altitude(const bmpx8x_context dev, int sealevel)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
// avoid potential divide-by-0, and set the default to 101325 Pa
|
||||
if (sealevel <= 0)
|
||||
sealevel = 101325;
|
||||
|
||||
return 44307.69 * (1.0 - powf((float)dev->pressure / (float)sealevel,
|
||||
0.190284));
|
||||
}
|
||||
|
||||
uint8_t bmpx8x_read_reg(const bmpx8x_context dev, uint8_t reg)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
return (uint8_t)mraa_i2c_read_byte_data(dev->i2c, reg);
|
||||
}
|
||||
|
||||
int bmpx8x_read_regs(const bmpx8x_context dev, uint8_t reg,
|
||||
uint8_t *buffer, int len)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
if (mraa_i2c_read_bytes_data(dev->i2c, reg, buffer, len) != len)
|
||||
return -1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
upm_result_t bmpx8x_write_reg(const bmpx8x_context dev,
|
||||
uint8_t reg, uint8_t val)
|
||||
{
|
||||
assert(dev != NULL);
|
||||
|
||||
if (mraa_i2c_write_byte_data(dev->i2c, val, reg))
|
||||
{
|
||||
printf("%s: mraa_i2c_write_byte_data() failed.\n",
|
||||
__FUNCTION__);
|
||||
return UPM_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* This driver was rewritten based on the original driver written by:
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -31,202 +36,85 @@
|
||||
#include "bmpx8x.hpp"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
|
||||
BMPX8X::BMPX8X (int bus, int devAddr, uint8_t mode) : m_controlAddr(devAddr), m_i2ControlCtx(bus) {
|
||||
|
||||
m_name = "BMPX8X";
|
||||
|
||||
mraa::Result ret = m_i2ControlCtx.address(m_controlAddr);
|
||||
if (ret != mraa::SUCCESS) {
|
||||
throw std::invalid_argument(std::string(__FUNCTION__) +
|
||||
": mraa_i2c_address() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (i2cReadReg_8 (0xD0) != 0x55) {
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": Invalid chip ID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode > BMP085_ULTRAHIGHRES) {
|
||||
mode = BMP085_ULTRAHIGHRES;
|
||||
}
|
||||
oversampling = mode;
|
||||
|
||||
/* read calibration data */
|
||||
ac1 = i2cReadReg_16 (BMP085_CAL_AC1);
|
||||
ac2 = i2cReadReg_16 (BMP085_CAL_AC2);
|
||||
ac3 = i2cReadReg_16 (BMP085_CAL_AC3);
|
||||
ac4 = i2cReadReg_16 (BMP085_CAL_AC4);
|
||||
ac5 = i2cReadReg_16 (BMP085_CAL_AC5);
|
||||
ac6 = i2cReadReg_16 (BMP085_CAL_AC6);
|
||||
|
||||
b1 = i2cReadReg_16 (BMP085_CAL_B1);
|
||||
b2 = i2cReadReg_16 (BMP085_CAL_B2);
|
||||
|
||||
mb = i2cReadReg_16 (BMP085_CAL_MB);
|
||||
mc = i2cReadReg_16 (BMP085_CAL_MC);
|
||||
md = i2cReadReg_16 (BMP085_CAL_MD);
|
||||
BMPX8X::BMPX8X (int bus, int addr) :
|
||||
m_bmpx8x(bmpx8x_init(bus, addr))
|
||||
{
|
||||
if (!m_bmpx8x)
|
||||
throw std::runtime_error(string(__FUNCTION__)
|
||||
+ ": bmpx8x_init() failed");
|
||||
}
|
||||
|
||||
int32_t
|
||||
BMPX8X::getPressure () {
|
||||
int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
|
||||
uint32_t B4, B7;
|
||||
|
||||
UT = getTemperatureRaw();
|
||||
UP = getPressureRaw();
|
||||
B5 = computeB5(UT);
|
||||
|
||||
// do pressure calcs
|
||||
B6 = B5 - 4000;
|
||||
X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11;
|
||||
X2 = ((int32_t)ac2 * B6) >> 11;
|
||||
X3 = X1 + X2;
|
||||
B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4;
|
||||
|
||||
X1 = ((int32_t)ac3 * B6) >> 13;
|
||||
X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
|
||||
X3 = ((X1 + X2) + 2) >> 2;
|
||||
B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
|
||||
B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling );
|
||||
|
||||
if (B7 < 0x80000000) {
|
||||
p = (B7 * 2) / B4
|
||||
;
|
||||
} else {
|
||||
p = (B7 / B4) * 2;
|
||||
}
|
||||
X1 = (p >> 8) * (p >> 8);
|
||||
X1 = (X1 * 3038) >> 16;
|
||||
X2 = (-7357 * p) >> 16;
|
||||
|
||||
p = p + ((X1 + X2 + (int32_t)3791)>>4);
|
||||
|
||||
return p;
|
||||
BMPX8X::~BMPX8X()
|
||||
{
|
||||
bmpx8x_close(m_bmpx8x);
|
||||
}
|
||||
|
||||
int32_t
|
||||
BMPX8X::getPressureRaw () {
|
||||
uint32_t raw;
|
||||
|
||||
i2cWriteReg (BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));
|
||||
|
||||
if (oversampling == BMP085_ULTRALOWPOWER) {
|
||||
usleep(5000);
|
||||
} else if (oversampling == BMP085_STANDARD) {
|
||||
usleep(8000);
|
||||
} else if (oversampling == BMP085_HIGHRES) {
|
||||
usleep(14000);
|
||||
} else {
|
||||
usleep(26000);
|
||||
}
|
||||
|
||||
raw = i2cReadReg_16 (BMP085_PRESSUREDATA);
|
||||
|
||||
raw <<= 8;
|
||||
raw |= i2cReadReg_8 (BMP085_PRESSUREDATA + 2);
|
||||
raw >>= (8 - oversampling);
|
||||
|
||||
return raw;
|
||||
void BMPX8X::init(BMPX8X_OSS_T oss)
|
||||
{
|
||||
if (bmpx8x_devinit(m_bmpx8x, oss))
|
||||
throw std::runtime_error(string(__FUNCTION__)
|
||||
+ ": bmpx8x_devinit() failed");
|
||||
}
|
||||
|
||||
int16_t
|
||||
BMPX8X::getTemperatureRaw () {
|
||||
i2cWriteReg (BMP085_CONTROL, BMP085_READTEMPCMD);
|
||||
usleep(5000);
|
||||
return i2cReadReg_16 (BMP085_TEMPDATA);
|
||||
void BMPX8X::update()
|
||||
{
|
||||
if (bmpx8x_update(m_bmpx8x))
|
||||
throw std::runtime_error(string(__FUNCTION__)
|
||||
+ ": bmpx8x_update() failed");
|
||||
}
|
||||
|
||||
float
|
||||
BMPX8X::getTemperature () {
|
||||
int32_t UT, B5; // following ds convention
|
||||
float temp;
|
||||
|
||||
UT = getTemperatureRaw ();
|
||||
|
||||
B5 = computeB5 (UT);
|
||||
temp = (B5 + 8) >> 4;
|
||||
temp /= 10;
|
||||
|
||||
return temp;
|
||||
void BMPX8X::reset()
|
||||
{
|
||||
if (bmpx8x_reset(m_bmpx8x))
|
||||
throw std::runtime_error(string(__FUNCTION__)
|
||||
+ ": bmpx8x_reset() failed");
|
||||
}
|
||||
|
||||
int32_t
|
||||
BMPX8X::getSealevelPressure(float altitudeMeters) {
|
||||
float pressure = getPressure ();
|
||||
return (int32_t)(pressure / pow(1.0-altitudeMeters/44330, 5.255));
|
||||
void BMPX8X::setOversampling(BMPX8X_OSS_T oss)
|
||||
{
|
||||
bmpx8x_set_oversampling(m_bmpx8x, oss);
|
||||
}
|
||||
|
||||
float
|
||||
BMPX8X::getAltitude (float sealevelPressure) {
|
||||
float altitude;
|
||||
|
||||
float pressure = getPressure ();
|
||||
|
||||
altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));
|
||||
|
||||
return altitude;
|
||||
uint8_t BMPX8X::readReg(uint8_t reg)
|
||||
{
|
||||
return bmpx8x_read_reg(m_bmpx8x, reg);
|
||||
}
|
||||
|
||||
int BMPX8X::readRegs(uint8_t reg, uint8_t *buffer, int len)
|
||||
{
|
||||
int rv = bmpx8x_read_regs(m_bmpx8x, reg, buffer, len);
|
||||
if (rv < 0)
|
||||
throw std::runtime_error(string(__FUNCTION__)
|
||||
+ ": bmpx8x_read_regs() failed");
|
||||
|
||||
int
|
||||
BMPX8X::getTemperatureCelsius() {
|
||||
return static_cast<int>(getTemperature() + 0.5);
|
||||
return rv;
|
||||
}
|
||||
|
||||
const char*
|
||||
BMPX8X::getModuleName() {
|
||||
return m_name.c_str();
|
||||
void BMPX8X::writeReg(uint8_t reg, uint8_t val)
|
||||
{
|
||||
if (bmpx8x_write_reg(m_bmpx8x, reg, val))
|
||||
throw std::runtime_error(string(__FUNCTION__)
|
||||
+ ": bmpx8x_write_reg() failed");
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
BMPX8X::computeB5(int32_t UT) {
|
||||
int32_t X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) >> 15;
|
||||
int32_t X2 = ((int32_t)mc << 11) / (X1+(int32_t)md);
|
||||
|
||||
return X1 + X2;
|
||||
int BMPX8X::getPressure()
|
||||
{
|
||||
return bmpx8x_get_pressure(m_bmpx8x);
|
||||
}
|
||||
|
||||
mraa::Result
|
||||
BMPX8X::i2cWriteReg (uint8_t reg, uint8_t value) {
|
||||
mraa::Result error = mraa::SUCCESS;
|
||||
|
||||
uint8_t data[2] = { reg, value };
|
||||
error = m_i2ControlCtx.address (m_controlAddr);
|
||||
error = m_i2ControlCtx.write (data, 2);
|
||||
|
||||
return error;
|
||||
float BMPX8X::getTemperature()
|
||||
{
|
||||
return bmpx8x_get_temperature(m_bmpx8x);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
BMPX8X::i2cReadReg_16 (int reg) {
|
||||
uint16_t data;
|
||||
|
||||
m_i2ControlCtx.address(m_controlAddr);
|
||||
m_i2ControlCtx.writeByte(reg);
|
||||
|
||||
m_i2ControlCtx.address(m_controlAddr);
|
||||
m_i2ControlCtx.read((uint8_t *)&data, 0x2);
|
||||
|
||||
uint8_t high = (data & 0xFF00) >> 8;
|
||||
data = (data << 8) & 0xFF00;
|
||||
data |= high;
|
||||
|
||||
return data;
|
||||
int BMPX8X::getSealevelPressure(float altitudeMeters)
|
||||
{
|
||||
return bmpx8x_get_sealevel_pressure(m_bmpx8x, altitudeMeters);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
BMPX8X::i2cReadReg_8 (int reg) {
|
||||
uint8_t data;
|
||||
|
||||
m_i2ControlCtx.address(m_controlAddr);
|
||||
m_i2ControlCtx.writeByte(reg);
|
||||
|
||||
m_i2ControlCtx.address(m_controlAddr);
|
||||
m_i2ControlCtx.read(&data, 0x1);
|
||||
|
||||
return data;
|
||||
float BMPX8X::getAltitude(int sealevelPressure)
|
||||
{
|
||||
return bmpx8x_get_altitude(m_bmpx8x, sealevelPressure);
|
||||
}
|
||||
|
230
src/bmpx8x/bmpx8x.h
Normal file
230
src/bmpx8x/bmpx8x.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* This driver was rewritten based on the original driver written by:
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mraa/i2c.h>
|
||||
|
||||
#include "upm.h"
|
||||
|
||||
#include "bmpx8x_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file bmpx8x.h
|
||||
* @library bmpx8x
|
||||
* @brief C API for the bmpx8x driver
|
||||
*
|
||||
* @include bmpx8x.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* Device context
|
||||
*/
|
||||
typedef struct _bmpx8x_context {
|
||||
mraa_i2c_context i2c;
|
||||
|
||||
// our oversampling (precision)
|
||||
BMPX8X_OSS_T oversampling;
|
||||
|
||||
// compensated temperature and pressure
|
||||
float temperature;
|
||||
int pressure;
|
||||
|
||||
// compensation coefficients
|
||||
int16_t ac1;
|
||||
int16_t ac2;
|
||||
int16_t ac3;
|
||||
uint16_t ac4;
|
||||
uint16_t ac5;
|
||||
uint16_t ac6;
|
||||
int16_t b1;
|
||||
int16_t b2;
|
||||
int16_t mb;
|
||||
int16_t mc;
|
||||
int16_t md;
|
||||
} *bmpx8x_context;
|
||||
|
||||
|
||||
/**
|
||||
* BMPX8X initialization.
|
||||
*
|
||||
* By default, the device is initialized to it's highest accuracy
|
||||
* (BMP085_OSS_ULTRAHIGHRES).
|
||||
*
|
||||
* @param bus I2C bus number.
|
||||
* @param addr I2C address of the device.
|
||||
* @return Device context, or NULL if an error occurred.
|
||||
*/
|
||||
bmpx8x_context bmpx8x_init(int bus, int addr);
|
||||
|
||||
/**
|
||||
* BMPX8X close function.
|
||||
*
|
||||
* @param dev Device context.
|
||||
*/
|
||||
void bmpx8x_close(bmpx8x_context dev);
|
||||
|
||||
/**
|
||||
* Return the chip ID.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @return The chip ID.
|
||||
*/
|
||||
uint8_t bmpx8x_get_chip_id(const bmpx8x_context dev);
|
||||
|
||||
/**
|
||||
* Initialize the device, read calibration data, and start
|
||||
* operation. This function is called from bmpx8x_init() so it
|
||||
* will not typically need to be called by a user unless the
|
||||
* device is reset. This method will call
|
||||
* bmpx8x_set_oversampling() with the passed parameter.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @param oss One of the BMPX8X_OSS_T values. The default set
|
||||
* at bmpx8x_init() time is BMP085_OSS_ULTRAHIGHRES.
|
||||
* @return UPM result.
|
||||
*/
|
||||
upm_result_t bmpx8x_devinit(const bmpx8x_context dev,
|
||||
BMPX8X_OSS_T oss);
|
||||
|
||||
/**
|
||||
* Perform a device reset. The device will be reset as if it was
|
||||
* just powered on. All compensation values will be lost. You
|
||||
* should call bmpx8x_devinit() afterward, or perform the same
|
||||
* steps that bmpx8x_devinit() performs before attempting to use
|
||||
* the device.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @return UPM result.
|
||||
*/
|
||||
upm_result_t bmpx8x_reset(const bmpx8x_context dev);
|
||||
|
||||
/**
|
||||
* Update the internal stored values from sensor data.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @return UPM result.
|
||||
*/
|
||||
upm_result_t bmpx8x_update(const bmpx8x_context dev);
|
||||
|
||||
/**
|
||||
* Set the oversampling (precision mode) of the device. Higher
|
||||
* precision requires more time to complete.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @param oss The desired oversampling mode, one of the
|
||||
* BMPX8X_OSS_T values.
|
||||
*/
|
||||
void bmpx8x_set_oversampling(const bmpx8x_context dev,
|
||||
BMPX8X_OSS_T oss);
|
||||
|
||||
/**
|
||||
* Returns the pressure in Pascals. bmpx8x_update() must have
|
||||
* been called prior to calling this function.
|
||||
*
|
||||
* @param dev Device context.
|
||||
* @return The pressure in Pascals.
|
||||
*/
|
||||
int bmpx8x_get_pressure(const bmpx8x_context dev);
|
||||
|
||||
/**
|
||||
* Returns the temperature in degrees Celsius. bmpx8x_update()
|
||||
* must have been called prior to calling this function.
|
||||
*
|
||||
* @param dev Device context.
|
||||
* @return The temperature in degrees Celsius.
|
||||
*/
|
||||
float bmpx8x_get_temperature(const bmpx8x_context dev);
|
||||
|
||||
/**
|
||||
* With a given current altitude, calculate pressure at sea level.
|
||||
* bmpx8x_update() must have been called prior to calling this
|
||||
* function.
|
||||
*
|
||||
* @param dev Device context.
|
||||
* @param altitude Current altitude in Meters.
|
||||
* @return The pressure in Pascals at sea level.
|
||||
*/
|
||||
int bmpx8x_get_sealevel_pressure(const bmpx8x_context dev,
|
||||
float altitude);
|
||||
|
||||
/**
|
||||
* With a given sea level, calculate altitude in meters.
|
||||
* bmpx8x_update() must have been called prior to calling this
|
||||
* function.
|
||||
*
|
||||
* @param dev Device context.
|
||||
* @param sealevel Sea level pressure in Pascals. If a negative
|
||||
* number, or zero is supplied, a default sealevel of 101325 Pa
|
||||
* will be used instead.
|
||||
* @return The current altitude in Meters.
|
||||
*/
|
||||
float bmpx8x_get_altitude(const bmpx8x_context dev, int sealevel);
|
||||
|
||||
/**
|
||||
* Read a register.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @param reg The register to read.
|
||||
* @return The value of the register.
|
||||
*/
|
||||
uint8_t bmpx8x_read_reg(const bmpx8x_context dev, uint8_t reg);
|
||||
|
||||
/**
|
||||
* Read contiguous registers into a buffer.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @param buffer The buffer to store the results.
|
||||
* @param len The number of registers to read.
|
||||
* @return The number of bytes read, or -1 on error.
|
||||
*/
|
||||
int bmpx8x_read_regs(const bmpx8x_context dev, uint8_t reg,
|
||||
uint8_t *buffer, int len);
|
||||
|
||||
/**
|
||||
* Write to a register.
|
||||
*
|
||||
* @param dev The device context.
|
||||
* @param reg The register to write to.
|
||||
* @param val The value to write.
|
||||
* @return UPM result.
|
||||
*/
|
||||
upm_result_t bmpx8x_write_reg(const bmpx8x_context dev,
|
||||
uint8_t reg, uint8_t val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* Credits to Adafruit.
|
||||
* Based on Adafruit BMP085 library.
|
||||
* This driver was rewritten based on the original driver written by:
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -28,182 +29,218 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mraa/i2c.hpp>
|
||||
#include <math.h>
|
||||
|
||||
#include "bmpx8x.h"
|
||||
|
||||
#include "interfaces/iPressureSensor.hpp"
|
||||
#include "interfaces/iTemperatureSensor.hpp"
|
||||
|
||||
#define ADDR 0x77 // device address
|
||||
|
||||
// registers address
|
||||
#define BMP085_ULTRALOWPOWER 0
|
||||
#define BMP085_STANDARD 1
|
||||
#define BMP085_HIGHRES 2
|
||||
#define BMP085_ULTRAHIGHRES 3
|
||||
#define BMP085_CAL_AC1 0xAA // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_AC2 0xAC // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_AC3 0xAE // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_AC4 0xB0 // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_AC5 0xB2 // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_AC6 0xB4 // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_B1 0xB6 // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_B2 0xB8 // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_MB 0xBA // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_MC 0xBC // R Calibration data (16 bits)
|
||||
#define BMP085_CAL_MD 0xBE // R Calibration data (16 bits)
|
||||
|
||||
#define BMP085_CONTROL 0xF4
|
||||
#define BMP085_TEMPDATA 0xF6
|
||||
#define BMP085_PRESSUREDATA 0xF6
|
||||
#define BMP085_READTEMPCMD 0x2E
|
||||
#define BMP085_READPRESSURECMD 0x34
|
||||
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
|
||||
namespace upm {
|
||||
|
||||
/**
|
||||
* @brief Bosch BMP & GY65 Atmospheric Pressure Sensor library
|
||||
* @defgroup bmpx8x libupm-bmpx8x
|
||||
* @ingroup seeed adafruit sparkfun i2c pressure
|
||||
*/
|
||||
/**
|
||||
* @brief Bosch BMP & GY65 Atmospheric Pressure Sensor library
|
||||
* @defgroup bmpx8x libupm-bmpx8x @ingroup seeed adafruit sparkfun i2c
|
||||
* pressure
|
||||
*/
|
||||
|
||||
/**
|
||||
* @library bmpx8x
|
||||
* @sensor bmpx8x
|
||||
* @comname BMP Atmospheric Pressure Sensor
|
||||
* @altname GY65 BMP085 BMP180 BMP183
|
||||
* @type pressure
|
||||
* @man seeed adafruit sparkfun
|
||||
* @con i2c
|
||||
* @web https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf
|
||||
* @web https://www.bosch-sensortec.com/bst/products/all_products/bmp180
|
||||
* @web https://cdn-shop.adafruit.com/datasheets/1900_BMP183.pdf
|
||||
*
|
||||
* @brief API for the GY65/BMP085 and BMP180 Atmospheric Pressure Sensors
|
||||
*
|
||||
* Bosch GY65/BMP085 and BMP180 are high-precision, ultra-low
|
||||
* power consumption pressure sensors. They operate in the range of
|
||||
* 30,000-110,000 Pa.
|
||||
*
|
||||
* This module has been tested on the GY65/BMP085 and BMP180 sensors.
|
||||
*
|
||||
* @image html bmp085.jpeg
|
||||
* @snippet bmpx8x.cxx Interesting
|
||||
*/
|
||||
/**
|
||||
* @library bmpx8x
|
||||
* @sensor bmpx8x
|
||||
* @comname BMP Atmospheric Pressure Sensor
|
||||
* @altname GY65 BMP085 BMP180 BMP183
|
||||
* @type pressure
|
||||
* @man seeed adafruit sparkfun
|
||||
* @con i2c
|
||||
* @web https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf
|
||||
* @web https://www.bosch-sensortec.com/bst/products/all_products/bmp180
|
||||
* @web https://cdn-shop.adafruit.com/datasheets/1900_BMP183.pdf
|
||||
*
|
||||
* @brief API for the GY65/BMP085 and BMP180 Atmospheric Pressure Sensors
|
||||
*
|
||||
* Bosch GY65/BMP085 and BMP180 are high-precision, ultra-low
|
||||
* power consumption pressure sensors. They operate in the range of
|
||||
* 30,000-110,000 Pa.
|
||||
*
|
||||
* This module has been tested on the GY65/BMP085 and BMP180 sensors.
|
||||
*
|
||||
* @image html bmp085.jpeg
|
||||
* @snippet bmpx8x.cxx Interesting
|
||||
*/
|
||||
|
||||
class BMPX8X : public IPressureSensor, public ITemperatureSensor {
|
||||
class BMPX8X : public IPressureSensor, public ITemperatureSensor {
|
||||
public:
|
||||
/**
|
||||
* Instantiates a BMPX8X object
|
||||
*
|
||||
* @param bus Number of the used bus
|
||||
* @param devAddr Address of the used I2C device
|
||||
* @param mode BMP085 mode
|
||||
* @param bus I2C bus to use.
|
||||
* @param addr The I2C address of the device.
|
||||
* @throws std::runtime_error on failure.
|
||||
*/
|
||||
BMPX8X (int bus, int devAddr=0x77, uint8_t mode=BMP085_ULTRAHIGHRES);
|
||||
BMPX8X(int bus=BMPX8X_DEFAULT_I2C_BUS,
|
||||
int addr=BMPX8X_DEFAULT_I2C_ADDR);
|
||||
|
||||
/**
|
||||
* BMPX8X object destructor; basically, it closes the I2C connection.
|
||||
* ~BMPX8X ();
|
||||
* LE: there is no need for the destructor, as the I2C connection
|
||||
* will be closed when the m_i2ControlCtx variable will go out of
|
||||
* scope (when all the BMPX8X objects will be destroyed)
|
||||
* BMPX8X object destructor.
|
||||
*/
|
||||
/**
|
||||
* Returns the calculated pressure
|
||||
*/
|
||||
int32_t getPressure ();
|
||||
virtual ~BMPX8X();
|
||||
|
||||
/**
|
||||
* Query the device and update the internal state. This
|
||||
* method must be called before calling getPressure(),
|
||||
* getTemperature(), getSealevelPressure(), and getAltitude()
|
||||
* to retrieve values.
|
||||
*
|
||||
* Gets raw pressure data
|
||||
* @throws std::runtime_error on failure.
|
||||
*/
|
||||
int32_t getPressureRaw ();
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Gets raw temperature data from the sensor
|
||||
*/
|
||||
int16_t getTemperatureRaw ();
|
||||
|
||||
/**
|
||||
* Returns the calculated temperature
|
||||
*/
|
||||
float getTemperature ();
|
||||
|
||||
/**
|
||||
* With a given absolute altitude, sea level can be calculated
|
||||
* Reset the device to power-on defaults. All calibration
|
||||
* data is lost when the device is reset, so you should call
|
||||
* init() before attempting to use the device.
|
||||
*
|
||||
* @param altitudeMeters Altitude
|
||||
* @throws std::runtime_error on failure.
|
||||
*/
|
||||
int32_t getSealevelPressure(float altitudeMeters = 0);
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* With a given sea level, altitude in meters can be calculated
|
||||
* Initialize the device, read calibration data, and start
|
||||
* operation. This function is called from the constructor,
|
||||
* so it will not typically need to be called by a user unless
|
||||
* the device is reset.
|
||||
*
|
||||
* @param sealevelPressure Sea level
|
||||
* @param oss One of the BMPX8X_OSS_T values. The
|
||||
* default is BMPX8X_OSS_ULTRAHIGHRES.
|
||||
* @throws std::runtime_error on failure.
|
||||
*/
|
||||
float getAltitude (float sealevelPressure = 101325);
|
||||
void init(BMPX8X_OSS_T oss=BMPX8X_OSS_ULTRAHIGHRES);
|
||||
|
||||
/**
|
||||
* Return latest calculated temperature value in Celsius
|
||||
* See ITemperatureSensor
|
||||
*/
|
||||
int getTemperatureCelsius();
|
||||
|
||||
/**
|
||||
* Return latest calculated pressure value in Pascals
|
||||
* See IPressureSensor
|
||||
*/
|
||||
int getPressurePa() { return getPressure(); };
|
||||
|
||||
/**
|
||||
* Returns name of module. This is the string in library name
|
||||
* after libupm_
|
||||
|
||||
* @return name of module
|
||||
*/
|
||||
const char* getModuleName();
|
||||
|
||||
/**
|
||||
* Calculates B5 (check the spec for more information)
|
||||
* Set the oversampling (precision mode) of the device.
|
||||
* Higher precision requires more time to complete. This call
|
||||
* takes effect the next time update() is called.
|
||||
*
|
||||
* @param UT
|
||||
* @param oss One of the BMPX8X_OSS_T values. The
|
||||
* default is BMPX8X_OSS_ULTRAHIGHRES.
|
||||
*/
|
||||
int32_t computeB5 (int32_t UT);
|
||||
void setOversampling(BMPX8X_OSS_T oss=BMPX8X_OSS_ULTRAHIGHRES);
|
||||
|
||||
/**
|
||||
* Reads a two-byte register
|
||||
* Returns the calculated pressure in Pascals. update() must
|
||||
* have been called prior to calling this function.
|
||||
*
|
||||
* @param reg Address of the register
|
||||
* @returns The pressure in Pascals.
|
||||
*/
|
||||
uint16_t i2cReadReg_16 (int reg);
|
||||
int getPressure();
|
||||
|
||||
/**
|
||||
* Writes to a one-byte register
|
||||
* Returns the calculated temperature in Celsius. update()
|
||||
* must have been called prior to calling this function.
|
||||
*
|
||||
* @param reg Address of the register
|
||||
* @param value Byte to be written
|
||||
* @returns The temperature in Celsius.
|
||||
*/
|
||||
mraa::Result i2cWriteReg (uint8_t reg, uint8_t value);
|
||||
float getTemperature();
|
||||
|
||||
/**
|
||||
* Reads a one-byte register
|
||||
* Using the supplied altitude in meters, compute the pressure
|
||||
* at sea level in Pascals. update() must have been called
|
||||
* prior to calling this function.
|
||||
*
|
||||
* @param reg Address of the register
|
||||
* @param meters The altitude in meters.
|
||||
* @returns The computed sea level pressure in Pascals.
|
||||
*/
|
||||
uint8_t i2cReadReg_8 (int reg);
|
||||
int getSealevelPressure(float meters);
|
||||
|
||||
/**
|
||||
* Using the current calculated altitude, compute the pressure
|
||||
* at sea level in Pascals. update() must have been called
|
||||
* prior to calling this function.
|
||||
*
|
||||
* @returns The computed sea level pressure in Pascals.
|
||||
*/
|
||||
int getSealevelPressure()
|
||||
{
|
||||
return getSealevelPressure(getAltitude());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current altitude in meters, given a sea level
|
||||
* pressure in Pascals. The default sea level pressure is
|
||||
* 101325 Pascals. update() must have been called prior to
|
||||
* calling this function.
|
||||
*
|
||||
* @param sealevelPressure The pressure at sea level in
|
||||
* Pascals. The default is 101325 Pascals.
|
||||
* @returns the computed altitude in meters.
|
||||
*/
|
||||
float getAltitude(int sealevelPressure = 101325);
|
||||
|
||||
/**
|
||||
* Return latest calculated temperature value in Celsius. See
|
||||
* ITemperatureSensor.
|
||||
*
|
||||
* @return The current temperature in Celsius.
|
||||
*/
|
||||
int getTemperatureCelsius()
|
||||
{
|
||||
update();
|
||||
return (int)getTemperature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return latest calculated pressure value in Pascals. See
|
||||
* IPressureSensor.
|
||||
*
|
||||
* @return The current pressure in Pascals.
|
||||
*/
|
||||
int getPressurePa()
|
||||
{
|
||||
update();
|
||||
return getPressure();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of module.
|
||||
*
|
||||
* @return The name of the module.
|
||||
*/
|
||||
const char *getModuleName()
|
||||
{
|
||||
return "BMPX8X";
|
||||
}
|
||||
|
||||
protected:
|
||||
// our underlying C context.
|
||||
bmpx8x_context m_bmpx8x;
|
||||
|
||||
/**
|
||||
* Read a register.
|
||||
*
|
||||
* @param reg The register to read.
|
||||
* @return The value of the register.
|
||||
*/
|
||||
uint8_t readReg(uint8_t reg);
|
||||
|
||||
/**
|
||||
* Read contiguous registers into a buffer.
|
||||
*
|
||||
* @param buffer The buffer to store the results.
|
||||
* @param len The number of registers to read.
|
||||
* @return The number of bytes read.
|
||||
* @throws std::runtime_error on failure.
|
||||
*/
|
||||
int readRegs(uint8_t reg, uint8_t *buffer, int len);
|
||||
|
||||
/**
|
||||
* Write to a register.
|
||||
*
|
||||
* @param reg The register to write to.
|
||||
* @param val The value to write.
|
||||
* @throws std::runtime_error on failure.
|
||||
*/
|
||||
void writeReg(uint8_t reg, uint8_t val);
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
||||
int m_controlAddr;
|
||||
mraa::I2c m_i2ControlCtx;
|
||||
|
||||
uint8_t oversampling;
|
||||
int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
|
||||
uint16_t ac4, ac5, ac6;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
110
src/bmpx8x/bmpx8x_defs.h
Normal file
110
src/bmpx8x/bmpx8x_defs.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* This driver was rewritten based on the original driver written by:
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define BMPX8X_DEFAULT_I2C_BUS 0
|
||||
#define BMPX8X_DEFAULT_I2C_ADDR 0x77
|
||||
#define BMPX8X_DEFAULT_CHIPID 0x55
|
||||
// special reset byte
|
||||
#define BMPX8X_RESET_BYTE 0xb6
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BMPX8X registers.
|
||||
*/
|
||||
typedef enum {
|
||||
BMPX8X_CAL_AC1 = 0xaa, // Calibration data (16
|
||||
// bits, msb/lsb)
|
||||
BMPX8X_CAL_AC2 = 0xac,
|
||||
BMPX8X_CAL_AC3 = 0xae,
|
||||
BMPX8X_CAL_AC4 = 0xb0,
|
||||
BMPX8X_CAL_AC5 = 0xb2,
|
||||
BMPX8X_CAL_AC6 = 0xb4,
|
||||
BMPX8X_CAL_B1 = 0xb6,
|
||||
BMPX8X_CAL_B2 = 0xb8,
|
||||
BMPX8X_CAL_MB = 0xba,
|
||||
BMPX8X_CAL_MC = 0xbc,
|
||||
BMPX8X_CAL_MD = 0xbe,
|
||||
|
||||
BMPX8X_CTRL_MEAS = 0xf4, // command reg
|
||||
|
||||
BMPX8X_OUTDATA_MSB = 0xf6,
|
||||
BMPX8X_OUTDATA_LSB = 0xf7,
|
||||
BMPX8X_OUTDATA_XLSB = 0xf8,
|
||||
|
||||
BMPX8X_RESET = 0xe0,
|
||||
|
||||
BMPX8X_CHIP_ID = 0xd0
|
||||
} BMPX8X_REGS_T;
|
||||
|
||||
/**
|
||||
* BMPX8X_CTRL_MEAS register bits
|
||||
*/
|
||||
typedef enum {
|
||||
BMPX8X_CTRL_MEAS_CMD0 = 0x01, // measurement command
|
||||
BMPX8X_CTRL_MEAS_CMD1 = 0x02,
|
||||
BMPX8X_CTRL_MEAS_CMD2 = 0x04,
|
||||
BMPX8X_CTRL_MEAS_CMD3 = 0x08,
|
||||
BMPX8X_CTRL_MEAS_CMD4 = 0x10,
|
||||
_BMPX8X_CTRL_MEAS_CMD_MASK = 31,
|
||||
_BMPX8X_CTRL_MEAS_CMD_SHIFT = 0,
|
||||
|
||||
BMPX8X_CTRL_MEAS_SCO = 0x20, // start conversion status
|
||||
|
||||
BMPX8X_CTRL_MEAS_OSS0 = 0x40, // oversampling (precision)
|
||||
BMPX8X_CTRL_MEAS_OSS1 = 0x80,
|
||||
_BMPX8X_CTRL_MEAS_OSS_MASK = 3,
|
||||
_BMPX8X_CTRL_MEAS_OSS_SHIFT = 6,
|
||||
} BMPX8X_CTRL_MEAS_BITS_T;
|
||||
|
||||
/**
|
||||
* BMPX8X_CTRL_MEAS_CMD commands.
|
||||
*/
|
||||
typedef enum {
|
||||
BMPX8X_CMD_READ_TEMP = 0x2e,
|
||||
BMPX8X_CMD_READ_PRESSURE = 0x34
|
||||
} BMPX8X_CMD_T;
|
||||
|
||||
/**
|
||||
* BMPX8X_CTRL_MEAS_OSS, Oversampling ratio values.
|
||||
*/
|
||||
typedef enum {
|
||||
BMPX8X_OSS_ULTRALOWPOWER = 0,
|
||||
BMPX8X_OSS_STANDARD = 1,
|
||||
BMPX8X_OSS_HIGHRES = 2,
|
||||
BMPX8X_OSS_ULTRAHIGHRES = 3
|
||||
} BMPX8X_OSS_T;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
137
src/bmpx8x/bmpx8x_fti.c
Normal file
137
src/bmpx8x/bmpx8x_fti.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 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 "bmpx8x.h"
|
||||
#include "upm_fti.h"
|
||||
|
||||
/**
|
||||
* This file implements the Function Table Interface (FTI) for this sensor
|
||||
*/
|
||||
|
||||
const char upm_bmpx8x_name[] = "BMPX8X";
|
||||
const char upm_bmpx8x_description[] = "BMPX8X Pressure and Temperature Sensor";
|
||||
const upm_protocol_t upm_bmpx8x_protocol[] = {UPM_I2C};
|
||||
const upm_sensor_t upm_bmpx8x_category[] = {UPM_TEMPERATURE, UPM_PRESSURE};
|
||||
|
||||
// forward declarations
|
||||
const void* upm_bmpx8x_get_ft(upm_sensor_t sensor_type);
|
||||
void* upm_bmpx8x_init_name();
|
||||
void upm_bmpx8x_close(void *dev);
|
||||
upm_result_t upm_bmpx8x_get_pressure(void *dev, float *value);
|
||||
upm_result_t upm_bmpx8x_get_temperature(void *dev, float *value,
|
||||
upm_temperature_u unit);
|
||||
|
||||
const upm_sensor_descriptor_t upm_bmpx8x_get_descriptor()
|
||||
{
|
||||
upm_sensor_descriptor_t usd;
|
||||
usd.name = upm_bmpx8x_name;
|
||||
usd.description = upm_bmpx8x_description;
|
||||
usd.protocol_size = 1;
|
||||
usd.protocol = upm_bmpx8x_protocol;
|
||||
usd.category_size = 2;
|
||||
usd.category = upm_bmpx8x_category;
|
||||
return usd;
|
||||
}
|
||||
|
||||
static const upm_sensor_ft ft =
|
||||
{
|
||||
.upm_sensor_init_name = upm_bmpx8x_init_name,
|
||||
.upm_sensor_close = upm_bmpx8x_close,
|
||||
};
|
||||
|
||||
static const upm_temperature_ft tft =
|
||||
{
|
||||
.upm_temperature_get_value = upm_bmpx8x_get_temperature,
|
||||
};
|
||||
|
||||
static const upm_pressure_ft pft =
|
||||
{
|
||||
.upm_pressure_get_value = upm_bmpx8x_get_pressure,
|
||||
};
|
||||
|
||||
const void* upm_bmpx8x_get_ft(upm_sensor_t sensor_type)
|
||||
{
|
||||
switch(sensor_type)
|
||||
{
|
||||
case UPM_SENSOR:
|
||||
return &ft;
|
||||
case UPM_PRESSURE:
|
||||
return &pft;
|
||||
case UPM_TEMPERATURE:
|
||||
return &tft;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void* upm_bmpx8x_init_name()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void upm_bmpx8x_close(void *dev)
|
||||
{
|
||||
bmpx8x_close((bmpx8x_context)dev);
|
||||
}
|
||||
|
||||
upm_result_t upm_bmpx8x_get_pressure(void *dev, float *value)
|
||||
{
|
||||
upm_result_t rv;
|
||||
|
||||
if ((rv = bmpx8x_update((bmpx8x_context)dev)))
|
||||
return rv;
|
||||
|
||||
*value = bmpx8x_get_pressure((bmpx8x_context)dev);
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
||||
|
||||
upm_result_t upm_bmpx8x_get_temperature(void *dev, float *value,
|
||||
upm_temperature_u unit)
|
||||
{
|
||||
upm_result_t rv;
|
||||
|
||||
if ((rv = bmpx8x_update((bmpx8x_context)dev)))
|
||||
return rv;
|
||||
|
||||
// always in C
|
||||
float temp = bmpx8x_get_temperature((bmpx8x_context)dev);
|
||||
|
||||
switch (unit)
|
||||
{
|
||||
case CELSIUS:
|
||||
*value = temp;
|
||||
return UPM_SUCCESS;
|
||||
|
||||
case KELVIN:
|
||||
*value = temp + 273.15;
|
||||
return UPM_SUCCESS;
|
||||
|
||||
case FAHRENHEIT:
|
||||
*value = temp * (9.0/5.0) + 32.0;
|
||||
return UPM_SUCCESS;
|
||||
}
|
||||
|
||||
return UPM_SUCCESS;
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "bmpx8x.hpp"
|
||||
%}
|
||||
|
||||
%include "bmpx8x_defs.h"
|
||||
%include "bmpx8x.hpp"
|
||||
|
||||
%pragma(java) jniclasscode=%{
|
||||
|
@ -5,4 +5,5 @@
|
||||
#include "bmpx8x.hpp"
|
||||
%}
|
||||
|
||||
%include "bmpx8x_defs.h"
|
||||
%include "bmpx8x.hpp"
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
%include "stdint.i"
|
||||
|
||||
%include "bmpx8x_defs.h"
|
||||
%include "bmpx8x.hpp"
|
||||
%{
|
||||
#include "bmpx8x.hpp"
|
||||
|
Reference in New Issue
Block a user