mirror of
https://github.com/eclipse/upm.git
synced 2025-03-16 05:27:28 +03:00

remove utf8 characters from: * examples/c++/mcp9808.cxx * examples/c++/tmp006.cxx * src/bmp280/bmp280.c * src/max30100/max30100.c add -j8 options to make command in scripts/sonar-scan.sh Signed-off-by: Nicolas Oliver <dario.n.oliver@intel.com>
781 lines
23 KiB
C
781 lines
23 KiB
C
/*
|
|
* Author: Jon Trulson <jtrulson@ics.com>
|
|
* Copyright (c) 2016-2017 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
|
|
* "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 <string.h>
|
|
#include <assert.h>
|
|
#include <upm_utilities.h>
|
|
|
|
#include "bmp280.h"
|
|
|
|
// number of bytes of stored calibration data (bmp280)
|
|
#define BMP280_CALIBRATION_BYTES (26)
|
|
// BME280 has these additional calibration regs
|
|
#define BME280_CALIBRATION_BYTES (7)
|
|
|
|
// Number of bytes to get bmp280 data
|
|
#define BMP280_DATA_LEN (6)
|
|
// Number of bytes to get bme280 data
|
|
#define BME280_DATA_LEN (2)
|
|
|
|
// Uncomment the following to use test data as specified in the
|
|
// datasheet, section 3.12. This really only tests the compensation
|
|
// algorithm, and only for the bmp280 parts (temperature/pressure).
|
|
|
|
// #define BMP280_USE_TEST_DATA
|
|
|
|
// SPI CS on and off functions
|
|
static void _csOn(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->gpio)
|
|
mraa_gpio_write(dev->gpio, 0);
|
|
}
|
|
|
|
static void _csOff(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->gpio)
|
|
mraa_gpio_write(dev->gpio, 1);
|
|
}
|
|
|
|
// These functions come from the BMP280 datasheet, section 3.11.3
|
|
|
|
// Returns temperature in DegC, resolution is 0.01 DegC. Output value
|
|
// of "5123" equals 51.23 DegC. t_fine carries fine temperature as
|
|
// global value
|
|
static int32_t _bmp280_compensate_T_int32(const bmp280_context dev,
|
|
int32_t adc_T)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
int32_t var1, var2, T;
|
|
var1 = ((((adc_T>>3) - ((int32_t)dev->dig_T1<<1))) * ((int32_t)dev->dig_T2)) >> 11;
|
|
var2 = (((((adc_T>>4) - ((int32_t)dev->dig_T1)) * ((adc_T>>4) - ((int32_t)dev->dig_T1))) >> 12) *
|
|
((int32_t)dev->dig_T3)) >> 14;
|
|
dev->t_fine = var1 + var2;
|
|
T = (dev->t_fine * 5 + 128) >> 8;
|
|
return T;
|
|
}
|
|
|
|
// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format
|
|
// (24 integer bits and 8 fractional bits). Output value of
|
|
// "24674867" represents 24674867/256 = 96386.2 Pa = 963.862 hPa
|
|
static uint32_t _bmp280_compensate_P_int64(const bmp280_context dev,
|
|
int32_t adc_P)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
int64_t var1, var2, p;
|
|
var1 = ((int64_t)dev->t_fine) - 128000;
|
|
var2 = var1 * var1 * (int64_t)dev->dig_P6;
|
|
var2 = var2 + ((var1*(int64_t)dev->dig_P5)<<17);
|
|
var2 = var2 + (((int64_t)dev->dig_P4)<<35);
|
|
var1 = ((var1 * var1 * (int64_t)dev->dig_P3)>>8) + ((var1 * (int64_t)dev->dig_P2)<<12);
|
|
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)dev->dig_P1)>>33;
|
|
if (var1 == 0)
|
|
{
|
|
return 0; // avoid exception caused by division by zero
|
|
}
|
|
p = 1048576-adc_P;
|
|
p = (((p<<31)-var2)*3125)/var1;
|
|
var1 = (((int64_t)dev->dig_P9) * (p>>13) * (p>>13)) >> 25;
|
|
var2 = (((int64_t)dev->dig_P8) * p) >> 19;
|
|
p = ((p + var1 + var2) >> 8) + (((int64_t)dev->dig_P7)<<4);
|
|
return (uint32_t)p;
|
|
}
|
|
|
|
// This function comes from the BME280 datasheet, section 4.2.3
|
|
// Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format
|
|
// (22 integer and 10 fractional bits). Output value of "47445"
|
|
// represents 47445/1024 = 46.333 %RH
|
|
// BME280 only
|
|
static uint32_t _bme280_compensate_H_int32(const bmp280_context dev,
|
|
int32_t adc_H)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
int32_t v_x1_u32r;
|
|
v_x1_u32r = (dev->t_fine - ((int32_t)76800));
|
|
v_x1_u32r = (((((adc_H << 14) - (((int32_t)dev->dig_H4) << 20) - (((int32_t)dev->dig_H5) * v_x1_u32r)) +
|
|
((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)dev->dig_H6)) >> 10) * (((v_x1_u32r * ((int32_t)dev->dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)dev->dig_H2) + 8192) >> 14));
|
|
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)dev->dig_H1)) >> 4));
|
|
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
|
|
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
|
|
return (int32_t)(v_x1_u32r>>12);
|
|
}
|
|
|
|
// read the calibration data
|
|
static upm_result_t _read_calibration_data(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
#if defined(BMP280_USE_TEST_DATA)
|
|
printf("%s: WARNING: Test data is being used\n", __FUNCTION__);
|
|
|
|
// This data is taken from the datasheet, section 3.12
|
|
dev->dig_T1 = 27504;
|
|
dev->dig_T2 = 26435;
|
|
dev->dig_T3 = -1000;
|
|
|
|
dev->dig_P1 = 36477;
|
|
dev->dig_P2 = -10685;
|
|
dev->dig_P3 = 3024;
|
|
dev->dig_P4 = 2855;
|
|
dev->dig_P5 = 140;
|
|
dev->dig_P6 = -7;
|
|
dev->dig_P7 = 15500;
|
|
dev->dig_P8 = -14600;
|
|
dev->dig_P9 = 6000;
|
|
|
|
// BME280 does not have any test data....
|
|
dev->dig_H1 = 0;
|
|
dev->dig_H2 = 0;
|
|
dev->dig_H3 = 0;
|
|
dev->dig_H4 = 0;
|
|
dev->dig_H5 = 0;
|
|
dev->dig_H6 = 0;
|
|
|
|
#else
|
|
|
|
// bmp280...
|
|
uint8_t calibData[BMP280_CALIBRATION_BYTES];
|
|
int rv;
|
|
if ( (rv = bmp280_read_regs(dev, BMP280_REG_CALIB00, calibData,
|
|
BMP280_CALIBRATION_BYTES))
|
|
!= BMP280_CALIBRATION_BYTES)
|
|
{
|
|
printf("%s: bmp280_read_regs(BMP280) failed.",
|
|
__FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
dev->dig_T1 = (uint16_t)((calibData[1] << 8) | calibData[0]);
|
|
dev->dig_T2 = (int16_t)((calibData[3] << 8) | calibData[2]);
|
|
dev->dig_T3 = (int16_t)((calibData[5] << 8) | calibData[4]);
|
|
|
|
dev->dig_P1 = (uint16_t)((calibData[7] << 8) | calibData[6]);
|
|
dev->dig_P2 = (int16_t)((calibData[9] << 8) | calibData[8]);
|
|
dev->dig_P3 = (int16_t)((calibData[11] << 8) | calibData[10]);
|
|
dev->dig_P4 = (int16_t)((calibData[13] << 8) | calibData[12]);
|
|
dev->dig_P5 = (int16_t)((calibData[15] << 8) | calibData[14]);
|
|
dev->dig_P6 = (int16_t)((calibData[17] << 8) | calibData[16]);
|
|
dev->dig_P7 = (int16_t)((calibData[19] << 8) | calibData[18]);
|
|
dev->dig_P8 = (int16_t)((calibData[21] << 8) | calibData[20]);
|
|
dev->dig_P9 = (int16_t)((calibData[23] << 8) | calibData[22]);
|
|
|
|
// bme280... (humidity calibration data)
|
|
if (dev->isBME)
|
|
{
|
|
dev->dig_H1 = bmp280_read_reg(dev, BME280_REG_CALIB_DIG_H1);
|
|
|
|
uint8_t hCalibData[BME280_CALIBRATION_BYTES];
|
|
if ( (rv = bmp280_read_regs(dev, BME280_REG_CALIB_DIG_H2_LSB,
|
|
hCalibData,
|
|
BME280_CALIBRATION_BYTES))
|
|
!= BME280_CALIBRATION_BYTES)
|
|
{
|
|
printf("%s: bmp280_read_regs(BME280) failed.",
|
|
__FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
dev->dig_H2 = (int16_t)((hCalibData[1] << 8) | hCalibData[0]);
|
|
|
|
dev->dig_H3 = hCalibData[2];
|
|
|
|
dev->dig_H4 = (int16_t)( (hCalibData[3] << 4) |
|
|
(hCalibData[4] & 0x0f) );
|
|
|
|
dev->dig_H5 = (int16_t)( ((hCalibData[4] & 0xf0) >> 4) |
|
|
(hCalibData[5] << 4) );
|
|
|
|
dev->dig_H6 = (int8_t)(hCalibData[6]);
|
|
}
|
|
#endif // defined(BMP280_USE_TEST_DATA)
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
bmp280_context bmp280_init(int bus, int addr, int cs)
|
|
{
|
|
bmp280_context dev =
|
|
(bmp280_context)malloc(sizeof(struct _bmp280_context));
|
|
|
|
if (!dev)
|
|
return NULL;
|
|
|
|
// zero out context
|
|
memset((void *)dev, 0, sizeof(struct _bmp280_context));
|
|
|
|
// make sure MRAA is initialized
|
|
if (mraa_init() != MRAA_SUCCESS)
|
|
{
|
|
printf("%s: mraa_init() failed.\n", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
if (addr < 0)
|
|
dev->isSPI = true;
|
|
|
|
if (dev->isSPI)
|
|
{
|
|
if (!(dev->spi = mraa_spi_init(bus)))
|
|
{
|
|
printf("%s: mraa_spi_init() failed.\n", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
// Only create cs context if we are actually using a valid pin.
|
|
// A hardware controlled pin should specify cs as -1.
|
|
if (cs >= 0)
|
|
{
|
|
if (!(dev->gpio = mraa_gpio_init(cs)))
|
|
{
|
|
printf("%s: mraa_gpio_init() failed.\n", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
mraa_gpio_dir(dev->gpio, MRAA_GPIO_OUT);
|
|
}
|
|
|
|
mraa_spi_mode(dev->spi, MRAA_SPI_MODE0);
|
|
if (mraa_spi_frequency(dev->spi, 5000000))
|
|
{
|
|
printf("%s: mraa_spi_frequency() failed.\n", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
// toggle CS on/off so chip switches into SPI mode. For a hw
|
|
// CS pin, the first SPI transaction should accomplish this.
|
|
_csOn(dev);
|
|
upm_delay_ms(10);
|
|
_csOff(dev);
|
|
}
|
|
else
|
|
{
|
|
// I2C
|
|
|
|
if (!(dev->i2c = mraa_i2c_init(bus)))
|
|
{
|
|
printf("%s: mraa_i2c_init() failed.\n", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
if (mraa_i2c_address(dev->i2c, addr))
|
|
{
|
|
printf("%s: mraa_i2c_address() failed.\n", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// check the chip id
|
|
|
|
uint8_t chipID = bmp280_read_reg(dev, BMP280_REG_CHIPID);
|
|
|
|
switch(chipID)
|
|
{
|
|
case BMP280_CHIPID: // BMP280
|
|
dev->isBME = false;
|
|
break;
|
|
|
|
case BME280_CHIPID: // BME280
|
|
dev->isBME = true;
|
|
break;
|
|
|
|
default: // ??
|
|
printf("%s: invalid chip id: %02x. Expected either %02x "
|
|
"(bmp280) or %02x (bme280)\n",
|
|
__FUNCTION__, chipID, BMP280_CHIPID, BME280_CHIPID);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
// set sleep mode for now
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_SLEEP);
|
|
|
|
// read calibration data
|
|
if (_read_calibration_data(dev))
|
|
{
|
|
printf("%s: _read_calibration_data() failed.", __FUNCTION__);
|
|
bmp280_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
// set the default mode to the highest resolution mode
|
|
bmp280_set_usage_mode(dev, BMP280_USAGE_MODE_INDOOR_NAV);
|
|
|
|
// set the default sea level pressure in hPA
|
|
dev->sea_level_hPA = BMP280_SEA_LEVEL_HPA;
|
|
|
|
return dev;
|
|
}
|
|
|
|
void bmp280_close(bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->i2c)
|
|
mraa_i2c_stop(dev->i2c);
|
|
|
|
if (dev->spi)
|
|
mraa_spi_stop(dev->spi);
|
|
|
|
if (dev->gpio)
|
|
mraa_gpio_close(dev->gpio);
|
|
|
|
free(dev);
|
|
}
|
|
|
|
upm_result_t bmp280_update(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
int32_t temp = 0;
|
|
int32_t pres = 0;
|
|
|
|
uint8_t bmp_data[BMP280_DATA_LEN];
|
|
memset(bmp_data, 0, BMP280_DATA_LEN);
|
|
|
|
// If we are using a forced mode, then we need to manually trigger
|
|
// the measurement and wait for it to complete.
|
|
|
|
if (dev->mode == BMP280_MODE_FORCED)
|
|
{
|
|
// bmp280 measure mode will return to sleep after completion...
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_FORCED);
|
|
|
|
uint8_t stat;
|
|
do
|
|
{
|
|
upm_delay_ms(10);
|
|
stat = bmp280_get_status(dev);
|
|
} while (stat & BMP280_STATUS_MEASURING);
|
|
}
|
|
|
|
int rv;
|
|
if ((rv = bmp280_read_regs(dev, BMP280_REG_PRESSURE_MSB,
|
|
bmp_data, BMP280_DATA_LEN))
|
|
!= BMP280_DATA_LEN)
|
|
{
|
|
printf("%s: bmp280_read_regs() failed.", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
// 20 bits unsigned stored in a 32bit signed quantity
|
|
|
|
#if defined(BMP280_USE_TEST_DATA)
|
|
// taken from datasheet, section 3.12
|
|
temp = 519888;
|
|
pres = 415148;
|
|
#else
|
|
temp = ( (bmp_data[5] >> 4) | (bmp_data[4] << 4) | (bmp_data[3] << 12) );
|
|
pres = ( (bmp_data[2] >> 4) | (bmp_data[1] << 4) | (bmp_data[0] << 12) );
|
|
#endif
|
|
|
|
dev->temperature = (float)_bmp280_compensate_T_int32(dev, temp);
|
|
dev->temperature /= 100.0;
|
|
|
|
dev->pressure = (float)_bmp280_compensate_P_int64(dev, pres);
|
|
dev->pressure /= 256.0;
|
|
|
|
// BME280?
|
|
if (dev->isBME)
|
|
{
|
|
uint8_t bme_data[BME280_DATA_LEN];
|
|
|
|
memset(bme_data, 0, BME280_DATA_LEN);
|
|
|
|
if ((rv = bmp280_read_regs(dev, BME280_REG_HUMIDITY_MSB,
|
|
bme_data, BME280_DATA_LEN))
|
|
!= BME280_DATA_LEN)
|
|
{
|
|
printf("%s: bmp280_read_regs(BME280) failed.",
|
|
__FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
// 20 bits unsigned stored in a 32bit signed quantity
|
|
int32_t hum = ( (bme_data[0] << 8) | bme_data[1] );
|
|
|
|
dev->humidity = (float)_bme280_compensate_H_int32(dev, hum);
|
|
dev->humidity /= 1024.0;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
void bmp280_set_sea_level_pressure(const bmp280_context dev,
|
|
float seaLevelhPA)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
dev->sea_level_hPA = seaLevelhPA;
|
|
}
|
|
|
|
float bmp280_get_altitude(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
// adapted from the US NOAA pdf: pressureAltitude.pdf
|
|
return 44307.69 * (1.0 - pow((dev->pressure/100.0)
|
|
/ dev->sea_level_hPA, 0.190284));
|
|
}
|
|
|
|
uint8_t bmp280_read_reg(const bmp280_context dev, uint8_t reg)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->isSPI)
|
|
{
|
|
reg |= 0x80; // needed for read
|
|
uint8_t pkt[2] = {reg, 0};
|
|
|
|
_csOn(dev);
|
|
if (mraa_spi_transfer_buf(dev->spi, pkt, pkt, 2))
|
|
{
|
|
_csOff(dev);
|
|
printf("%s: mraa_spi_transfer_buf() failed.",
|
|
__FUNCTION__);
|
|
|
|
return 0xff;
|
|
}
|
|
_csOff(dev);
|
|
|
|
return pkt[1];
|
|
}
|
|
else
|
|
{
|
|
return (uint8_t)mraa_i2c_read_byte_data(dev->i2c, reg);
|
|
}
|
|
}
|
|
|
|
int bmp280_read_regs(const bmp280_context dev,
|
|
uint8_t reg, uint8_t *buffer, int len)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->isSPI)
|
|
{
|
|
reg |= 0x80; // needed for read
|
|
|
|
uint8_t sbuf[len + 1];
|
|
memset((char *)sbuf, 0, len + 1);
|
|
sbuf[0] = reg;
|
|
|
|
// We need to do it this way for edison - ie: use a single
|
|
// transfer rather than breaking it up into two like we used
|
|
// to, since we have no control over CS. This means a buffer
|
|
// copy is now required, but that's the way it goes.
|
|
|
|
_csOn(dev);
|
|
if (mraa_spi_transfer_buf(dev->spi, sbuf, sbuf, len + 1))
|
|
{
|
|
_csOff(dev);
|
|
printf("%s: mraa_spi_transfer_buf() failed.",
|
|
__FUNCTION__);
|
|
|
|
return 0;
|
|
}
|
|
_csOff(dev);
|
|
|
|
// now copy it into user buffer
|
|
for (int i=0; i<len; i++)
|
|
buffer[i] = sbuf[i + 1];
|
|
}
|
|
else
|
|
{
|
|
if (mraa_i2c_read_bytes_data(dev->i2c, reg, buffer, len) != len)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
upm_result_t bmp280_write_reg(const bmp280_context dev,
|
|
uint8_t reg, uint8_t val)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->isSPI)
|
|
{
|
|
reg &= 0x7f; // mask off 0x80 for writing
|
|
uint8_t pkt[2] = {reg, val};
|
|
|
|
_csOn(dev);
|
|
if (mraa_spi_transfer_buf(dev->spi, pkt, NULL, 2))
|
|
{
|
|
_csOff(dev);
|
|
printf("%s: mraa_spi_transfer_buf() failed.",
|
|
__FUNCTION__);
|
|
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
_csOff(dev);
|
|
}
|
|
else
|
|
{
|
|
if (mraa_i2c_write_byte_data(dev->i2c, val, reg))
|
|
{
|
|
printf("%s: mraa_i2c_write_byte_data() failed.",
|
|
__FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
uint8_t bmp280_get_chip_id(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
return bmp280_read_reg(dev, BMP280_REG_CHIPID);
|
|
}
|
|
|
|
void bmp280_reset(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
bmp280_write_reg(dev, BMP280_REG_RESET, BMP280_RESET_BYTE);
|
|
upm_delay(1);
|
|
}
|
|
|
|
float bmp280_get_temperature(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
return dev->temperature;
|
|
}
|
|
|
|
float bmp280_get_pressure(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
return dev->pressure;
|
|
}
|
|
|
|
// BME280 only
|
|
float bmp280_get_humidity(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->isBME)
|
|
return dev->humidity;
|
|
else
|
|
return 0.0;
|
|
}
|
|
|
|
void bmp280_set_filter(const bmp280_context dev, BMP280_FILTER_T filter)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
uint8_t reg = bmp280_read_reg(dev, BMP280_REG_CONFIG);
|
|
|
|
reg &= ~(_BMP280_CONFIG_FILTER_MASK << _BMP280_CONFIG_FILTER_SHIFT);
|
|
reg |= (filter << _BMP280_CONFIG_FILTER_SHIFT);
|
|
|
|
bmp280_write_reg(dev, BMP280_REG_CONFIG, reg);
|
|
}
|
|
|
|
void bmp280_set_timer_standby(const bmp280_context dev,
|
|
BMP280_T_SB_T tsb)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
uint8_t reg = bmp280_read_reg(dev, BMP280_REG_CONFIG);
|
|
|
|
reg &= ~(_BMP280_CONFIG_T_SB_MASK << _BMP280_CONFIG_T_SB_SHIFT);
|
|
reg |= (tsb << _BMP280_CONFIG_T_SB_SHIFT);
|
|
|
|
bmp280_write_reg(dev, BMP280_REG_CONFIG, reg);
|
|
}
|
|
|
|
void bmp280_set_measure_mode(const bmp280_context dev,
|
|
BMP280_MODES_T mode)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
uint8_t reg = bmp280_read_reg(dev, BMP280_REG_CTRL_MEAS);
|
|
|
|
reg &= ~(_BMP280_CTRL_MEAS_MODE_MASK << _BMP280_CTRL_MEAS_MODE_SHIFT);
|
|
reg |= (mode << _BMP280_CTRL_MEAS_MODE_SHIFT);
|
|
|
|
bmp280_write_reg(dev, BMP280_REG_CTRL_MEAS, reg);
|
|
dev->mode = mode;
|
|
}
|
|
|
|
void bmp280_set_oversample_rate_pressure(const bmp280_context dev,
|
|
BMP280_OSRS_P_T rate)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
uint8_t reg = bmp280_read_reg(dev, BMP280_REG_CTRL_MEAS);
|
|
|
|
reg &= ~(_BMP280_CTRL_MEAS_OSRS_P_MASK << _BMP280_CTRL_MEAS_OSRS_P_SHIFT);
|
|
reg |= (rate << _BMP280_CTRL_MEAS_OSRS_P_SHIFT);
|
|
|
|
bmp280_write_reg(dev, BMP280_REG_CTRL_MEAS, reg);
|
|
}
|
|
|
|
void bmp280_set_oversample_rate_temperature(const bmp280_context dev,
|
|
BMP280_OSRS_T_T rate)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
uint8_t reg = bmp280_read_reg(dev, BMP280_REG_CTRL_MEAS);
|
|
|
|
reg &= ~(_BMP280_CTRL_MEAS_OSRS_T_MASK << _BMP280_CTRL_MEAS_OSRS_T_SHIFT);
|
|
reg |= (rate << _BMP280_CTRL_MEAS_OSRS_T_SHIFT);
|
|
|
|
bmp280_write_reg(dev, BMP280_REG_CTRL_MEAS, reg);
|
|
}
|
|
|
|
// bme280 only
|
|
void bmp280_set_oversample_rate_humidity(const bmp280_context dev,
|
|
BME280_OSRS_H_T rate)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
if (dev->isBME)
|
|
{
|
|
uint8_t reg = bmp280_read_reg(dev, BME280_REG_CTRL_HUM);
|
|
|
|
reg &= ~(_BME280_CTRL_HUM_OSRS_H_MASK << _BME280_CTRL_HUM_OSRS_H_SHIFT);
|
|
reg |= (rate << _BME280_CTRL_HUM_OSRS_H_SHIFT);
|
|
|
|
bmp280_write_reg(dev, BME280_REG_CTRL_HUM, reg);
|
|
}
|
|
}
|
|
|
|
uint8_t bmp280_get_status(const bmp280_context dev)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
return bmp280_read_reg(dev, BMP280_REG_STATUS);
|
|
}
|
|
|
|
void bmp280_set_usage_mode(const bmp280_context dev, BMP280_USAGE_MODE_T mode)
|
|
{
|
|
assert(dev != NULL);
|
|
|
|
// set up the regs for the given usage mode. These settings come
|
|
// from the recomendations in the BMP280 datasheet, section 3.4
|
|
// Filter Selection.
|
|
|
|
dev->temperature = 0;
|
|
dev->pressure = 0;
|
|
dev->humidity = 0;
|
|
|
|
// set sleep mode first
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_SLEEP);
|
|
|
|
switch (mode)
|
|
{
|
|
case BMP280_USAGE_MODE_HANDHELD_LOW_POWER:
|
|
bmp280_set_oversample_rate_pressure(dev,
|
|
BMP280_OSRS_P_OVERSAMPLING_16);
|
|
bmp280_set_oversample_rate_temperature(dev,
|
|
BMP280_OSRS_T_OVERSAMPLING_2);
|
|
bmp280_set_oversample_rate_humidity(dev,
|
|
BME280_OSRS_H_OVERSAMPLING_1);
|
|
bmp280_set_filter(dev, BMP280_FILTER_4);
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_NORMAL);
|
|
|
|
break;
|
|
|
|
case BMP280_USAGE_MODE_HANDHELD_DYNAMIC:
|
|
bmp280_set_oversample_rate_pressure(dev,
|
|
BMP280_OSRS_P_OVERSAMPLING_4);
|
|
bmp280_set_oversample_rate_temperature(dev,
|
|
BMP280_OSRS_T_OVERSAMPLING_1);
|
|
bmp280_set_oversample_rate_humidity(dev,
|
|
BME280_OSRS_H_OVERSAMPLING_1);
|
|
bmp280_set_filter(dev, BMP280_FILTER_16);
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_NORMAL);
|
|
|
|
break;
|
|
|
|
case BMP280_USAGE_MODE_WEATHER_MONITOR:
|
|
bmp280_set_oversample_rate_pressure(dev,
|
|
BMP280_OSRS_P_OVERSAMPLING_1);
|
|
bmp280_set_oversample_rate_temperature(dev,
|
|
BMP280_OSRS_T_OVERSAMPLING_1);
|
|
bmp280_set_oversample_rate_humidity(dev,
|
|
BME280_OSRS_H_OVERSAMPLING_1);
|
|
bmp280_set_filter(dev, BMP280_FILTER_OFF);
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_FORCED);
|
|
|
|
break;
|
|
|
|
case BMP280_USAGE_MODE_FLOOR_CHG_DETECT:
|
|
bmp280_set_oversample_rate_pressure(dev,
|
|
BMP280_OSRS_P_OVERSAMPLING_4);
|
|
bmp280_set_oversample_rate_temperature(dev,
|
|
BMP280_OSRS_T_OVERSAMPLING_1);
|
|
bmp280_set_oversample_rate_humidity(dev,
|
|
BME280_OSRS_H_OVERSAMPLING_1);
|
|
bmp280_set_filter(dev, BMP280_FILTER_4);
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_NORMAL);
|
|
|
|
break;
|
|
|
|
case BMP280_USAGE_MODE_DROP_DETECT:
|
|
bmp280_set_oversample_rate_pressure(dev,
|
|
BMP280_OSRS_P_OVERSAMPLING_2);
|
|
bmp280_set_oversample_rate_temperature(dev,
|
|
BMP280_OSRS_T_OVERSAMPLING_1);
|
|
bmp280_set_oversample_rate_humidity(dev,
|
|
BME280_OSRS_H_OVERSAMPLING_1);
|
|
bmp280_set_filter(dev, BMP280_FILTER_OFF);
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_NORMAL);
|
|
|
|
break;
|
|
|
|
case BMP280_USAGE_MODE_INDOOR_NAV:
|
|
bmp280_set_oversample_rate_pressure(dev,
|
|
BMP280_OSRS_P_OVERSAMPLING_16);
|
|
bmp280_set_oversample_rate_temperature(dev,
|
|
BMP280_OSRS_T_OVERSAMPLING_2);
|
|
bmp280_set_oversample_rate_humidity(dev,
|
|
BME280_OSRS_H_OVERSAMPLING_1);
|
|
bmp280_set_filter(dev, BMP280_FILTER_16);
|
|
bmp280_set_measure_mode(dev, BMP280_MODE_NORMAL);
|
|
|
|
break;
|
|
|
|
default:
|
|
printf("%s: invalid usage mode specified, mode unchanged.",
|
|
__FUNCTION__);
|
|
}
|
|
}
|