mirror of
https://github.com/cmur2/python-bme680.git
synced 2024-12-22 22:54:29 +01:00
Added packaging, dropped copy of C code
This commit is contained in:
parent
3751865cb6
commit
16853dc4f2
@ -1,9 +0,0 @@
|
|||||||
all: main
|
|
||||||
|
|
||||||
lib:
|
|
||||||
gcc -c -fpic bme680.c
|
|
||||||
ar rcs libbme680.a bme680.o
|
|
||||||
gcc -shared -o libbme680.so bme680.o
|
|
||||||
|
|
||||||
main: lib
|
|
||||||
gcc main.c -L. -static -lbme680 -o main
|
|
@ -1,239 +0,0 @@
|
|||||||
# BME680 sensor API
|
|
||||||
## Introduction
|
|
||||||
This package contains the Bosch Sensortec's BME680 gas sensor API
|
|
||||||
|
|
||||||
The sensor driver package includes bme680.h, bme680.c and bme680_defs.h files
|
|
||||||
|
|
||||||
## Version
|
|
||||||
File | Version | Date
|
|
||||||
-----|---------|-----
|
|
||||||
bme680.c | 3.5.1 | 5 Jul 2017
|
|
||||||
bme680.h | 3.5.1 | 5 Jul 2017
|
|
||||||
bme680_defs.h | 3.5.1 | 5 Jul 2017
|
|
||||||
|
|
||||||
## Integration details
|
|
||||||
* Integrate bme680.h, bme680_defs.h and bme680.c file in to your project.
|
|
||||||
* Include the bme680.h file in your code like below.
|
|
||||||
``` c
|
|
||||||
#include "bme680.h"
|
|
||||||
```
|
|
||||||
|
|
||||||
## File information
|
|
||||||
* bme680_defs.h : This header file has the constants, macros and datatype declarations.
|
|
||||||
* bme680.h : This header file contains the declarations of the sensor driver APIs.
|
|
||||||
* bme680.c : This source file contains the definitions of the sensor driver APIs.
|
|
||||||
|
|
||||||
## Supported sensor interfaces
|
|
||||||
* SPI 4-wire
|
|
||||||
* I2C
|
|
||||||
|
|
||||||
## Usage guide
|
|
||||||
### Initializing the sensor
|
|
||||||
To initialize the sensor, you will first need to create a device structure. You
|
|
||||||
can do this by creating an instance of the structure bme680_dev. Then go on to
|
|
||||||
fill in the various parameters as shown below
|
|
||||||
|
|
||||||
#### Example for SPI 4-Wire
|
|
||||||
``` c
|
|
||||||
struct bme680_dev gas_sensor;
|
|
||||||
|
|
||||||
/* You may assign a chip select identifier to be handled later */
|
|
||||||
gas_sensor.dev_id = 0;
|
|
||||||
gas_sensor.intf = BME680_SPI_INTF;
|
|
||||||
gas_sensor.read = user_spi_read;
|
|
||||||
gas_sensor.write = user_spi_write;
|
|
||||||
gas_sensor.delay_ms = user_delay_ms;
|
|
||||||
|
|
||||||
int8_t rslt = BME680_OK;
|
|
||||||
rslt = bme680_init(&gas_sensor);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example for I2C
|
|
||||||
``` c
|
|
||||||
struct bme680_dev gas_sensor;
|
|
||||||
|
|
||||||
gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY;
|
|
||||||
gas_sensor.intf = BME680_I2C_INTF;
|
|
||||||
gas_sensor.read = user_i2c_read;
|
|
||||||
gas_sensor.write = user_i2c_write;
|
|
||||||
gas_sensor.delay_ms = user_delay_ms;
|
|
||||||
|
|
||||||
int8_t rslt = BME680_OK;
|
|
||||||
rslt = bme680_init(&gas_sensor);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuring the sensor
|
|
||||||
#### Example for configuring the sensor in forced mode
|
|
||||||
``` c
|
|
||||||
uint8_t set_required_settings;
|
|
||||||
|
|
||||||
/* Set the temperature, pressure and humidity settings */
|
|
||||||
gas_sensor.tph_sett.os_hum = BME680_OS_2X;
|
|
||||||
gas_sensor.tph_sett.os_pres = BME680_OS_4X;
|
|
||||||
gas_sensor.tph_sett.os_temp = BME680_OS_8X;
|
|
||||||
gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3;
|
|
||||||
|
|
||||||
/* Set the remaining gas sensor settings and link the heating profile */
|
|
||||||
gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
|
|
||||||
/* Create a ramp heat waveform in 3 steps */
|
|
||||||
gas_sensor.gas_sett.heatr_temp = 320; /* degree Celsius */
|
|
||||||
gas_sensor.gas_sett.heatr_dur = 150; /* milliseconds */
|
|
||||||
|
|
||||||
/* Select the power mode */
|
|
||||||
/* Must be set before writing the sensor configuration */
|
|
||||||
gas_sensor.power_mode = BME680_FORCED_MODE;
|
|
||||||
|
|
||||||
/* Set the required sensor settings needed */
|
|
||||||
set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL
|
|
||||||
| BME680_GAS_SENSOR_SEL;
|
|
||||||
|
|
||||||
/* Set the desired sensor configuration */
|
|
||||||
rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor);
|
|
||||||
|
|
||||||
/* Set the power mode */
|
|
||||||
rslt = bme680_set_sensor_mode(&gas_sensor);
|
|
||||||
|
|
||||||
/* Get the total measurement duration so as to sleep or wait till the
|
|
||||||
* measurement is complete */
|
|
||||||
uint16_t meas_period;
|
|
||||||
bme680_get_profile_dur(&meas_period, &gas_sensor);
|
|
||||||
user_delay_ms(meas_period); /* Delay till the measurement is ready */
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reading sensor data
|
|
||||||
#### Example for reading all sensor data
|
|
||||||
``` c
|
|
||||||
struct bme680_field_data data;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
rslt = bme680_get_sensor_data(&data, &gas_sensor);
|
|
||||||
|
|
||||||
printf("T: %.2f degC, P: %.2f hPa, H %.2f %%rH ", data.temperature / 100.0f,
|
|
||||||
data.pressure / 100.0f, data.humidity / 1000.0f );
|
|
||||||
/* Avoid using measurements from an unstable heating setup */
|
|
||||||
if(data.status & BME680_HEAT_STAB_MSK)
|
|
||||||
printf(", G: %d ohms", data.gas_resistance);
|
|
||||||
|
|
||||||
printf("\r\n");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Templates for function pointers
|
|
||||||
``` c
|
|
||||||
|
|
||||||
void user_delay_ms(uint32_t period)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Return control or wait,
|
|
||||||
* for a period amount of milliseconds
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
|
|
||||||
{
|
|
||||||
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The parameter dev_id can be used as a variable to select which Chip Select pin has
|
|
||||||
* to be set low to activate the relevant device on the SPI bus
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data on the bus should be like
|
|
||||||
* |----------------+---------------------+-------------|
|
|
||||||
* | MOSI | MISO | Chip Select |
|
|
||||||
* |----------------+---------------------|-------------|
|
|
||||||
* | (don't care) | (don't care) | HIGH |
|
|
||||||
* | (reg_addr) | (don't care) | LOW |
|
|
||||||
* | (don't care) | (reg_data[0]) | LOW |
|
|
||||||
* | (....) | (....) | LOW |
|
|
||||||
* | (don't care) | (reg_data[len - 1]) | LOW |
|
|
||||||
* | (don't care) | (don't care) | HIGH |
|
|
||||||
* |----------------+---------------------|-------------|
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
|
|
||||||
{
|
|
||||||
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The parameter dev_id can be used as a variable to select which Chip Select pin has
|
|
||||||
* to be set low to activate the relevant device on the SPI bus
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data on the bus should be like
|
|
||||||
* |---------------------+--------------+-------------|
|
|
||||||
* | MOSI | MISO | Chip Select |
|
|
||||||
* |---------------------+--------------|-------------|
|
|
||||||
* | (don't care) | (don't care) | HIGH |
|
|
||||||
* | (reg_addr) | (don't care) | LOW |
|
|
||||||
* | (reg_data[0]) | (don't care) | LOW |
|
|
||||||
* | (....) | (....) | LOW |
|
|
||||||
* | (reg_data[len - 1]) | (don't care) | LOW |
|
|
||||||
* | (don't care) | (don't care) | HIGH |
|
|
||||||
* |---------------------+--------------|-------------|
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
|
|
||||||
{
|
|
||||||
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The parameter dev_id can be used as a variable to store the I2C address of the device
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data on the bus should be like
|
|
||||||
* |------------+---------------------|
|
|
||||||
* | I2C action | Data |
|
|
||||||
* |------------+---------------------|
|
|
||||||
* | Start | - |
|
|
||||||
* | Write | (reg_addr) |
|
|
||||||
* | Stop | - |
|
|
||||||
* | Start | - |
|
|
||||||
* | Read | (reg_data[0]) |
|
|
||||||
* | Read | (....) |
|
|
||||||
* | Read | (reg_data[len - 1]) |
|
|
||||||
* | Stop | - |
|
|
||||||
* |------------+---------------------|
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
|
|
||||||
{
|
|
||||||
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The parameter dev_id can be used as a variable to store the I2C address of the device
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data on the bus should be like
|
|
||||||
* |------------+---------------------|
|
|
||||||
* | I2C action | Data |
|
|
||||||
* |------------+---------------------|
|
|
||||||
* | Start | - |
|
|
||||||
* | Write | (reg_addr) |
|
|
||||||
* | Write | (reg_data[0]) |
|
|
||||||
* | Write | (....) |
|
|
||||||
* | Write | (reg_data[len - 1]) |
|
|
||||||
* | Stop | - |
|
|
||||||
* |------------+---------------------|
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
|
|
@ -1,189 +0,0 @@
|
|||||||
/**\mainpage
|
|
||||||
* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* Neither the name of the copyright holder nor the names of the
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
||||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
|
|
||||||
* OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
* ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
|
||||||
*
|
|
||||||
* The information provided is believed to be accurate and reliable.
|
|
||||||
* The copyright holder assumes no responsibility
|
|
||||||
* for the consequences of use
|
|
||||||
* of such information nor for any infringement of patents or
|
|
||||||
* other rights of third parties which may result from its use.
|
|
||||||
* No license is granted by implication or otherwise under any patent or
|
|
||||||
* patent rights of the copyright holder.
|
|
||||||
*
|
|
||||||
* File bme680_selftest.c
|
|
||||||
* @date 5 Jul 2017
|
|
||||||
* @version 3.5.1
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @addtogroup bme680_selftest
|
|
||||||
* @brief
|
|
||||||
* @{*/
|
|
||||||
|
|
||||||
#include "bme680_selftest.h"
|
|
||||||
|
|
||||||
#define MIN_TEMPERATURE INT16_C(0) /* 0 degree Celsius */
|
|
||||||
#define MAX_TEMPERATURE INT16_C(4000) /* 40 degree Celsius */
|
|
||||||
|
|
||||||
#define MIN_PRESSURE UINT32_C(90000) /* 900 hecto Pascals */
|
|
||||||
#define MAX_PRESSURE UINT32_C(110000) /* 1100 hecto Pascals */
|
|
||||||
|
|
||||||
#define MIN_HUMIDITY UINT32_C(20000) /* 20% relative humidity */
|
|
||||||
#define MAX_HUMIDITY UINT32_C(80000) /* 80% relative humidity*/
|
|
||||||
|
|
||||||
#define HEATR_DUR 2000
|
|
||||||
#define N_MEAS 6
|
|
||||||
#define LOW_TEMP 200
|
|
||||||
#define HIGH_TEMP 350
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Function to analyze the sensor data
|
|
||||||
*
|
|
||||||
* @param[in] data Array of measurement data
|
|
||||||
* @param[in] n_meas Number of measurements
|
|
||||||
*
|
|
||||||
* @return Error code
|
|
||||||
* @retval 0 Success
|
|
||||||
* @retval > 0 Warning
|
|
||||||
*/
|
|
||||||
static int8_t analyze_sensor_data(struct bme680_field_data *data, uint8_t n_meas);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Self-test API for the BME680
|
|
||||||
*/
|
|
||||||
int8_t bme680_self_test(struct bme680_dev *dev)
|
|
||||||
{
|
|
||||||
int8_t rslt = BME680_OK;
|
|
||||||
struct bme680_field_data data[N_MEAS];
|
|
||||||
|
|
||||||
struct bme680_dev t_dev;
|
|
||||||
|
|
||||||
/* Copy required parameters from reference bme680_dev struct */
|
|
||||||
t_dev.dev_id = dev->dev_id;
|
|
||||||
t_dev.amb_temp = 25;
|
|
||||||
t_dev.read = dev->read;
|
|
||||||
t_dev.write = dev->write;
|
|
||||||
t_dev.intf = dev->intf;
|
|
||||||
t_dev.delay_ms = dev->delay_ms;
|
|
||||||
|
|
||||||
rslt = bme680_init(&t_dev);
|
|
||||||
|
|
||||||
if (rslt == BME680_OK) {
|
|
||||||
/* Select the power mode */
|
|
||||||
/* Must be set before writing the sensor configuration */
|
|
||||||
t_dev.power_mode = BME680_FORCED_MODE;
|
|
||||||
|
|
||||||
uint16_t settings_sel;
|
|
||||||
|
|
||||||
/* Set the temperature, pressure and humidity & filter settings */
|
|
||||||
t_dev.tph_sett.os_hum = BME680_OS_1X;
|
|
||||||
t_dev.tph_sett.os_pres = BME680_OS_16X;
|
|
||||||
t_dev.tph_sett.os_temp = BME680_OS_2X;
|
|
||||||
|
|
||||||
/* Set the remaining gas sensor settings and link the heating profile */
|
|
||||||
t_dev.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
|
|
||||||
t_dev.gas_sett.heatr_dur = HEATR_DUR;
|
|
||||||
|
|
||||||
settings_sel = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_GAS_SENSOR_SEL;
|
|
||||||
|
|
||||||
uint16_t profile_dur = 0;
|
|
||||||
bme680_get_profile_dur(&profile_dur, &t_dev);
|
|
||||||
|
|
||||||
uint8_t i = 0;
|
|
||||||
while ((rslt == BME680_OK) && (i < N_MEAS)) {
|
|
||||||
if (rslt == BME680_OK) {
|
|
||||||
|
|
||||||
if (i % 2 == 0)
|
|
||||||
t_dev.gas_sett.heatr_temp = LOW_TEMP; /* Lower temperature */
|
|
||||||
else
|
|
||||||
t_dev.gas_sett.heatr_temp = HIGH_TEMP; /* Higher temperature */
|
|
||||||
|
|
||||||
rslt = bme680_set_sensor_settings(settings_sel, &t_dev);
|
|
||||||
|
|
||||||
if (rslt == BME680_OK) {
|
|
||||||
|
|
||||||
rslt = bme680_set_sensor_mode(&t_dev); /* Trigger a measurement */
|
|
||||||
|
|
||||||
t_dev.delay_ms(profile_dur); /* Wait for the measurement to complete */
|
|
||||||
|
|
||||||
rslt = bme680_get_sensor_data(&data[i], &t_dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rslt == BME680_OK)
|
|
||||||
rslt = analyze_sensor_data(data, N_MEAS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Function to analyze the sensor data
|
|
||||||
*/
|
|
||||||
static int8_t analyze_sensor_data(struct bme680_field_data *data, uint8_t n_meas)
|
|
||||||
{
|
|
||||||
int8_t rslt = BME680_OK;
|
|
||||||
uint8_t self_test_failed = 0, i;
|
|
||||||
uint32_t cent_res = 0;
|
|
||||||
|
|
||||||
if ((data[0].temperature < MIN_TEMPERATURE) || (data[0].temperature > MAX_TEMPERATURE))
|
|
||||||
self_test_failed++;
|
|
||||||
|
|
||||||
if ((data[0].pressure < MIN_PRESSURE) || (data[0].pressure > MAX_PRESSURE))
|
|
||||||
self_test_failed++;
|
|
||||||
|
|
||||||
if ((data[0].humidity < MIN_HUMIDITY) || (data[0].humidity > MAX_HUMIDITY))
|
|
||||||
self_test_failed++;
|
|
||||||
|
|
||||||
for (i = 0; i < n_meas; i++) /* Every gas measurement should be valid */
|
|
||||||
if (!(data[i].status & (BME680_GASM_VALID_MSK | BME680_HEAT_STAB_MSK)))
|
|
||||||
self_test_failed++;
|
|
||||||
|
|
||||||
for (i = 2; i < n_meas; i += 2) {
|
|
||||||
/* Invert formula to get integer values for centroid resistance, i.e. > 1 */
|
|
||||||
cent_res = (data[i - 2].gas_resistance + data[i].gas_resistance) / (2 * data[i - 1].gas_resistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cent_res < 3) || (cent_res > 20)) /* 0.05 > cent_res^-1 < 0.03 */
|
|
||||||
self_test_failed++;
|
|
||||||
|
|
||||||
if (self_test_failed)
|
|
||||||
rslt = BME680_W_SELF_TEST_FAILED;
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @}*/
|
|
@ -1,88 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* Neither the name of the copyright holder nor the names of the
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
||||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
|
|
||||||
* OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
* ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
|
||||||
*
|
|
||||||
* The information provided is believed to be accurate and reliable.
|
|
||||||
* The copyright holder assumes no responsibility
|
|
||||||
* for the consequences of use
|
|
||||||
* of such information nor for any infringement of patents or
|
|
||||||
* other rights of third parties which may result from its use.
|
|
||||||
* No license is granted by implication or otherwise under any patent or
|
|
||||||
* patent rights of the copyright holder.
|
|
||||||
*
|
|
||||||
* @file bme680_selftest.h
|
|
||||||
* @date 5 Jul 2017
|
|
||||||
* @version 3.5.1
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @addtogroup bme680_selftest
|
|
||||||
* @brief
|
|
||||||
* @{*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BME680_SELFTEST_H_
|
|
||||||
#define BME680_SELFTEST_H_
|
|
||||||
|
|
||||||
#include "bme680.h"
|
|
||||||
|
|
||||||
/*! CPP guard */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BME680_W_SELF_TEST_FAILED 3
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Self-test API for the BME680
|
|
||||||
*
|
|
||||||
* @param[in] Device structure containing relevant information on how
|
|
||||||
* to communicate with the sensor
|
|
||||||
*
|
|
||||||
* @return Error code
|
|
||||||
* @retval 0 Success
|
|
||||||
* @retval < 0 Error
|
|
||||||
* @retval > 0 Warning
|
|
||||||
*/
|
|
||||||
int8_t bme680_self_test(struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*! CPP guard */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BME680_SELFTEST_H_ */
|
|
||||||
|
|
||||||
/** @}*/
|
|
File diff suppressed because it is too large
Load Diff
@ -1,228 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* Neither the name of the copyright holder nor the names of the
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
||||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
|
|
||||||
* OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
* ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
|
||||||
*
|
|
||||||
* The information provided is believed to be accurate and reliable.
|
|
||||||
* The copyright holder assumes no responsibility
|
|
||||||
* for the consequences of use
|
|
||||||
* of such information nor for any infringement of patents or
|
|
||||||
* other rights of third parties which may result from its use.
|
|
||||||
* No license is granted by implication or otherwise under any patent or
|
|
||||||
* patent rights of the copyright holder.
|
|
||||||
*
|
|
||||||
* @file bme680.h
|
|
||||||
* @date 5 Jul 2017
|
|
||||||
* @version 3.5.1
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*! @file bme680.h
|
|
||||||
@brief Sensor driver for BME680 sensor */
|
|
||||||
/*!
|
|
||||||
* @defgroup BME680 SENSOR API
|
|
||||||
* @{*/
|
|
||||||
#ifndef BME680_H_
|
|
||||||
#define BME680_H_
|
|
||||||
|
|
||||||
/*! CPP guard */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Header includes */
|
|
||||||
#include "bme680_defs.h"
|
|
||||||
|
|
||||||
int16_t calc_temperature(uint32_t temp_adc, struct bme680_dev *dev);
|
|
||||||
uint32_t calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/* function prototype declarations */
|
|
||||||
/*!
|
|
||||||
* @brief This API is the entry point.
|
|
||||||
* It reads the chip-id and calibration data from the sensor.
|
|
||||||
*
|
|
||||||
* @param[in,out] dev : Structure instance of bme680_dev
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error
|
|
||||||
*/
|
|
||||||
int8_t bme680_init(struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API writes the given data to the register address
|
|
||||||
* of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] reg_addr : Register address from where the data to be written.
|
|
||||||
* @param[in] reg_data : Pointer to data buffer which is to be written
|
|
||||||
* in the sensor.
|
|
||||||
* @param[in] len : No of bytes of data to write..
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error
|
|
||||||
*/
|
|
||||||
int8_t bme680_set_regs(const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API reads the data from the given register address of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] reg_addr : Register address from where the data to be read
|
|
||||||
* @param[out] reg_data : Pointer to data buffer to store the read data.
|
|
||||||
* @param[in] len : No of bytes of data to be read.
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error
|
|
||||||
*/
|
|
||||||
int8_t bme680_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API performs the soft reset of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error.
|
|
||||||
*/
|
|
||||||
int8_t bme680_soft_reset(struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API is used to set the power mode of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev
|
|
||||||
* @note : Pass the value to bme680_dev.power_mode structure variable.
|
|
||||||
*
|
|
||||||
* value | mode
|
|
||||||
* -------------|------------------
|
|
||||||
* 0x00 | BME680_SLEEP_MODE
|
|
||||||
* 0x01 | BME680_FORCED_MODE
|
|
||||||
*
|
|
||||||
* * @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error
|
|
||||||
*/
|
|
||||||
int8_t bme680_set_sensor_mode(struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API is used to get the power mode of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev
|
|
||||||
* @note : bme680_dev.power_mode structure variable hold the power mode.
|
|
||||||
*
|
|
||||||
* value | mode
|
|
||||||
* ---------|------------------
|
|
||||||
* 0x00 | BME680_SLEEP_MODE
|
|
||||||
* 0x01 | BME680_FORCED_MODE
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error
|
|
||||||
*/
|
|
||||||
int8_t bme680_get_sensor_mode(struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API is used to set the profile duration of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
* @param[in] duration : Duration of the measurement in ms.
|
|
||||||
*
|
|
||||||
* @return Nothing
|
|
||||||
*/
|
|
||||||
void bme680_set_profile_dur(uint16_t duration, struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API is used to get the profile duration of the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
* @param[in] duration : Duration of the measurement in ms.
|
|
||||||
*
|
|
||||||
* @return Nothing
|
|
||||||
*/
|
|
||||||
void bme680_get_profile_dur(uint16_t *duration, struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API reads the pressure, temperature and humidity and gas data
|
|
||||||
* from the sensor, compensates the data and store it in the bme680_data
|
|
||||||
* structure instance passed by the user.
|
|
||||||
*
|
|
||||||
* @param[out] data: Structure instance to hold the data.
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error
|
|
||||||
*/
|
|
||||||
int8_t bme680_get_sensor_data(struct bme680_field_data *data, struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API is used to set the oversampling, filter and T,P,H, gas selection
|
|
||||||
* settings in the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
* @param[in] desired_settings : Variable used to select the settings which
|
|
||||||
* are to be set in the sensor.
|
|
||||||
*
|
|
||||||
* Macros | Functionality
|
|
||||||
*-------------------------|----------------------------------------------
|
|
||||||
* BME680_OST_SEL | To set temperature oversampling.
|
|
||||||
* BME680_OSP_SEL | To set pressure oversampling.
|
|
||||||
* BME680_OSH_SEL | To set humidity oversampling.
|
|
||||||
* BME680_GAS_MEAS_SEL | To set gas measurement setting.
|
|
||||||
* BME680_FILTER_SEL | To set filter setting.
|
|
||||||
* BME680_HCNTRL_SEL | To set humidity control setting.
|
|
||||||
* BME680_RUN_GAS_SEL | To set run gas setting.
|
|
||||||
* BME680_NBCONV_SEL | To set NB conversion setting.
|
|
||||||
* BME680_GAS_SENSOR_SEL | To set all gas sensor related settings
|
|
||||||
*
|
|
||||||
* @note : Below are the macros to be used by the user for selecting the
|
|
||||||
* desired settings. User can do OR operation of these macros for configuring
|
|
||||||
* multiple settings.
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error.
|
|
||||||
*/
|
|
||||||
int8_t bme680_set_sensor_settings(uint16_t desired_settings, struct bme680_dev *dev);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief This API is used to get the oversampling, filter and T,P,H, gas selection
|
|
||||||
* settings in the sensor.
|
|
||||||
*
|
|
||||||
* @param[in] dev : Structure instance of bme680_dev.
|
|
||||||
* @param[in] desired_settings : Variable used to select the settings which
|
|
||||||
* are to be get from the sensor.
|
|
||||||
*
|
|
||||||
* @return Result of API execution status
|
|
||||||
* @retval zero -> Success / +ve value -> Warning / -ve value -> Error.
|
|
||||||
*/
|
|
||||||
int8_t bme680_get_sensor_settings(uint16_t desired_settings, struct bme680_dev *dev);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* End of CPP guard */
|
|
||||||
#endif /* BME680_H_ */
|
|
||||||
/** @}*/
|
|
@ -1,529 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* Neither the name of the copyright holder nor the names of the
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
||||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
|
|
||||||
* OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
* ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
|
||||||
*
|
|
||||||
* The information provided is believed to be accurate and reliable.
|
|
||||||
* The copyright holder assumes no responsibility
|
|
||||||
* for the consequences of use
|
|
||||||
* of such information nor for any infringement of patents or
|
|
||||||
* other rights of third parties which may result from its use.
|
|
||||||
* No license is granted by implication or otherwise under any patent or
|
|
||||||
* patent rights of the copyright holder.
|
|
||||||
*
|
|
||||||
* @file bme680_defs.h
|
|
||||||
* @date 5 Jul 2017
|
|
||||||
* @version 3.5.1
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! @file bme680_defs.h
|
|
||||||
@brief Sensor driver for BME680 sensor */
|
|
||||||
/*!
|
|
||||||
* @defgroup BME680 SENSOR API
|
|
||||||
* @brief
|
|
||||||
* @{*/
|
|
||||||
#ifndef BME680_DEFS_H_
|
|
||||||
#define BME680_DEFS_H_
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
/* header includes */
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
#include <linux/types.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
#if (LONG_MAX) > 0x7fffffff
|
|
||||||
#define __have_long64 1
|
|
||||||
#elif (LONG_MAX) == 0x7fffffff
|
|
||||||
#define __have_long32 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(UINT8_C)
|
|
||||||
#define INT8_C(x) x
|
|
||||||
#if (INT_MAX) > 0x7f
|
|
||||||
#define UINT8_C(x) x
|
|
||||||
#else
|
|
||||||
#define UINT8_C(x) x##U
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(UINT16_C)
|
|
||||||
#define INT16_C(x) x
|
|
||||||
#if (INT_MAX) > 0x7fff
|
|
||||||
#define UINT16_C(x) x
|
|
||||||
#else
|
|
||||||
#define UINT16_C(x) x##U
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(INT32_C) && !defined(UINT32_C)
|
|
||||||
#if __have_long32
|
|
||||||
#define INT32_C(x) x##L
|
|
||||||
#define UINT32_C(x) x##UL
|
|
||||||
#else
|
|
||||||
#define INT32_C(x) x
|
|
||||||
#define UINT32_C(x) x##U
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(INT64_C) && !defined(UINT64_C)
|
|
||||||
#if __have_long64
|
|
||||||
#define INT64_C(x) x##L
|
|
||||||
#define UINT64_C(x) x##UL
|
|
||||||
#else
|
|
||||||
#define INT64_C(x) x##LL
|
|
||||||
#define UINT64_C(x) x##ULL
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
/**@}*/
|
|
||||||
|
|
||||||
/**\name C standard macros */
|
|
||||||
#ifndef NULL
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define NULL 0
|
|
||||||
#else
|
|
||||||
#define NULL ((void *) 0)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** BME680 General config */
|
|
||||||
#define BME680_POLL_PERIOD_MS UINT8_C(10)
|
|
||||||
|
|
||||||
/** BME680 I2C addresses */
|
|
||||||
#define BME680_I2C_ADDR_PRIMARY UINT8_C(0x76)
|
|
||||||
#define BME680_I2C_ADDR_SECONDARY UINT8_C(0x77)
|
|
||||||
|
|
||||||
/** BME680 unique chip identifier */
|
|
||||||
#define BME680_CHIP_ID UINT8_C(0x61)
|
|
||||||
|
|
||||||
/** BME680 coefficients related defines */
|
|
||||||
#define BME680_COEFF_SIZE UINT8_C(0x41)
|
|
||||||
#define BME680_COEFF_ADDR1_LEN UINT8_C(25)
|
|
||||||
#define BME680_COEFF_ADDR2_LEN UINT8_C(16)
|
|
||||||
|
|
||||||
/** BME680 field_x related defines */
|
|
||||||
#define BME680_FIELD_LENGTH UINT8_C(15)
|
|
||||||
#define BME680_FIELD_ADDR_OFFSET UINT8_C(17)
|
|
||||||
|
|
||||||
/** Soft reset command */
|
|
||||||
#define BME680_SOFT_RESET_CMD UINT8_C(0xb6)
|
|
||||||
|
|
||||||
/** Error code definitions */
|
|
||||||
#define BME680_OK INT8_C(0)
|
|
||||||
/* Errors */
|
|
||||||
#define BME680_E_NULL_PTR INT8_C(-1)
|
|
||||||
#define BME680_E_COM_FAIL INT8_C(-2)
|
|
||||||
#define BME680_E_DEV_NOT_FOUND INT8_C(-3)
|
|
||||||
#define BME680_E_INVALID_LENGTH INT8_C(-4)
|
|
||||||
|
|
||||||
/* Warnings */
|
|
||||||
#define BME680_W_DEFINE_PWR_MODE INT8_C(1)
|
|
||||||
#define BME680_W_NO_NEW_DATA INT8_C(2)
|
|
||||||
|
|
||||||
/* Info's */
|
|
||||||
#define BME680_I_MIN_CORRECTION UINT8_C(1)
|
|
||||||
#define BME680_I_MAX_CORRECTION UINT8_C(2)
|
|
||||||
|
|
||||||
/** Register map */
|
|
||||||
/** Other coefficient's address */
|
|
||||||
#define BME680_ADDR_RES_HEAT_VAL_ADDR UINT8_C(0x00)
|
|
||||||
#define BME680_ADDR_RES_HEAT_RANGE_ADDR UINT8_C(0x02)
|
|
||||||
#define BME680_ADDR_RANGE_SW_ERR_ADDR UINT8_C(0x04)
|
|
||||||
#define BME680_ADDR_SENS_CONF_START UINT8_C(0x5A)
|
|
||||||
#define BME680_ADDR_GAS_CONF_START UINT8_C(0x64)
|
|
||||||
|
|
||||||
/** Field settings */
|
|
||||||
#define BME680_FIELD0_ADDR UINT8_C(0x1d)
|
|
||||||
|
|
||||||
/** Heater settings */
|
|
||||||
#define BME680_RES_HEAT0_ADDR UINT8_C(0x5a)
|
|
||||||
#define BME680_GAS_WAIT0_ADDR UINT8_C(0x64)
|
|
||||||
|
|
||||||
/** Sensor configuration registers */
|
|
||||||
#define BME680_CONF_HEAT_CTRL_ADDR UINT8_C(0x70)
|
|
||||||
#define BME680_CONF_ODR_RUN_GAS_NBC_ADDR UINT8_C(0x71)
|
|
||||||
#define BME680_CONF_OS_H_ADDR UINT8_C(0x72)
|
|
||||||
#define BME680_MEM_PAGE_ADDR UINT8_C(0xf3)
|
|
||||||
#define BME680_CONF_T_P_MODE_ADDR UINT8_C(0x74)
|
|
||||||
#define BME680_CONF_ODR_FILT_ADDR UINT8_C(0x75)
|
|
||||||
|
|
||||||
/** Coefficient's address */
|
|
||||||
#define BME680_COEFF_ADDR1 UINT8_C(0x89)
|
|
||||||
#define BME680_COEFF_ADDR2 UINT8_C(0xe1)
|
|
||||||
|
|
||||||
/** Chip identifier */
|
|
||||||
#define BME680_CHIP_ID_ADDR UINT8_C(0xd0)
|
|
||||||
|
|
||||||
/** Soft reset register */
|
|
||||||
#define BME680_SOFT_RESET_ADDR UINT8_C(0xe0)
|
|
||||||
|
|
||||||
/** Heater control settings */
|
|
||||||
#define BME680_ENABLE_HEATER UINT8_C(0x00)
|
|
||||||
#define BME680_DISABLE_HEATER UINT8_C(0x08)
|
|
||||||
|
|
||||||
/** Gas measurement settings */
|
|
||||||
#define BME680_DISABLE_GAS_MEAS UINT8_C(0x00)
|
|
||||||
#define BME680_ENABLE_GAS_MEAS UINT8_C(0x01)
|
|
||||||
|
|
||||||
/** Over-sampling settings */
|
|
||||||
#define BME680_OS_NONE UINT8_C(0)
|
|
||||||
#define BME680_OS_1X UINT8_C(1)
|
|
||||||
#define BME680_OS_2X UINT8_C(2)
|
|
||||||
#define BME680_OS_4X UINT8_C(3)
|
|
||||||
#define BME680_OS_8X UINT8_C(4)
|
|
||||||
#define BME680_OS_16X UINT8_C(5)
|
|
||||||
|
|
||||||
/** IIR filter settings */
|
|
||||||
#define BME680_FILTER_SIZE_0 UINT8_C(0)
|
|
||||||
#define BME680_FILTER_SIZE_1 UINT8_C(1)
|
|
||||||
#define BME680_FILTER_SIZE_3 UINT8_C(2)
|
|
||||||
#define BME680_FILTER_SIZE_7 UINT8_C(3)
|
|
||||||
#define BME680_FILTER_SIZE_15 UINT8_C(4)
|
|
||||||
#define BME680_FILTER_SIZE_31 UINT8_C(5)
|
|
||||||
#define BME680_FILTER_SIZE_63 UINT8_C(6)
|
|
||||||
#define BME680_FILTER_SIZE_127 UINT8_C(7)
|
|
||||||
|
|
||||||
/** Power mode settings */
|
|
||||||
#define BME680_SLEEP_MODE UINT8_C(0)
|
|
||||||
#define BME680_FORCED_MODE UINT8_C(1)
|
|
||||||
|
|
||||||
/** Delay related macro declaration */
|
|
||||||
#define BME680_RESET_PERIOD UINT32_C(10)
|
|
||||||
|
|
||||||
/** SPI memory page settings */
|
|
||||||
#define BME680_MEM_PAGE0 UINT8_C(0x10)
|
|
||||||
#define BME680_MEM_PAGE1 UINT8_C(0x00)
|
|
||||||
|
|
||||||
/** Ambient humidity shift value for compensation */
|
|
||||||
#define BME680_HUM_REG_SHIFT_VAL UINT8_C(4)
|
|
||||||
|
|
||||||
/** Run gas enable and disable settings */
|
|
||||||
#define BME680_RUN_GAS_DISABLE UINT8_C(0)
|
|
||||||
#define BME680_RUN_GAS_ENABLE UINT8_C(1)
|
|
||||||
|
|
||||||
/** Buffer length macro declaration */
|
|
||||||
#define BME680_TMP_BUFFER_LENGTH UINT8_C(40)
|
|
||||||
#define BME680_REG_BUFFER_LENGTH UINT8_C(6)
|
|
||||||
#define BME680_FIELD_DATA_LENGTH UINT8_C(3)
|
|
||||||
#define BME680_GAS_REG_BUF_LENGTH UINT8_C(20)
|
|
||||||
#define BME680_GAS_HEATER_PROF_LEN_MAX UINT8_C(10)
|
|
||||||
|
|
||||||
/** Settings selector */
|
|
||||||
#define BME680_OST_SEL UINT16_C(1)
|
|
||||||
#define BME680_OSP_SEL UINT16_C(2)
|
|
||||||
#define BME680_OSH_SEL UINT16_C(4)
|
|
||||||
#define BME680_GAS_MEAS_SEL UINT16_C(8)
|
|
||||||
#define BME680_FILTER_SEL UINT16_C(16)
|
|
||||||
#define BME680_HCNTRL_SEL UINT16_C(32)
|
|
||||||
#define BME680_RUN_GAS_SEL UINT16_C(64)
|
|
||||||
#define BME680_NBCONV_SEL UINT16_C(128)
|
|
||||||
#define BME680_GAS_SENSOR_SEL UINT16_C(BME680_GAS_MEAS_SEL | BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)
|
|
||||||
|
|
||||||
/** Number of conversion settings*/
|
|
||||||
#define BME680_NBCONV_MIN UINT8_C(0)
|
|
||||||
#define BME680_NBCONV_MAX UINT8_C(10)
|
|
||||||
|
|
||||||
/** Mask definitions */
|
|
||||||
#define BME680_GAS_MEAS_MSK UINT8_C(0x30)
|
|
||||||
#define BME680_NBCONV_MSK UINT8_C(0X0F)
|
|
||||||
#define BME680_FILTER_MSK UINT8_C(0X1C)
|
|
||||||
#define BME680_OST_MSK UINT8_C(0XE0)
|
|
||||||
#define BME680_OSP_MSK UINT8_C(0X1C)
|
|
||||||
#define BME680_OSH_MSK UINT8_C(0X07)
|
|
||||||
#define BME680_HCTRL_MSK UINT8_C(0x08)
|
|
||||||
#define BME680_RUN_GAS_MSK UINT8_C(0x10)
|
|
||||||
#define BME680_MODE_MSK UINT8_C(0x03)
|
|
||||||
#define BME680_RHRANGE_MSK UINT8_C(0x30)
|
|
||||||
#define BME680_RSERROR_MSK UINT8_C(0xf0)
|
|
||||||
#define BME680_NEW_DATA_MSK UINT8_C(0x80)
|
|
||||||
#define BME680_GAS_INDEX_MSK UINT8_C(0x0f)
|
|
||||||
#define BME680_GAS_RANGE_MSK UINT8_C(0x0f)
|
|
||||||
#define BME680_GASM_VALID_MSK UINT8_C(0x20)
|
|
||||||
#define BME680_HEAT_STAB_MSK UINT8_C(0x10)
|
|
||||||
#define BME680_MEM_PAGE_MSK UINT8_C(0x10)
|
|
||||||
#define BME680_SPI_RD_MSK UINT8_C(0x80)
|
|
||||||
#define BME680_SPI_WR_MSK UINT8_C(0x7f)
|
|
||||||
#define BME680_BIT_H1_DATA_MSK UINT8_C(0x0F)
|
|
||||||
|
|
||||||
/** Bit position definitions for sensor settings */
|
|
||||||
#define BME680_GAS_MEAS_POS UINT8_C(4)
|
|
||||||
#define BME680_FILTER_POS UINT8_C(2)
|
|
||||||
#define BME680_OST_POS UINT8_C(5)
|
|
||||||
#define BME680_OSP_POS UINT8_C(2)
|
|
||||||
#define BME680_RUN_GAS_POS UINT8_C(4)
|
|
||||||
|
|
||||||
/** Array Index to Field data mapping for Calibration Data*/
|
|
||||||
#define BME680_T2_LSB_REG (1)
|
|
||||||
#define BME680_T2_MSB_REG (2)
|
|
||||||
#define BME680_T3_REG (3)
|
|
||||||
#define BME680_P1_LSB_REG (5)
|
|
||||||
#define BME680_P1_MSB_REG (6)
|
|
||||||
#define BME680_P2_LSB_REG (7)
|
|
||||||
#define BME680_P2_MSB_REG (8)
|
|
||||||
#define BME680_P3_REG (9)
|
|
||||||
#define BME680_P4_LSB_REG (11)
|
|
||||||
#define BME680_P4_MSB_REG (12)
|
|
||||||
#define BME680_P5_LSB_REG (13)
|
|
||||||
#define BME680_P5_MSB_REG (14)
|
|
||||||
#define BME680_P7_REG (15)
|
|
||||||
#define BME680_P6_REG (16)
|
|
||||||
#define BME680_P8_LSB_REG (19)
|
|
||||||
#define BME680_P8_MSB_REG (20)
|
|
||||||
#define BME680_P9_LSB_REG (21)
|
|
||||||
#define BME680_P9_MSB_REG (22)
|
|
||||||
#define BME680_P10_REG (23)
|
|
||||||
#define BME680_H2_MSB_REG (25)
|
|
||||||
#define BME680_H2_LSB_REG (26)
|
|
||||||
#define BME680_H1_LSB_REG (26)
|
|
||||||
#define BME680_H1_MSB_REG (27)
|
|
||||||
#define BME680_H3_REG (28)
|
|
||||||
#define BME680_H4_REG (29)
|
|
||||||
#define BME680_H5_REG (30)
|
|
||||||
#define BME680_H6_REG (31)
|
|
||||||
#define BME680_H7_REG (32)
|
|
||||||
#define BME680_T1_LSB_REG (33)
|
|
||||||
#define BME680_T1_MSB_REG (34)
|
|
||||||
#define BME680_GH2_LSB_REG (35)
|
|
||||||
#define BME680_GH2_MSB_REG (36)
|
|
||||||
#define BME680_GH1_REG (37)
|
|
||||||
#define BME680_GH3_REG (38)
|
|
||||||
|
|
||||||
/** BME680 register buffer index settings*/
|
|
||||||
#define BME680_REG_FILTER_INDEX UINT8_C(5)
|
|
||||||
#define BME680_REG_TEMP_INDEX UINT8_C(4)
|
|
||||||
#define BME680_REG_PRES_INDEX UINT8_C(4)
|
|
||||||
#define BME680_REG_HUM_INDEX UINT8_C(2)
|
|
||||||
#define BME680_REG_NBCONV_INDEX UINT8_C(1)
|
|
||||||
#define BME680_REG_RUN_GAS_INDEX UINT8_C(1)
|
|
||||||
#define BME680_REG_HCTRL_INDEX UINT8_C(0)
|
|
||||||
|
|
||||||
/** Macro to combine two 8 bit data's to form a 16 bit data */
|
|
||||||
#define BME680_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)
|
|
||||||
|
|
||||||
/** Macro to SET and GET BITS of a register */
|
|
||||||
#define BME680_SET_BITS(reg_data, bitname, data) \
|
|
||||||
((reg_data & ~(bitname##_MSK)) | \
|
|
||||||
((data << bitname##_POS) & bitname##_MSK))
|
|
||||||
#define BME680_GET_BITS(reg_data, bitname) ((reg_data & (bitname##_MSK)) >> \
|
|
||||||
(bitname##_POS))
|
|
||||||
|
|
||||||
/** Macro variant to handle the bitname position if it is zero */
|
|
||||||
#define BME680_SET_BITS_POS_0(reg_data, bitname, data) \
|
|
||||||
((reg_data & ~(bitname##_MSK)) | \
|
|
||||||
(data & bitname##_MSK))
|
|
||||||
#define BME680_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK))
|
|
||||||
|
|
||||||
/** Type definitions */
|
|
||||||
/*
|
|
||||||
* Generic communication function pointer
|
|
||||||
* @param[in] dev_id: Place holder to store the id of the device structure
|
|
||||||
* Can be used to store the index of the Chip select or
|
|
||||||
* I2C address of the device.
|
|
||||||
* @param[in] reg_addr: Used to select the register the where data needs to
|
|
||||||
* be read from or written to.
|
|
||||||
* @param[in/out] reg_data: Data array to read/write
|
|
||||||
* @param[in] len: Length of the data array
|
|
||||||
*/
|
|
||||||
typedef int8_t (*bme680_com_fptr_t)(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delay function pointer
|
|
||||||
* @param[in] period: Time period in milliseconds
|
|
||||||
*/
|
|
||||||
typedef void (*bme680_delay_fptr_t)(uint32_t period);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Interface selection Enumerations
|
|
||||||
*/
|
|
||||||
enum bme680_intf {
|
|
||||||
/*! SPI interface */
|
|
||||||
BME680_SPI_INTF,
|
|
||||||
/*! I2C interface */
|
|
||||||
BME680_I2C_INTF
|
|
||||||
};
|
|
||||||
|
|
||||||
/* structure definitions */
|
|
||||||
/*!
|
|
||||||
* @brief Sensor field data structure
|
|
||||||
*/
|
|
||||||
struct bme680_field_data {
|
|
||||||
/*! Contains new_data, gasm_valid & heat_stab */
|
|
||||||
uint8_t status;
|
|
||||||
/*! The index of the heater profile used */
|
|
||||||
uint8_t gas_index;
|
|
||||||
/*! Measurement index to track order */
|
|
||||||
uint8_t meas_index;
|
|
||||||
/*! Temperature in degree celsius x100 */
|
|
||||||
int16_t temperature;
|
|
||||||
/*! Pressure in Pascal */
|
|
||||||
uint32_t pressure;
|
|
||||||
/*! Humidity in % relative humidity x1000 */
|
|
||||||
uint32_t humidity;
|
|
||||||
/*! Gas resistance in Ohms */
|
|
||||||
uint32_t gas_resistance;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Structure to hold the Calibration data
|
|
||||||
*/
|
|
||||||
struct bme680_calib_data {
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
uint16_t par_h1;
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
uint16_t par_h2;
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
int8_t par_h3;
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
int8_t par_h4;
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
int8_t par_h5;
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
uint8_t par_h6;
|
|
||||||
/*! Variable to store calibrated humidity data */
|
|
||||||
int8_t par_h7;
|
|
||||||
/*! Variable to store calibrated gas data */
|
|
||||||
int8_t par_gh1;
|
|
||||||
/*! Variable to store calibrated gas data */
|
|
||||||
int16_t par_gh2;
|
|
||||||
/*! Variable to store calibrated gas data */
|
|
||||||
int8_t par_gh3;
|
|
||||||
/*! Variable to store calibrated temperature data */
|
|
||||||
uint16_t par_t1;
|
|
||||||
/*! Variable to store calibrated temperature data */
|
|
||||||
int16_t par_t2;
|
|
||||||
/*! Variable to store calibrated temperature data */
|
|
||||||
int8_t par_t3;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
uint16_t par_p1;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int16_t par_p2;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int8_t par_p3;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int16_t par_p4;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int16_t par_p5;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int8_t par_p6;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int8_t par_p7;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int16_t par_p8;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
int16_t par_p9;
|
|
||||||
/*! Variable to store calibrated pressure data */
|
|
||||||
uint8_t par_p10;
|
|
||||||
/*! Variable to store t_fine size */
|
|
||||||
int32_t t_fine;
|
|
||||||
/*! Variable to store heater resistance range */
|
|
||||||
uint8_t res_heat_range;
|
|
||||||
/*! Variable to store heater resistance value */
|
|
||||||
int8_t res_heat_val;
|
|
||||||
/*! Variable to store error range */
|
|
||||||
int8_t range_sw_err;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief BME680 sensor settings structure which comprises of ODR,
|
|
||||||
* over-sampling and filter settings.
|
|
||||||
*/
|
|
||||||
struct bme680_tph_sett {
|
|
||||||
/*! Humidity oversampling */
|
|
||||||
uint8_t os_hum;
|
|
||||||
/*! Temperature oversampling */
|
|
||||||
uint8_t os_temp;
|
|
||||||
/*! Pressure oversampling */
|
|
||||||
uint8_t os_pres;
|
|
||||||
/*! Filter coefficient */
|
|
||||||
uint8_t filter;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief BME680 gas sensor which comprises of gas settings
|
|
||||||
* and status parameters
|
|
||||||
*/
|
|
||||||
struct bme680_gas_sett {
|
|
||||||
/*! Variable to store nb conversion */
|
|
||||||
uint8_t nb_conv;
|
|
||||||
/*! Variable to store heater control */
|
|
||||||
uint8_t heatr_ctrl;
|
|
||||||
/*! Run gas enable value */
|
|
||||||
uint8_t run_gas;
|
|
||||||
/*! Pointer to store heater temperature */
|
|
||||||
uint16_t heatr_temp;
|
|
||||||
/*! Pointer to store duration profile */
|
|
||||||
uint16_t heatr_dur;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief BME680 device structure
|
|
||||||
*/
|
|
||||||
struct bme680_dev {
|
|
||||||
/*! Chip Id */
|
|
||||||
uint8_t chip_id;
|
|
||||||
/*! Device Id */
|
|
||||||
uint8_t dev_id;
|
|
||||||
/*! SPI/I2C interface */
|
|
||||||
enum bme680_intf intf;
|
|
||||||
/*! Memory page used */
|
|
||||||
uint8_t mem_page;
|
|
||||||
/*! Ambient temperature in Degree C*/
|
|
||||||
int8_t amb_temp;
|
|
||||||
/*! Sensor calibration data */
|
|
||||||
struct bme680_calib_data calib;
|
|
||||||
/*! Sensor settings */
|
|
||||||
struct bme680_tph_sett tph_sett;
|
|
||||||
/*! Gas Sensor settings */
|
|
||||||
struct bme680_gas_sett gas_sett;
|
|
||||||
/*! Sensor power modes */
|
|
||||||
uint8_t power_mode;
|
|
||||||
/*! New sensor fields */
|
|
||||||
uint8_t new_fields;
|
|
||||||
/*! Store the info messages */
|
|
||||||
uint8_t info_msg;
|
|
||||||
/*! Burst read structure */
|
|
||||||
bme680_com_fptr_t read;
|
|
||||||
/*! Burst write structure */
|
|
||||||
bme680_com_fptr_t write;
|
|
||||||
/*! Delay in ms */
|
|
||||||
bme680_delay_fptr_t delay_ms;
|
|
||||||
/*! Communication function result */
|
|
||||||
int8_t com_rslt;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* BME680_DEFS_H_ */
|
|
||||||
/** @}*/
|
|
||||||
/** @}*/
|
|
@ -1,42 +0,0 @@
|
|||||||
# Change Log
|
|
||||||
All notable changes to the BME680 Sensor API will be documented in this file.
|
|
||||||
|
|
||||||
## v3.5.1, 5 Jul 2017
|
|
||||||
### Changed
|
|
||||||
- Fixed bug with overwriting of the result with communication results
|
|
||||||
- Added member in the dev structure to store communication results
|
|
||||||
- Updated set profile duration API to not return a result.
|
|
||||||
- Added new API to get the duration for the existing profile
|
|
||||||
- Fixed bug with setting gas configuration. Reduced to writing only relevant bytes
|
|
||||||
- Updated readme
|
|
||||||
- Updated documentation for the type definitions
|
|
||||||
- Removed mode check for get sensor data and setting and getting profile dur
|
|
||||||
|
|
||||||
|
|
||||||
## v3.5.0, 28 Jun 2017
|
|
||||||
### Changed
|
|
||||||
- Fixed bug with getting and setting mem pages
|
|
||||||
- Changed initialization sequence to be more robust
|
|
||||||
- Added additional tries while reading data in case of inadequate delay
|
|
||||||
|
|
||||||
|
|
||||||
## v3.4.0, 8 Jun 2017
|
|
||||||
### Changed
|
|
||||||
- Modified the bme680_get_sensor_data API. User has to now pass the struct that stores the data rather than retrieving from the bme680_dev structure.
|
|
||||||
- Fixed possible bugs
|
|
||||||
|
|
||||||
## v3.3.0, 24 May 2017
|
|
||||||
### Changed
|
|
||||||
- Name changes in the BME680 device structure.
|
|
||||||
- Removed sequential and parallel modes.
|
|
||||||
- Removed ODR related sensor settings
|
|
||||||
- Modified get sensor settings API with user selection.
|
|
||||||
- Removed sort sensor data and swap fields API which are not required.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- BME680 set profile duration API.
|
|
||||||
|
|
||||||
## v3.2.1, 17 May 2017
|
|
||||||
### Added
|
|
||||||
- Took the reference as base version 3.2.1 of BME680 sensor and added.
|
|
||||||
|
|
Binary file not shown.
@ -1,69 +0,0 @@
|
|||||||
#include "bme680.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct bme680_dev gas_sensor;
|
|
||||||
|
|
||||||
uint8_t coeff1[25] = {
|
|
||||||
192, 108, 103, 3, 47, 80, 144, 236,
|
|
||||||
214, 88, 255, 42, 30, 169, 255, 54,
|
|
||||||
30, 0, 0, 199, 239, 69, 248, 30,
|
|
||||||
1
|
|
||||||
};
|
|
||||||
uint8_t coeff2[16] = {
|
|
||||||
64, 206, 39, 0, 45, 20, 120,
|
|
||||||
156, 24, 102, 142, 171, 226, 18, 16,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len){
|
|
||||||
switch(reg_addr){
|
|
||||||
case BME680_CHIP_ID_ADDR:
|
|
||||||
data[0] = BME680_CHIP_ID;
|
|
||||||
return BME680_OK;
|
|
||||||
|
|
||||||
case BME680_COEFF_ADDR1:
|
|
||||||
memcpy(data, coeff1, len);
|
|
||||||
return BME680_OK;
|
|
||||||
|
|
||||||
case BME680_COEFF_ADDR2:
|
|
||||||
memcpy(data, coeff2, len);
|
|
||||||
return BME680_OK;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_delay_ms(uint32_t period){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY;
|
|
||||||
gas_sensor.intf = BME680_I2C_INTF;
|
|
||||||
gas_sensor.read = user_i2c_read;
|
|
||||||
gas_sensor.write = user_i2c_write;
|
|
||||||
gas_sensor.delay_ms = user_delay_ms;
|
|
||||||
|
|
||||||
int8_t rslt = BME680_OK;
|
|
||||||
rslt = bme680_init(&gas_sensor);
|
|
||||||
if(rslt == BME680_OK){
|
|
||||||
printf("CHIP OK\n");
|
|
||||||
printf("%d\n",gas_sensor.calib.par_t1);
|
|
||||||
printf("%d\n",gas_sensor.calib.par_t2);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t buff[15] = {128,0, 79,186,144, 122,185,64, 76,59, 128,0,0, 220,120};
|
|
||||||
|
|
||||||
uint32_t adc_pres = (uint32_t) (((uint32_t) buff[2] * 4096) | ((uint32_t) buff[3] * 16) | ((uint32_t) buff[4] / 16));
|
|
||||||
uint32_t adc_temp = (uint32_t) (((uint32_t) buff[5] * 4096) | ((uint32_t) buff[6] * 16) | ((uint32_t) buff[7] / 16));
|
|
||||||
uint16_t adc_hum = (uint16_t) (((uint32_t) buff[8] * 256) | (uint32_t) buff[9]);
|
|
||||||
uint16_t adc_gas_res = (uint16_t) ((uint32_t) buff[13] * 4 | (((uint32_t) buff[14]) / 64));
|
|
||||||
uint8_t gas_range = buff[14] & BME680_GAS_RANGE_MSK;
|
|
||||||
|
|
||||||
printf("%d\n",calc_temperature(adc_temp, &gas_sensor));
|
|
||||||
printf("%d\n",calc_pressure(adc_pres, &gas_sensor));
|
|
||||||
}
|
|
5
library/CHANGELOG.txt
Normal file
5
library/CHANGELOG.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
1.0.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
@ -2,7 +2,7 @@ from .constants import *
|
|||||||
import math
|
import math
|
||||||
import time
|
import time
|
||||||
|
|
||||||
__version__ = '0.0.1'
|
__version__ = '1.0.0'
|
||||||
|
|
||||||
class BME680(BME680Data):
|
class BME680(BME680Data):
|
||||||
"""BOSCH BME680
|
"""BOSCH BME680
|
@ -39,7 +39,7 @@ classifiers = ['Development Status :: 5 - Production/Stable',
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = 'bme680',
|
name = 'bme680',
|
||||||
version = '0.0.1',
|
version = '1.0.0',
|
||||||
author = 'Philip Howard',
|
author = 'Philip Howard',
|
||||||
author_email = 'phil@pimoroni.com',
|
author_email = 'phil@pimoroni.com',
|
||||||
description = """Python library for driving the Pimoroni BME680 Breakout""",
|
description = """Python library for driving the Pimoroni BME680 Breakout""",
|
5
packaging/CHANGELOG
Normal file
5
packaging/CHANGELOG
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
bme680 (1.0.0) stable; urgency=low
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- Phil Howard <phil@pimoroni.com> Mon, 08 Sep 2014 00:00:00 +0000
|
9
packaging/debian/README
Normal file
9
packaging/debian/README
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
README
|
||||||
|
|
||||||
|
Python library for the BME680 gas, temperature, pressure and humidity sensor. Supports communication over i2c only.
|
||||||
|
|
||||||
|
IMPORTANT
|
||||||
|
|
||||||
|
The bme680 library requires i2c.
|
||||||
|
To enable run `curl get.pimoroni.com/i2c | bash`
|
||||||
|
or use raspi-config and reboot your Raspberry Pi.
|
5
packaging/debian/changelog
Normal file
5
packaging/debian/changelog
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
bme680 (1.0.0) stable; urgency=low
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- Phil Howard <phil@pimoroni.com> Mon, 08 Sep 2014 00:00:00 +0000
|
1
packaging/debian/clean
Normal file
1
packaging/debian/clean
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.egg-info/*
|
1
packaging/debian/compat
Normal file
1
packaging/debian/compat
Normal file
@ -0,0 +1 @@
|
|||||||
|
9
|
29
packaging/debian/control
Normal file
29
packaging/debian/control
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Source: bme680
|
||||||
|
Maintainer: Phil Howard <phil@pimoroni.com>
|
||||||
|
Homepage: https://github.com/pimoroni/bme680
|
||||||
|
Section: python
|
||||||
|
Priority: extra
|
||||||
|
Build-Depends: debhelper (>= 9.0.0), dh-python, python-all (>= 2.7), python-setuptools, python3-all (>= 3.4), python3-setuptools
|
||||||
|
Standards-Version: 3.9.6
|
||||||
|
X-Python-Version: >= 2.7
|
||||||
|
X-Python3-Version: >= 3.4
|
||||||
|
|
||||||
|
Package: python-bme680
|
||||||
|
Architecture: all
|
||||||
|
Section: python
|
||||||
|
Depends: ${misc:Depends}, ${python:Depends}, python-rpi.gpio, python-spidev
|
||||||
|
Description: Python library for the BME680 gas, temperature, pressure and humidity sensor.
|
||||||
|
The BME680 is a gas, temperature, pressure and humidity sensor.
|
||||||
|
Supports communication over i2c only.
|
||||||
|
.
|
||||||
|
This is the Python 2 version of the package.
|
||||||
|
|
||||||
|
Package: python3-bme680
|
||||||
|
Architecture: all
|
||||||
|
Section: python
|
||||||
|
Depends: ${misc:Depends}, ${python3:Depends}, python3-rpi.gpio, python3-spidev
|
||||||
|
Description: Python library for the BME680 gas, temperature, pressure and humidity sensor.
|
||||||
|
The BME680 is a gas, temperature, pressure and humidity sensor.
|
||||||
|
Supports communication over i2c only.
|
||||||
|
.
|
||||||
|
This is the Python 3 version of the package.
|
26
packaging/debian/copyright
Normal file
26
packaging/debian/copyright
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: bme680
|
||||||
|
Source: https://github.com/pimoroni/bme680
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2016 Pimoroni Ltd <phil@pimoroni.com>
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
License: MIT
|
||||||
|
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.
|
12
packaging/debian/rules
Executable file
12
packaging/debian/rules
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
export DH_OPTIONS
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --with python2,python3 --buildsystem=python_distutils
|
||||||
|
|
||||||
|
override_dh_auto_install:
|
||||||
|
python setup.py install --root debian/python-bme680 --install-layout=deb
|
||||||
|
python3 setup.py install --root debian/python3-bme680 --install-layout=deb
|
1
packaging/debian/source/format
Normal file
1
packaging/debian/source/format
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
1
packaging/debian/source/options
Normal file
1
packaging/debian/source/options
Normal file
@ -0,0 +1 @@
|
|||||||
|
extend-diff-ignore = "^[^/]+\.egg-info/"
|
165
packaging/makeall.sh
Executable file
165
packaging/makeall.sh
Executable file
@ -0,0 +1,165 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# script control variables
|
||||||
|
|
||||||
|
reponame="" # leave this blank for auto-detection
|
||||||
|
libname="" # leave this blank for auto-detection
|
||||||
|
packagename="" # leave this blank for auto-selection
|
||||||
|
|
||||||
|
debianlog="debian/changelog"
|
||||||
|
debcontrol="debian/control"
|
||||||
|
debcopyright="debian/copyright"
|
||||||
|
debrules="debian/rules"
|
||||||
|
debreadme="debian/README"
|
||||||
|
|
||||||
|
debdir="$(pwd)"
|
||||||
|
rootdir="$(dirname $debdir)"
|
||||||
|
libdir="$rootdir/library"
|
||||||
|
|
||||||
|
FLAG=false
|
||||||
|
|
||||||
|
# function define
|
||||||
|
|
||||||
|
success() {
|
||||||
|
echo "$(tput setaf 2)$1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
inform() {
|
||||||
|
echo "$(tput setaf 6)$1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
warning() {
|
||||||
|
echo "$(tput setaf 1)$1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
newline() {
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# assessing repo and library variables
|
||||||
|
|
||||||
|
if [ -z "$reponame" ] || [ -z "$libname" ]; then
|
||||||
|
inform "detecting reponame and libname..."
|
||||||
|
else
|
||||||
|
inform "using reponame and libname overrides"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$reponame" ]; then
|
||||||
|
if [[ $rootdir == *"python"* ]]; then
|
||||||
|
repodir="$(dirname $rootdir)"
|
||||||
|
reponame="$(basename $repodir)"
|
||||||
|
else
|
||||||
|
repodir="$rootdir"
|
||||||
|
reponame="$(basename $repodir)"
|
||||||
|
fi
|
||||||
|
reponame=$(echo "$reponame" | tr "[A-Z]" "[a-z]")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$libname" ]; then
|
||||||
|
cd "$libdir"
|
||||||
|
libname=$(grep "name" setup.py | tr -d "[:space:]" | cut -c 7- | rev | cut -c 3- | rev)
|
||||||
|
libname=$(echo "$libname" | tr "[A-Z]" "[a-z]") && cd "$debdir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$packagename" ]; then
|
||||||
|
packagename="$libname"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "reponame is $reponame and libname is $libname"
|
||||||
|
echo "output packages will be python-$packagename and python3-$packagename"
|
||||||
|
|
||||||
|
# checking generating changelog file
|
||||||
|
|
||||||
|
./makelog.sh
|
||||||
|
version=$(head -n 1 "$libdir/CHANGELOG.txt")
|
||||||
|
echo "building $libname version $version"
|
||||||
|
|
||||||
|
# checking debian/changelog file
|
||||||
|
|
||||||
|
inform "checking debian/changelog file..."
|
||||||
|
|
||||||
|
if ! head -n 1 $debianlog | grep "$libname" &> /dev/null; then
|
||||||
|
warning "library not mentioned in header!" && FLAG=true
|
||||||
|
elif head -n 1 $debianlog | grep "UNRELEASED"; then
|
||||||
|
warning "this changelog is not going to generate a release!"
|
||||||
|
warning "change distribution to 'stable'" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# checking debian/copyright file
|
||||||
|
|
||||||
|
inform "checking debian/copyright file..."
|
||||||
|
|
||||||
|
if ! grep "^Source" $debcopyright | grep "$reponame" &> /dev/null; then
|
||||||
|
warning "$(grep "^Source" $debcopyright)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep "^Upstream-Name" $debcopyright | grep "$libname" &> /dev/null; then
|
||||||
|
warning "$(grep "^Upstream-Name" $debcopyright)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# checking debian/control file
|
||||||
|
|
||||||
|
inform "checking debian/control file..."
|
||||||
|
|
||||||
|
if ! grep "^Source" $debcontrol | grep "$libname" &> /dev/null; then
|
||||||
|
warning "$(grep "^Source" $debcontrol)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep "^Homepage" $debcontrol | grep "$reponame" &> /dev/null; then
|
||||||
|
warning "$(grep "^Homepage" $debcontrol)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep "^Package: python-$packagename" $debcontrol &> /dev/null; then
|
||||||
|
warning "$(grep "^Package: python-" $debcontrol)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep "^Package: python3-$packagename" $debcontrol &> /dev/null; then
|
||||||
|
warning "$(grep "^Package: python3-" $debcontrol)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep "^Priority: extra" $debcontrol &> /dev/null; then
|
||||||
|
warning "$(grep "^Priority" $debcontrol)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# checking debian/rules file
|
||||||
|
|
||||||
|
inform "checking debian/rules file..."
|
||||||
|
|
||||||
|
if ! grep "debian/python-$packagename" $debrules &> /dev/null; then
|
||||||
|
warning "$(grep "debian/python-" $debrules)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep "debian/python3-$packagename" $debrules &> /dev/null; then
|
||||||
|
warning "$(grep "debian/python3-" $debrules)" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# checking debian/README file
|
||||||
|
|
||||||
|
inform "checking debian/readme file..."
|
||||||
|
|
||||||
|
if ! grep -e "$libname" -e "$reponame" $debreadme &> /dev/null; then
|
||||||
|
warning "README does not seem to mention product, repo or lib!" && FLAG=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# summary of checks pre build
|
||||||
|
|
||||||
|
if $FLAG; then
|
||||||
|
warning "Check all of the above and correct!" && exit 1
|
||||||
|
else
|
||||||
|
inform "we're good to go... bulding!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# building deb and final checks
|
||||||
|
|
||||||
|
./makedeb.sh
|
||||||
|
|
||||||
|
inform "running lintian..."
|
||||||
|
lintian -v $(find -name "python*$version*.deb")
|
||||||
|
lintian -v $(find -name "python3*$version*.deb")
|
||||||
|
|
||||||
|
inform "checking signatures..."
|
||||||
|
gpg --verify $(find -name "*$version*changes")
|
||||||
|
gpg --verify $(find -name "*$version*dsc")
|
||||||
|
|
||||||
|
exit 0
|
30
packaging/makedeb.sh
Executable file
30
packaging/makedeb.sh
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
gettools="no"
|
||||||
|
setup="yes"
|
||||||
|
cleanup="yes"
|
||||||
|
pkgfiles=( "build" "changes" "deb" "dsc" "tar.xz" )
|
||||||
|
|
||||||
|
|
||||||
|
if [ $gettools == "yes" ]; then
|
||||||
|
sudo apt-get update && sudo apt-get install build-essential debhelper devscripts dh-make dh-python dput gnupg
|
||||||
|
sudo apt-get install python-all python-setuptools python3-all python3-setuptools
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $setup == "yes" ]; then
|
||||||
|
rm -R ../library/build ../library/debian &> /dev/null
|
||||||
|
cp -R ./debian/ ../library/
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ../library && debuild -aarmhf
|
||||||
|
|
||||||
|
for file in ${pkgfiles[@]}; do
|
||||||
|
mv ../*.$file ../packaging
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $cleanup == "yes" ]; then
|
||||||
|
debuild clean
|
||||||
|
rm -R ./build ./debian &> /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
82
packaging/makelog.sh
Executable file
82
packaging/makelog.sh
Executable file
@ -0,0 +1,82 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# script control variables
|
||||||
|
|
||||||
|
libname="" # leave this blank for auto-detection
|
||||||
|
sibname=() # name of sibling in packages list
|
||||||
|
versionwarn="yes" # set to anything but 'yes' to turn off warning
|
||||||
|
|
||||||
|
debdir="$(pwd)"
|
||||||
|
rootdir="$(dirname $debdir)"
|
||||||
|
libdir="$rootdir/library"
|
||||||
|
|
||||||
|
mainlog="CHANGELOG"
|
||||||
|
debianlog="debian/changelog"
|
||||||
|
pypilog="$libdir/CHANGELOG.txt"
|
||||||
|
|
||||||
|
# function define
|
||||||
|
|
||||||
|
success() {
|
||||||
|
echo "$(tput setaf 2)$1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
inform() {
|
||||||
|
echo "$(tput setaf 6)$1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
warning() {
|
||||||
|
echo "$(tput setaf 1)$1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
newline() {
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# generate debian changelog
|
||||||
|
|
||||||
|
cat $mainlog > $debianlog
|
||||||
|
inform "seeded debian changelog"
|
||||||
|
|
||||||
|
# generate pypi changelog
|
||||||
|
|
||||||
|
sed -e "/--/d" -e "s/ \*/\*/" \
|
||||||
|
-e "s/.*\([0-9].[0-9].[0-9]\).*/\1/" \
|
||||||
|
-e '/[0-9].[0-9].[0-9]/ a\
|
||||||
|
-----' $mainlog | cat -s > $pypilog
|
||||||
|
|
||||||
|
version=$(head -n 1 $pypilog)
|
||||||
|
inform "pypi changelog generated"
|
||||||
|
|
||||||
|
# touch up version in setup.py file
|
||||||
|
|
||||||
|
if [ -n $(grep version "$libdir/setup.py" &> /dev/null) ]; then
|
||||||
|
inform "touched up version in setup.py"
|
||||||
|
sed -i "s/'[0-9].[0-9].[0-9]'/'$version'/" "$libdir/setup.py"
|
||||||
|
else
|
||||||
|
warning "couldn't touch up version in setup, no match found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# touch up version in lib or package siblings
|
||||||
|
|
||||||
|
if [ -z "$libname" ]; then
|
||||||
|
cd "$libdir"
|
||||||
|
libname=$(grep "name" setup.py | tr -d "[:space:]" | cut -c 7- | rev | cut -c 3- | rev)
|
||||||
|
libname=$(echo "$libname" | tr "[A-Z]" "[a-z]") && cd "$debdir"
|
||||||
|
sibname+=( "$libname" )
|
||||||
|
elif [ "$libname" != "package" ]; then
|
||||||
|
sibname+=( "$libname" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
for sibling in ${sibname[@]}; do
|
||||||
|
if grep -e "__version__" "$libdir/$sibling.py" &> /dev/null; then
|
||||||
|
sed -i "s/__version__ = '[0-9].[0-9].[0-9]'/__version__ = '$version'/" "$libdir/$sibling.py"
|
||||||
|
inform "touched up version in $sibling.py"
|
||||||
|
elif grep -e "__version__" "$libdir/$sibling/__init__.py" &> /dev/null; then
|
||||||
|
sed -i "s/__version__ = '[0-9].[0-9].[0-9]'/__version__ = '$version'/" "$libdir/$sibling/__init__.py"
|
||||||
|
inform "touched up version in $sibling/__init__.py"
|
||||||
|
elif [ "$versionwarn" == "yes" ]; then
|
||||||
|
warning "couldn't touch up __version__ in $sibling, no match found"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in New Issue
Block a user