diff --git a/BME680_SensorAPI_Example_Guide.pdf b/BME680_SensorAPI_Example_Guide.pdf
deleted file mode 100644
index 87eeca2..0000000
Binary files a/BME680_SensorAPI_Example_Guide.pdf and /dev/null differ
diff --git a/README.md b/README.md
index eb19a0e..5cf73d2 100644
--- a/README.md
+++ b/README.md
@@ -1,148 +1,239 @@
-## Table of Contents
-- [Introduction](#intro)
-- [Version](#ver)
-- [Integration details](#integration)
-- [Driver files information](#fileinfo)
-- [Supported sensor interface](#interface)
-- [Simple Integration Example](#sample)
+# BME680 sensor API
+## Introduction
+This package contains the Bosch Sensortec's BME680 gas sensor API
-### Introduction
-- This package contains the Bosch Sensortec MEMS BME680 sensor driver (sensor API)
-- The sensor driver package includes below files
- * bme680.c
- * bme680.h
- * bme680_calculations.c
- * bme680_calculations.h
- * bme680_internal.h
- * sensor_api_common_types.h
+The sensor driver package includes bme680.h, bme680.c and bme680_defs.h files
-### Version
+## Version
File | Version | Date
-----|---------|-----
-bme680.c | 2.2.0 | 5 May 2017
-bme680.h | 2.2.0 | 5 May 2017
-bme680_calculations.c | 2.2.0 | 5 May 2017
-bme680_calculations.h | 2.2.0 | 5 May 2017
-bme680_internal.h | 2.2.0 | 5 May 2017
-sensor_api_common_types.h | 2.2.0 | 5 May 2017
+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 files bme680.c, bme680.h, bme680_calculations.c, bme680_calculations.h, bme680_internal.h and sensor_api_common_types.h into your project.
-- Include the bme680.h file in your code like below.
+## 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"
-```
-- The BME680_SensorAPI_Example_Guide.pdf contains examples for API use cases.
-
-### Driver files information
-- bme680.h
- * This header file has the constant definitions, user data types and supported sensor driver calls declarations which is required by the user.
-- bme680.c
- * This file contains the implementation for the sensor driver APIs.
-- bme680_calculations.h
- * This header file has the internal function declaration for the sensor calculation.
-- bme680_calculations.c
- * This file contains the implementation of the sensor calculations for sensor driver APIs.
-- bme680_internal.h
- * This header file has the register address definition, internal constant definitions.
-- sensor_api_common_types.h
- * This header file has the data type definition for different compiler platform.
-
-### Supported sensor interface
-- This BME680 sensor driver supports SPI and I2C interfaces
-
-### Simple Integration Example
-- A simple example for BME680 is given below.
-- Example meant for Single BME680 sensor in Force Mode with Temperature, Pressure, Humidity and Gas Enabled
-- Please refer bme680.h to refer the API calls for the integration.
-``` c
-/* include bme680 main header */
-#include "bme680.h"
-/*!
-* BME680_MAX_NO_OF_SENSOR = 2; defined in bme680.h file
-* In order to interface only one sensor over SPI, user must change the value of
-* BME680_MAX_NO_OF_SENSOR = 1
-* Test setup: It has been assumed that �BME680 sensor_0� interfaced over SPI with
-* Native chip select line
-*/
-/* BME680 sensor structure instance */
-struct bme680_t bme680_sensor_no[BME680_MAX_NO_OF_SENSOR];
-/* BME680 sensor's compensated data structure instance */
-struct bme680_comp_field_data compensate_data_sensor[BME680_MAX_NO_OF_SENSOR][3];
-/* BME680 sensor's uncompensated data structure instance */
-struct bme680_uncomp_field_data uncompensated_data_of_sensor[BME680_MAX_NO_OF_SENSOR][3];
-/* BME680 sensor's configuration structure instance */
-struct bme680_sens_conf set_conf_sensor[BME680_MAX_NO_OF_SENSOR];
-/* BME680 sensor's heater configuration structure instance */
-struct bme680_heater_conf set_heatr_conf_sensor[BME680_MAX_NO_OF_SENSOR];
-
-void main(void)
-{
- unsigned int i = 0;
- enum bme680_return_type com_rslt = BME680_COMM_RES_ERROR;
-
- /* Do BME680 sensor structure instance initialization*/
- /* Sensor_0 interface over SPI with native chip select line */
- /* USER defined SPI bus read function */
- bme680_sensor_no[0].bme680_bus_read = BME680_SPI_bus_read_user;
- /* USER defined SPI bus write function */
- bme680_sensor_no[0].bme680_bus_write = BME680_SPI_bus_write_user;
- /* USER defined SPI burst read function */
- bme680_sensor_no[0].bme680_burst_read = BME680_SPI_bus_read_user;
- /* USER defined delay function */
- bme680_sensor_no[0].delay_msec = BME680_delay_msec_user;
- /* Mention communication interface */
- bme680_sensor_no[0].interface = BME680_SPI_INTERFACE;
-
- /* get chip id and calibration parameter */
- com_rslt = bme680_init(&bme680_sensor_no[0]);
-
- /* Do Sensor initialization */
- for (i=0;i 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;
+}
+
+/** @}*/
diff --git a/Self test/bme680_selftest.h b/Self test/bme680_selftest.h
new file mode 100644
index 0000000..1b1be60
--- /dev/null
+++ b/Self test/bme680_selftest.h
@@ -0,0 +1,88 @@
+/**
+ * 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_ */
+
+/** @}*/
diff --git a/bme680.c b/bme680.c
index d4efcc2..1b53aa5 100644
--- a/bme680.c
+++ b/bme680.c
@@ -1,2558 +1,1105 @@
/**\mainpage
-*
-****************************************************************************
-* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
-*
-* File : bme680.c
-*
-* Date: 5 May 2017
-*
-* Revision : 2.2.0 $
-*
-* Usage: Sensor Driver for BME680 sensor
-*
-****************************************************************************
-*
-* \section Disclaimer
-*
-* Common:
-* Bosch Sensortec products are developed for the consumer goods industry.
-* They may only be used within the parameters of the respective valid
-* product data sheet. Bosch Sensortec products are provided with the
-* express understanding that there is no warranty of fitness for a
-* particular purpose.They are not fit for use in life-sustaining,
-* safety or security sensitive systems or any system or device
-* that may lead to bodily harm or property damage if the system
-* or device malfunctions. In addition,Bosch Sensortec products are
-* not fit for use in products which interact with motor vehicle systems.
-* The resale and or use of products are at the purchasers own risk and
-* his own responsibility. The examination of fitness for the intended use
-* is the sole responsibility of the Purchaser.
-*
-* The purchaser shall indemnify Bosch Sensortec from all third party
-* claims, including any claims for incidental, or consequential damages,
-* arising from any product use not covered by the parameters of
-* the respective valid product data sheet or not approved by
-* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
-* connection with such claims.
-*
-* The purchaser must monitor the market for the purchased products,
-* particularly with regard to product safety and inform Bosch Sensortec
-* without delay of all security relevant incidents.
-*
-* Engineering Samples are marked with an asterisk (*) or (e).
-* Samples may vary from the valid technical specifications of the product
-* series. They are therefore not intended or fit for resale to third
-* parties or for use in end products. Their sole purpose is internal
-* client testing. The testing of an engineering sample may in no way
-* replace the testing of a product series. Bosch Sensortec assumes
-* no liability for the use of engineering samples.
-* By accepting the engineering samples, the Purchaser agrees to indemnify
-* Bosch Sensortec from all claims arising from the use of engineering
-* samples.
-*
-* Special:
-* This software module (hereinafter called "Software") and any information
-* on application-sheets (hereinafter called "Information") is provided
-* free of charge for the sole purpose to support your application work.
-* The Software and Information is subject to the following
-* terms and conditions:
-*
-* The Software is specifically designed for the exclusive use for
-* Bosch Sensortec products by personnel who have special experience
-* and training. Do not use this Software if you do not have the
-* proper experience or training.
-*
-* This Software package is provided `` as is `` and without any expressed
-* or implied warranties,including without limitation, the implied warranties
-* of merchantability and fitness for a particular purpose.
-*
-* Bosch Sensortec and their representatives and agents deny any liability
-* for the functional impairment
-* of this Software in terms of fitness, performance and safety.
-* Bosch Sensortec and their representatives and agents shall not be liable
-* for any direct or indirect damages or injury, except as
-* otherwise stipulated in mandatory applicable law.
-*
-* The Information provided is believed to be accurate and reliable.
-* Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are
-* subject to change without notice.
-**************************************************************************/
-/*! \file bme680.c
- \brief BME680 Sensor Driver Support source File */
+ * 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.c
+ * @date 5 Jul 2017
+ * @version 3.5.1
+ *
+ */
-/***************************************************************************
- Header files
-****************************************************************************/
+/*! @file bme680.c
+ @brief Sensor driver for BME680 sensor */
#include "bme680.h"
-#include "bme680_calculations.h"
-#include "bme680_internal.h"
-
-/***************************************************************************
- Macros, Enums, Constants
-****************************************************************************/
-
-
-/***************************************************************************
- File globals, typedefs
-****************************************************************************/
-
-
-/* Static function declarations */
-static enum bme680_return_type bme680_get_calib_param(struct bme680_t *bme680);
-
-static void bme680_scale_to_multiplication_factor(u16 *duration_u16);
-
-#ifndef __KERNEL__
-static void bme680_buffer_restruct_burst_write(u8 arr[], u8 reg_addr,
- u8 data_size, u8 arr_size);
-#endif
-
-static u8 bme680_find_largest_index(u8 *meas_index);
-
-static enum bme680_return_type bme680_set_memory_page(u8 memory_page_u8,
- struct bme680_t *bme680);
-
-static void bme680_align_sensor_type_uncomp_data(u8 *a_data_u8, u8 index,
- u8 offset, u8 sensor_type,
- struct bme680_uncomp_field_data *uncomp_data);
-
-static void bme680_packing_calib_param(u8 *a_data_u8, struct bme680_t *bme680);
-
-static void bme680_copy_ordered_sensor_field_data(
- struct bme680_uncomp_field_data *sensor_data,
- u8 latest, u8 recent, u8 old, u8 sensor_type,
- struct bme680_uncomp_field_data *temp_sensor_data);
-
-static void bme680_get_latest_recent_old_field_index(
- struct bme680_uncomp_field_data *sensor_data,
- struct bme680_t *bme680);
-
-#ifdef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
-static enum bme680_return_type bme680_get_field_specific_uncomp_data(
- u8 field_index, u8 sensor_type, u8 *a_data_u8, struct bme680_t *bme680);
-
-static enum bme680_return_type bme680_Temp_field_specific_uncomp_read(
- u8 field_index, u8 *a_data_u8, struct bme680_t *bme680);
-
-static enum bme680_return_type bme680_Pressure_field_specific_uncomp_read(
- u8 field_index, u8 *a_data_u8, struct bme680_t *bme680);
-
-static enum bme680_return_type bme680_Humidity_field_specific_uncomp_read(
- u8 field_index, u8 *a_data_u8, struct bme680_t *bme680);
-
-static enum bme680_return_type bme680_Gas_field_specific_uncomp_read(
- u8 field_index, u8 *a_data_u8, struct bme680_t *bme680);
-
-#endif
-
-
-/***************************************************************************
- Function definitions
-****************************************************************************/
+/**static variables */
+/**Look up table for the possible gas range values */
+uint32_t lookupTable1[16] = { UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647),
+ UINT32_C(2147483647), UINT32_C(2126008810), UINT32_C(2147483647), UINT32_C(2130303777), UINT32_C(2147483647),
+ UINT32_C(2147483647), UINT32_C(2143188679), UINT32_C(2136746228), UINT32_C(2147483647), UINT32_C(2126008810),
+ UINT32_C(2147483647), UINT32_C(2147483647) };
+/**Look up table for the possible gas range values */
+uint32_t lookupTable2[16] = { UINT32_C(4096000000), UINT32_C(2048000000), UINT32_C(1024000000), UINT32_C(512000000),
+ UINT32_C(255744255), UINT32_C(127110228), UINT32_C(64000000), UINT32_C(32258064), UINT32_C(16016016), UINT32_C(
+ 8000000), UINT32_C(4000000), UINT32_C(2000000), UINT32_C(1000000), UINT32_C(500000), UINT32_C(250000),
+ UINT32_C(125000) };
/*!
- * @brief This function is used to read the
- * the chip id and calibration data of the BME680 sensor
- * chip id is read in the register 0xD0/0x50(I2C/SPI) from bit 0 to 7
+ * @brief This internal API is used to read the calibrated data from the sensor.
*
- * @param bme680 structure pointer.
+ * This function is used to retrieve the calibration
+ * data from the image registers of the sensor.
*
- * @note Structure with the below data to be filled
- * before passing to this function.
- * @note Device address( applicable only for I2C, bypassed for SPI)
- * @note Bus interface functions.
- * @note Delay function
- * @note With the above data properly set, Chip id will be read from the sensor
- *
- * @note While changing the parameter of the bme680_t
- * @note consider the following point:
- * Changing the reference value of the parameter
- * will change the local copy or local reference
- * make sure your changes will not
- * affect the reference value of the parameter
- * (Better case don't change the reference value of the parameter)
- *
- *
- *
- *
- * @return Either the results of bus communication status or
- * chip_id fail status
- * @retval 0 -> Success both bus communication & chip_id
- * @retval any negative value -> Bus communication failed
- * -4 -> chip_id corrupted and bus communication ok
- *
- *
-*/
-enum bme680_return_type bme680_init(struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 data_u8 = 0;
- /* assign the pointer*/
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /*SPI address 0x45*/
- /* read the chip id*/
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_PAGE0_SPI_ID_REG,
- &data_u8,
- BME680_GEN_READ_DATA_LENGTH);
- } else if (BME680_I2C_INTERFACE == bme680->interface) {
- /* read the chip id*/
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_PAGE0_I2C_ID_REG,
- &data_u8,
- BME680_GEN_READ_DATA_LENGTH);
- }
- bme680->chip_id = data_u8;
-
- if (BME680_COMM_RES_OK == com_status) {
- if (BME680_CHIP_ID == bme680->chip_id) {
- /* read the calibration values*/
- com_status = bme680_get_calib_param(bme680);
- } else {
- com_status = BME680_CHIP_ID_ERROR;
- }
- }
- return com_status;
-}
-/*!
- * @brief This function is used to retrieve the calibration
- * data from the image registers of the sensor.
- *
- * @note Registers 8Ah to A1h for calibration data 1 to 24
+ * @note Registers 89h to A1h for calibration data 1 to 24
* from bit 0 to 7
- * @note Registers E1h to F0h for calibration data 25 to 40
+ * @note Registers E1h to F0h for calibration data 25 to 40
* from bit 0 to 7
- * @param bme680 structure pointer.
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-static enum bme680_return_type bme680_get_calib_param(struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* array of data holding the calibration values*/
- u8 v_data_u8 = 0;
- u8 a_data_u8[BME680_CALIB_PARAM_SIZE];
- u8 index = 0;
-
-
- for (; index < BME680_CALIB_PARAM_SIZE; index++)
- a_data_u8[index] = 0;
-
- /* check the bme680 structure pointer as NULL*/
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(
- BME680_PAGE0_INTERFACE_SPI, bme680);
-
- if (BME680_COMM_RES_OK == com_status) {
-
- /* read the pressure and temperature
- calibration data*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_CALIB_SPI_ADDR_1,
- a_data_u8,
- BME680_CALIB_DATA_LENGTH_GAS);
- /* read the humidity and gas
- calibration data*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_CALIB_SPI_ADDR_2,
- (a_data_u8 +
- BME680_CALIB_DATA_LENGTH_GAS),
- BME680_CALIB_DATA_LENGTH);
- }
- } else if (BME680_I2C_INTERFACE == bme680->interface) {
- /* read the pressure and temperature
- calibration data*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_CALIB_I2C_ADDR_1,
- a_data_u8,
- BME680_CALIB_DATA_LENGTH_GAS);
- /* read the humidity and gas
- calibration data*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_CALIB_I2C_ADDR_2,
- (a_data_u8 +
- BME680_CALIB_DATA_LENGTH_GAS),
- BME680_CALIB_DATA_LENGTH);
-
- } else {
- com_status = BME680_COMM_RES_ERROR;
- }
-
- if (BME680_COMM_RES_OK == com_status) {
- /*read TPGH calibration*/
- bme680_packing_calib_param(a_data_u8, bme680);
-
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(BME680_PAGE1_INTERFACE_SPI,
- bme680);
- }
-
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_RES_HEAT_RANGE,
- &v_data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- bme680->cal_param.res_heat_range = BME680_GET_REG(v_data_u8,
- BME680_MASK_RES_HEAT_RANGE,
- BME680_SHIFT_RES_HEAT_RANGE);
-
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_RES_HEAT_VAL,
- &v_data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- bme680->cal_param.res_heat_val = v_data_u8;
-
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_RANGE_SWITCHING_ERR,
- &v_data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- bme680->cal_param.range_switching_error = BME680_GET_REG(
- (s8)v_data_u8,
- (s8)BME680_MASK_RANGE_ERR,
- BME680_SHIFT_RANGE_ERR);
- }
-
- }
- return com_status;
-}
-
-/*!
- * @brief This function is used to write the data to
- * the given register
- *
- *
- * @param addr_u8 -> Address of the register
- * @param data_u8 -> The data to write to the register
- * @param len_u8 -> No of bytes to write
- * @param bme680 structure pointer.
- *
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
+ * @param[in] dev :Structure instance of bme680_dev.
*
+ * @return Result of API execution status.
+ * @retval zero -> Success / +ve value -> Warning / -ve value -> Error
*/
-enum bme680_return_type bme680_write_reg(u8 addr_u8, u8 *data_u8, u8 len_u8,
- struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- com_status = (enum bme680_return_type)bme680->bme680_bus_write(
- bme680->dev_addr,
- addr_u8,
- data_u8,
- len_u8);
- }
- return com_status;
-}
+static int8_t get_calib_data(struct bme680_dev *dev);
+
/*!
- * @brief This function is used to reads the data from
- * the given register
- *
- *
- * @param addr_u8 -> Address of the register
- * @param data_u8 -> Pointer to store the
- * received data from the register
- * @param len_u8 -> No of bytes to read
- * @param bme680 structure pointer.
- *
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
+ * @brief This internal API is used to set the gas configuration 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
*/
-enum bme680_return_type bme680_read_reg(u8 addr_u8, u8 *data_u8, u8 len_u8,
- struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- addr_u8,
- data_u8,
- len_u8);
- }
- return com_status;
-}
+static int8_t set_gas_config(struct bme680_dev *dev);
/*!
- * @brief This function is used to read the new data0
- * @note Field-0(new_data_0),
- * Field-1(new_data_1) and Field-2(new_data_2)
- * @note Page-1
+ * @brief This internal API is used to get the gas configuration of the sensor.
*
+ * @param[in] dev :Structure instance of bme680_dev.
*
- * @param new_data_u8: The value of new data
- * @param field_u8: The value of field selection for new data
- * field | value
- * -----------|-------------
- * 0 | BME680_FIELD_ZERO
- * 1 | BME680_FIELD_ONE
- * 2 | BME680_FIELD_TWO
- *
- * field | Register
- * -------------------|------------
- * BME680_FIELD_ZERO | 0x1D bit 7
- * BME680_FIELD_ONE | 0x2E bit 7
- * BME680_FIELD_TWO | 0x3F bit 7
- *
- *
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_get_new_data(u8 *new_data_u8, u8 field_u8,
- struct bme680_t *bme680)
-{
-
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(
- BME680_PAGE1_INTERFACE_SPI,
- bme680);
-
- }
-
- if (BME680_I2C_INTERFACE == bme680->interface)
- com_status = BME680_COMM_RES_OK;
-
- if (BME680_COMM_RES_OK == com_status) {
-
- switch (field_u8) {
- case BME680_FIELD_ZERO:
- /* read field0 new data zero*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0,
- new_data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- break;
- case BME680_FIELD_ONE:
- /* read field1 new data one*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- (BME680_ADDR_FIELD_0 +
- BME680_FIELD_ONE_OFFSET),
- new_data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- break;
- case BME680_FIELD_TWO:
- /* read field2 new data two*/
- com_status =
- (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- (BME680_ADDR_FIELD_0 +
- BME680_FIELD_TWO_OFFSET),
- new_data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- break;
- default:
- com_status = BME680_COMM_RES_ERROR;
- break;
- }
- if (BME680_COMM_RES_OK == com_status)
- *new_data_u8 = BME680_GET_REG(*new_data_u8,
- BME680_MASK_NEW_DATA,
- BME680_SHIFT_NEW_DATA);
-
- }
- }
- return com_status;
-}
+ * @return Result of API execution status.
+ * @retval zero -> Success / +ve value -> Warning / -ve value -> Error
+ */
+static int8_t get_gas_config(struct bme680_dev *dev);
/*!
- * @brief This function is used to read the uncompensated
- * sensor data from Field-0, Field-1, Field-2 and page-1
+ * @brief This internal API is used to calculate the Heat duration value.
*
- * @param uncomp_data:
- * Pointer to store the value of uncompensated sensor
- * data of pressure, temperature, humidity and gas
+ * @param[in] dur :Value of the duration to be shared.
*
- * @param field_count : total no of field data which needs
- * to be read from the sensor
- *
- * @note:
- * field_count = 1 : only latest field data out of 3 fields
- * field_count = 2 : latest and recent field data out of 3 field
- * field_count = 3 : All 3 latest, recent and old field data
- *
- * @param sensor_type : Type of sensor
- * e.g; BME680_PRESSURE,BME680_TEMPERATURE,BME680_HUMIDITY
- * BME680_GAS,BME680_ALL
- *
- * @note: if "BME680_SPECIFIC_FIELD_DATA_READ_ENABLED" is not defined in
- * bme680.h then for any sensor_type function will perform
- * read operation for BME680_ALL.
- *
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- * @note error code is returned when data readout is attempted
- * in sleep mode or when field_count is not in the below range
- * it must be 1<= field_count <= 3
- *
-*/
-enum bme680_return_type bme680_get_uncomp_data(
- struct bme680_uncomp_field_data *uncomp_data, u8 field_count,
- u8 sensor_type, struct bme680_t *bme680)
-{
- /* used to return the communication result*/
-
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 index = 0;
- u8 a_data_u8[BME680_LEN_ALL_FIELD_SIZE];
- struct bme680_uncomp_field_data temp_sensor_data[BME680_THREE];
-
- #ifdef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
-
- /*Array to store the new_data status of all 3 fields*/
- u8 new_data[BME680_THREE] = {0, 0,
- 0};
- #endif
- /*clear the the latest, recent and old field index*/
- bme680->latest_field_index = 0;
- bme680->recent_field_index = 0;
- bme680->old_field_index = 0;
-
- if ((field_count < BME680_PRESENT_DATA_FIELD
- || field_count > BME680_ALL_DATA_FIELD)
- || (BME680_SLEEP_MODE == bme680->last_set_mode)) {
- com_status = BME680_COMM_RES_ERROR;
- } else {
- com_status = BME680_COMM_RES_OK;
- }
- if (BME680_COMM_RES_OK == com_status) {
- #ifndef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
- sensor_type = BME680_ALL;
- field_count = BME680_ALL_DATA_FIELD;
- #endif
-
- if (BME680_FORCED_MODE == bme680->last_set_mode) {
-
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0, a_data_u8,
- BME680_SINGLE_FIELD_LENGTH);
- field_count = BME680_PRESENT_DATA_FIELD;
- } else {
- #ifdef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
-
- /*read status field of all 3 filed and extract the new_data
- flag status.*/
- com_status = bme680_read_status_fields(uncomp_data, a_data_u8,
- new_data, bme680);
-
- /*get the latest, recent and old field index*/
- bme680_get_latest_recent_old_field_index(uncomp_data, bme680);
-
-
- /*By default read latest field data */
- if (BME680_TRUE == new_data[bme680->latest_field_index]) {
- com_status =
- bme680_get_field_specific_uncomp_data(
- bme680->latest_field_index,
- sensor_type,
- a_data_u8,
- bme680);
-
- }
- if (BME680_PRESENT_AND_PREVIOUS_DATA_FIELD == field_count) {
- /* read recent field data */
- if (BME680_TRUE ==
- new_data[bme680->recent_field_index]) {
- com_status =
- bme680_get_field_specific_uncomp_data(
- bme680->recent_field_index,
- sensor_type,
- a_data_u8,
- bme680);
- }
-
- } else if (BME680_ALL_DATA_FIELD == field_count) {
-
- /* read recent field data */
- if (BME680_TRUE ==
- new_data[bme680->recent_field_index]) {
- com_status =
- bme680_get_field_specific_uncomp_data(
- bme680->recent_field_index,
- sensor_type,
- a_data_u8,
- bme680);
- }
-
- /* read old field data */
- if (BME680_TRUE ==
- new_data[bme680->old_field_index]) {
- com_status =
- bme680_get_field_specific_uncomp_data(
- bme680->old_field_index,
- sensor_type,
- a_data_u8,
- bme680);
-
- }
- }
- #else
- if (BME680_ALL == sensor_type) {
- /*read uncompensated sensor data of field 0,1,2*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0, a_data_u8,
- BME680_LEN_ALL_FIELD_SIZE);
- }
- (uncomp_data + 0)->status.meas_index = a_data_u8[1];
- (uncomp_data + 1)->status.meas_index = a_data_u8[18];
- (uncomp_data + 2)->status.meas_index = a_data_u8[35];
-
- /*get the latest, recent and old field index*/
- bme680_get_latest_recent_old_field_index(uncomp_data, bme680);
- #endif
- }
-
- if (BME680_COMM_RES_OK == com_status) {
-
- bme680_align_uncomp_data(a_data_u8,
- field_count,
- sensor_type,
- uncomp_data,
- bme680);
- if (BME680_FORCED_MODE != bme680->last_set_mode) {
-
- for (index = 0; index <
- BME680_ALL_DATA_FIELD; index++)
- temp_sensor_data[index] =
- *(uncomp_data + index);
-
-
- bme680_copy_ordered_sensor_field_data(
- uncomp_data, bme680->latest_field_index,
- bme680->recent_field_index,
- bme680->old_field_index, sensor_type,
- temp_sensor_data);
- }
- }
- }
- return com_status;
-}
-#ifdef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
-/*!
- * @brief This function is used to read the uncompensated
- * data according to sensor type
- * @note Field-0, Field-1 and Field-2
- * @note Page-1
- *
- *
- * @param field_index : index of the field which needs
- * to be read from the sensor
- *
- * @param sensor_type : Type of sensor
- * e.g; BME680_PRESSURE,BME680_TEMPERATURE,BME680_HUMIDITY
- * BME680_GAS,BME680_ALL
- *
- * @param a_data_u8 : pointer to store read data.
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_get_field_specific_uncomp_data(
- u8 field_index, u8 sensor_type, u8 *a_data_u8, struct bme680_t *bme680)
-{
-
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
-
-
- if (BME680_PRESSURE == sensor_type ||
- BME680_TEMPERATURE == sensor_type ||
- BME680_HUMIDITY == sensor_type) {
-
- com_status = bme680_Temp_field_specific_uncomp_read(
- field_index,
- a_data_u8,
- bme680);
-
- switch (sensor_type) {
- case BME680_PRESSURE:
- com_status = bme680_Pressure_field_specific_uncomp_read(
- field_index,
- a_data_u8,
- bme680);
-
- break;
- case BME680_HUMIDITY:
- com_status = bme680_Humidity_field_specific_uncomp_read(
- field_index,
- a_data_u8,
- bme680);
-
- break;
- }
- } else if (BME680_GAS == sensor_type) {
-
- com_status = bme680_Gas_field_specific_uncomp_read(field_index,
- a_data_u8,
- bme680);
-
- } else if (BME680_ALL == sensor_type) {
- /*read uncompensated sensor data of field 0,1,2*/
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0,
- a_data_u8,
- BME680_LEN_ALL_FIELD_SIZE);
-
- }
- return com_status;
-}
-
+ * @return uint8_t threshold duration after calculation.
+ */
+static uint8_t calc_heater_dur(uint16_t dur);
/*!
- * @brief This function is used to read the uncompensated
- * Temperature for specific Field type.
- * Field-0, Field-1 and Field-2
+ * @brief This internal API is used to calculate the temperature value.
*
- * @param field_index : index of the field which needs
- * to be read from the sensor
+ * @param[in] dev :Structure instance of bme680_dev.
+ * @param[in] temp_adc :Contains the temperature ADC value .
*
- * @param a_data_u8 : pointer to store read data.
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_Temp_field_specific_uncomp_read(
-u8 field_index, u8 *a_data_u8, struct bme680_t *bme680)
-{
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* local buffer length is 5 and it's the maximum */
- u8 temp_data_u8[BME680_THREE];
- u8 count = 0;
-
- for (count = 0; count < BME680_THREE; count++)
- temp_data_u8[count] = 0;
-
- /*read uncompensated Temperature of field 0*/
- if (BME680_FIELD_INDEX0 == field_index) {
- /*read the 3 byte of T1 data form 0x22*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0_TEMP1,
- temp_data_u8,
- BME680_TEMPERATURE_DATA_LEN);
- /*Assign data to the reserved index
- 5,6 & 7 of the input buffer*/
- for (count = 0;
- count < BME680_TEMPERATURE_DATA_LEN; count++)
- a_data_u8[5 + count] = temp_data_u8[count];
-
- /*read the 3 byte of T2 data form 0x27*/
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0_TEMP2,
- temp_data_u8,
- BME680_TEMPERATURE_DATA_LEN);
- /*Assign data to the reserved index
- 10,11 & 12 of the input buffer*/
- for (count = 0;
- count < BME680_TEMPERATURE_DATA_LEN; count++)
- a_data_u8[10 + count] = temp_data_u8[count];
-
- /*read uncompensated Temperature of field 1*/
- } else if (BME680_FIELD_INDEX1 == field_index) {
-
- /*read the 3 byte of T1 data form 0x33*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_1_TEMP1,
- temp_data_u8,
- BME680_TEMPERATURE_DATA_LEN);
- /*Assign data to the reserved index
- 22,23 & 24 of the input buffer*/
- for (count = 0;
- count < BME680_TEMPERATURE_DATA_LEN; count++)
- a_data_u8[22 + count] = temp_data_u8[count];
-
- /*read the 3 byte of T2 data form 0x38*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_1_TEMP2,
- temp_data_u8,
- BME680_TEMPERATURE_DATA_LEN);
- /*Assign data to the reserved index
- 27,28 & 29 of the input buffer*/
- for (count = 0;
- count < BME680_TEMPERATURE_DATA_LEN; count++)
- a_data_u8[27 + count] = temp_data_u8[count];
-
- /*read uncompensated Temperature of field 2*/
- } else if (BME680_FIELD_INDEX2 == field_index) {
-
- /*read the 3 byte of T1 data form 0x44*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_2_TEMP1,
- temp_data_u8,
- BME680_TEMPERATURE_DATA_LEN);
- /*Assign data to the reserved index
- 39,40 & 41 of the input buffer*/
- for (count = 0;
- count < BME680_TEMPERATURE_DATA_LEN; count++)
- a_data_u8[39 + count] = temp_data_u8[count];
-
- /*read the 3 byte of T2 data form 0x49*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_2_TEMP2,
- temp_data_u8,
- BME680_TEMPERATURE_DATA_LEN);
- /*Assign data to the reserved index
- 44,45 & 46 of the input buffer*/
- for (count = 0;
- count < BME680_TEMPERATURE_DATA_LEN; count++)
- a_data_u8[44 + count] = temp_data_u8[count];
-
- }
- return com_status;
-}
-/*!
- * @brief This function is used to read the uncompensated
- * Pressure for specific Field type.
- * Field-0, Field-1 and Field-2
- *
- * @param field_index : index of the field which needs
- * to be read from the sensor
- *
- *
- * @param a_data_u8 : pointer to store read data.
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_Pressure_field_specific_uncomp_read(
-u8 field_index, u8 *a_data_u8, struct bme680_t *bme680)
-{
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* local buffer length is 5 and it's the maximum */
- u8 temp_data_u8[BME680_THREE];
- u8 count = 0;
-
- for (count = 0; count < BME680_THREE; count++)
- temp_data_u8[count] = 0;
-
- /*read uncompensated Pressure of field 0*/
- if (BME680_FIELD_INDEX0 == field_index) {
- /*read the 3 byte of P data form 0x1F*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0_PRESS,
- temp_data_u8,
- BME680_PRESSURE_DATA_LEN);
- /*Assign data to the reserved index
- 2,3 & 4 of the input buffer*/
- for (count = 0;
- count < BME680_PRESSURE_DATA_LEN; count++)
- a_data_u8[2 + count] = temp_data_u8[count];
-
- /*read uncompensated Pressure of field 1*/
- } else if (BME680_FIELD_INDEX1 == field_index) {
-
- /*read the 3 byte of P data
- form 0x30*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_1_PRESS,
- temp_data_u8,
- BME680_PRESSURE_DATA_LEN);
- /*Assign data to the
- reserved index
- 19,20 & 21 of the input buffer*/
- for (count = 0;
- count < BME680_PRESSURE_DATA_LEN; count++)
- a_data_u8[19 + count] = temp_data_u8[count];
-
- /*read uncompensated Pressure of field 2*/
- } else if (BME680_FIELD_INDEX2 == field_index) {
-
- /*read the 3 byte of P data
- form 0x41*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_2_PRESS,
- temp_data_u8,
- BME680_PRESSURE_DATA_LEN);
- /*Assign data to the reserved
- index 36,37 & 38 of the input
- buffer*/
- for (count = 0;
- count < BME680_PRESSURE_DATA_LEN; count++)
- a_data_u8[36 + count] = temp_data_u8[count];
-
- }
- return com_status;
-}
-/*!
- * @brief This function is used to read the uncompensated
- * Humidity for specific Field type.
- * Field-0, Field-1 and Field-2
- *
- * @param field_index : index of the field which needs
- * to be read from the sensor
- *
- *
- * @param a_data_u8 : pointer to store read data.
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_Humidity_field_specific_uncomp_read(
-u8 field_index, u8 *a_data_u8, struct bme680_t *bme680)
-{
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* local buffer length is 5 and it's the maximum */
- u8 temp_data_u8[BME680_TWO];
- u8 count = 0;
-
- for (count = 0; count < BME680_TWO; count++)
- temp_data_u8[count] = 0;
- /*read uncompensated Humidity of field 0*/
- if (BME680_FIELD_INDEX0 == field_index) {
- /*read the 2 byte of H data form 0x25*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0_HUM,
- temp_data_u8,
- BME680_HUMIDITY_DATA_LEN);
- /*Assign data to the reserved index
- 8 & 9 of the input buffer*/
- for (count = 0;
- count < BME680_HUMIDITY_DATA_LEN; count++)
- a_data_u8[8 + count] = temp_data_u8[count];
-
- /*read uncompensated Humidity of field 1*/
- } else if (BME680_FIELD_INDEX1 == field_index) {
-
- /*read the 2 byte of H data form 0x36*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_1_HUM,
- temp_data_u8,
- BME680_HUMIDITY_DATA_LEN);
- /*Assign data to the reserved index
- 25 & 26 of the input buffer*/
- for (count = 0;
- count < BME680_HUMIDITY_DATA_LEN; count++)
- a_data_u8[25 + count] = temp_data_u8[count];
-
- /*read uncompensated Humidity of field 2*/
- } else if (BME680_FIELD_INDEX2 == field_index) {
-
- /*read the 2 byte of H data form 0x47*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_2_HUM,
- temp_data_u8,
- BME680_HUMIDITY_DATA_LEN);
- /*Assign data to the reserved index
- 42 & 43 of the input buffer*/
- for (count = 0;
- count < BME680_HUMIDITY_DATA_LEN; count++)
- a_data_u8[42 + count] = temp_data_u8[count];
-
- }
- return com_status;
-}
-/*!
- * @brief This function is used to read the uncompensated
- * Gas for specific Field type.
- * Field-0, Field-1 and Field-2
- *
- * @param field_index : index of the field which needs
- * to be read from the sensor
- *
- *
- * @param a_data_u8 : pointer to store read data.
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_Gas_field_specific_uncomp_read(
- u8 field_index, u8 *a_data_u8, struct bme680_t *bme680)
-{
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* local buffer length is 5 and it's the maximum */
- u8 temp_data_u8[BME680_TWO];
- u8 count = 0;
-
- for (count = 0; count < BME680_TWO; count++)
- temp_data_u8[count] = 0;
-
- /*read uncompensated Gas of field 0*/
- if (BME680_FIELD_INDEX0 == field_index) {
- /*Default field_0 required*/
- /*read the 2 byte of G data form 0x2A*/
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_0_GAS,
- temp_data_u8,
- BME680_GAS_DATA_LEN);
- /*Assign data to the reserved index
- 13,14 of the input buffer*/
- for (count = 0;
- count < BME680_GAS_DATA_LEN; count++)
- a_data_u8[13 + count] = temp_data_u8[count];
-
- /*read uncompensated Gas of field 1*/
- } else if (BME680_FIELD_INDEX1 == field_index) {
-
- /*read the 2 byte of G data form 0x3B*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_1_GAS,
- temp_data_u8,
- BME680_GAS_DATA_LEN);
- /*Assign data to the reserved index
- 30,31 of the input buffer*/
- for (count = 0;
- count < BME680_GAS_DATA_LEN; count++)
- a_data_u8[30 + count] = temp_data_u8[count];
-
- /*read uncompensated Gas of field 2*/
- } else if (BME680_FIELD_INDEX2 == field_index) {
-
- /*read the 2 byte of G data form 0x4C*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_FIELD_2_GAS,
- temp_data_u8,
- BME680_GAS_DATA_LEN);
- /*Assign data to the reserved index
- 47,48 of the input buffer*/
- for (count = 0;
- count < BME680_GAS_DATA_LEN; count++)
- a_data_u8[47 + count] = temp_data_u8[count];
-
- }
- return com_status;
-}
-
-#endif
-
-
-
+ * @return uint32_t calculated temperature.
+ */
+static int16_t calc_temperature(uint32_t temp_adc, struct bme680_dev *dev);
/*!
- * @brief This function is used to get the
- * Operational Mode from the sensor in the
- * register 0x74 bit 0 and 1
+ * @brief This internal API is used to calculate the pressure value.
*
- * @param power_mode_u8 : Pointer to store the received value
- * of power mode
- * value | mode
- * -----------|------------------
- * 0x00 | BME680_SLEEP_MODE
- * 0x01 | BME680_FORCED_MODE
- * 0x02 | BME680_PARALLEL_MODE
- * 0x03 | BME680_SEQUENTIAL_MODE
+ * @param[in] dev :Structure instance of bme680_dev.
+ * @param[in] pres_adc :Contains the pressure ADC value .
*
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_get_power_mode(u8 *power_mode_u8,
- struct bme680_t *bme680)
-{
- u8 data_u8 = 0;
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- /* read power mode*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- BME680_ADDR_OP_MODE,
- &data_u8,
- BME680_GEN_READ_DATA_LENGTH);
-
- if (BME680_COMM_RES_OK == com_status) {
- *power_mode_u8 = BME680_GET_REG(data_u8,
- BME680_MASK_OP_MODE,
- BME680_SHIFT_OP_MODE);
- /* updating power mode in global structure*/
- if (bme680->last_set_mode != BME680_FORCED_MODE)
- bme680->last_set_mode = *power_mode_u8;
-
- }
- }
- return com_status;
-}
-/*!
- * @brief This function is used to set the
- * Operational Mode of the sensor in the
- * register 0x74 bit 0 and 1
- *
- * @param power_mode_u8 : The value of power mode
- * value | mode
- * -------------|------------------
- * 0x00 | BME680_SLEEP_MODE
- * 0x01 | BME680_FORCED_MODE
- * 0x02 | BME680_PARALLEL_MODE
- * 0x03 | BME680_SEQUENTIAL_MODE
- *
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- *
-*/
-enum bme680_return_type bme680_set_power_mode(u8 power_mode_u8,
- struct bme680_t *bme680)
-{
- u8 data_u8 = 0;
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- /* write power mode*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- BME680_ADDR_OP_MODE,
- &data_u8,
- BME680_GEN_READ_DATA_LENGTH);
- if (BME680_COMM_RES_OK == com_status) {
- data_u8 = BME680_SET_REG(data_u8, power_mode_u8,
- BME680_MASK_OP_MODE, BME680_SHIFT_OP_MODE);
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_write(bme680->dev_addr,
- BME680_ADDR_OP_MODE,
- &data_u8,
- BME680_GEN_WRITE_DATA_LENGTH);
- }
- /* updating power mode in global structure*/
- if (BME680_COMM_RES_OK == com_status)
- bme680->last_set_mode = power_mode_u8;
- }
- return com_status;
-}
-/*!
- * @brief This function is used to set the sensor configuration
- *
- * @param sens_conf : structure pointer which points to
- * bme680_sens_conf structure passed by the user.
- *
- * @param bme680 structure pointer.
- *
- * @note reference input values from user are below
- *
- * heatr_ctrl = BME680_HEATR_CTRL_ENABLE;
- * odr = BME680_ODR_20MS;
- * run_gas = BME680_RUN_GAS_ENABLE;
- * nb_conv = 0x01;
- * osrs_hum = BME680_OSRS_1X;
- * osrs_pres = BME680_OSRS_1X;
- * osrs_temp = BME680_OSRS_1X;
- * filter = BME680_FILTER_COEFF_1;
- * spi_3w = BME680_SPI_3W_DISABLE;
- * intr = BME680_SPI_3W_INTR_DISABLE
- *
- * @note nb_conv parameter is specific to power mode
- * refer data sheet for detailed info.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
-*/
-enum bme680_return_type bme680_set_sensor_config(
- struct bme680_sens_conf *sens_conf, struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 data_u8[(BME680_SENS_CONF_LEN*2)-1];
- u8 index;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(
- BME680_PAGE1_INTERFACE_SPI, bme680);
- }
- if (BME680_I2C_INTERFACE == bme680->interface)
- com_status = BME680_COMM_RES_OK;
-
- if (BME680_COMM_RES_OK == com_status) {
-
- for (index = 0; index < (BME680_SENS_CONF_LEN * 2) - 2;
- index++)
- data_u8[index] = 0;
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_SENSOR_CONFIG,
- data_u8,
- (BME680_SENS_CONF_LEN));
-
- if (BME680_COMM_RES_OK == com_status) {
- data_u8[BME680_INDEX_CTRL_GAS_0] =
- (sens_conf->heatr_ctrl & 0x01)
- << BME680_SHIFT_HEATR_CTRL;
-
- data_u8[BME680_INDEX_CTRL_GAS_1] =
- ((sens_conf->odr & 0x08) << BME680_SHIFT_ODR_3)
- | ((sens_conf->run_gas & 0x01) <<
- BME680_SHIFT_RUN_GAS) |
- (sens_conf->nb_conv & 0x0F);
-
- data_u8[BME680_INDEX_CTRL_HUM] =
- ((sens_conf->intr & 0x01) <<
- BME680_SHIFT_SPI_3W_INT) |
- (sens_conf->osrs_hum & 0x07);
-
- data_u8[BME680_INDEX_CTRL_MEAS] =
- ((sens_conf->osrs_pres & 0x07) <<
- BME680_SHIFT_OSRS_PRES) |
- ((sens_conf->osrs_temp & 0x07) <<
- BME680_SHIFT_OSRS_TEMP) |
- (data_u8[BME680_INDEX_CTRL_MEAS] & 0x03);
-
- data_u8[BME680_INDEX_CONFIG] =
- (((sens_conf->odr) & 0x07) <<
- BME680_SHIFT_ODR_2_0) |
- ((sens_conf->filter & 0x07) <<
- BME680_SHIFT_FILTER) |
- (sens_conf->spi_3w & 0x01);
-
-#ifndef __KERNEL__
- bme680_buffer_restruct_burst_write(data_u8,
- 0x70,
- BME680_SENS_CONF_LEN,
- (BME680_SENS_CONF_LEN * 2)-1);
-
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_write(bme680->dev_addr,
- BME680_ADDR_SENSOR_CONFIG,
- data_u8,
- (BME680_SENS_CONF_LEN * 2)-1);
-#else
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_write(bme680->dev_addr,
- BME680_ADDR_SENSOR_CONFIG,
- data_u8,
- BME680_SENS_CONF_LEN);
-#endif
- }
- }
- }
- return com_status;
-}
-/*!
- * @brief This function is used to get the sensor configuration
- *
- * @param sens_conf : structure pointer which points to
- * bme680_sens_conf structure passed by the user to store the
- * received configuration
- *
- * @param bme680 structure pointer.
- *
- * @note reference output values from the sensor are below
- *
- * heatr_ctrl = BME680_HEATR_CTRL_ENABLE;
- * odr = BME680_ODR_20MS;
- * run_gas = BME680_RUN_GAS_ENABLE;
- * nb_conv = 0x01;
- * osrs_hum = BME680_OSRS_1X;
- * osrs_pres = BME680_OSRS_1X;
- * osrs_temp = BME680_OSRS_1X;
- * filter = BME680_FILTER_COEFF_1;
- * spi_3w = BME680_SPI_3W_DISABLE;
- * intr = BME680_SPI_3W_INTR_DISABLE
- *
- * @note actual settings may differ as configured by user earlier using
- * bme680_set_sensor_config function.
- * @note nb_conv parameter is specific to power mode
- * refer data sheet for detailed info.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
-
-*/
-enum bme680_return_type bme680_get_sensor_config(
- struct bme680_sens_conf *sens_conf, struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 data_u8[BME680_SENS_CONF_LEN];
- u8 index;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(
- BME680_PAGE1_INTERFACE_SPI, bme680);
-
- }
-
- else if (BME680_I2C_INTERFACE == bme680->interface)
- com_status = BME680_COMM_RES_OK;
-
- if (BME680_COMM_RES_OK == com_status) {
-
- for (index = 0; index < BME680_SENS_CONF_LEN ; index++)
- data_u8[index] = 0;
-
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_SENSOR_CONFIG,
- data_u8,
- BME680_SENS_CONF_LEN);
- if (BME680_COMM_RES_OK == com_status) {
- sens_conf->heatr_ctrl = (enum bme680_heatr_ctrl)
- BME680_GET_REG(data_u8[BME680_INDEX_CTRL_GAS_0],
- BME680_MASK_HEATR_CTRL,
- BME680_SHIFT_HEATR_CTRL);
- sens_conf->run_gas = (enum bme680_run_gas)
- BME680_GET_REG(data_u8[BME680_INDEX_CTRL_GAS_1],
- BME680_MASK_RUN_GAS,
- BME680_SHIFT_RUN_GAS);
- sens_conf->nb_conv = BME680_GET_REG(
- data_u8[BME680_INDEX_CTRL_GAS_1],
- BME680_MASK_PROF_INDEX,
- BME680_SHIFT_PROF_INDEX);
- sens_conf->odr = (enum bme680_odr)((BME680_GET_REG(
- data_u8[BME680_INDEX_CTRL_GAS_1],
- BME680_MASK_ODR_3,
- BME680_SHIFT_ODR_3)) | (BME680_GET_REG(
- data_u8[BME680_INDEX_CONFIG],
- BME680_MASK_ODR_2_0,
- BME680_SHIFT_ODR_2_0)));
- sens_conf->osrs_hum = (enum bme680_osrs_x)
- BME680_GET_REG(data_u8[BME680_INDEX_CTRL_HUM],
- BME680_MASK_OSRS_HUM,
- BME680_SHIFT_OSRS_HUM);
- sens_conf->intr = (enum bme680_spi_3w_intr)
- BME680_GET_REG(data_u8[BME680_INDEX_CTRL_HUM],
- BME680_MASK_SPI_3W_INT,
- BME680_SHIFT_SPI_3W_INT);
- sens_conf->osrs_pres = (enum bme680_osrs_x)
- BME680_GET_REG(data_u8[BME680_INDEX_CTRL_MEAS],
- BME680_MASK_OSRS_PRES,
- BME680_SHIFT_OSRS_PRES);
-
- sens_conf->osrs_temp = (enum bme680_osrs_x)
- BME680_GET_REG(data_u8[BME680_INDEX_CTRL_MEAS],
- BME680_MASK_OSRS_TEMP,
- BME680_SHIFT_OSRS_TEMP);
- sens_conf->filter = (enum bme680_filter)BME680_GET_REG(
- data_u8[BME680_INDEX_CONFIG],
- BME680_MASK_FILTER,
- BME680_SHIFT_FILTER);
- sens_conf->spi_3w = (enum bme680_spi_3w)BME680_GET_REG(
- data_u8[BME680_INDEX_CONFIG],
- BME680_MASK_SPI_3W_EN,
- BME680_SHIFT_SPI_3W_EN);
- }
- }
- }
- return com_status;
-}
-
+ * @return uint32_t calculated pressure.
+ */
+static uint32_t calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev);
/*!
- * @brief This function is used for setting gas heater configuration
- * of the sensor from register 5A to 6E address
+ * @brief This internal API is used to calculate the humidity value.
*
- * @param heatr_conf : structure pointer of Heater configuration
- * structure
+ * @param[in] dev :Structure instance of bme680_dev.
+ * @param[in] hum_adc :Contains the humidity ADC value.
*
- * @param bme680 structure pointer.
- *
- * @note reference input values from user are below
- *
- * heater_temp - target temperature (200 to 400 deg cls)
- * heatr_dur - heater duration ( 1 to 4032 ms)
- * heatr_dur_shared - wait time for parallel mode
- * profile_cnt - user configurable profiles(1 to 10)
- *
- * @note heatr_dur and heatr_duration share behaviour varies
- * between parallel and other modes.
- * kindly refer data-sheet
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
-*/
-enum bme680_return_type bme680_set_gas_heater_config(
- struct bme680_heater_conf *heatr_conf, struct bme680_t *bme680)
-{
-
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 data_u8[(BME680_SENS_HEATR_CONF_LEN << 1)-1] = {0};
- u8 index;
- u8 power_mode = 0;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(
- BME680_PAGE1_INTERFACE_SPI, bme680);
- } else if (BME680_I2C_INTERFACE == bme680->interface)
- com_status = BME680_COMM_RES_OK;
-
- if (BME680_COMM_RES_OK == com_status) {
-
- /* get power mode to identify parallel or other modes */
- com_status = bme680_get_power_mode(&power_mode, bme680);
- for (index = 0; index < heatr_conf->profile_cnt;
- index++) {
-
- #ifdef FIXED_POINT_COMPENSATION
- data_u8[index] =
- bme680_convert_temperature_to_resistance_int32(
- heatr_conf->heater_temp[index],
- 25, bme680);
- #else
- data_u8[index] =
- bme680_convert_temperature_to_resistance_double(
- heatr_conf->heater_temp[index],
- 25, bme680);
- #endif
- if (power_mode != BME680_PARALLEL_MODE)
- bme680_scale_to_multiplication_factor(
- &heatr_conf->heatr_dur[index]);
- data_u8[index + 10] = heatr_conf->heatr_dur[index];
-
- }
- if (BME680_PARALLEL_MODE == power_mode) {
- heatr_conf->heatr_dur_shared =
- (heatr_conf->heatr_dur_shared * 1000) /
- BME680_GAS_WAIT_STEP_SIZE;
- bme680_scale_to_multiplication_factor(
- &heatr_conf->heatr_dur_shared);
- data_u8[20] = heatr_conf->heatr_dur_shared;
-
- }
-#ifndef __KERNEL__
- bme680_buffer_restruct_burst_write(data_u8,
- BME680_ADDR_SENS_CONF_START,
- BME680_SENS_HEATR_CONF_LEN,
- (BME680_SENS_HEATR_CONF_LEN << 1)-1);
-
- com_status = (enum bme680_return_type)bme680->bme680_bus_write(
- bme680->dev_addr,
- BME680_ADDR_SENS_CONF_START,
- data_u8,
- (BME680_SENS_HEATR_CONF_LEN << 1)-1);
-#else
- com_status = (enum bme680_return_type)bme680->bme680_bus_write(
- bme680->dev_addr,
- BME680_ADDR_SENS_CONF_START,
- data_u8,
- BME680_SENS_HEATR_CONF_LEN);
-#endif
- }
- }
- return com_status;
-}
+ * @return uint32_t calculated humidity.
+ */
+static uint32_t calc_humidity(uint16_t hum_adc, const struct bme680_dev *dev);
/*!
- * @brief This function is used to convert the gas duration
- * according to multiplication factor of the sensor
+ * @brief This internal API is used to calculate the Gas Resistance value.
*
- * @note
- * gas_wait_X(5:0) define 64 timer values
- * gas_wait_X(7:6) define a multiplication factor
+ * @param[in] dev :Structure instance of bme680_dev.
+ * @param[in] gas_res_adc :Contains the Gas Resistance ADC value.
+ * @param[in] gas_range :Contains the range of gas values.
*
- * gas_wait_X (7:6) | multiplication factor
- * ------------------|------------------------------
- * 00 | 1
- * 01 | 4
- * 10 | 16
- * 11 | 64
- *
- * @param duration_u16 : pointer to store the
- * the converted gas duration
- *
- * @return none
-*/
-
-static void bme680_scale_to_multiplication_factor(u16 *duration_u16)
-{
-
- u8 factor = 0;
-
- while ((*duration_u16) > BME680_GAS_WAIT_MAX_TIMER_VALUE) {
- (*duration_u16) = (*duration_u16) >> 2;
- factor += 1;
- }
- (*duration_u16) = (*duration_u16) + (factor * 64);
-
-}
+ * @return uint32_t calculated gas resistance.
+ */
+static uint32_t calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev);
/*!
- * @brief This function is used to rearrange the buffer
- * according to burst write configuration of BME680 sensor
+ * @brief This internal API is used to calculate the Heat Resistance value.
*
- * @param arr : interface buffer for SPI or I2C
- * @param reg_addr : register address to write
- * @param data_size : no of bytes of data to write
- * @param arr_size : size of the array
+ * @param[in] dev :Structure instance of bme680_dev.
+ * @param[in] temp :Contains the temporary value.
*
- * @return none
- *
-*/
-#ifndef __KERNEL__
-static void bme680_buffer_restruct_burst_write(u8 arr[], u8 reg_addr,
- u8 data_size, u8 arr_size)
-{
- s8 index, sub_index = 0;
-
- for (index = 0 ; index < (data_size - 1); index++) {
- arr[arr_size - 1 - sub_index] = arr[data_size - index - 1];
- arr[arr_size - 2 - sub_index] = reg_addr + data_size - 1;
- --reg_addr;
- sub_index += 2;
- }
-
-}
-#endif
-/*!
- * @brief This function is used to read the sensor heater
- * configuration from register 5A to 6E address
- *
- * @param heatr_conf : structure pointer of Heater
- * configuration structure
- *
- * @param bme680 structure pointer.
- *
- * @note reference output values from the sensor are below
- *
- * heater_temp - target temperature (200 to 400 deg cls)
- * heatr_dur - heater duration ( 1 to 4032 ms)
- * heatr_dur_shared - wait time for parallel mode
- *
- * @note heatr_dur and heatr_duration share behaviour varies
- * between parallel and other modes.
- * kindly refer data-sheet
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- * @note if error code is -5 = BME680_PROFILE_CNT_ERROR
- * means profile count is not set by user.
- * it must be set before calling this function.
- *
-*/
-enum bme680_return_type bme680_get_gas_heater_config(
- struct bme680_heater_conf *heatr_conf, struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 data_u8[BME680_SENS_HEATR_CONF_LEN];
- u8 index;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
- } else {
- if (BME680_SPI_INTERFACE == bme680->interface) {
- /* memory page switch the SPI address*/
- com_status = bme680_set_memory_page(
- BME680_PAGE1_INTERFACE_SPI, bme680);
- } else if (BME680_I2C_INTERFACE == bme680->interface)
- com_status = BME680_COMM_RES_OK;
-
- if (BME680_COMM_RES_OK == com_status) {
-
- for (index = 0; index < BME680_SENS_HEATR_CONF_LEN; index++)
- data_u8[index] = 0;
-
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- BME680_ADDR_SENS_CONF_START,
- data_u8,
- BME680_SENS_HEATR_CONF_LEN);
- if (BME680_COMM_RES_OK == com_status) {
- /* 0<= pc <=10 has been modified in order to
- * avoid warning, "pointless comparison of
- * unsigned int with zero"
- */
- if ((heatr_conf->profile_cnt > 0 &&
- heatr_conf->profile_cnt <= BME680_PROFILE_MAX) ||
- (heatr_conf->profile_cnt == 0)) {
- for (index = 0; index < BME680_PROFILE_MAX;
- index++) {
- heatr_conf->heater_temp[index] =
- data_u8[index];
- heatr_conf->heatr_dur[index] =
- data_u8[index + 10];
- }
- } else {
- com_status = BME680_PROFILE_CNT_ERROR;
- }
-
- heatr_conf->heatr_dur_shared = data_u8[20];
- }
- }
- }
- return com_status;
-
-
-}
+ * @return uint8_t calculated heater resistance.
+ */
+static uint8_t calc_heater_res(uint16_t temp, const struct bme680_dev *dev);
/*!
- * @brief This function is used to compensate the TPHG raw
- * values of the sensor in order to convert to meaningful values
+ * @brief This internal API is used to calculate the field data of sensor.
*
- * @param uncomp_data : Pointer to array of structure which
- * contains the uncompensated TPHG data
- * @param comp_data : Pointer to array of structure which
- * stores the compensated TPHG data
- * @param field_count : total no of field data which needs to be
- * compensated.
+ * @param[out] data :Structure instance to hold the data
+ * @param[in] dev :Structure instance of bme680_dev.
*
- *field_count | Expected values
- * -------------|-----------------------
- * 1 | ONLY_ONE FIELD
- * 2 | ONLY_TWO_FIELD
- * 3 | THREE_FIELD
- *
- * @param sensor_type : Type of sensor
- *
- * sensor_type | Expected values
- * ---------------------|-------------------
- * BME680_ALL | TPGH data
- * BME680_PRESSURE | Pressure data
- * BME680_TEMPERATURE| Temp data
- * BME680_HUMIDITY | Humidity data
- * BME680_GAS | Gas data
- *
- * @note: if "BME680_SPECIFIC_FIELD_DATA_READ_ENABLED" is not defined in
- * bme680.h then for any sensor_type function will perform
- * read operation for BME680_ALL.
- * @note : pressure and humidity depends on temperature.
- *
- * @param bme680 : structure pointer.
- *
- * @note Undefined behaviour for values other than mentioned above
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
- *
- * @note error code is returned when data readout is attempted
- * in sleep mode or when field_count is not in the below range
- * it must be 1<= field_count <= 3
- *
-*/
-enum bme680_return_type bme680_compensate_data(
- struct bme680_uncomp_field_data *uncomp_data,
- struct bme680_comp_field_data *comp_data,
- u8 field_count, u8 sensor_type, struct bme680_t *bme680)
-{
+ * @return int8_t result of the field data from sensor.
+ */
+static int8_t read_field_data(struct bme680_field_data *data, struct bme680_dev *dev);
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- u8 index;
- u8 max_count = 3;
-
- if ((field_count < 1 || field_count > 3)
- || (BME680_SLEEP_MODE == bme680->last_set_mode)) {
- com_status = BME680_COMM_RES_ERROR;
- } else {
-
- if (BME680_FORCED_MODE == bme680->last_set_mode)
- field_count = BME680_PRESENT_DATA_FIELD;
-
-#ifndef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
- sensor_type = BME680_ALL;
- field_count = BME680_ALL_DATA_FIELD;
-#endif
-
-for (index = 0; ((index < field_count) &&
- (index < max_count)); index++) {
-
-#ifdef FIXED_POINT_COMPENSATION
- switch (sensor_type) {
-
- case BME680_TEMPERATURE:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_int32(
- (uncomp_data+index)->temp_adcv,
- bme680);
- break;
- case BME680_PRESSURE:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_int32(
- (uncomp_data+index)->temp_adcv,
- bme680);
- (comp_data + index)->comp_pressure =
- bme680_compensate_pressure_int32(
- (uncomp_data+index)->pres_adcv,
- bme680);
- break;
- case BME680_HUMIDITY:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_int32(
- (uncomp_data+index)->temp_adcv,
- bme680);
- (comp_data + index)->comp_humidity =
- bme680_compensate_humidity_int32(
- (uncomp_data+index)->hum_adcv,
- bme680);
- break;
- case BME680_GAS:
- (comp_data + index)->comp_gas = bme680_calculate_gas_int32(
- (uncomp_data+index)->gas_res_adcv,
- (uncomp_data + index)->gas_range, bme680);
- break;
- case BME680_ALL:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_int32(
- (uncomp_data+index)->temp_adcv,
- bme680);
-
- (comp_data + index)->comp_pressure =
- bme680_compensate_pressure_int32(
- (uncomp_data+index)->pres_adcv,
- bme680);
-
- (comp_data + index)->comp_humidity =
- bme680_compensate_humidity_int32(
- (uncomp_data+index)->hum_adcv,
- bme680);
-
- (comp_data + index)->comp_gas = bme680_calculate_gas_int32(
- (uncomp_data+index)->gas_res_adcv,
- (uncomp_data + index)->gas_range,
- bme680);
- break;
-}
-
-#else
- switch (sensor_type) {
-
- case BME680_TEMPERATURE:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_double(
- (uncomp_data+index)->temp_adcv,
- bme680);
- break;
- case BME680_PRESSURE:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_double(
- (uncomp_data+index)->temp_adcv,
- bme680);
- (comp_data + index)->comp_pressure =
- bme680_compensate_pressure_double(
- (uncomp_data+index)->pres_adcv,
- bme680);
- break;
- case BME680_HUMIDITY:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_double(
- (uncomp_data+index)->temp_adcv,
- bme680);
- (comp_data + index)->comp_humidity =
- bme680_compensate_humidity_double(
- (uncomp_data+index)->hum_adcv,
- (comp_data + index)->comp_temperature1,
- bme680);
- break;
- case BME680_GAS:
- (comp_data + index)->comp_gas =
- bme680_compensate_gas_double(
- (uncomp_data+index)->gas_res_adcv,
- (uncomp_data + index)->gas_range,
- bme680);
- break;
- case BME680_ALL:
- (comp_data + index)->comp_temperature1 =
- bme680_compensate_temperature_double(
- (uncomp_data+index)->temp_adcv,
- bme680);
- (comp_data + index)->comp_pressure =
- bme680_compensate_pressure_double(
- (uncomp_data+index)->pres_adcv,
- bme680);
- (comp_data + index)->comp_humidity =
- bme680_compensate_humidity_double(
- (uncomp_data+index)->hum_adcv,
- (comp_data + index)->comp_temperature1,
- bme680);
- (comp_data + index)->comp_gas = bme680_compensate_gas_double(
- (uncomp_data+index)->gas_res_adcv,
- (uncomp_data + index)->gas_range,
- bme680);
- break;
- }
-
-
-#endif
- }
- com_status = BME680_COMM_RES_OK;
- }
- return com_status;
-
-}
/*!
- * @brief This function is used to write memory page
- * from the register 0x73 bit 4
+ * @brief This internal API is used to set the memory page
+ * based on register address.
*
- *
- * @param memory_page_u8:
- * The value of memory page
- * value | Description
+ * The value of memory page
+ * value | Description
* --------|--------------
- * 0 | BME680_PAGE0_INTERFACE_SPI
- * 1 | BME680_PAGE1_INTERFACE_SPI
+ * 0 | BME680_PAGE0_SPI
+ * 1 | BME680_PAGE1_SPI
*
+ * @param[in] dev :Structure instance of bme680_dev.
+ * @param[in] reg_addr :Contains the register address array.
*
- * @param bme680 structure pointer.
+ * @return Result of API execution status
+ * @retval zero -> Success / +ve value -> Warning / -ve value -> Error
+ */
+static int8_t set_mem_page(uint8_t reg_addr, struct bme680_dev *dev);
+
+/*!
+ * @brief This internal API is used to get the memory page based
+ * on register address.
*
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval any negative value -> Error
+ * The value of memory page
+ * value | Description
+ * --------|--------------
+ * 0 | BME680_PAGE0_SPI
+ * 1 | BME680_PAGE1_SPI
*
+ * @param[in] dev :Structure instance of bme680_dev.
*
-*/
-static enum bme680_return_type bme680_set_memory_page(u8 memory_page_u8,
- struct bme680_t *bme680)
+ * @return Result of API execution status
+ * @retval zero -> Success / +ve value -> Warning / -ve value -> Error
+ */
+static int8_t get_mem_page(struct bme680_dev *dev);
+
+/*!
+ * @brief This internal API is used to validate the device pointer for
+ * null conditions.
+ *
+ * @param[in] dev :Structure instance of bme680_dev.
+ *
+ * @return Result of API execution status
+ * @retval zero -> Success / +ve value -> Warning / -ve value -> Error
+ */
+static int8_t null_ptr_check(const struct bme680_dev *dev);
+
+/*!
+ * @brief This internal API is used to check the boundary
+ * conditions.
+ *
+ * @param[in] value :pointer to the value.
+ * @param[in] min :minimum value.
+ * @param[in] max :maximum value.
+ * @param[in] dev :Structure instance of bme680_dev.
+ *
+ * @return Result of API execution status
+ * @retval zero -> Success / +ve value -> Warning / -ve value -> Error
+ */
+static int8_t boundary_check(uint8_t *value, uint8_t min, uint8_t max, struct bme680_dev *dev);
+
+/****************** Global Function Definitions *******************************/
+/*!
+ *@brief This API is the entry point.
+ *It reads the chip-id and calibration data from the sensor.
+ */
+int8_t bme680_init(struct bme680_dev *dev)
{
- u8 data_u8 = 0;
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
- /* check the bme680 is NULL pointer */
- if (BME680_NULL_PTR == bme680) {
- com_status = BME680_ERROR_NULL_PTR;
+ int8_t rslt;
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK)
+ {
+ /* Soft reset to restore it to default values*/
+ rslt = bme680_soft_reset(dev);
+
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(BME680_CHIP_ID_ADDR, &dev->chip_id, 1, dev);
+ if (rslt == BME680_OK) {
+ if (dev->chip_id == BME680_CHIP_ID) {
+ rslt = get_calib_data(dev);
+ } else {
+ rslt = BME680_E_DEV_NOT_FOUND;
+ }
+ }
+ }
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This API reads the data from the given register address of the sensor.
+ */
+int8_t bme680_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, struct bme680_dev *dev)
+{
+ int8_t rslt;
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ if (dev->intf == BME680_SPI_INTF) {
+ /* Set the memory page */
+ rslt = set_mem_page(reg_addr, dev);
+ if (rslt == BME680_OK)
+ reg_addr = reg_addr | BME680_SPI_RD_MSK;
+ }
+ dev->com_rslt = dev->read(dev->dev_id, reg_addr, reg_data, len);
+ if (dev->com_rslt != 0)
+ rslt = BME680_E_COM_FAIL;
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This API writes the given data to the register address
+ * of the sensor.
+ */
+int8_t bme680_set_regs(const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, struct bme680_dev *dev)
+{
+ int8_t rslt;
+ /* Length of the temporary buffer is 2*(length of register)*/
+ uint8_t tmp_buff[BME680_TMP_BUFFER_LENGTH] = { 0 };
+ uint16_t index;
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ if ((len > 0) && (len < BME680_TMP_BUFFER_LENGTH / 2)) {
+ /* Interleave the 2 arrays */
+ for (index = 0; index < len; index++) {
+ if (dev->intf == BME680_SPI_INTF) {
+ /* Set the memory page */
+ rslt = set_mem_page(reg_addr[index], dev);
+ tmp_buff[(2 * index)] = reg_addr[index] & BME680_SPI_WR_MSK;
+ } else {
+ tmp_buff[(2 * index)] = reg_addr[index];
+ }
+ tmp_buff[(2 * index) + 1] = reg_data[index];
+ }
+ /* Write the interleaved array */
+ if (rslt == BME680_OK) {
+ dev->com_rslt = dev->write(dev->dev_id, tmp_buff[0], &tmp_buff[1], (2 * len) - 1);
+ if (dev->com_rslt != 0)
+ rslt = BME680_E_COM_FAIL;
+ }
} else {
- /* write memory page*/
- com_status = (enum bme680_return_type)bme680->bme680_bus_read(
- bme680->dev_addr,
- BME680_ADDR_SPI_MEM_PAGE,
- &data_u8,
- BME680_GEN_READ_DATA_LENGTH);
- data_u8 = BME680_SET_REG(data_u8, memory_page_u8,
- BME680_MASK_MEM_PAGE,
- BME680_SHIFT_SPI_MEM_PAGE);
- if (BME680_COMM_RES_OK == com_status)
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_write(
- bme680->dev_addr,
- BME680_ADDR_SPI_MEM_PAGE,
- &data_u8,
- BME680_GEN_WRITE_DATA_LENGTH);
+ rslt = BME680_E_INVALID_LENGTH;
+ }
}
- return com_status;
+
+ return rslt;
}
/*!
- * @brief This function is used to Align uncompensated data
- * from function bme680_get_uncomp_data()
- *
- * @param a_data_u8 : pointer to buffer
- * @param field_count : total no of field data which needs
- * to be compensated
- * @param sensor_type : Type of sensor
- *
- * sensor_type | Expected values
- * ---------------------|-------------------
- * BME680_ALL | TPGH data
- * BME680_PRESSURE | Pressure data
- * BME680_TEMPERATURE| Temp data
- * BME680_HUMIDITY | Humidity data
- * BME680_GAS | Gas data
- *
- * @note : pressure and humidity depends on temperature.
- *
- * @param uncomp_data : Pointer to array of structure which
- * contains the uncompensated TPHG data
- * @param bme680 structure pointer.
- * @return - None
- *
- *
-*/
-void bme680_align_uncomp_data(u8 *a_data_u8, u8 field_count, u8 sensor_type,
- struct bme680_uncomp_field_data *uncomp_data, struct bme680_t *bme680)
+ * @brief This API performs the soft reset of the sensor.
+ */
+int8_t bme680_soft_reset(struct bme680_dev *dev)
{
- u8 offset = 0;
- s8 index = 0;
+ int8_t rslt;
+ uint8_t reg_addr = BME680_SOFT_RESET_ADDR;
+ /* 0xb6 is the soft reset command */
+ uint8_t soft_rst_cmd = BME680_SOFT_RESET_CMD;
- if (BME680_FORCED_MODE != bme680->last_set_mode)
- field_count = BME680_ALL_DATA_FIELD;
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ if (dev->intf == BME680_SPI_INTF)
+ rslt = get_mem_page(dev);
- for (index = 0; index < field_count; index++) {
-
- offset = (index * BME680_FIELD_SIZE);
-
- /* field_index status */
- (uncomp_data + index)->status.new_data = BME680_GET_REG(
- a_data_u8[FIELD_0_MEAS_STATUS_0 + offset],
- BME680_MASK_NEW_DATA,
- BME680_SHIFT_NEW_DATA);
- (uncomp_data + index)->status.gas_meas_stat = BME680_GET_REG(
- a_data_u8[FIELD_0_MEAS_STATUS_0 + offset],
- BME680_MASK_GAS_MEAS_STAT,
- BME680_SHIFT_GAS_MEAS_STAT);
- (uncomp_data + index)->status.tphg_meas_stat = BME680_GET_REG(
- a_data_u8[FIELD_0_MEAS_STATUS_0 + offset],
- BME680_MASK_TPHG_MEAS_STAT,
- BME680_SHIFT_TPHG_MEAS_STAT);
- (uncomp_data + index)->status.gas_meas_index = BME680_GET_REG(
- a_data_u8[FIELD_0_MEAS_STATUS_0 + offset],
- BME680_MASK_GAS_MEAS_INDEX,
- BME680_SHIFT_GAS_MEAS_INDEX);
- (uncomp_data + index)->status.meas_index =
- a_data_u8[FIELD_0_MEAS_STATUS_1 + offset];
- (uncomp_data + index)->gas_range = BME680_GET_REG(
- a_data_u8[FIELD_0_GAS_RL_LSB + offset],
- BME680_MASK_GAS_RANGE,
- BME680_SHIFT_GAS_RANGE);
- (uncomp_data + index)->status.gas_valid = BME680_GET_REG(
- a_data_u8[FIELD_0_GAS_RL_LSB + offset],
- BME680_MASK_GAS_VALID,
- BME680_SHIFT_GAS_VALID);
- (uncomp_data + index)->status.heatr_stab = BME680_GET_REG(
- a_data_u8[FIELD_0_GAS_RL_LSB + offset],
- BME680_MASK_HEATR_STAB,
- BME680_SHIFT_HEATR_STAB);
-
- /* uncompensated field zero
- pressure data*/
- bme680_align_sensor_type_uncomp_data(a_data_u8, index, offset,
- sensor_type,
- uncomp_data);
+ /* Reset the device */
+ if (rslt == BME680_OK) {
+ rslt = bme680_set_regs(®_addr, &soft_rst_cmd, 1, dev);
+ /* Wait for 5ms */
+ dev->delay_ms(BME680_RESET_PERIOD);
+ if (rslt == BME680_OK) {
+ /* After reset get the memory page */
+ if (dev->intf == BME680_SPI_INTF)
+ rslt = get_mem_page(dev);
+ }
+ }
}
+ return rslt;
}
/*!
- * @brief This function is used to get the index of latest, recent and old
- * field data according to the sub_meas_index parameter.
- *
- * @param sensor_data : structure pointer of uncompensated array
- * of 3 structure
- *
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval Any Negative -> Error
- *
- *
-*/
-void bme680_get_latest_recent_old_field_index(
- struct bme680_uncomp_field_data *sensor_data,
- struct bme680_t *bme680)
+ * @brief This API is used to set the oversampling, filter and T,P,H, gas selection
+ * settings in the sensor.
+ */
+int8_t bme680_set_sensor_settings(uint16_t desired_settings, struct bme680_dev *dev)
{
- /* Array holding the filed0, field1 and field2
- temperature, pressure, humidity and gas data*/
- u8 latest = 0;
- u8 recent = 0;
- u8 old = 0;
- u8 index = 0;
- u8 large_index = 0;
- u8 max_index = 2;
- u8 meas_index[3];
+ int8_t rslt;
+ uint8_t reg_addr;
+ uint8_t data = 0;
+ uint8_t count = 0;
+ uint8_t reg_array[BME680_REG_BUFFER_LENGTH] = { 0 };
+ uint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };
+ uint8_t intended_power_mode = dev->power_mode; /* Save intended power mode */
- for (index = 0; index < 3; index++)
- meas_index[index] = 0;
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ if (desired_settings & BME680_GAS_MEAS_SEL)
+ rslt = set_gas_config(dev);
- index = 0;
- for (index = 0; index < 3; index++)
- meas_index[index] = (sensor_data + index)->status.meas_index;
+ dev->power_mode = BME680_SLEEP_MODE;
+ if (rslt == BME680_OK)
+ rslt = bme680_set_sensor_mode(dev);
+ /* Selecting the filter */
+ if (desired_settings & BME680_FILTER_SEL) {
+ rslt = boundary_check(&dev->tph_sett.filter, BME680_FILTER_SIZE_0, BME680_FILTER_SIZE_127, dev);
+ reg_addr = BME680_CONF_ODR_FILT_ADDR;
- index = 0;
- latest = DIFF(meas_index[0], meas_index[1]);
- if ((DIFF(meas_index[0], meas_index[1]) > 2) ||
- (DIFF(meas_index[1], meas_index[2]) > 2)) {
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(reg_addr, &data, 1, dev);
- while (meas_index[index++] != 255)
- ;
- old = --index;
- if (index == 2) {
- recent = index - 2;
- latest = index - 1;
- } else if (index == 1) {
- recent = index + 1;
- latest = index - 1;
- } else {
- recent = index + 1;
- latest = index + 2;
+ if (desired_settings & BME680_FILTER_SEL)
+ data = BME680_SET_BITS(data, BME680_FILTER, dev->tph_sett.filter);
+
+ reg_array[count] = reg_addr; /* Append configuration */
+ data_array[count] = data;
+ count++;
+ }
+
+ /* Selecting heater control for the sensor */
+ if (desired_settings & BME680_HCNTRL_SEL) {
+ rslt = boundary_check(&dev->gas_sett.heatr_ctrl, BME680_ENABLE_HEATER, BME680_DISABLE_HEATER, dev);
+ reg_addr = BME680_CONF_HEAT_CTRL_ADDR;
+
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(reg_addr, &data, 1, dev);
+ data = BME680_SET_BITS_POS_0(data, BME680_HCTRL, dev->gas_sett.heatr_ctrl);
+
+ reg_array[count] = reg_addr; /* Append configuration */
+ data_array[count] = data;
+ count++;
+ }
+
+ /* Selecting heater T,P oversampling for the sensor */
+ if (desired_settings & (BME680_OST_SEL | BME680_OSP_SEL)) {
+ rslt = boundary_check(&dev->tph_sett.os_temp, BME680_OS_NONE, BME680_OS_16X, dev);
+ reg_addr = BME680_CONF_T_P_MODE_ADDR;
+
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(reg_addr, &data, 1, dev);
+
+ if (desired_settings & BME680_OST_SEL)
+ data = BME680_SET_BITS(data, BME680_OST, dev->tph_sett.os_temp);
+
+ if (desired_settings & BME680_OSP_SEL)
+ data = BME680_SET_BITS(data, BME680_OSP, dev->tph_sett.os_pres);
+
+ reg_array[count] = reg_addr;
+ data_array[count] = data;
+ count++;
+ }
+
+ /* Selecting humidity oversampling for the sensor */
+ if (desired_settings & BME680_OSH_SEL) {
+ rslt = boundary_check(&dev->tph_sett.os_hum, BME680_OS_NONE, BME680_OS_16X, dev);
+ reg_addr = BME680_CONF_OS_H_ADDR;
+
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(reg_addr, &data, 1, dev);
+ data = BME680_SET_BITS_POS_0(data, BME680_OSH, dev->tph_sett.os_hum);
+
+ reg_array[count] = reg_addr; /* Append configuration */
+ data_array[count] = data;
+ count++;
+ }
+
+ /* Selecting the runGas and NB conversion settings for the sensor */
+ if (desired_settings & (BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)) {
+ rslt = boundary_check(&dev->gas_sett.run_gas, BME680_RUN_GAS_DISABLE, BME680_RUN_GAS_ENABLE, dev);
+ if (rslt == BME680_OK)
+ rslt = boundary_check(&dev->gas_sett.nb_conv, BME680_NBCONV_MIN, BME680_NBCONV_MAX, dev);
+ reg_addr = BME680_CONF_ODR_RUN_GAS_NBC_ADDR;
+
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(reg_addr, &data, 1, dev);
+
+ if (desired_settings & BME680_RUN_GAS_SEL)
+ data = BME680_SET_BITS(data, BME680_RUN_GAS, dev->gas_sett.run_gas);
+
+ if (desired_settings & BME680_NBCONV_SEL)
+ data = BME680_SET_BITS_POS_0(data, BME680_NBCONV, dev->gas_sett.nb_conv);
+
+ reg_array[count] = reg_addr; /* Append configuration */
+ data_array[count] = data;
+ count++;
+ }
+
+ if (rslt == BME680_OK)
+ rslt = bme680_set_regs(reg_array, data_array, count, dev);
+
+ /* Restore previous intended power mode */
+ dev->power_mode = intended_power_mode;
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This API is used to get the oversampling, filter and T,P,H, gas selection
+ * settings in the sensor.
+ */
+int8_t bme680_get_sensor_settings(uint16_t desired_settings, struct bme680_dev *dev)
+{
+ int8_t rslt;
+ /* starting address of the register array for burst read*/
+ uint8_t reg_addr = BME680_CONF_HEAT_CTRL_ADDR;
+ uint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(reg_addr, data_array, BME680_REG_BUFFER_LENGTH, dev);
+
+ if (rslt == BME680_OK) {
+ if (desired_settings & BME680_GAS_MEAS_SEL)
+ rslt = get_gas_config(dev);
+
+ /* get the T,P,H ,Filter,ODR settings here */
+ if (desired_settings & BME680_FILTER_SEL)
+ dev->tph_sett.filter = BME680_GET_BITS(data_array[BME680_REG_FILTER_INDEX], BME680_FILTER);
+
+ if (desired_settings & (BME680_OST_SEL | BME680_OSP_SEL)) {
+ dev->tph_sett.os_temp = BME680_GET_BITS(data_array[BME680_REG_TEMP_INDEX], BME680_OST);
+ dev->tph_sett.os_pres = BME680_GET_BITS(data_array[BME680_REG_PRES_INDEX], BME680_OSP);
}
+ if (desired_settings & BME680_OSH_SEL)
+ dev->tph_sett.os_hum = BME680_GET_BITS_POS_0(data_array[BME680_REG_HUM_INDEX], BME680_OSH);
+
+ /* get the gas related settings */
+ if (desired_settings & BME680_HCNTRL_SEL)
+ dev->gas_sett.heatr_ctrl = BME680_GET_BITS_POS_0(data_array[BME680_REG_HCTRL_INDEX], BME680_HCTRL);
+
+ if (desired_settings & (BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)) {
+ dev->gas_sett.nb_conv = BME680_GET_BITS_POS_0(data_array[BME680_REG_NBCONV_INDEX], BME680_NBCONV);
+ dev->gas_sett.run_gas = BME680_GET_BITS(data_array[BME680_REG_RUN_GAS_INDEX], BME680_RUN_GAS);
+ }
+ }
} else {
- large_index = bme680_find_largest_index(meas_index);
- latest = large_index;
- if (large_index == max_index) {
- recent = max_index - 1;
- old = max_index - 2;
- } else if (large_index == (max_index - 1)) {
- recent = max_index - 2;
- old = max_index;
-
- } else {
- recent = max_index;
- old = max_index - 1;
- }
-
+ rslt = BME680_E_NULL_PTR;
}
- bme680->latest_field_index = latest;
- bme680->recent_field_index = recent;
- bme680->old_field_index = old;
-}
-/*!
- * @brief This function is used to read the status of all 3 fields
- *
- * @param uncomp_data : Pointer to array of uncompensated data structure.
- * @param a_data_u8: pointer to store the read status data.
- * @param new_data: pointer to store the new_data value of given field
- * @param bme680 structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval Any Negative -> Error
- *
- *
-*/
-enum bme680_return_type bme680_read_status_fields(
- struct bme680_uncomp_field_data *uncomp_data,
- u8 *a_data_u8, u8 *new_data,
- struct bme680_t *bme680)
-{
- /* used to return the communication result*/
- enum bme680_return_type com_status = BME680_COMM_RES_ERROR;
-
- u8 count = 0;
- /* local buffer length is 5 and it's the maximum */
- u8 temp_data_u8[2] = {0, 0};
-
-
- /*read the 2 byte of status form 0x1D - field_0*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- BME680_ADDR_FIELD_0_STATUS,
- temp_data_u8,
- BME680_STATUS_DATA_LEN);
- /* Assign data to the reserved
- index of the input buffer */
- for (count = 0;
- count < BME680_STATUS_DATA_LEN; count++)
- a_data_u8[0 + count] = temp_data_u8[count];
-
- (uncomp_data + 0)->status.meas_index = a_data_u8[1];
-
- if (BME680_COMM_RES_OK == com_status)
- new_data[0] = BME680_GET_REG(a_data_u8[0],
- BME680_MASK_NEW_DATA,
- BME680_SHIFT_NEW_DATA);
-
-
- /*read the 2 byte of status form 0x2E - field_1*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- BME680_ADDR_FIELD_1_STATUS,
- temp_data_u8,
- BME680_STATUS_DATA_LEN);
- /*Assign data to the reserved index
- 17 and 18 of the input buffer*/
- for (count = 0;
- count < BME680_STATUS_DATA_LEN; count++)
- a_data_u8[17 + count] = temp_data_u8[count];
-
- (uncomp_data + 1)->status.meas_index = a_data_u8[18];
-
- if (BME680_COMM_RES_OK == com_status)
- new_data[1] = BME680_GET_REG(a_data_u8[17],
- BME680_MASK_NEW_DATA,
- BME680_SHIFT_NEW_DATA);
-
- /*read the 2 byte of status form 0x3F - field_2*/
- com_status = (enum bme680_return_type)
- bme680->bme680_bus_read(bme680->dev_addr,
- BME680_ADDR_FIELD_2_STATUS,
- temp_data_u8,
- BME680_STATUS_DATA_LEN);
- /*Assign data to the reserved index
- 34 and 35 of the input buffer*/
- for (count = 0;
- count < BME680_STATUS_DATA_LEN; count++)
- a_data_u8[34 + count] = temp_data_u8[count];
-
- (uncomp_data + 2)->status.meas_index = a_data_u8[35];
- if (BME680_COMM_RES_OK == com_status)
- new_data[2] = BME680_GET_REG(a_data_u8[34],
- BME680_MASK_NEW_DATA,
- BME680_SHIFT_NEW_DATA);
- return com_status;
+ return rslt;
}
/*!
- * @brief This function is used to copy the ordered
- * uncompensated data
- *
- * @param sensor_data : structure pointer of uncompensated array
- * of 3 structure
- * @param latest : total no of field
- * @param recent : total no of field
- * @param old : total no of field
- *
- * @param sensor_type : type of the sensor
- * @param temp_sensor_data: structure pointer.
- *
- * @return results of bus communication function
- * @retval 0 -> Success
- * @retval Any Negative -> Error
- *
- *
-*/
-void bme680_copy_ordered_sensor_field_data(
- struct bme680_uncomp_field_data *sensor_data,
- u8 latest, u8 recent, u8 old, u8 sensor_type,
- struct bme680_uncomp_field_data *temp_sensor_data)
+ * @brief This API is used to set the power mode of the sensor.
+ */
+int8_t bme680_set_sensor_mode(struct bme680_dev *dev)
{
+ int8_t rslt;
+ uint8_t tmp_pow_mode;
+ uint8_t pow_mode = 0;
+ uint8_t reg_addr = BME680_CONF_T_P_MODE_ADDR;
- u8 index = 0;
-#ifndef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
- sensor_type = BME680_ALL;
-#endif
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ /* Call recursively until in sleep */
+ do {
+ rslt = bme680_get_regs(BME680_CONF_T_P_MODE_ADDR, &tmp_pow_mode, 1, dev);
+ if (rslt == BME680_OK) {
+ /* Put to sleep before changing mode */
+ pow_mode = (tmp_pow_mode & BME680_MODE_MSK);
-#ifdef BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
- /* copy status of all field */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- sensor_data[index].status =
- temp_sensor_data[latest].status;
- else if (index == BME680_FIELD_INDEX1)
- sensor_data[index].status =
- temp_sensor_data[recent].status;
- else
- sensor_data[index].status =
- temp_sensor_data[old].status;
+ if (pow_mode != BME680_SLEEP_MODE) {
+ tmp_pow_mode = tmp_pow_mode & (~BME680_MODE_MSK); /* Set to sleep */
+ rslt = bme680_set_regs(®_addr, &tmp_pow_mode, 1, dev);
+ dev->delay_ms(BME680_POLL_PERIOD_MS);
+ }
+ }
+ } while (pow_mode != BME680_SLEEP_MODE);
+
+ /* Already in sleep */
+ if (dev->power_mode != BME680_SLEEP_MODE) {
+ tmp_pow_mode = (tmp_pow_mode & ~BME680_MODE_MSK) | (dev->power_mode & BME680_MODE_MSK);
+ if (rslt == BME680_OK)
+ rslt = bme680_set_regs(®_addr, &tmp_pow_mode, 1, dev);
+ }
}
- if (BME680_PRESSURE == sensor_type || BME680_TEMPERATURE == sensor_type
- || BME680_HUMIDITY == sensor_type) {
- /* copy temperature data
- by default for Pressure and Humidity
- */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- sensor_data[index].temp_adcv =
- temp_sensor_data[latest].temp_adcv;
- else if (index == BME680_FIELD_INDEX1)
- sensor_data[index].temp_adcv =
- temp_sensor_data[recent].temp_adcv;
- else {
- sensor_data[index].temp_adcv =
- temp_sensor_data[old].temp_adcv;
- }
- }
- switch (sensor_type) {
- case BME680_PRESSURE:
- /* copying only pressure data */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- sensor_data[index].pres_adcv =
- temp_sensor_data[latest].pres_adcv;
- else if (index == BME680_FIELD_INDEX1)
- sensor_data[index].pres_adcv =
- temp_sensor_data[recent].pres_adcv;
- else {
- sensor_data[index].pres_adcv =
- temp_sensor_data[old].pres_adcv;
- }
- }
- break;
- case BME680_HUMIDITY:
- /* copying only humidity data */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- sensor_data[index].hum_adcv =
- temp_sensor_data[latest].hum_adcv;
- else if (index == BME680_FIELD_INDEX1)
- sensor_data[index].hum_adcv =
- temp_sensor_data[recent].hum_adcv;
- else {
- sensor_data[index].hum_adcv =
- temp_sensor_data[old].hum_adcv;
- }
- }
- break;
- }
- } else if (BME680_GAS == sensor_type) {
- /* copying only gas data */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- sensor_data[index].gas_res_adcv =
- temp_sensor_data[latest].gas_res_adcv;
- else if (index == BME680_FIELD_INDEX1)
- sensor_data[index].gas_res_adcv =
- temp_sensor_data[recent].gas_res_adcv;
- else {
- sensor_data[index].gas_res_adcv =
- temp_sensor_data[old].gas_res_adcv;
- }
- }
- } else if (BME680_ALL == sensor_type) {
- /* copying T,P,G,& H data */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- *(sensor_data + index) =
- *(temp_sensor_data + latest);
- else if (index == BME680_FIELD_INDEX1)
- *(sensor_data + index) =
- *(temp_sensor_data + recent);
- else
- *(sensor_data + index) =
- *(temp_sensor_data + old);
- }
- }
- #else
- if (BME680_ALL == sensor_type) {
- /* copying T,P,G,& H data */
- for (index = 0; index < BME680_MAX_FIELD_INDEX;
- index++) {
- if (index == BME680_FIELD_INDEX0)
- *(sensor_data + index) =
- *(temp_sensor_data + latest);
- else if (index == BME680_FIELD_INDEX1)
- *(sensor_data + index) =
- *(temp_sensor_data + recent);
- else
- *(sensor_data + index) =
- *(temp_sensor_data + old);
- }
- }
-#endif
+ return rslt;
}
+
/*!
- * @brief This utility function is to return the largest number
- * index of the input array passed to the function.
- *
- * @param meas_index: pointer to the integer array
- *
- * @return index of largest element of the array
- *
- *
-*/
-static u8 bme680_find_largest_index(u8 *meas_index)
+ * @brief This API is used to get the power mode of the sensor.
+ */
+int8_t bme680_get_sensor_mode(struct bme680_dev *dev)
{
+ int8_t rslt;
+ uint8_t mode;
- u8 index = 0;
- u8 temp_index = 0;
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(BME680_CONF_T_P_MODE_ADDR, &mode, 1, dev);
+ /* Masking the other register bit info*/
+ dev->power_mode = mode & BME680_MODE_MSK;
+ }
- if (*(meas_index + index) > *(meas_index + (index + 2))) {
- if (*(meas_index + index) > *(meas_index + (index + 1)))
- temp_index = index;
- else
- temp_index = index + 1;
+ return rslt;
+}
+
+/*!
+ * @brief This API is used to set the profile duration of the sensor.
+ */
+void bme680_set_profile_dur(uint16_t duration, struct bme680_dev *dev)
+{
+ uint32_t tph_dur; /* Calculate in us */
+
+ /* TPH measurement duration */
+ tph_dur = ((uint32_t) (dev->tph_sett.os_temp + dev->tph_sett.os_pres + dev->tph_sett.os_hum) * UINT32_C(1963));
+ tph_dur += UINT32_C(477 * 4); /* TPH switching duration */
+ tph_dur += UINT32_C(477 * 5); /* Gas measurement duration */
+ tph_dur += UINT32_C(500); /* Get it to the closest whole number.*/
+ tph_dur /= UINT32_C(1000); /* Convert to ms */
+
+ tph_dur += UINT32_C(1); /* Wake up duration of 1ms */
+ /* The remaining time should be used for heating */
+ dev->gas_sett.heatr_dur = duration - (uint16_t) tph_dur;
+}
+
+/*!
+ * @brief This API is used to get the profile duration of the sensor.
+ */
+void bme680_get_profile_dur(uint16_t *duration, struct bme680_dev *dev)
+{
+ uint32_t tph_dur; /* Calculate in us */
+
+ /* TPH measurement duration */
+ tph_dur = ((uint32_t) (dev->tph_sett.os_temp + dev->tph_sett.os_pres + dev->tph_sett.os_hum) * UINT32_C(1963));
+ tph_dur += UINT32_C(477 * 4); /* TPH switching duration */
+ tph_dur += UINT32_C(477 * 5); /* Gas measurement duration */
+ tph_dur += UINT32_C(500); /* Get it to the closest whole number.*/
+ tph_dur /= UINT32_C(1000); /* Convert to ms */
+
+ tph_dur += UINT32_C(1); /* Wake up duration of 1ms */
+ /* The remaining time should be used for heating */
+ *duration = dev->gas_sett.heatr_dur + (uint16_t) tph_dur;
+}
+
+/*!
+ * @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.
+ */
+int8_t bme680_get_sensor_data(struct bme680_field_data *data, struct bme680_dev *dev)
+{
+ int8_t rslt;
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ /* Reading the sensor data in forced mode only */
+ rslt = read_field_data(data, dev);
+ if (rslt == BME680_OK) {
+ if (data->status & BME680_NEW_DATA_MSK)
+ dev->new_fields = 1;
+ else
+ dev->new_fields = 0;
+ }
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This internal API is used to read the calibrated data from the sensor.
+ */
+static int8_t get_calib_data(struct bme680_dev *dev)
+{
+ int8_t rslt;
+ uint8_t coeff_array[BME680_COEFF_SIZE] = { 0 };
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(BME680_COEFF_ADDR1, coeff_array, BME680_COEFF_ADDR1_LEN, dev);
+ /* Append the second half in the same array */
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(BME680_COEFF_ADDR2, &coeff_array[BME680_COEFF_ADDR1_LEN], BME680_COEFF_ADDR2_LEN,
+ dev);
+
+ /* Temperature related coefficients */
+ dev->calib.par_t1 = (uint16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_T1_MSB_REG],
+ coeff_array[BME680_T1_LSB_REG]));
+ dev->calib.par_t2 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_T2_MSB_REG],
+ coeff_array[BME680_T2_LSB_REG]));
+ dev->calib.par_t3 = (int8_t) (coeff_array[BME680_T3_REG]);
+
+ /* Pressure related coefficients */
+ dev->calib.par_p1 = (uint16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P1_MSB_REG],
+ coeff_array[BME680_P1_LSB_REG]));
+ dev->calib.par_p2 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P2_MSB_REG],
+ coeff_array[BME680_P2_LSB_REG]));
+ dev->calib.par_p3 = (int8_t) coeff_array[BME680_P3_REG];
+ dev->calib.par_p4 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P4_MSB_REG],
+ coeff_array[BME680_P4_LSB_REG]));
+ dev->calib.par_p5 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P5_MSB_REG],
+ coeff_array[BME680_P5_LSB_REG]));
+ dev->calib.par_p6 = (int8_t) (coeff_array[BME680_P6_REG]);
+ dev->calib.par_p7 = (int8_t) (coeff_array[BME680_P7_REG]);
+ dev->calib.par_p8 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P8_MSB_REG],
+ coeff_array[BME680_P8_LSB_REG]));
+ dev->calib.par_p9 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_P9_MSB_REG],
+ coeff_array[BME680_P9_LSB_REG]));
+ dev->calib.par_p10 = (uint8_t) (coeff_array[BME680_P10_REG]);
+
+ /* Humidity related coefficients */
+ dev->calib.par_h1 = (uint16_t) (((uint16_t) coeff_array[BME680_H1_MSB_REG] << BME680_HUM_REG_SHIFT_VAL)
+ | (coeff_array[BME680_H1_LSB_REG] & BME680_BIT_H1_DATA_MSK));
+ dev->calib.par_h2 = (uint16_t) (((uint16_t) coeff_array[BME680_H2_MSB_REG] << BME680_HUM_REG_SHIFT_VAL)
+ | ((coeff_array[BME680_H2_LSB_REG]) >> BME680_HUM_REG_SHIFT_VAL));
+ dev->calib.par_h3 = (int8_t) coeff_array[BME680_H3_REG];
+ dev->calib.par_h4 = (int8_t) coeff_array[BME680_H4_REG];
+ dev->calib.par_h5 = (int8_t) coeff_array[BME680_H5_REG];
+ dev->calib.par_h6 = (uint8_t) coeff_array[BME680_H6_REG];
+ dev->calib.par_h7 = (int8_t) coeff_array[BME680_H7_REG];
+
+ /* Gas heater related coefficients */
+ dev->calib.par_gh1 = (int8_t) coeff_array[BME680_GH1_REG];
+ dev->calib.par_gh2 = (int16_t) (BME680_CONCAT_BYTES(coeff_array[BME680_GH2_MSB_REG],
+ coeff_array[BME680_GH2_LSB_REG]));
+ dev->calib.par_gh3 = (int8_t) coeff_array[BME680_GH3_REG];
+
+ /* Other coefficients */
+ uint8_t temp_var = 0; /* Temporary variable */
+
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(BME680_ADDR_RES_HEAT_RANGE_ADDR, &temp_var, 1, dev);
+
+ dev->calib.res_heat_range = ((temp_var & BME680_RHRANGE_MSK) / 16);
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(BME680_ADDR_RES_HEAT_VAL_ADDR, &temp_var, 1, dev);
+
+ dev->calib.res_heat_val = (int8_t) temp_var;
+ if (rslt == BME680_OK)
+ rslt = bme680_get_regs(BME680_ADDR_RANGE_SW_ERR_ADDR, &temp_var, 1, dev);
+ }
+ }
+ dev->calib.range_sw_err = ((int8_t) temp_var & (int8_t) BME680_RSERROR_MSK) / 16;
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This internal API is used to set the gas configuration of the sensor.
+ */
+static int8_t set_gas_config(struct bme680_dev *dev)
+{
+ int8_t rslt;
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+
+ uint8_t reg_addr[2], reg_data[2];
+
+ if (dev->power_mode == BME680_FORCED_MODE) {
+ reg_addr[0] = BME680_RES_HEAT0_ADDR;
+ reg_data[0] = calc_heater_res(dev->gas_sett.heatr_temp, dev);
+ reg_addr[1] = BME680_GAS_WAIT0_ADDR;
+ reg_data[1] = calc_heater_dur(dev->gas_sett.heatr_dur);
+ dev->gas_sett.nb_conv = 0;
+ } else {
+ rslt = BME680_W_DEFINE_PWR_MODE;
+ }
+ if (rslt == BME680_OK)
+ rslt = bme680_set_regs(reg_addr, reg_data, 2, dev);
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This internal API is used to get the gas configuration of the sensor.
+ */
+static int8_t get_gas_config(struct bme680_dev *dev)
+{
+ int8_t rslt;
+ /* starting address of the register array for burst read*/
+ uint8_t reg_addr1 = BME680_ADDR_SENS_CONF_START;
+ uint8_t reg_addr2 = BME680_ADDR_GAS_CONF_START;
+ uint8_t data_array[BME680_GAS_HEATER_PROF_LEN_MAX] = { 0 };
+ uint8_t index;
+
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ if (BME680_SPI_INTF == dev->intf) {
+ /* Memory page switch the SPI address*/
+ rslt = set_mem_page(reg_addr1, dev);
+ }
+
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(reg_addr1, data_array, BME680_GAS_HEATER_PROF_LEN_MAX, dev);
+ if (rslt == BME680_OK) {
+ for (index = 0; index < BME680_GAS_HEATER_PROF_LEN_MAX; index++)
+ dev->gas_sett.heatr_temp = data_array[index];
+ }
+
+ rslt = bme680_get_regs(reg_addr2, data_array, BME680_GAS_HEATER_PROF_LEN_MAX, dev);
+ if (rslt == BME680_OK) {
+ for (index = 0; index < BME680_GAS_HEATER_PROF_LEN_MAX; index++)
+ dev->gas_sett.heatr_dur = data_array[index];
+ }
+ }
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This internal API is used to calculate the temperature value.
+ */
+static int16_t calc_temperature(uint32_t temp_adc, struct bme680_dev *dev)
+{
+ int64_t var1;
+ int64_t var2;
+ int64_t var3;
+ int16_t calc_temp;
+
+ var1 = ((int32_t) temp_adc / 8) - ((int32_t) dev->calib.par_t1 * 2);
+ var2 = (var1 * (int32_t) dev->calib.par_t2) / 2048;
+ var3 = ((var1 / 2) * (var1 / 2)) / 4096;
+ var3 = ((var3) * ((int32_t) dev->calib.par_t3 * 16)) / 16384;
+ dev->calib.t_fine = (int32_t) (var2 + var3);
+ calc_temp = (int16_t) (((dev->calib.t_fine * 5) + 128) / 256);
+
+ return calc_temp;
+}
+
+/*!
+ * @brief This internal API is used to calculate the pressure value.
+ */
+static uint32_t calc_pressure(uint32_t pres_adc, const struct bme680_dev *dev)
+{
+ int32_t var1;
+ int32_t var2;
+ int32_t var3;
+ int32_t calc_pres;
+
+ var1 = (((int32_t) dev->calib.t_fine) / 2) - 64000;
+ var2 = ((var1 / 4) * (var1 / 4)) / 2048;
+ var2 = ((var2) * (int32_t) dev->calib.par_p6) / 4;
+ var2 = var2 + ((var1 * (int32_t) dev->calib.par_p5) * 2);
+ var2 = (var2 / 4) + ((int32_t) dev->calib.par_p4 * 65536);
+ var1 = ((var1 / 4) * (var1 / 4)) / 8192;
+ var1 = (((var1) * ((int32_t) dev->calib.par_p3 * 32)) / 8) + (((int32_t) dev->calib.par_p2 * var1) / 2);
+ var1 = var1 / 262144;
+ var1 = ((32768 + var1) * (int32_t) dev->calib.par_p1) / 32768;
+ calc_pres = (int32_t) (1048576 - pres_adc);
+ calc_pres = (int32_t) ((calc_pres - (var2 / 4096)) * (3125));
+ calc_pres = ((calc_pres / var1) * 2);
+ var1 = ((int32_t) dev->calib.par_p9 * (int32_t) (((calc_pres / 8) * (calc_pres / 8)) / 8192)) / 4096;
+ var2 = ((int32_t) (calc_pres / 4) * (int32_t) dev->calib.par_p8) / 8192;
+ var3 = ((int32_t) (calc_pres / 256) * (int32_t) (calc_pres / 256) * (int32_t) (calc_pres / 256)
+ * (int32_t) dev->calib.par_p10) / 131072;
+ calc_pres = (int32_t) (calc_pres) + ((var1 + var2 + var3 + ((int32_t) dev->calib.par_p7 * 128)) / 16);
+
+ return (uint32_t) calc_pres;
+}
+
+/*!
+ * @brief This internal API is used to calculate the humidity value.
+ */
+static uint32_t calc_humidity(uint16_t hum_adc, const struct bme680_dev *dev)
+{
+ int32_t var1;
+ int32_t var2;
+ int32_t var3;
+ int32_t var4;
+ int32_t var5;
+ int32_t var6;
+ int32_t temp_scaled;
+ int32_t calc_hum;
+
+ temp_scaled = (((int32_t) dev->calib.t_fine * 5) + 128) / 256;
+ var1 = (int32_t) (hum_adc - ((int32_t) ((int32_t) dev->calib.par_h1 * 16)))
+ - (((temp_scaled * (int32_t) dev->calib.par_h3) / ((int32_t) 100)) / 2);
+ var2 = ((int32_t) dev->calib.par_h2
+ * (((temp_scaled * (int32_t) dev->calib.par_h4) / ((int32_t) 100))
+ + (((temp_scaled * ((temp_scaled * (int32_t) dev->calib.par_h5) / ((int32_t) 100))) / 64)
+ / ((int32_t) 100)) + (int32_t) (1 * 16384))) / 1024;
+ var3 = var1 * var2;
+ var4 = (int32_t) dev->calib.par_h6 * 128;
+ var4 = ((var4) + ((temp_scaled * (int32_t) dev->calib.par_h7) / ((int32_t) 100))) / 16;
+ var5 = ((var3 / 16384) * (var3 / 16384)) / 1024;
+ var6 = (var4 * var5) / 2;
+ calc_hum = (((var3 + var6) / 1024) * ((int32_t) 1000)) / 4096;
+
+ if (calc_hum > 100000) /* Cap at 100%rH */
+ calc_hum = 100000;
+ else if (calc_hum < 0)
+ calc_hum = 0;
+
+ return (uint32_t) calc_hum;
+}
+
+/*!
+ * @brief This internal API is used to calculate the Gas Resistance value.
+ */
+static uint32_t calc_gas_resistance(uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev)
+{
+ int64_t var1;
+ uint64_t var2;
+ int64_t var3;
+ uint32_t calc_gas_res;
+
+ var1 = (int64_t) ((1340 + (5 * (int64_t) dev->calib.range_sw_err)) * ((int64_t) lookupTable1[gas_range])) / 65536;
+ var2 = (((int64_t) ((int64_t) gas_res_adc * 32768) - (int64_t) (16777216)) + var1);
+ var3 = (((int64_t) lookupTable2[gas_range] * (int64_t) var1) / 512);
+ calc_gas_res = (uint32_t) ((var3 + ((int64_t) var2 / 2)) / (int64_t) var2);
+
+ return calc_gas_res;
+}
+
+/*!
+ * @brief This internal API is used to calculate the Heat Resistance value.
+ */
+static uint8_t calc_heater_res(uint16_t temp, const struct bme680_dev *dev)
+{
+ uint8_t heatr_res;
+ int32_t var1;
+ int32_t var2;
+ int32_t var3;
+ int32_t var4;
+ int32_t var5;
+ int32_t heatr_res_x100;
+
+ if (temp < 200) /* Cap temperature */
+ temp = 200;
+ else if (temp > 400)
+ temp = 400;
+
+ var1 = (((int32_t) dev->amb_temp * dev->calib.par_gh3) / 1000) * 256;
+ var2 = (dev->calib.par_gh1 + 784) * (((((dev->calib.par_gh2 + 154009) * temp * 5) / 100) + 3276800) / 10);
+ var3 = var1 + (var2 / 2);
+ var4 = (var3 / (dev->calib.res_heat_range + 4));
+ var5 = (131 * dev->calib.res_heat_val) + 65536;
+ heatr_res_x100 = (int32_t) (((var4 / var5) - 250) * 34);
+ heatr_res = (uint8_t) ((heatr_res_x100 + 50) / 100);
+
+ return heatr_res;
+}
+
+/*!
+ * @brief This internal API is used to calculate the Heat duration value.
+ */
+static uint8_t calc_heater_dur(uint16_t dur)
+{
+ uint8_t factor = 0;
+ uint8_t durval;
+
+ if (dur >= 0xfc0) {
+ durval = 0xff; /* Max duration*/
} else {
- temp_index = index + 2;
+ while (dur > 0x3F) {
+ dur = dur / 4;
+ factor += 1;
+ }
+ durval = (uint8_t) (dur + (factor * 64));
}
- return temp_index;
+ return durval;
}
+
/*!
- * @brief This function is used to uncompensated data
- * for the specified sensor type and called from the
- * function bme680_align_uncomp_data()
- *
- * @param a_data_u8 : pointer to buffer
- * @param index : index value
- * @param offset : offset value
- * @param uncomp_data : Pointer to array of structure which
- * contains the uncompensated TPHG data
- * @param sensor_type : type of sensor which needs
- * to be compensated.
- *
- * sensor_type | Expected values
- * ---------------------|-------------------
- * BME680_ALL | TPGH data
- * BME680_PRESSURE | Pressure data
- * BME680_TEMPERATURE| Temp data
- * BME680_HUMIDITY | Humidity data
- * BME680_GAS | Gas data
- *
- * @note : pressure and humidity depends on temperature.
- *
- * @param bme680 structure pointer.
- *
- * @return - None
- *
- *
-*/
-
-static void bme680_align_sensor_type_uncomp_data(u8 *a_data_u8, u8 index,
- u8 offset, u8 sensor_type,
- struct bme680_uncomp_field_data *uncomp_data)
+ * @brief This internal API is used to calculate the field data of sensor.
+ */
+static int8_t read_field_data(struct bme680_field_data *data, struct bme680_dev *dev)
{
+ int8_t rslt;
+ uint8_t buff[BME680_FIELD_LENGTH] = { 0 };
+ uint8_t gas_range;
+ uint32_t adc_temp;
+ uint32_t adc_pres;
+ uint16_t adc_hum;
+ uint16_t adc_gas_res;
+ uint8_t tries = 10;
- switch (sensor_type) {
- case BME680_PRESSURE:
- /* uncompensated field zero
- temperature data*/
- (uncomp_data + index)->temp_adcv = (u32)(((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_MSB_DATA + offset]))
- << 12) | ((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_LSB_DATA + offset]))
- << 4) | ((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_XLSB_DATA + offset]
- >> 4));
- /* uncompensated field zero
- pressure data*/
- (uncomp_data + index)->pres_adcv = (u32)(((((u32)a_data_u8[
- BME680_DATA_FRAME_PRESSURE_MSB_DATA + offset])) << 12) |
- ((((u32)a_data_u8[BME680_DATA_FRAME_PRESSURE_LSB_DATA
- + offset])) << 4) | ((u32)a_data_u8[
- BME680_DATA_FRAME_PRESSURE_XLSB_DATA + offset] >> 4));
- break;
- case BME680_TEMPERATURE:
- /* uncompensated field zero
- temperature data*/
- (uncomp_data + index)->temp_adcv = (u32)(((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_MSB_DATA + offset]))
- << 12) | ((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_LSB_DATA + offset]))
- << 4) | ((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_XLSB_DATA + offset]
- >> 4));
- break;
- case BME680_HUMIDITY:
- /* uncompensated field zero
- temperature data*/
- (uncomp_data + index)->temp_adcv = (u32)(((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_MSB_DATA + offset]))
- << 12) | ((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_LSB_DATA + offset]))
- << 4) | ((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_XLSB_DATA + offset]
- >> 4));
- /* uncompensated field zero
- humidity data*/
- (uncomp_data + index)->hum_adcv = (u16)(((((u16)a_data_u8[
- BME680_DATA_FRAME_HUMIDITY_MSB_DATA + offset])) << 8)|
- ((a_data_u8[BME680_DATA_FRAME_HUMIDITY_LSB_DATA +
- offset])));
- break;
- case BME680_GAS:
- /* Gas values are updated
- only if gas valid is set */
- /* uncompensated field zero Gas data*/
- if (BME680_TRUE == (uncomp_data + index)->status.gas_valid) {
- (uncomp_data + index)->gas_res_adcv =
- (u16)(((((u16)a_data_u8[
- BME680_DATA_FRAME_GAS_MSB_DATA + offset])) << 2)
- | ((((u16)a_data_u8[
- BME680_DATA_FRAME_GAS_LSB_DATA + offset])
- & BME680_GAS_BIT_MASK) >> 6));
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ do {
+ if (rslt == BME680_OK) {
+ rslt = bme680_get_regs(((uint8_t) (BME680_FIELD0_ADDR)), buff, (uint16_t) BME680_FIELD_LENGTH, dev);
+
+ data->status = buff[0] & BME680_NEW_DATA_MSK;
+ data->gas_index = buff[0] & BME680_GAS_INDEX_MSK;
+ data->meas_index = buff[1];
+
+ /* read the raw data from the sensor */
+ adc_pres = (uint32_t) (((uint32_t) buff[2] * 4096) | ((uint32_t) buff[3] * 16) | ((uint32_t) buff[4] / 16));
+ adc_temp = (uint32_t) (((uint32_t) buff[5] * 4096) | ((uint32_t) buff[6] * 16) | ((uint32_t) buff[7] / 16));
+ adc_hum = (uint16_t) (((uint32_t) buff[8] * 256) | (uint32_t) buff[9]);
+ adc_gas_res = (uint16_t) ((uint32_t) buff[13] * 4 | (((uint32_t) buff[14]) / 64));
+ gas_range = buff[14] & BME680_GAS_RANGE_MSK;
+
+ data->status |= buff[14] & BME680_GASM_VALID_MSK;
+ data->status |= buff[14] & BME680_HEAT_STAB_MSK;
+
+ if (data->status & BME680_NEW_DATA_MSK) {
+ data->temperature = calc_temperature(adc_temp, dev);
+ data->pressure = calc_pressure(adc_pres, dev);
+ data->humidity = calc_humidity(adc_hum, dev);
+ data->gas_resistance = calc_gas_resistance(adc_gas_res, gas_range, dev);
+ break;
+ } else {
+ dev->delay_ms(BME680_POLL_PERIOD_MS);
+ }
}
- break;
- case BME680_ALL:
- /* uncompensated field zero
- pressure data*/
- (uncomp_data + index)->pres_adcv = (u32)
- (((((u32)a_data_u8[BME680_DATA_FRAME_PRESSURE_MSB_DATA +
- offset])) << 12) | ((((u32)a_data_u8[
- BME680_DATA_FRAME_PRESSURE_LSB_DATA + offset])) << 4) |
- ((u32)a_data_u8[BME680_DATA_FRAME_PRESSURE_XLSB_DATA +
- offset] >> 4));
- /* uncompensated field zero
- temperature data*/
- (uncomp_data + index)->temp_adcv = (u32)(((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_MSB_DATA + offset]))
- << 12) | ((((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_LSB_DATA + offset]))
- << 4) | ((u32)a_data_u8[
- BME680_DATA_FRAME_TEMPERATURE1_XLSB_DATA + offset]
- >> 4));
- /* uncompensated field zero
- humidity data*/
- (uncomp_data + index)->hum_adcv = (u16)(((((u16)a_data_u8[
- BME680_DATA_FRAME_HUMIDITY_MSB_DATA + offset])) << 8)|
- ((a_data_u8[BME680_DATA_FRAME_HUMIDITY_LSB_DATA +
- offset])));
- /* Gas values are updated
- only if gas valid is set */
- /* uncompensated field zero Gas data*/
- if (BME680_TRUE == (uncomp_data + index)->status.gas_valid) {
- (uncomp_data + index)->gas_res_adcv =
- (u16)(((((u16)a_data_u8[
- BME680_DATA_FRAME_GAS_MSB_DATA
- + offset])) << 2) | ((((u16)a_data_u8[
- BME680_DATA_FRAME_GAS_LSB_DATA + offset]) &
- BME680_GAS_BIT_MASK) >> 6));
+ tries--;
+ } while (tries);
+
+ if (!tries)
+ rslt = BME680_W_NO_NEW_DATA;
+
+ return rslt;
+}
+
+/*!
+ * @brief This internal API is used to set the memory page based on register address.
+ */
+static int8_t set_mem_page(uint8_t reg_addr, struct bme680_dev *dev)
+{
+ int8_t rslt;
+ uint8_t reg;
+ uint8_t mem_page;
+
+ /* Check for null pointers in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ if (reg_addr > 0x7f)
+ mem_page = BME680_MEM_PAGE1;
+ else
+ mem_page = BME680_MEM_PAGE0;
+
+ if (mem_page != dev->mem_page) {
+ dev->mem_page = mem_page;
+
+ dev->com_rslt = dev->read(dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, ®, 1);
+ if (dev->com_rslt != 0)
+ rslt = BME680_E_COM_FAIL;
+
+ if (rslt == BME680_OK) {
+ reg = reg & (~BME680_MEM_PAGE_MSK);
+ reg = reg | (dev->mem_page & BME680_MEM_PAGE_MSK);
+
+ dev->com_rslt = dev->write(dev->dev_id, BME680_MEM_PAGE_ADDR & BME680_SPI_WR_MSK, ®, 1);
+ if (dev->com_rslt != 0)
+ rslt = BME680_E_COM_FAIL;
+ }
}
- break;
}
+ return rslt;
}
-
-static void bme680_packing_calib_param(u8 *a_data_u8, struct bme680_t *bme680)
+/*!
+ * @brief This internal API is used to get the memory page based on register address.
+ */
+static int8_t get_mem_page(struct bme680_dev *dev)
{
+ int8_t rslt;
+ uint8_t reg;
- /* read temperature calibration*/
- bme680->cal_param.par_T1 = (u16)((((u16)(a_data_u8[DIG_T1_MSB_REG]))
- << 8) | a_data_u8[DIG_T1_LSB_REG]);
- bme680->cal_param.par_T2 = (s16)(((((u16)a_data_u8[DIG_T2_MSB_REG]))
- << 8) | a_data_u8[DIG_T2_LSB_REG]);
- bme680->cal_param.par_T3 = (s8)(a_data_u8[DIG_T3_REG]);
-
- /* read pressure calibration*/
- bme680->cal_param.par_P1 = (u16)((((u16)(a_data_u8[DIG_P1_MSB_REG])) <<
- 8) | a_data_u8[DIG_P1_LSB_REG]);
- bme680->cal_param.par_P2 = (s16)(((((u16)a_data_u8[DIG_P2_MSB_REG]))
- << 8) | a_data_u8[DIG_P2_LSB_REG]);
- bme680->cal_param.par_P3 = (s8)a_data_u8[DIG_P3_REG];
- bme680->cal_param.par_P4 = (s16)(((((u16)a_data_u8[DIG_P4_MSB_REG]))
- << 8) | a_data_u8[DIG_P4_LSB_REG]);
- bme680->cal_param.par_P5 = (s16)(((((u16)a_data_u8[DIG_P5_MSB_REG]))
- << 8) | a_data_u8[DIG_P5_LSB_REG]);
- bme680->cal_param.par_P6 = (s8)(a_data_u8[DIG_P6_REG]);
- bme680->cal_param.par_P7 = (s8)(a_data_u8[DIG_P7_REG]);
- bme680->cal_param.par_P8 = (s16)(((((u16)a_data_u8[DIG_P8_MSB_REG]))
- << 8) | a_data_u8[DIG_P8_LSB_REG]);
- bme680->cal_param.par_P9 = (s16)(((((u16)a_data_u8[DIG_P9_MSB_REG]))
- << 8) | a_data_u8[DIG_P9_LSB_REG]);
- bme680->cal_param.par_P10 = (u8)(a_data_u8[DIG_P10_REG]);
-
- /* read humidity calibration*/
- bme680->cal_param.par_H1 = (u16)(((((u16)a_data_u8[DIG_H1_MSB_REG]))
- << 4) | (a_data_u8[DIG_H1_LSB_REG] & BME680_BIT_MASK_H1_DATA));
- bme680->cal_param.par_H2 = (u16)(((((u16)a_data_u8[DIG_H2_MSB_REG]))
- << 4) | ((a_data_u8[DIG_H2_LSB_REG]) >> 4));
- bme680->cal_param.par_H3 = (s8)a_data_u8[DIG_H3_REG];
- bme680->cal_param.par_H4 = (s8) a_data_u8[DIG_H4_REG];
- bme680->cal_param.par_H5 = (s8) a_data_u8[DIG_H5_REG];
- bme680->cal_param.par_H6 = (u8)a_data_u8[DIG_H6_REG];
- bme680->cal_param.par_H7 = (s8)a_data_u8[DIG_H7_REG];
-
- /* read gas calibration*/
- bme680->cal_param.par_GH1 = (s8)a_data_u8[DIG_GH1_REG];
- bme680->cal_param.par_GH2 = (s16)(((((u16)a_data_u8[DIG_GH2_MSB_REG]))
- <<8) | a_data_u8[DIG_GH2_LSB_REG]);
- bme680->cal_param.par_GH3 = (s8)a_data_u8[DIG_GH3_REG];
+ /* Check for null pointer in the device structure*/
+ rslt = null_ptr_check(dev);
+ if (rslt == BME680_OK) {
+ dev->com_rslt = dev->read(dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, ®, 1);
+ if (dev->com_rslt != 0)
+ rslt = BME680_E_COM_FAIL;
+ else
+ dev->mem_page = reg & BME680_MEM_PAGE_MSK;
+ }
+ return rslt;
}
+/*!
+ * @brief This internal API is used to validate the boundary
+ * conditions.
+ */
+static int8_t boundary_check(uint8_t *value, uint8_t min, uint8_t max, struct bme680_dev *dev)
+{
+ int8_t rslt = BME680_OK;
+
+ if (value != NULL) {
+ /* Check if value is below minimum value */
+ if (*value < min) {
+ /* Auto correct the invalid value to minimum value */
+ *value = min;
+ dev->info_msg |= BME680_I_MIN_CORRECTION;
+ }
+ /* Check if value is above maximum value */
+ if (*value > max) {
+ /* Auto correct the invalid value to maximum value */
+ *value = max;
+ dev->info_msg |= BME680_I_MAX_CORRECTION;
+ }
+ } else {
+ rslt = BME680_E_NULL_PTR;
+ }
+
+ return rslt;
+}
+
+/*!
+ * @brief This internal API is used to validate the device structure pointer for
+ * null conditions.
+ */
+static int8_t null_ptr_check(const struct bme680_dev *dev)
+{
+ int8_t rslt;
+
+ if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_ms == NULL)) {
+ /* Device structure pointer is not valid */
+ rslt = BME680_E_NULL_PTR;
+ } else {
+ /* Device structure is fine */
+ rslt = BME680_OK;
+ }
+
+ return rslt;
+}
diff --git a/bme680.h b/bme680.h
index a309c18..38b8628 100644
--- a/bme680.h
+++ b/bme680.h
@@ -1,667 +1,225 @@
/**
-*
-****************************************************************************
-* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
-*
-* File : bme680.h
-*
-* Date: 5 May 2017
-*
-* Revision : 2.2.0 $
-*
-* Usage: Sensor Driver for BME680 sensor
-*
-****************************************************************************
-*
-* \section Disclaimer
-*
-* Common:
-* Bosch Sensortec products are developed for the consumer goods industry.
-* They may only be used within the parameters of the respective valid
-* product data sheet. Bosch Sensortec products are provided with the
-* express understanding that there is no warranty of fitness for a
-* particular purpose.They are not fit for use in life-sustaining,
-* safety or security sensitive systems or any system or device
-* that may lead to bodily harm or property damage if the system
-* or device malfunctions. In addition,Bosch Sensortec products are
-* not fit for use in products which interact with motor vehicle systems.
-* The resale and or use of products are at the purchasers own risk and
-* his own responsibility. The examination of fitness for the intended use
-* is the sole responsibility of the Purchaser.
-*
-* The purchaser shall indemnify Bosch Sensortec from all third party
-* claims, including any claims for incidental, or consequential damages,
-* arising from any product use not covered by the parameters of
-* the respective valid product data sheet or not approved by
-* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
-* connection with such claims.
-*
-* The purchaser must monitor the market for the purchased products,
-* particularly with regard to product safety and inform Bosch Sensortec
-* without delay of all security relevant incidents.
-*
-* Engineering Samples are marked with an asterisk (*) or (e).
-* Samples may vary from the valid technical specifications of the product
-* series. They are therefore not intended or fit for resale to third
-* parties or for use in end products. Their sole purpose is internal
-* client testing. The testing of an engineering sample may in no way
-* replace the testing of a product series. Bosch Sensortec assumes
-* no liability for the use of engineering samples.
-* By accepting the engineering samples, the Purchaser agrees to indemnify
-* Bosch Sensortec from all claims arising from the use of engineering
-* samples.
-*
-* Special:
-* This software module (hereinafter called "Software") and any information
-* on application-sheets (hereinafter called "Information") is provided
-* free of charge for the sole purpose to support your application work.
-* The Software and Information is subject to the following
-* terms and conditions:
-*
-* The Software is specifically designed for the exclusive use for
-* Bosch Sensortec products by personnel who have special experience
-* and training. Do not use this Software if you do not have the
-* proper experience or training.
-*
-* This Software package is provided `` as is `` and without any expressed
-* or implied warranties,including without limitation, the implied warranties
-* of merchantability and fitness for a particular purpose.
-*
-* Bosch Sensortec and their representatives and agents deny any liability
-* for the functional impairment
-* of this Software in terms of fitness, performance and safety.
-* Bosch Sensortec and their representatives and agents shall not be liable
-* for any direct or indirect damages or injury, except as
-* otherwise stipulated in mandatory applicable law.
-*
-* The Information provided is believed to be accurate and reliable.
-* Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are
-* subject to change without notice.
-**************************************************************************/
-/*! \file bme680.h
- \brief BME680 Sensor Driver Support Header File */
-
-#ifndef __BME680_H__
-#define __BME680_H__
+ * 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
-/* BME680 Release version 2.0.0
-BME680 Release Version format major_version.minor_version.point_version
-Example: 2.0.0 */
-#define BME680_API_REL_MAJOR_VERSION (2)
-#define BME680_API_REL_MINOR_VERSION (0)
-#define BME680_API_REL_POINT_VERSION (1)
-
-/***************************************************************************
- Header files
-****************************************************************************/
-#include "sensor_api_common_types.h"
-
-
-/* sensor_api_common_types.h */
-
-/************************************************************************
- Macros, Enums, Constants
-*************************************************************************/
-#define BME680_PRESSURE (0U)
-#define BME680_TEMPERATURE (1U)
-#define BME680_HUMIDITY (2U)
-#define BME680_GAS (3U)
-#define BME680_ALL (4U)
-
-#define BME680_STATUS_DATA_LEN (2U)
-#define BME680_TEMPERATURE_DATA_LEN (3U)
-#define BME680_PRESSURE_DATA_LEN (3U)
-#define BME680_GAS_DATA_LEN (2U)
-#define BME680_HUMIDITY_DATA_LEN (2U)
-
-#define BME680_PRESENT_DATA_FIELD (1U)
-#define BME680_PRESENT_AND_PREVIOUS_DATA_FIELD (2U)
-#define BME680_ALL_DATA_FIELD (3U)
-
-#define BME680_MAX_FIELD_INDEX (3U)
-#define BME680_FIELD_INDEX0 (0U)
-#define BME680_FIELD_INDEX1 (1U)
-#define BME680_FIELD_INDEX2 (2U)
-
-/***************************************************************/
-/**\name BUS READ AND WRITE FUNCTION POINTERS */
-/***************************************************************/
-
-
-/**< function pointer to the SPI or I2C burst read function */
-typedef s8 (*sensor_burst_read)(u8 slave_addr, u8 reg_addr, u8 *data_u8,
- u32 length_u32);
-
-typedef s8 (*sensor_write)(u8 dev_addr, u8 reg_addr, u8 *reg_data_ptr,
- u8 data_len);
-/**< function pointer for Write operation in either I2C or SPI*/
-typedef s8 (*sensor_read)(u8 dev_addr, u8 reg_addr, u8 *reg_data_ptr,
- u8 data_len);
-/**< function pointer for Read operation in either I2C or SPI*/
-
-#define BME680_MAX_NO_OF_SENSOR (2)
-/**< This macro used for maximum number of sensor*/
-
-#define BME680_MDELAY_DATA_TYPE u32
-/**< This macro used for delay*/
-
-#define BME680_CHIP_ID (0x61)
-/**< BME680 chip identifier */
-
-#define BME680_SPECIFIC_FIELD_DATA_READ_ENABLED
-/**< This macro is used to prevent the compilation
-of single function calls when not used */
-
-/*
- * Use below macro for fixed Point Calculation
- * else Floating Point calculation will be used
-*/
-
-/* #define FIXED_POINT_COMPENSATION */
-
-/* temperature to Resistance formulae #defines */
-
-/*
- * Use any of the below constants according to
- * the heater version of the sensor used
-*/
-
-#define HEATER_C1_ENABLE
-
-/* Sensor Specific constants */
-#define BME680_SLEEP_MODE (0x00)
-#define BME680_FORCED_MODE (0x01)
-#define BME680_PARALLEL_MODE (0x02)
-#define BME680_SEQUENTIAL_MODE (0x03)
-#define BME680_GAS_PROFILE_TEMPERATURE_MIN (200)
-#define BME680_GAS_PROFILE_TEMPERATURE_MAX (400)
-#define BME680_GAS_RANGE_RL_LENGTH (16)
-#define BME680_SIGN_BIT_MASK (0x08)
-
-#ifdef FIXED_POINT_COMPENSATION
-/**< Multiply by 1000, In order to convert
-float value into fixed point */
-#define BME680_MAX_HUMIDITY_VALUE (102400)
-#define BME680_MIN_HUMIDITY_VALUE (0)
-#else
-#define BME680_MAX_HUMIDITY_VALUE (double)(100.0)
-#define BME680_MIN_HUMIDITY_VALUE (double)(0.0)
-#endif
-
-/* BME680 I2C addresses */
-#define BME680_I2C_ADDR_PRIMARY (0x76)
-#define BME680_I2C_ADDR_SECONDARY (0x77)
-
-/* Maximum no of gas profiles to be used */
-#define BME680_MAX_PROFILES (10)
-
-
-/**************************************************************/
-/**\name Interface selection macro */
-/*************************************************************/
-
-#define BME680_SPI_INTERFACE (1)
-#define BME680_I2C_INTERFACE (2)
-
-
-
-/* bme680_internal.h */
-
-/***************************************************************/
-/**\name COMMON USED CONSTANTS */
-/***************************************************************/
-/* Constants */
-#define BME680_NULL_PTR ((void *)0)
-#define BME680_RETURN_FUNCTION_TYPE s8
-
-/* Section 3.5: Function macros */
-#define BME680_SET_REG(reg, data, mask, shift)\
- ((reg & mask) | ((data << shift) & ~mask))
-#define BME680_GET_REG(reg, mask, shift)\
- ((reg & ~mask) >> shift)
-#define DIFF(a, b) ((a > b)?(a - b):(b - a))
-
-
-/*************************************************************
- Module globals, typedefs
-**************************************************************/
+/* Header includes */
+#include "bme680_defs.h"
+/* function prototype declarations */
/*!
- * @brief This structure holds all
- * calibration parameters
- */
-struct bme680_calibration_param_t {
-
- s8 par_T3;/** Success / +ve value -> Warning / -ve value -> Error
+ */
+int8_t bme680_init(struct bme680_dev *dev);
/*!
- * @brief This function is used to Align uncompensated data
- * from function bme680_get_uncomp_data()
-*/
-void bme680_align_uncomp_data(u8 *a_data_u8, u8 field_count, u8 sensor_type,
- struct bme680_uncomp_field_data *uncomp_data,
- struct bme680_t *bme680);
+ * @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 function is used to read the status according to filed index.
-*/
-enum bme680_return_type bme680_read_status_fields(
- struct bme680_uncomp_field_data *uncomp_data,
- u8 *a_data_u8, u8 *new_data,
- struct bme680_t *bme680);
-/* bme680_calculations.h */
+ * @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
-
-#endif
+#endif /* End of CPP guard */
+#endif /* BME680_H_ */
+/** @}*/
diff --git a/bme680_calculations.c b/bme680_calculations.c
deleted file mode 100644
index 130b028..0000000
--- a/bme680_calculations.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/**
-*
-****************************************************************************
-* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
-*
-* File : bme680_calculations.c
-*
-* Date: 5 May 2017
-*
-* Revision : 2.2.0 $
-*
-* Usage: Sensor Driver for BME680 sensor
-*
-****************************************************************************
-*
-* \section Disclaimer
-*
-* Common:
-* Bosch Sensortec products are developed for the consumer goods industry.
-* They may only be used within the parameters of the respective valid
-* product data sheet. Bosch Sensortec products are provided with the
-* express understanding that there is no warranty of fitness for a
-* particular purpose.They are not fit for use in life-sustaining,
-* safety or security sensitive systems or any system or device
-* that may lead to bodily harm or property damage if the system
-* or device malfunctions. In addition,Bosch Sensortec products are
-* not fit for use in products which interact with motor vehicle systems.
-* The resale and or use of products are at the purchasers own risk and
-* his own responsibility. The examination of fitness for the intended use
-* is the sole responsibility of the Purchaser.
-*
-* The purchaser shall indemnify Bosch Sensortec from all third party
-* claims, including any claims for incidental, or consequential damages,
-* arising from any product use not covered by the parameters of
-* the respective valid product data sheet or not approved by
-* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
-* connection with such claims.
-*
-* The purchaser must monitor the market for the purchased products,
-* particularly with regard to product safety and inform Bosch Sensortec
-* without delay of all security relevant incidents.
-*
-* Engineering Samples are marked with an asterisk (*) or (e).
-* Samples may vary from the valid technical specifications of the product
-* series. They are therefore not intended or fit for resale to third
-* parties or for use in end products. Their sole purpose is internal
-* client testing. The testing of an engineering sample may in no way
-* replace the testing of a product series. Bosch Sensortec assumes
-* no liability for the use of engineering samples.
-* By accepting the engineering samples, the Purchaser agrees to indemnify
-* Bosch Sensortec from all claims arising from the use of engineering
-* samples.
-*
-* Special:
-* This software module (hereinafter called "Software") and any information
-* on application-sheets (hereinafter called "Information") is provided
-* free of charge for the sole purpose to support your application work.
-* The Software and Information is subject to the following
-* terms and conditions:
-*
-* The Software is specifically designed for the exclusive use for
-* Bosch Sensortec products by personnel who have special experience
-* and training. Do not use this Software if you do not have the
-* proper experience or training.
-*
-* This Software package is provided `` as is `` and without any expressed
-* or implied warranties,including without limitation, the implied warranties
-* of merchantability and fitness for a particular purpose.
-*
-* Bosch Sensortec and their representatives and agents deny any liability
-* for the functional impairment
-* of this Software in terms of fitness, performance and safety.
-* Bosch Sensortec and their representatives and agents shall not be liable
-* for any direct or indirect damages or injury, except as
-* otherwise stipulated in mandatory applicable law.
-*
-* The Information provided is believed to be accurate and reliable.
-* Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are
-* subject to change without notice.
-**************************************************************************/
-/*! \file bme680_calculations.c
- \brief BME680 Sensor Driver calculation source File */
-
-/***************************************************************************
- Header files
-****************************************************************************/
-#include "bme680_calculations.h"
-
-
-/***************************************************************************
- Macros, Enums, Constants
-****************************************************************************/
-
-
-/***************************************************************************
- File globals, typedefs
-****************************************************************************/
-
-
-/***************************************************************************
- Function definitions
-****************************************************************************/
-/* bme680.c */
-#ifdef FIXED_POINT_COMPENSATION
-/*!
- * @brief This function is used to convert uncompensated gas data to
- * compensated gas data using compensation formula(integer version)
- *
- * @param gas_adc_u16: The value of gas resistance calculated
- * using temperature
- * @param gas_range_u8: The value of gas range form register value
- * @param bme680: structure pointer.
- *
- * @return calculated compensated gas from compensation formula
- * @retval compensated gas data
- *
- *
-*/
-s32 bme680_calculate_gas_int32(u16 gas_adc_u16, u8 gas_range_u8,
- struct bme680_t *bme680)
-{
- s8 range_switching_error_val = 0;
- s64 var1 = 0;
- s64 var2 = 0;
- s32 gas_res = 0;
-
-
-
- const u64 lookup_k1_range[BME680_GAS_RANGE_RL_LENGTH] = {
- 2147483647UL, 2147483647UL, 2147483647UL, 2147483647UL, 2147483647UL,
- 2126008810UL, 2147483647UL, 2130303777UL, 2147483647UL, 2147483647UL,
- 2143188679UL, 2136746228UL, 2147483647UL, 2126008810UL, 2147483647UL,
- 2147483647UL};
-
- const u64 lookup_k2_range[BME680_GAS_RANGE_RL_LENGTH] = {
- 4096000000UL, 2048000000UL, 1024000000UL, 512000000UL,
- 255744255UL, 127110228UL, 64000000UL, 32258064UL, 16016016UL,
- 8000000UL, 4000000UL, 2000000UL, 1000000UL, 500000UL, 250000UL,
- 125000UL};
-
-
-
- range_switching_error_val =
- bme680->cal_param.range_switching_error;
-
-
- var1 = (s64)((1340 + (5 * (s64)range_switching_error_val)) *
- ((s64)lookup_k1_range[gas_range_u8])) >> 16;
- var2 = (s64)((s64)gas_adc_u16 << 15) - (s64)(1 << 24) + var1;
- #ifndef __KERNEL__
- gas_res = (s32)(((((s64)lookup_k2_range[gas_range_u8] *
- (s64)var1) >> 9) + (var2 >> 1)) / var2);
- #else
- gas_res = (s32)(div64_s64(((((s64)lookup_k2_range[gas_range_u8] *
- (s64)var1) >> 9) + (var2 >> 1)), var2));
- #endif
- return gas_res;
-}
-/*!
- * @brief This function is used to convert the uncompensated
- * temperature data to compensated temperature data using
- * compensation formula(integer version)
- * @note Returns the value in 0.01 degree Centigrade
- * Output value of "5123" equals 51.23 DegC.
- *
- *
- *
- * @param v_uncomp_temperature_u32 : value of uncompensated temperature
- * @param bme680: structure pointer.
- *
- * @return Returns the compensated temperature data
- *
-*/
-s32 bme680_compensate_temperature_int32(u32 v_uncomp_temperature_u32,
- struct bme680_t *bme680)
-{
- s32 var1 = 0;
- s32 var2 = 0;
- s32 var3 = 0;
- s32 temp_comp = 0;
-
- var1 = ((s32)v_uncomp_temperature_u32 >> 3) -
- ((s32)bme680->cal_param.par_T1 << 1);
- var2 = (var1 * (s32)bme680->cal_param.par_T2) >> 11;
- var3 = ((((var1 >> 1) * (var1 >> 1)) >> 12) *
- ((s32)bme680->cal_param.par_T3 << 4)) >> 14;
- bme680->cal_param.t_fine = var2 + var3;
- temp_comp = ((bme680->cal_param.t_fine * 5) + 128) >> 8;
-
- return temp_comp;
-
-}
-
-/*!
- * @brief This function is used to convert the uncompensated
- * humidity data to compensated humidity data using
- * compensation formula(integer version)
- *
- * @note Returns the value in %rH as unsigned 32bit integer
- * in Q22.10 format(22 integer 10 fractional bits).
- * @note An output value of 42313
- * represents 42313 / 1024 = 41.321 %rH
- *
- *
- *
- * @param v_uncomp_humidity_u32: value of uncompensated humidity
- * @param bme680: structure pointer.
- *
- * @return Return the compensated humidity data
- *
-*/
-s32 bme680_compensate_humidity_int32(u32 v_uncomp_humidity_u32,
- struct bme680_t *bme680)
-{
- s32 temp_scaled = 0;
- s32 var1 = 0;
- s32 var2 = 0;
- s32 var3 = 0;
- s32 var4 = 0;
- s32 var5 = 0;
- s32 var6 = 0;
- s32 humidity_comp = 0;
-
- temp_scaled = (((s32)bme680->cal_param.t_fine * 5) + 128) >> 8;
- var1 = (s32)v_uncomp_humidity_u32 -
- ((s32)((s32)bme680->cal_param.par_H1 << 4)) -
- (((temp_scaled * (s32)bme680->cal_param.par_H3) /
- ((s32)100)) >> 1);
-
- var2 = ((s32)bme680->cal_param.par_H2 *
- (((temp_scaled * (s32)bme680->cal_param.par_H4) /
- ((s32)100)) + (((temp_scaled *
- ((temp_scaled * (s32)bme680->cal_param.par_H5) /
- ((s32)100))) >> 6) / ((s32)100)) + (s32)(1 << 14))) >> 10;
-
- var3 = var1 * var2;
-
- var4 = ((((s32)bme680->cal_param.par_H6) << 7) +
- ((temp_scaled * (s32)bme680->cal_param.par_H7) /
- ((s32)100))) >> 4;
-
- var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
- var6 = (var4 * var5) >> 1;
-
- humidity_comp = (var3 + var6) >> 12;
- if (humidity_comp > BME680_MAX_HUMIDITY_VALUE)
- humidity_comp = BME680_MAX_HUMIDITY_VALUE;
- else if (humidity_comp < BME680_MIN_HUMIDITY_VALUE)
- humidity_comp = BME680_MIN_HUMIDITY_VALUE;
-
- return humidity_comp;
-}
-
-
-/*!
- * @brief This function is used to convert the uncompensated
- * pressure data to compensated pressure data data using
- * compensation formula(integer version)
- *
- * @note Returns the value in Pascal(Pa)
- * Output value of "96386" equals 96386 Pa =
- * 963.86 hPa = 963.86 millibar
- *
- *
- *
- * @param v_uncomp_pressure_u32 : value of uncompensated pressure
- * @param bme680: structure pointer.
- *
- * @return Return the compensated pressure data
- *
-*/
-s32 bme680_compensate_pressure_int32(u32 v_uncomp_pressure_u32,
- struct bme680_t *bme680)
-{
- s32 var1 = 0;
- s32 var2 = 0;
- s32 var3 = 0;
- s32 var4 = 0;
- s32 pressure_comp = 0;
-
- var1 = (((s32)bme680->cal_param.t_fine) >> 1) - 64000;
- var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) *
- (s32)bme680->cal_param.par_P6) >> 2;
- var2 = var2 + ((var1 * (s32)bme680->cal_param.par_P5) << 1);
- var2 = (var2 >> 2) + ((s32)bme680->cal_param.par_P4 << 16);
- var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
- ((s32)bme680->cal_param.par_P3 << 5)) >> 3) +
- (((s32)bme680->cal_param.par_P2 * var1) >> 1);
- var1 = var1 >> 18;
- var1 = ((32768 + var1) * (s32)bme680->cal_param.par_P1) >> 15;
- pressure_comp = 1048576 - v_uncomp_pressure_u32;
- pressure_comp = (s32)((pressure_comp - (var2 >> 12)) * ((u32)3125));
- var4 = (1 << 31);
- if (pressure_comp >= var4)
- pressure_comp = ((pressure_comp / (u32)var1) << 1);
- else
- pressure_comp = ((pressure_comp << 1) / (u32)var1);
- var1 = ((s32)bme680->cal_param.par_P9 * (s32)(((pressure_comp >> 3) *
- (pressure_comp >> 3)) >> 13)) >> 12;
- var2 = ((s32)(pressure_comp >> 2) *
- (s32)bme680->cal_param.par_P8) >> 13;
- var3 = ((s32)(pressure_comp >> 8) * (s32)(pressure_comp >> 8) *
- (s32)(pressure_comp >> 8) *
- (s32)bme680->cal_param.par_P10) >> 17;
-
- pressure_comp = (s32)(pressure_comp) + ((var1 + var2 + var3 +
- ((s32)bme680->cal_param.par_P7 << 7)) >> 4);
-
- return pressure_comp;
-}
-/*!
- * @brief This function is used to convert temperature to resistance
- * using the integer compensation formula
- *
- * @param heater_temp_u16: The value of heater temperature
- * @param ambient_temp_s16: The value of ambient temperature
- * @param bme680: structure pointer.
- *
- * @return calculated resistance from temperature
- *
- *
- *
-*/
-u8 bme680_convert_temperature_to_resistance_int32(u16 heater_temp_u16,
- s16 ambient_temp_s16, struct bme680_t *bme680)
-{
- s32 var1 = 0;
- s32 var2 = 0;
- s32 var3 = 0;
- s32 var4 = 0;
- s32 var5 = 0;
- s32 res_heat_x100 = 0;
- u8 res_heat = 0;
-
-
- if ((heater_temp_u16 >= BME680_GAS_PROFILE_TEMPERATURE_MIN)
- && (heater_temp_u16 <= BME680_GAS_PROFILE_TEMPERATURE_MAX)) {
-
- var1 = (((s32)ambient_temp_s16 *
- bme680->cal_param.par_GH3) / 10) << 8;
- var2 = (bme680->cal_param.par_GH1 + 784) *
- (((((bme680->cal_param.par_GH2 + 154009) *
- heater_temp_u16 * 5) / 100) + 3276800) / 10);
- var3 = var1 + (var2 >> 1);
- var4 = (var3 / (bme680->cal_param.res_heat_range + 4));
-
- var5 = (131 * bme680->cal_param.res_heat_val) + 65536;
-
- res_heat_x100 = (s32)(((var4 / var5) - 250) * 34);
- res_heat = (u8) ((res_heat_x100 + 50) / 100);
-
- }
- return res_heat;
-}
-/*!
- * @brief Reads actual humidity from uncompensated humidity
- * @note Returns the value in %rH as unsigned 16bit integer
- * @note An output value of 42313
- * represents 42313/512 = 82.643 %rH
- *
- *
- *
- * @param v_uncomp_humidity_u32: value of uncompensated humidity
- * @param bme680: structure pointer.
- *
- * @return Return the actual relative humidity output as u16
- *
-*/
-u16 bme680_compensate_H_int32_sixteen_bit_output(u32 v_uncomp_humidity_u32,
- struct bme680_t *bme680)
-{
- u32 v_x1_u32 = 0;
- u16 v_x2_u32 = 0;
-
- v_x1_u32 = (u32) bme680_compensate_humidity_int32(
- v_uncomp_humidity_u32, bme680);
- v_x2_u32 = (u16)(v_x1_u32 >> 1);
- return v_x2_u32;
-}
-
-/*!
- * @brief Reads actual temperature from uncompensated temperature
- * @note Returns the value with 500LSB/DegC centred around 24 DegC
- * output value of "5123" equals(5123/500)+24 = 34.246DegC
- *
- *
- * @param v_uncomp_temperature_u32: value of uncompensated temperature
- * @param bme680: structure pointer.
- *
- *
- * @return Return the actual temperature as s16 output
- *
-*/
-s16 bme680_compensate_T_int32_sixteen_bit_output(u32 v_uncomp_temperature_u32,
- struct bme680_t *bme680)
-{
- s16 temperature = 0;
-
- bme680_compensate_temperature_int32(v_uncomp_temperature_u32, bme680);
- temperature = (s16)((((
- bme680->cal_param.t_fine - 122880) * 25) + 128) >> 8);
-
- return temperature;
-}
-
-/*!
- * @brief Reads actual pressure from uncompensated pressure
- * @note Returns the value in Pa.
- * @note Output value of "12337434"
- * @note represents 12337434 / 128 = 96386.2 Pa = 963.862 hPa
- *
- *
- *
- * @param v_uncomp_pressure_u32 : value of uncompensated pressure
- * @param bme680: structure pointer.
- *
- * @return the actual pressure in u32
- *
-*/
-u32 bme680_compensate_P_int32_twentyfour_bit_output(u32 v_uncomp_pressure_u32,
- struct bme680_t *bme680)
-{
- u32 pressure = 0;
-
- pressure = (u32)bme680_compensate_pressure_int32(
- v_uncomp_pressure_u32, bme680);
- pressure = (u32)(pressure >> 1);
- return pressure;
-}
-#else
-/*!
- * @brief This function is used to convert uncompensated gas data to
- * compensated gas data using compensation formula
- *
- * @param gas_adc_u16: The value of gas resistance calculated
- * using temperature
- * @param gas_range_u8: The value of gas range form register value
- * @param bme680: structure pointer.
- *
- * @return calculated compensated gas from compensation formula
- * @retval compensated gas
- *
- *
-*/
-
-double bme680_compensate_gas_double(u16 gas_adc_u16, u8 gas_range_u8,
- struct bme680_t *bme680)
-{
- double gas_res_d = 0;
-
-
-#ifdef HEATER_C1_ENABLE
-
- const double lookup_k1_range[BME680_GAS_RANGE_RL_LENGTH] = {
- 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,
- 0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0};
- const double lookup_k2_range[BME680_GAS_RANGE_RL_LENGTH] = {
- 0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,
- -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
- s8 range_switching_error_val = 0;
- double var1 = 0;
- double var2 = 0;
- double var3 = 0;
-
-
-
- range_switching_error_val =
- bme680->cal_param.range_switching_error;
-
-
- var1 = (1340.0 + (5.0 * range_switching_error_val));
- var2 = (var1) * (1.0 + lookup_k1_range[gas_range_u8]/100.0);
- var3 = 1.0 + (lookup_k2_range[gas_range_u8]/100.0);
-
- gas_res_d = 1.0 / (double)(var3 * (0.000000125) *
- (double)(1 << gas_range_u8)
- * (((((double)gas_adc_u16) - 512.00)/var2) + 1.0));
-
-#else
- gas_res_d = 1.0 / ((0.000000125) * (double)(1 << gas_range_u8) *
- ((((double)(gas_adc_u16) - 512.00) / 1365.3333) + 1.0));
-#endif
- return gas_res_d;
-}
-
-
-/*!
- * @brief This function is used to convert the uncompensated
- * humidity data to compensated humidity data data using
- * compensation formula
- * @note returns the value in relative humidity (%rH)
- * @note Output value of "42.12" equals 42.12 %rH
- *
- * @param uncom_humidity_u16 : value of uncompensated humidity
- * @param comp_temperature : value of compensated temperature
- * @param bme680: structure pointer.
- *
- *
- * @return Return the compensated humidity data in floating point
- *
-*/
-double bme680_compensate_humidity_double(u16 uncom_humidity_u16,
- double comp_temperature, struct bme680_t *bme680)
-{
- double humidity_comp = 0;
- double var1 = 0;
- double var2 = 0;
- double var3 = 0;
- double var4 = 0;
-
- var1 = (double)((double)uncom_humidity_u16) - (((double)
- bme680->cal_param.par_H1 * 16.0) +
- (((double)bme680->cal_param.par_H3 / 2.0)
- * comp_temperature));
-
- var2 = var1 * ((double)(
- ((double) bme680->cal_param.par_H2 / 262144.0)
- *(1.0 + (((double)bme680->cal_param.par_H4 / 16384.0)
- * comp_temperature) + (((double)bme680->cal_param.par_H5
- / 1048576.0) * comp_temperature
- * comp_temperature))));
- var3 = (double) bme680->cal_param.par_H6 / 16384.0;
- var4 = (double) bme680->cal_param.par_H7 / 2097152.0;
-
- humidity_comp = var2 +
- ((var3 + (var4 * comp_temperature)) * var2 * var2);
- if (humidity_comp > BME680_MAX_HUMIDITY_VALUE)
- humidity_comp = BME680_MAX_HUMIDITY_VALUE;
- else if (humidity_comp < BME680_MIN_HUMIDITY_VALUE)
- humidity_comp = BME680_MIN_HUMIDITY_VALUE;
- return humidity_comp;
-}
-
-/*!
- * @brief This function is used to convert the uncompensated
- * pressure data to compensated data using compensation formula
- * @note Returns pressure in Pa as double.
- * @note Output value of "96386.2"
- * equals 96386.2 Pa = 963.862 hPa.
- *
- *
- * @param uncom_pressure_u32 : value of uncompensated pressure
- * @param bme680: structure pointer.
- *
- * @return Return the compensated pressure data in floating point
- *
-*/
-double bme680_compensate_pressure_double(u32 uncom_pressure_u32,
- struct bme680_t *bme680)
-{
- double data1_d = 0;
- double data2_d = 0;
- double data3_d = 0;
- double pressure_comp = 0;
-
- data1_d = (((double)bme680->cal_param.t_fine / 2.0) - 64000.0);
- data2_d = data1_d * data1_d * (((double)bme680->cal_param.par_P6) /
- (131072.0));
- data2_d = data2_d + (data1_d * ((double)bme680->cal_param.par_P5) *
- 2.0);
- data2_d = (data2_d / 4.0) + (((double)bme680->cal_param.par_P4) *
- 65536.0);
- data1_d = (((((double)bme680->cal_param.par_P3 * data1_d
- * data1_d) / 16384.0) + ((double)bme680->cal_param.par_P2
- * data1_d)) / 524288.0);
- data1_d = ((1.0 + (data1_d / 32768.0)) *
- ((double)bme680->cal_param.par_P1));
- pressure_comp = (1048576.0 - ((double)uncom_pressure_u32));
- /* Avoid exception caused by division by zero */
- if ((int)data1_d != 0) {
- pressure_comp = (((pressure_comp - (data2_d
- / 4096.0)) * 6250.0) / data1_d);
- data1_d = (((double)bme680->cal_param.par_P9) *
- pressure_comp * pressure_comp) / 2147483648.0;
- data2_d = pressure_comp * (((double)bme680->cal_param.par_P8)
- / 32768.0);
- data3_d = ((pressure_comp / 256.0) * (pressure_comp / 256.0) *
- (pressure_comp / 256.0) *
- (bme680->cal_param.par_P10 / 131072.0));
- pressure_comp = (pressure_comp + (data1_d + data2_d + data3_d +
- ((double)bme680->cal_param.par_P7 * 128.0)) / 16.0);
- return pressure_comp;
-
- } else {
- return 0;
- }
-
-
-}
-
-/*!
- * @brief This function used to convert temperature data
- * to uncompensated temperature data using compensation formula
- * @note returns the value in Degree centigrade
- * @note Output value of "51.23" equals 51.23 DegC.
- *
- * @param uncom_temperature_u32 : value of uncompensated temperature
- * @param bme680: structure pointer.
- *
- * @return Return the actual temperature in floating point
- *
-*/
-double bme680_compensate_temperature_double(u32 uncom_temperature_u32,
- struct bme680_t *bme680)
-{
- double data1_d = 0;
- double data2_d = 0;
- double temperature = 0;
- /* calculate x1 data */
- data1_d = ((((double)uncom_temperature_u32 / 16384.0)
- - ((double)bme680->cal_param.par_T1 / 1024.0))
- * ((double)bme680->cal_param.par_T2));
- /* calculate x2 data */
- data2_d = (((((double)uncom_temperature_u32 / 131072.0) -
- ((double)bme680->cal_param.par_T1 / 8192.0)) *
- (((double)uncom_temperature_u32 / 131072.0) -
- ((double)bme680->cal_param.par_T1 / 8192.0))) *
- ((double)bme680->cal_param.par_T3 * 16.0));
- /* t fine value*/
- bme680->cal_param.t_fine = (s32)(data1_d + data2_d);
- /* compensated temperature data*/
- temperature = ((data1_d + data2_d) /
- 5120.0);
-
-
- return temperature;
-}
-
-
-/*!
- * @brief This function is used to convert temperature to resistance
- * using the compensation formula
- *
- * @param heater_temp_u16: The value of heater temperature
- * @param ambient_temp_s16: The value of ambient temperature
- * @param bme680: structure pointer.
- *
- * @return calculated resistance from temperature
- *
- *
- *
-*/
-double bme680_convert_temperature_to_resistance_double(u16 heater_temp_u16,
- s16 ambient_temp_s16, struct bme680_t *bme680)
-{
- double var1 = 0;
- double var2 = 0;
- double var3 = 0;
- double var4 = 0;
- double var5 = 0;
- double res_heat = 0;
-
- if ((heater_temp_u16 >= BME680_GAS_PROFILE_TEMPERATURE_MIN)
- && (heater_temp_u16 <= BME680_GAS_PROFILE_TEMPERATURE_MAX)) {
-#ifdef HEATER_C1_ENABLE
- var1 = (((double)bme680->cal_param.par_GH1 / (16.0)) + 49.0);
- var2 = ((((double)bme680->cal_param.par_GH2
- /(32768.0)) * (0.0005)) + 0.00235);
-#endif
- var3 = ((double)bme680->cal_param.par_GH3 / (1024.0));
- var4 = (var1 * (1.0 + (var2 * (double)heater_temp_u16)));
- var5 = (var4 + (var3 * (double)ambient_temp_s16));
-
-#ifdef HEATER_C1_ENABLE
- res_heat = (u8)(3.4 * ((var5 *
- (4 / (4 + (double)bme680->cal_param.res_heat_range)) *
- (1/(1 + ((double)bme680->cal_param.res_heat_val
- * 0.002)))) - 25));
-#else
- res_heat = (((var5 * (4.0 /
- (4.0 + (double)bme680->cal_param.res_heat_range)))
- - 25.0) * 3.4);
-#endif
-
- }
- return (u8)res_heat;
-}
-
-#endif
-/* bme680.c */
diff --git a/bme680_calculations.h b/bme680_calculations.h
deleted file mode 100644
index 797c042..0000000
--- a/bme680_calculations.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/**
-*
-****************************************************************************
-* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
-*
-* File : bme680_calculations.h
-*
-* Date: 5 May 2017
-*
-* Revision : 2.2.0 $
-*
-* Usage: Sensor Driver for BME680 sensor
-*
-****************************************************************************
-*
-* \section Disclaimer
-*
-* Common:
-* Bosch Sensortec products are developed for the consumer goods industry.
-* They may only be used within the parameters of the respective valid
-* product data sheet. Bosch Sensortec products are provided with the
-* express understanding that there is no warranty of fitness for a
-* particular purpose.They are not fit for use in life-sustaining,
-* safety or security sensitive systems or any system or device
-* that may lead to bodily harm or property damage if the system
-* or device malfunctions. In addition,Bosch Sensortec products are
-* not fit for use in products which interact with motor vehicle systems.
-* The resale and or use of products are at the purchasers own risk and
-* his own responsibility. The examination of fitness for the intended use
-* is the sole responsibility of the Purchaser.
-*
-* The purchaser shall indemnify Bosch Sensortec from all third party
-* claims, including any claims for incidental, or consequential damages,
-* arising from any product use not covered by the parameters of
-* the respective valid product data sheet or not approved by
-* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
-* connection with such claims.
-*
-* The purchaser must monitor the market for the purchased products,
-* particularly with regard to product safety and inform Bosch Sensortec
-* without delay of all security relevant incidents.
-*
-* Engineering Samples are marked with an asterisk (*) or (e).
-* Samples may vary from the valid technical specifications of the product
-* series. They are therefore not intended or fit for resale to third
-* parties or for use in end products. Their sole purpose is internal
-* client testing. The testing of an engineering sample may in no way
-* replace the testing of a product series. Bosch Sensortec assumes
-* no liability for the use of engineering samples.
-* By accepting the engineering samples, the Purchaser agrees to indemnify
-* Bosch Sensortec from all claims arising from the use of engineering
-* samples.
-*
-* Special:
-* This software module (hereinafter called "Software") and any information
-* on application-sheets (hereinafter called "Information") is provided
-* free of charge for the sole purpose to support your application work.
-* The Software and Information is subject to the following
-* terms and conditions:
-*
-* The Software is specifically designed for the exclusive use for
-* Bosch Sensortec products by personnel who have special experience
-* and training. Do not use this Software if you do not have the
-* proper experience or training.
-*
-* This Software package is provided `` as is `` and without any expressed
-* or implied warranties,including without limitation, the implied warranties
-* of merchantability and fitness for a particular purpose.
-*
-* Bosch Sensortec and their representatives and agents deny any liability
-* for the functional impairment
-* of this Software in terms of fitness, performance and safety.
-* Bosch Sensortec and their representatives and agents shall not be liable
-* for any direct or indirect damages or injury, except as
-* otherwise stipulated in mandatory applicable law.
-*
-* The Information provided is believed to be accurate and reliable.
-* Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are
-* subject to change without notice.
-**************************************************************************/
-/*! \file bme680_calculations.h
- \brief BME680 Sensor Driver calculation Header File */
-
-/*************************************************************************/
-#ifndef __BME680_CALCULATIONS_H__
-#define __BME680_CALCULATIONS_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/***************************************************************************
- Header files
- ****************************************************************************/
-#include "bme680.h"
-
-/***************************************************************************
- Macros, Enums, Constants
- ****************************************************************************/
-
-/***************************************************************************
- Module globals, typedefs
- ****************************************************************************/
-
-/***************************************************************************
- Function definitions
- ****************************************************************************/
-/* bme680_calculations.h */
-#ifdef FIXED_POINT_COMPENSATION
-/**************************************************************/
-/**\name FUNCTION FOR INTEGER OUTPUT GAS*/
-/**************************************************************/
-/*!
- * @brief This function is used to convert uncompensated gas data to
- * compensated gas data using compensation formula(integer version)
- */
-s32 bme680_calculate_gas_int32(u16 gas_adc_u16, u8 gas_range_u8,
- struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION FOR INTEGER OUTPUT TEMPERATURE*/
-/**************************************************************/
-/*!
- * @brief This function is used to convert the uncompensated
- * temperature data to compensated temperature data using
- * compensation formula(integer version)
- *
- * @note Returns the value in 0.01 degree Centigrade
- * Output value of "5123" equals 51.23 DegC.
- */
-s32 bme680_compensate_temperature_int32(u32 v_uncomp_temperature_u32,
- struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION FOR INTEGER OUTPUT HUMIDITY*/
-/**************************************************************/
-/*!
- * @brief This function is used to convert the uncompensated
- * humidity data to compensated humidity data using
- * compensation formula(integer version)
- *
- * @note Returns the value in %rH as unsigned 32bit integer
- * in Q22.10 format(22 integer 10 fractional bits).
- * @note An output value of 42313 represents 42313 / 1024 = 41.321 %rH
- */
-s32 bme680_compensate_humidity_int32(u32 v_uncomp_humidity_u32,
- struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION FOR INTEGER OUTPUT PRESSURE*/
-/**************************************************************/
-/*!
- * @brief This function is used to convert the uncompensated
- * pressure data to compensated pressure data data using
- * compensation formula(integer version)
- *
- * @note Returns the value in Pascal(Pa)
- * Output value of "96386" equals 96386 Pa = 963.86 hPa = 963.86 millibar
- */
-s32 bme680_compensate_pressure_int32(u32 v_uncomp_pressure_u32,
- struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION FOR INTEGER TEMPERATURE-RESISTANCE*/
-/**************************************************************/
-/*!
- * @brief This function is used to convert temperature to resistance
- * using the integer compensation formula
- */
-u8 bme680_convert_temperature_to_resistance_int32(u16 heater_temp_u16,
- s16 ambient_temp_s16, struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION TO CONVERT INT32_H to U16_H BIT OPUTPUT*/
-/**************************************************************/
-/*!
- * @brief Reads actual humidity from uncompensated humidity
- *
- * @note Returns the value in %rH as unsigned 16bit integer
- * @note An output value of 42313 represents 42313/512 = 82.643 %rH
- */
-u16 bme680_compensate_H_int32_sixteen_bit_output(u32 v_uncomp_humidity_u32,
- struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION TO CONVERT INT32_T to S16_T BIT OPUTPUT*/
-/**************************************************************/
-/*!
- * @brief Reads actual temperature from uncompensated temperature
- *
- * @note Returns the value with 500LSB/DegC centred around 24 DegC
- * output value of "5123" equals(5123/500)+24 = 34.246DegC
- */
-s16 bme680_compensate_T_int32_sixteen_bit_output(u32 v_uncomp_temperature_u32,
- struct bme680_t *bme680);
-/**************************************************************/
-/**\name FUNCTION TO CONVERT INT32_P to U24_P BIT OPUTPUT*/
-/**************************************************************/
-/*!
- * @brief Reads actual pressure from uncompensated pressure in Pa.
- *
- * @note Output value of "12337434" represents
- * 12337434 / 128 = 96386.2 Pa = 963.862 hPa
- */
-u32 bme680_compensate_P_int32_twentyfour_bit_output(u32 v_uncomp_pressure_u32,
- struct bme680_t *bme680);
-
-#else
-/**************************************************************/
-/**\name FUNCTION FOR FLOAT OUTPUT GAS */
-/**************************************************************/
-/*!
- * @brief This function is used to convert uncompensated gas data to
- * compensated gas data using compensation formula
- */
-double bme680_compensate_gas_double(u16 gas_adc_u16, u8 gas_range_u8,
- struct bme680_t *bme680);
-
-/**************************************************************/
-/**\name FUNCTION FOR FLOAT OUTPUT HUMIDITY */
-/**************************************************************/
-
-/*!
- * @brief This function is used to convert the uncompensated
- * humidity data to compensated humidity data data using
- * compensation formula
- *
- * @note returns the value in relative humidity (%rH)
- * @note Output value of "42.12" equals 42.12 %rH
- */
-double bme680_compensate_humidity_double(u16 uncom_humidity_u16,
- double comp_temperature, struct bme680_t *bme680);
-
-/**************************************************************/
-/**\name FUNCTION FOR FLOAT OUTPUT PRESSURE*/
-/**************************************************************/
-/*!
- * @brief This function is used to convert the uncompensated
- * pressure data to compensated data using compensation formula
- *
- * @note Returns pressure in Pa as double.
- * @note Output value of "96386.2" equals 96386.2 Pa = 963.862 hPa.
- */
-double bme680_compensate_pressure_double(u32 uncom_pressure_u32,
- struct bme680_t *bme680);
-
-/**************************************************************/
-/**\name FUNCTION FOR FLOAT OUTPUT TEMPERATURE*/
-/**************************************************************/
-
-/*!
- * @brief This function used to convert temperature data
- * to uncompensated temperature data using compensation formula
- *
- * @note returns the value in Degree centigrade
- * @note Output value of "51.23" equals 51.23 DegC.
- */
-double bme680_compensate_temperature_double(u32 uncom_temperature_u32,
- struct bme680_t *bme680);
-
-/**************************************************************/
-/**\name FUNCTION FOR TEMPERATURE TO RESISTANCE */
-/**************************************************************/
-
-/*!
- * @brief This function is used to convert temperature to resistance
- * using the compensation formula
- */
-double bme680_convert_temperature_to_resistance_double(u16 heater_temp_u16,
- s16 ambient_temp_s16, struct bme680_t *bme680);
-#endif
-/* bme680_calculations.h */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/bme680_defs.h b/bme680_defs.h
new file mode 100644
index 0000000..4ef701f
--- /dev/null
+++ b/bme680_defs.h
@@ -0,0 +1,529 @@
+/**
+ * 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
+#else
+#include
+#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_ */
+/** @}*/
+/** @}*/
diff --git a/bme680_internal.h b/bme680_internal.h
deleted file mode 100644
index 3d79c4e..0000000
--- a/bme680_internal.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/**
-*
-****************************************************************************
-* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
-*
-* File : bme680_internal.h
-*
-* Date: 5 May 2017
-*
-* Revision : 2.2.0 $
-*
-* Usage: Sensor Driver for BME680 sensor
-*
-****************************************************************************
-*
-* \section Disclaimer
-*
-* Common:
-* Bosch Sensortec products are developed for the consumer goods industry.
-* They may only be used within the parameters of the respective valid
-* product data sheet. Bosch Sensortec products are provided with the
-* express understanding that there is no warranty of fitness for a
-* particular purpose.They are not fit for use in life-sustaining,
-* safety or security sensitive systems or any system or device
-* that may lead to bodily harm or property damage if the system
-* or device malfunctions. In addition,Bosch Sensortec products are
-* not fit for use in products which interact with motor vehicle systems.
-* The resale and or use of products are at the purchasers own risk and
-* his own responsibility. The examination of fitness for the intended use
-* is the sole responsibility of the Purchaser.
-*
-* The purchaser shall indemnify Bosch Sensortec from all third party
-* claims, including any claims for incidental, or consequential damages,
-* arising from any product use not covered by the parameters of
-* the respective valid product data sheet or not approved by
-* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
-* connection with such claims.
-*
-* The purchaser must monitor the market for the purchased products,
-* particularly with regard to product safety and inform Bosch Sensortec
-* without delay of all security relevant incidents.
-*
-* Engineering Samples are marked with an asterisk (*) or (e).
-* Samples may vary from the valid technical specifications of the product
-* series. They are therefore not intended or fit for resale to third
-* parties or for use in end products. Their sole purpose is internal
-* client testing. The testing of an engineering sample may in no way
-* replace the testing of a product series. Bosch Sensortec assumes
-* no liability for the use of engineering samples.
-* By accepting the engineering samples, the Purchaser agrees to indemnify
-* Bosch Sensortec from all claims arising from the use of engineering
-* samples.
-*
-* Special:
-* This software module (hereinafter called "Software") and any information
-* on application-sheets (hereinafter called "Information") is provided
-* free of charge for the sole purpose to support your application work.
-* The Software and Information is subject to the following
-* terms and conditions:
-*
-* The Software is specifically designed for the exclusive use for
-* Bosch Sensortec products by personnel who have special experience
-* and training. Do not use this Software if you do not have the
-* proper experience or training.
-*
-* This Software package is provided `` as is `` and without any expressed
-* or implied warranties,including without limitation, the implied warranties
-* of merchantability and fitness for a particular purpose.
-*
-* Bosch Sensortec and their representatives and agents deny any liability
-* for the functional impairment
-* of this Software in terms of fitness, performance and safety.
-* Bosch Sensortec and their representatives and agents shall not be liable
-* for any direct or indirect damages or injury, except as
-* otherwise stipulated in mandatory applicable law.
-*
-* The Information provided is believed to be accurate and reliable.
-* Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are
-* subject to change without notice.
-**************************************************************************/
-/*! \file bme680_internal.h
- \brief BME680 Sensor Driver internal support Header File */
-
-#ifndef _BME680_INTERNAL_H
-#define _BME680_INTERNAL_H
-
-/***************************************************************************
- Header files
-****************************************************************************/
-
-
-
-
-/***************************************************************************
- Macros Enums, Constants only sensor Specific constants
-****************************************************************************/
-/* bme680_internal.h */
-/* Pre-processor switch for separating between I2C and SPI addresses */
-
-#define BME680_CALIB_SPI_ADDR_1 (0x09)
-#define BME680_CALIB_SPI_ADDR_2 (0x61)
-#define BME680_PAGE0_SPI_ID_REG (0x50)
-
-#define BME680_CALIB_I2C_ADDR_1 (0x89)
-#define BME680_CALIB_I2C_ADDR_2 (0xE1)
-#define BME680_PAGE0_I2C_ID_REG (0xD0)
-
-#define BME680_OVERSAMP_TEMP_SHIFT (0x03)
-#define BME680_GAS_WAIT_STEP_SIZE (477)
-
-#define BME680_SENS_CONF_LEN (0x06)
-#define BME680_SENS_HEATR_CONF_LEN (0x15)
-
-#define BME680_TRUE (1)
-#define BME680_FALSE (0)
-
-#define BME680_CALIB_PARAM_SIZE ((u8)41)
-#define BME680_PAGE0_INTERFACE_SPI ((u8)0)
-#define BME680_PAGE1_INTERFACE_SPI ((u8)1)
-#define BME680_CALIB_DATA_LENGTH_GAS (25)
-#define BME680_CALIB_DATA_LENGTH (16)
-#define BME680_BIT_MASK_H1_DATA (0x0F)
-#define BME680_FIELD_ZERO (0)
-#define BME680_FIELD_ONE (1)
-#define BME680_FIELD_TWO (2)
-#define BME680_FIELD_ONE_OFFSET (17)
-#define BME680_FIELD_TWO_OFFSET (34)
-#define BME680_FIELD_SIZE (17)
-
-/* Sensor Specific constants */
-#define BME680_GAS_BIT_MASK (0x00C0)
-#define BME680_GAS_WAIT_MAX_TIMER_VALUE (0x3F)
-#define BME680_GAS_WAIT_MIN_TIMER_VALUE (0x00)
-
-#define BME680_PROFILE_MAX (10)
-
-
-#define BME680_ADDR_SPI_MEM_PAGE (0x73)
-#define BME680_ADDR_OP_MODE (0x74)
-#define BME680_ADDR_SENS_CONF_START (0x5A)
-#define BME680_ADDR_FIELD_0 (0x1D)
-#define BME680_ADDR_SENSOR_CONFIG (0x70)
-#define BME680_ADDR_RES_HEAT_VAL (0x00)
-#define BME680_ADDR_RES_HEAT_RANGE (0x02)
-#define BME680_ADDR_RANGE_SWITCHING_ERR (0x04)
-
-/* Section 3.2: Sub-register addresses, masks and bit shifts */
-
-#define BME680_MASK_OP_MODE (0xFC)
-#define BME680_MASK_HEATR_CTRL (0xF7)
-#define BME680_MASK_ODR_3 (0x7F)
-#define BME680_MASK_ODR_2_0 (0x1F)
-#define BME680_MASK_RUN_GAS (0xEF)
-#define BME680_MASK_PROF_INDEX (0xF0)
-#define BME680_MASK_OSRS_HUM (0xF8)
-#define BME680_MASK_OSRS_PRES (0xE3)
-#define BME680_MASK_OSRS_TEMP (0x1F)
-#define BME680_MASK_FILTER (0xE3)
-#define BME680_MASK_NEW_DATA (0x7F)
-#define BME680_MASK_GAS_MEAS_STAT (0xBF)
-#define BME680_MASK_TPHG_MEAS_STAT (0xDF)
-#define BME680_MASK_GAS_MEAS_INDEX (0xF0)
-#define BME680_MASK_GAS_RANGE (0xF0)
-#define BME680_MASK_GAS_VALID (0xDF)
-#define BME680_MASK_HEATR_STAB (0xEF)
-#define BME680_MASK_SPI_3W_INT (0xBF)
-#define BME680_MASK_SPI_3W_EN (0xFE)
-#define BME680_MASK_MEM_PAGE (0xEF)
-#define BME680_MASK_RES_HEAT_RANGE (0xCF)
-#define BME680_MASK_RANGE_ERR (0x0F)
-
-/* Section : Register settings/values */
-/* Lengths to support burst reads/writes */
-
-#define BME680_SINGLE_FIELD_LENGTH (15)
-#define BME680_LEN_ALL_FIELD_SIZE (49)
-
-
-#define BME680_ADDR_FIELD_0_STATUS (0x1D)
-#define BME680_ADDR_FIELD_1_STATUS (0x2E)
-#define BME680_ADDR_FIELD_2_STATUS (0x3F)
-#define BME680_ADDR_FIELD_0_TEMP1 (0x22)
-#define BME680_ADDR_FIELD_0_TEMP2 (0x27)
-#define BME680_ADDR_FIELD_1_TEMP1 (0x33)
-#define BME680_ADDR_FIELD_1_TEMP2 (0x38)
-#define BME680_ADDR_FIELD_2_TEMP1 (0x44)
-#define BME680_ADDR_FIELD_2_TEMP2 (0x49)
-#define BME680_ADDR_FIELD_0_PRESS (0x1F)
-#define BME680_ADDR_FIELD_1_PRESS (0x30)
-#define BME680_ADDR_FIELD_2_PRESS (0x41)
-#define BME680_ADDR_FIELD_0_HUM (0x25)
-#define BME680_ADDR_FIELD_1_HUM (0x36)
-#define BME680_ADDR_FIELD_2_HUM (0x47)
-#define BME680_ADDR_FIELD_0_GAS (0x2A)
-#define BME680_ADDR_FIELD_1_GAS (0x3B)
-#define BME680_ADDR_FIELD_2_GAS (0x4C)
-
-
-/*******************************************************/
-/* Array Index to Field data mapping*/
-/********************************************************/
-/* For Calibration Data*/
-
-#define DIG_T2_LSB_REG (1)
-#define DIG_T2_MSB_REG (2)
-#define DIG_T3_REG (3)
-#define DIG_P1_LSB_REG (5)
-#define DIG_P1_MSB_REG (6)
-#define DIG_P2_LSB_REG (7)
-#define DIG_P2_MSB_REG (8)
-#define DIG_P3_REG (9)
-#define DIG_P4_LSB_REG (11)
-#define DIG_P4_MSB_REG (12)
-#define DIG_P5_LSB_REG (13)
-#define DIG_P5_MSB_REG (14)
-#define DIG_P7_REG (15)
-#define DIG_P6_REG (16)
-#define DIG_P8_LSB_REG (19)
-#define DIG_P8_MSB_REG (20)
-#define DIG_P9_LSB_REG (21)
-#define DIG_P9_MSB_REG (22)
-#define DIG_P10_REG (23)
-#define DIG_H2_MSB_REG (25)
-#define DIG_H2_LSB_REG (26)
-#define DIG_H1_LSB_REG (26)
-#define DIG_H1_MSB_REG (27)
-#define DIG_H3_REG (28)
-#define DIG_H4_REG (29)
-#define DIG_H5_REG (30)
-#define DIG_H6_REG (31)
-#define DIG_H7_REG (32)
-#define DIG_T1_LSB_REG (33)
-#define DIG_T1_MSB_REG (34)
-#define DIG_GH2_LSB_REG (35)
-#define DIG_GH2_MSB_REG (36)
-#define DIG_GH1_REG (37)
-#define DIG_GH3_REG (38)
-
-/* For TPHG data */
-
-#define FIELD_0_MEAS_STATUS_0 (0)
-#define FIELD_0_MEAS_STATUS_1 (1)
-#define FIELD_0_GAS_RL_LSB (14)
-
-/*!
-@brief data frame includes temperature, pressure, humidity
-and gas data*/
-#define BME680_DATA_FRAME_PRESSURE_MSB_DATA ((u8)2)
-#define BME680_DATA_FRAME_PRESSURE_LSB_DATA ((u8)3)
-#define BME680_DATA_FRAME_PRESSURE_XLSB_DATA ((u8)4)
-#define BME680_DATA_FRAME_TEMPERATURE1_MSB_DATA ((u8)5)
-#define BME680_DATA_FRAME_TEMPERATURE1_LSB_DATA ((u8)6)
-#define BME680_DATA_FRAME_TEMPERATURE1_XLSB_DATA ((u8)7)
-#define BME680_DATA_FRAME_HUMIDITY_MSB_DATA ((u8)8)
-#define BME680_DATA_FRAME_HUMIDITY_LSB_DATA ((u8)9)
-#define BME680_DATA_FRAME_GAS_MSB_DATA ((u8)13)
-#define BME680_DATA_FRAME_GAS_LSB_DATA ((u8)14)
-
-
-/* Positions to support indexing in an array */
-#define BME680_INDEX_CTRL_GAS_0 (0)
-#define BME680_INDEX_CTRL_GAS_1 (1)
-#define BME680_INDEX_CTRL_HUM (2)
-#define BME680_INDEX_CTRL_MEAS (4)
-#define BME680_INDEX_CONFIG (5)
-
-/* Constants to store the bit shift parameters */
-#define BME680_SHIFT_OP_MODE (0)
-#define BME680_SHIFT_HEATR_CTRL (3)
-#define BME680_SHIFT_ODR_3 (4)
-#define BME680_SHIFT_ODR_2_0 (5)
-#define BME680_SHIFT_RUN_GAS (4)
-#define BME680_SHIFT_PROF_INDEX (0)
-#define BME680_SHIFT_OSRS_HUM (0)
-#define BME680_SHIFT_OSRS_TEMP (5)
-#define BME680_SHIFT_OSRS_PRES (2)
-#define BME680_SHIFT_FILTER (2)
-#define BME680_SHIFT_NEW_DATA (7)
-#define BME680_SHIFT_GAS_MEAS_STAT (6)
-#define BME680_SHIFT_TPHG_MEAS_STAT (5)
-#define BME680_SHIFT_GAS_MEAS_INDEX (0)
-#define BME680_SHIFT_GAS_RANGE (0)
-#define BME680_SHIFT_GAS_VALID (5)
-#define BME680_SHIFT_HEATR_STAB (4)
-#define BME680_SHIFT_SPI_3W_INT (6)
-#define BME680_SHIFT_SPI_3W_EN (0)
-#define BME680_SHIFT_SPI_MEM_PAGE (4)
-#define BME680_SHIFT_RES_HEAT_RANGE (4)
-#define BME680_SHIFT_RANGE_ERR (4)
-
-#define BME680_ONE (1)
-#define BME680_TWO (2)
-#define BME680_THREE (3)
-
-#define BME680_GEN_READ_DATA_LENGTH ((u8)1)
-#define BME680_GEN_WRITE_DATA_LENGTH ((u8)1)
-
-/* bme680_internal.h */
-/***************************************************************************
- Module globals, typedefs
-****************************************************************************/
-
-
-/***************************************************************************
- Function definitions
-****************************************************************************/
-
-
-#endif
diff --git a/changelog.md b/changelog.md
new file mode 100644
index 0000000..36bc4ab
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,42 @@
+# 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.
+
diff --git a/sensor_api_common_types.h b/sensor_api_common_types.h
deleted file mode 100644
index 9177171..0000000
--- a/sensor_api_common_types.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/**
-*
-****************************************************************************
-* Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
-*
-* File : sensor_api_common_types.h
-*
-* Date: 5 May 2017
-*
-* Revision : 2.2.0 $
-*
-* Usage: Sensor Driver for BME680 sensor
-*
-****************************************************************************
-*
-* \section Disclaimer
-*
-* Common:
-* Bosch Sensortec products are developed for the consumer goods industry.
-* They may only be used within the parameters of the respective valid
-* product data sheet. Bosch Sensortec products are provided with the
-* express understanding that there is no warranty of fitness for a
-* particular purpose.They are not fit for use in life-sustaining,
-* safety or security sensitive systems or any system or device
-* that may lead to bodily harm or property damage if the system
-* or device malfunctions. In addition,Bosch Sensortec products are
-* not fit for use in products which interact with motor vehicle systems.
-* The resale and or use of products are at the purchasers own risk and
-* his own responsibility. The examination of fitness for the intended use
-* is the sole responsibility of the Purchaser.
-*
-* The purchaser shall indemnify Bosch Sensortec from all third party
-* claims, including any claims for incidental, or consequential damages,
-* arising from any product use not covered by the parameters of
-* the respective valid product data sheet or not approved by
-* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
-* connection with such claims.
-*
-* The purchaser must monitor the market for the purchased products,
-* particularly with regard to product safety and inform Bosch Sensortec
-* without delay of all security relevant incidents.
-*
-* Engineering Samples are marked with an asterisk (*) or (e).
-* Samples may vary from the valid technical specifications of the product
-* series. They are therefore not intended or fit for resale to third
-* parties or for use in end products. Their sole purpose is internal
-* client testing. The testing of an engineering sample may in no way
-* replace the testing of a product series. Bosch Sensortec assumes
-* no liability for the use of engineering samples.
-* By accepting the engineering samples, the Purchaser agrees to indemnify
-* Bosch Sensortec from all claims arising from the use of engineering
-* samples.
-*
-* Special:
-* This software module (hereinafter called "Software") and any information
-* on application-sheets (hereinafter called "Information") is provided
-* free of charge for the sole purpose to support your application work.
-* The Software and Information is subject to the following
-* terms and conditions:
-*
-* The Software is specifically designed for the exclusive use for
-* Bosch Sensortec products by personnel who have special experience
-* and training. Do not use this Software if you do not have the
-* proper experience or training.
-*
-* This Software package is provided `` as is `` and without any expressed
-* or implied warranties,including without limitation, the implied warranties
-* of merchantability and fitness for a particular purpose.
-*
-* Bosch Sensortec and their representatives and agents deny any liability
-* for the functional impairment
-* of this Software in terms of fitness, performance and safety.
-* Bosch Sensortec and their representatives and agents shall not be liable
-* for any direct or indirect damages or injury, except as
-* otherwise stipulated in mandatory applicable law.
-*
-* The Information provided is believed to be accurate and reliable.
-* Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are
-* subject to change without notice.
-**************************************************************************/
-/*! \file sensor_api_common_types.h
- \brief sensor API common data types Header File */
-
-#ifndef __SENSOR_API_COMMON_TYPES_H__
-#define __SENSOR_API_COMMON_TYPES_H__
-
-
-/***************************************************************************/
-
-
-/***************************************************************************
- Macros, Enum, Constant
-****************************************************************************/
-/* sensor_api_common_types.h */
-/*!
-* @brief The following definition is used for defining the data types
-*
-* @note While porting the API please consider the following
-* @note Please check the version of C standard
-* @note Are you using Linux platform
-*/
-
-/*!
-* @brief For the Linux platform support
-* Please use the types.h for your data types definitions
-*/
-#ifdef __KERNEL__
-
-#include
-#include
- /* singed integer type*/
- typedef int8_t s8;/**< used for signed 8bit */
- typedef int16_t s16;/**< used for signed 16bit */
- typedef int32_t s32;/**< used for signed 32bit */
- typedef int64_t s64;/**< used for signed 64bit */
-
- typedef u_int8_t u8;/**< used for unsigned 8bit */
- typedef u_int16_t u16;/**< used for unsigned 16bit */
- typedef u_int32_t u32;/**< used for unsigned 32bit */
- /*typedef u_int64_t u64;*//**< used for unsigned 64bit */
- typedef signed long long int s64;
-#else /* ! __KERNEL__ */
- /**********************************************************
- * These definitions are used to define the C
- * standard version data types
- ***********************************************************/
-# if defined(__STDC_VERSION__)
- /************************************************
- * compiler is C11 C standard
- ************************************************/
-#if (__STDC_VERSION__ == 201112L)
- /************************************************/
-#include
-
- /************************************************/
- /*unsigned integer types*/
- typedef uint8_t u8;/**< used for unsigned 8bit */
- typedef uint16_t u16;/**< used for unsigned 16bit */
- typedef uint32_t u32;/**< used for unsigned 32bit */
- typedef uint64_t u64;/**< used for unsigned 64bit */
-
- /*signed integer types*/
- typedef int8_t s8;/**< used for signed 8bit */
- typedef int16_t s16;/**< used for signed 16bit */
- typedef int32_t s32;/**< used for signed 32bit */
- typedef int64_t s64;/**< used for signed 64bit */
- /*typedef signed long long int s64;*/
- /************************************************
- * compiler is C99 C standard
- ************************************************/
-#elif (__STDC_VERSION__ == 199901L)
-
- /* stdint.h is a C99 supported c library.
- which is used to fixed the integer size*/
- /************************************************/
-#include
- /************************************************/
-
- /*unsigned integer types*/
- typedef uint8_t u8;/**< used for unsigned 8bit */
- typedef uint16_t u16;/**< used for unsigned 16bit */
- typedef uint32_t u32;/**< used for unsigned 32bit */
- typedef uint64_t u64;/**< used for unsigned 64bit */
-
- /*signed integer types*/
- typedef int8_t s8;/**< used for signed 8bit */
- typedef int16_t s16;/**< used for signed 16bit */
- typedef int32_t s32;/**< used for signed 32bit */
- /*typedef int64_t s64;*//**< used for signed 64bit */
-
- typedef signed long long int s64;
- /************************************************
- * compiler is C89 or other C standard
- ************************************************/
-#else /* !defined(__STDC_VERSION__) */
- /*!
- * @brief By default it is defined as 32 bit machine configuration
- * define your data types based on your
- * machine/compiler/controller configuration
- */
-#define MACHINE_32_BIT
-
- /*! @brief
- * If your machine support 16 bit
- * define the MACHINE_16_BIT
- */
-#ifdef MACHINE_16_BIT
-#include
- /*signed integer types*/
- typedef signed char s8;/**< used for signed 8bit */
- typedef signed short int s16;/**< used for signed 16bit */
- typedef signed long int s32;/**< used for signed 32bit */
-
-#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
- typedef long int s64;/**< used for signed 64bit */
- typedef unsigned long int u64;/**< used for unsigned 64bit */
-#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
- typedef long long int s64;/**< used for signed 64bit */
- typedef unsigned long long int u64;/**< used for unsigned 64bit */
-#else
-#warning Either the correct data type for signed 64 bit integer \
- could not be found, or 64 bit integers are not
- supported in your environment.
-#warning If 64 bit integers are supported on your platform, \
- please set s64 manually.
-#endif
-
- /*unsigned integer types*/
- typedef unsigned char u8;/**< used for unsigned 8bit */
- typedef unsigned short int u16;/**< used for unsigned 16bit */
- typedef unsigned int u32;/**< used for unsigned 32bit */
-
- /* If your machine support 32 bit
- define the MACHINE_32_BIT*/
-#elif defined MACHINE_32_BIT
- /*signed integer types*/
- typedef signed char s8;/**< used for signed 8bit */
- typedef signed short int s16;/**< used for signed 16bit */
- typedef signed int s32;/**< used for signed 32bit */
- typedef signed long long int s64;/**< used for signed 64bit */
-
- /*unsigned integer types*/
- typedef unsigned char u8;/**< used for unsigned 8bit */
- typedef unsigned short int u16;/**< used for unsigned 16bit */
- typedef unsigned int u32;/**< used for unsigned 32bit */
- typedef unsigned long long int u64;/**< used for unsigned 64bit */
-
- /* If your machine support 64 bit
- define the MACHINE_64_BIT*/
-#elif defined MACHINE_64_BIT
- /*signed integer types*/
- typedef signed char s8;/**< used for signed 8bit */
- typedef signed short int s16;/**< used for signed 16bit */
- typedef signed int s32;/**< used for signed 32bit */
- typedef signed long int s64;/**< used for signed 64bit */
-
- /*unsigned integer types*/
- typedef unsigned char u8;/**< used for unsigned 8bit */
- typedef unsigned short int u16;/**< used for unsigned 16bit */
- typedef unsigned int u32;/**< used for unsigned 32bit */
- typedef unsigned long int u64;/**< used for unsigned 64bit */
-
-#else
-#warning The data types defined above which not supported \
- define the data types manually
-#endif
-#endif
-
- /*** This else will execute for the compilers
- * which are not supported the C standards
- * Like C89/C99/C11***/
-#else
- /*!
- * @brief By default it is defined as 32 bit machine configuration
- * define your data types based on your
- * machine/compiler/controller configuration
- */
-#define MACHINE_32_BIT
- /* If your machine support 16 bit
- define the MACHINE_16_BIT*/
-#ifdef MACHINE_16_BIT
-#include
- /*signed integer types*/
- typedef signed char s8;/**< used for signed 8bit */
- typedef signed short int s16;/**< used for signed 16bit */
- typedef signed long int s32;/**< used for signed 32bit */
-
-#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
- typedef long int s64;/**< used for signed 64bit */
- typedef unsigned long int u64;/**< used for unsigned 64bit */
-#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
- typedef long long int s64;/**< used for signed 64bit */
- typedef unsigned long long int u64;/**< used for unsigned 64bit */
-#else
-#warning Either the correct data type for signed 64 bit integer \
- could not be found, or 64 bit integers are not
- supported in your environment.
-#warning If 64 bit integers are supported on your platform, \
- please set s64 manually.
-#endif
-
- /*unsigned integer types*/
- typedef unsigned char u8;/**< used for unsigned 8bit */
- typedef unsigned short int u16;/**< used for unsigned 16bit */
- typedef unsigned int u32;/**< used for unsigned 32bit */
- /*! @brief If your machine support 32 bit
- define the MACHINE_32_BIT*/
-#elif defined MACHINE_32_BIT
- /*signed integer types*/
- typedef signed char s8;/**< used for signed 8bit */
- typedef signed short int s16;/**< used for signed 16bit */
- typedef signed int s32;/**< used for signed 32bit */
- typedef signed long long int s64;/**< used for signed 64bit */
-
- /*unsigned integer types*/
- typedef unsigned char u8;/**< used for unsigned 8bit */
- typedef unsigned short int u16;/**< used for unsigned 16bit */
- typedef unsigned int u32;/**< used for unsigned 32bit
- - int and long int is same for u32*/
- typedef unsigned long long int u64;/**< used for unsigned 64bit */
-
- /* If your machine support 64 bit
- define the MACHINE_64_BIT*/
-#elif defined MACHINE_64_BIT
- /*signed integer types*/
- typedef signed char s8;/**< used for signed 8bit */
- typedef signed short int s16;/**< used for signed 16bit */
- typedef signed int s32;/**< used for signed 32bit */
- typedef signed long int s64;/**< used for signed 64bit */
-
- /*unsigned integer types*/
- typedef unsigned char u8;/**< used for unsigned 8bit */
- typedef unsigned short int u16;/**< used for unsigned 16bit */
- typedef unsigned int u32;/**< used for unsigned 32bit */
- typedef unsigned long int u64;/**< used for unsigned 64bit */
-
-#else
-#warning The data types defined above which not supported \
- define the data types manually
-#endif
-#endif
-#endif
-
-/* sensor_api_common_types.h */
-
-/***************************************************************************
- Module globals, typedefs
-****************************************************************************/
-
-/***************************************************************************
- Function definition
-****************************************************************************/
-
-#endif
-
-