commit 23b98a4290a054d1e124e3cc759885de110b6ca3 Author: SIMS IOT Devices <92898043+SIMS-IOT-Devices@users.noreply.github.com> Date: Sun Oct 16 01:38:22 2022 +0300 Add files via upload diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7b661c7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "proj5.c" "bme280.c" + INCLUDE_DIRS ".") diff --git a/bme280.c b/bme280.c new file mode 100644 index 0000000..cdefeb9 --- /dev/null +++ b/bme280.c @@ -0,0 +1,2297 @@ +/* +**************************************************************************** +* Copyright (C) 2015 - 2016 Bosch Sensortec GmbH +* +* bme280.c +* Date: 2016/07/04 +* Revision: 2.0.5(Pressure and Temperature compensation code revision is 1.1 +* and Humidity compensation code revision is 1.0) +* +* Usage: Sensor Driver file for BME280 sensor +* +**************************************************************************** +* License: +* +* 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. +**************************************************************************/ + +#include "bme280.h" +static struct bme280_t *p_bme280; /**< pointer to BME280 */ + +/*! + * @brief This function is used for initialize + * the bus read and bus write functions + * and assign the chip id and I2C address of the BME280 sensor + * chip id is read in the register 0xD0 bit from 0 to 7 + * + * @param bme280 structure pointer. + * + * @note While changing the parameter of the bme280_t + * @note consider the following point: + * Changing the reference value of the parameter + * will changes 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 results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_init(struct bme280_t *bme280) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 v_chip_id_read_count = BME280_CHIP_ID_READ_COUNT; + + /* assign BME280 ptr */ + p_bme280 = bme280; + + while (v_chip_id_read_count > 0) + { + + /* read Chip Id */ + com_rslt = p_bme280->BME280_BUS_READ_FUNC(p_bme280->dev_addr, + BME280_CHIP_ID_REG, &v_data_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* Check for the correct chip id */ + if (v_data_u8 == BME280_CHIP_ID) + break; + v_chip_id_read_count--; + /* Delay added concerning the low speed of power up system to + facilitate the proper reading of the chip ID */ + p_bme280->delay_msec(BME280_REGISTER_READ_DELAY); + } + /*assign chip ID to the global structure*/ + p_bme280->chip_id = v_data_u8; + /*com_rslt status of chip ID read*/ + com_rslt = (v_chip_id_read_count == BME280_INIT_VALUE) ? BME280_CHIP_ID_READ_FAIL : BME280_CHIP_ID_READ_SUCCESS; + + if (com_rslt == BME280_CHIP_ID_READ_SUCCESS) + { + /* readout bme280 calibparam structure */ + com_rslt += bme280_get_calib_param(); + } + return com_rslt; +} +/*! + * @brief This API is used to read uncompensated temperature + * in the registers 0xFA, 0xFB and 0xFC + * @note 0xFA -> MSB -> bit from 0 to 7 + * @note 0xFB -> LSB -> bit from 0 to 7 + * @note 0xFC -> LSB -> bit from 4 to 7 + * + * @param v_uncomp_temperature_s32 : The value of uncompensated temperature + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_temperature( + s32 *v_uncomp_temperature_s32) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + /* Array holding the MSB and LSb value + a_data_u8r[0] - Temperature MSB + a_data_u8r[1] - Temperature LSB + a_data_u8r[2] - Temperature XLSB + */ + u8 a_data_u8r[BME280_TEMPERATURE_DATA_SIZE] = { + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE}; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_TEMPERATURE_MSB_REG, + a_data_u8r, + BME280_TEMPERATURE_DATA_LENGTH); + *v_uncomp_temperature_s32 = (s32)((( + (u32)(a_data_u8r[BME280_TEMPERATURE_MSB_DATA])) + << BME280_SHIFT_BIT_POSITION_BY_12_BITS) | + (((u32)(a_data_u8r[BME280_TEMPERATURE_LSB_DATA])) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS) | + ((u32)a_data_u8r[BME280_TEMPERATURE_XLSB_DATA] >> + BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + } + return com_rslt; +} +/*! + * @brief Reads actual temperature from uncompensated temperature + * @note Returns the value in 0.01 degree Centigrade + * Output value of "5123" equals 51.23 DegC. + * + * + * + * @param v_uncomp_temperature_s32 : value of uncompensated temperature + * + * + * @return Returns the actual temperature + * + */ +s32 bme280_compensate_temperature_int32(s32 v_uncomp_temperature_s32) +{ + s32 v_x1_u32r = BME280_INIT_VALUE; + s32 v_x2_u32r = BME280_INIT_VALUE; + s32 temperature = BME280_INIT_VALUE; + + /* calculate x1*/ + v_x1_u32r = + ((((v_uncomp_temperature_s32 >> BME280_SHIFT_BIT_POSITION_BY_03_BITS) - + ((s32)p_bme280->cal_param.dig_T1 + << BME280_SHIFT_BIT_POSITION_BY_01_BIT))) * + ((s32)p_bme280->cal_param.dig_T2)) >> + BME280_SHIFT_BIT_POSITION_BY_11_BITS; + /* calculate x2*/ + v_x2_u32r = (((((v_uncomp_temperature_s32 >> BME280_SHIFT_BIT_POSITION_BY_04_BITS) - + ((s32)p_bme280->cal_param.dig_T1)) * + ((v_uncomp_temperature_s32 >> BME280_SHIFT_BIT_POSITION_BY_04_BITS) - + ((s32)p_bme280->cal_param.dig_T1))) >> + BME280_SHIFT_BIT_POSITION_BY_12_BITS) * + ((s32)p_bme280->cal_param.dig_T3)) >> + BME280_SHIFT_BIT_POSITION_BY_14_BITS; + /* calculate t_fine*/ + p_bme280->cal_param.t_fine = v_x1_u32r + v_x2_u32r; + /* calculate temperature*/ + temperature = (p_bme280->cal_param.t_fine * 5 + 128) >> BME280_SHIFT_BIT_POSITION_BY_08_BITS; + return temperature; +} +/*! + * @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_s32: value of uncompensated temperature + * + * + * + * @return Return the actual temperature as s16 output + * + */ +s16 bme280_compensate_temperature_int32_sixteen_bit_output( + s32 v_uncomp_temperature_s32) +{ + s16 temperature = BME280_INIT_VALUE; + + bme280_compensate_temperature_int32( + v_uncomp_temperature_s32); + temperature = (s16)(((( + p_bme280->cal_param.t_fine - 122880) * + 25) + + 128) >> + BME280_SHIFT_BIT_POSITION_BY_08_BITS); + + return temperature; +} +/*! + * @brief This API is used to read uncompensated pressure. + * in the registers 0xF7, 0xF8 and 0xF9 + * @note 0xF7 -> MSB -> bit from 0 to 7 + * @note 0xF8 -> LSB -> bit from 0 to 7 + * @note 0xF9 -> LSB -> bit from 4 to 7 + * + * + * + * @param v_uncomp_pressure_s32 : The value of uncompensated pressure + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_pressure( + s32 *v_uncomp_pressure_s32) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + /* Array holding the MSB and LSb value + a_data_u8[0] - Pressure MSB + a_data_u8[1] - Pressure LSB + a_data_u8[2] - Pressure XLSB + */ + u8 a_data_u8[BME280_PRESSURE_DATA_SIZE] = { + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE}; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_PRESSURE_MSB_REG, + a_data_u8, BME280_PRESSURE_DATA_LENGTH); + *v_uncomp_pressure_s32 = (s32)(( + ((u32)(a_data_u8[BME280_PRESSURE_MSB_DATA])) + << BME280_SHIFT_BIT_POSITION_BY_12_BITS) | + (((u32)(a_data_u8[BME280_PRESSURE_LSB_DATA])) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS) | + ((u32)a_data_u8[BME280_PRESSURE_XLSB_DATA] >> + BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + } + return com_rslt; +} +/*! + * @brief Reads actual pressure from uncompensated pressure + * @note Returns the value in Pascal(Pa) + * Output value of "96386" equals 96386 Pa = + * 963.86 hPa = 963.86 millibar + * + * + * + * @param v_uncomp_pressure_s32 : value of uncompensated pressure + * + * + * + * @return Return the actual pressure output as u32 + * + */ +u32 bme280_compensate_pressure_int32(s32 v_uncomp_pressure_s32) +{ + s32 v_x1_u32 = BME280_INIT_VALUE; + s32 v_x2_u32 = BME280_INIT_VALUE; + u32 v_pressure_u32 = BME280_INIT_VALUE; + + /* calculate x1*/ + v_x1_u32 = (((s32)p_bme280->cal_param.t_fine) >> BME280_SHIFT_BIT_POSITION_BY_01_BIT) - (s32)64000; + /* calculate x2*/ + v_x2_u32 = (((v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_02_BITS) * (v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_02_BITS)) >> BME280_SHIFT_BIT_POSITION_BY_11_BITS) * ((s32)p_bme280->cal_param.dig_P6); + /* calculate x2*/ + v_x2_u32 = v_x2_u32 + ((v_x1_u32 * + ((s32)p_bme280->cal_param.dig_P5)) + << BME280_SHIFT_BIT_POSITION_BY_01_BIT); + /* calculate x2*/ + v_x2_u32 = (v_x2_u32 >> BME280_SHIFT_BIT_POSITION_BY_02_BITS) + + (((s32)p_bme280->cal_param.dig_P4) + << BME280_SHIFT_BIT_POSITION_BY_16_BITS); + /* calculate x1*/ + v_x1_u32 = (((p_bme280->cal_param.dig_P3 * + (((v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_02_BITS) * + (v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_02_BITS)) >> + BME280_SHIFT_BIT_POSITION_BY_13_BITS)) >> + BME280_SHIFT_BIT_POSITION_BY_03_BITS) + + ((((s32)p_bme280->cal_param.dig_P2) * + v_x1_u32) >> + BME280_SHIFT_BIT_POSITION_BY_01_BIT)) >> + BME280_SHIFT_BIT_POSITION_BY_18_BITS; + /* calculate x1*/ + v_x1_u32 = ((((32768 + v_x1_u32)) * + ((s32)p_bme280->cal_param.dig_P1)) >> + BME280_SHIFT_BIT_POSITION_BY_15_BITS); + /* calculate pressure*/ + v_pressure_u32 = + (((u32)(((s32)1048576) - v_uncomp_pressure_s32) - (v_x2_u32 >> BME280_SHIFT_BIT_POSITION_BY_12_BITS))) * 3125; + if (v_pressure_u32 < 0x80000000) + /* Avoid exception caused by division by zero */ + if (v_x1_u32 != BME280_INIT_VALUE) + v_pressure_u32 = + (v_pressure_u32 + << BME280_SHIFT_BIT_POSITION_BY_01_BIT) / + ((u32)v_x1_u32); + else + return BME280_INVALID_DATA; + else + /* Avoid exception caused by division by zero */ + if (v_x1_u32 != BME280_INIT_VALUE) + v_pressure_u32 = (v_pressure_u32 / (u32)v_x1_u32) * 2; + else + return BME280_INVALID_DATA; + + v_x1_u32 = (((s32)p_bme280->cal_param.dig_P9) * + ((s32)(((v_pressure_u32 >> BME280_SHIFT_BIT_POSITION_BY_03_BITS) * (v_pressure_u32 >> BME280_SHIFT_BIT_POSITION_BY_03_BITS)) >> BME280_SHIFT_BIT_POSITION_BY_13_BITS))) >> + BME280_SHIFT_BIT_POSITION_BY_12_BITS; + v_x2_u32 = (((s32)(v_pressure_u32 >> BME280_SHIFT_BIT_POSITION_BY_02_BITS)) * + ((s32)p_bme280->cal_param.dig_P8)) >> + BME280_SHIFT_BIT_POSITION_BY_13_BITS; + v_pressure_u32 = (u32)((s32)v_pressure_u32 + + ((v_x1_u32 + v_x2_u32 + p_bme280->cal_param.dig_P7) >> BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + + return v_pressure_u32; +} +/*! + * @brief This API is used to read uncompensated humidity. + * in the registers 0xF7, 0xF8 and 0xF9 + * @note 0xFD -> MSB -> bit from 0 to 7 + * @note 0xFE -> LSB -> bit from 0 to 7 + * + * + * + * @param v_uncomp_humidity_s32 : The value of uncompensated humidity + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_humidity( + s32 *v_uncomp_humidity_s32) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + /* Array holding the MSB and LSb value + a_data_u8[0] - Humidity MSB + a_data_u8[1] - Humidity LSB + */ + u8 a_data_u8[BME280_HUMIDITY_DATA_SIZE] = { + BME280_INIT_VALUE, BME280_INIT_VALUE}; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_HUMIDITY_MSB_REG, a_data_u8, + BME280_HUMIDITY_DATA_LENGTH); + *v_uncomp_humidity_s32 = (s32)((((u32)(a_data_u8[BME280_HUMIDITY_MSB_DATA])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + ((u32)(a_data_u8[BME280_HUMIDITY_LSB_DATA]))); + } + return com_rslt; +} +/*! + * @brief Reads actual humidity from uncompensated humidity + * @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_s32: value of uncompensated humidity + * + * @return Return the actual relative humidity output as u32 + * + */ +u32 bme280_compensate_humidity_int32(s32 v_uncomp_humidity_s32) +{ + s32 v_x1_u32 = BME280_INIT_VALUE; + + /* calculate x1*/ + v_x1_u32 = (p_bme280->cal_param.t_fine - ((s32)76800)); + /* calculate x1*/ + v_x1_u32 = (((((v_uncomp_humidity_s32 + << BME280_SHIFT_BIT_POSITION_BY_14_BITS) - + (((s32)p_bme280->cal_param.dig_H4) + << BME280_SHIFT_BIT_POSITION_BY_20_BITS) - + (((s32)p_bme280->cal_param.dig_H5) * v_x1_u32)) + + ((s32)16384)) >> + BME280_SHIFT_BIT_POSITION_BY_15_BITS) * + (((((((v_x1_u32 * + ((s32)p_bme280->cal_param.dig_H6)) >> + BME280_SHIFT_BIT_POSITION_BY_10_BITS) * + (((v_x1_u32 * ((s32)p_bme280->cal_param.dig_H3)) >> BME280_SHIFT_BIT_POSITION_BY_11_BITS) + ((s32)32768))) >> + BME280_SHIFT_BIT_POSITION_BY_10_BITS) + + ((s32)2097152)) * + ((s32)p_bme280->cal_param.dig_H2) + + 8192) >> + 14)); + v_x1_u32 = (v_x1_u32 - (((((v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_15_BITS) * + (v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_15_BITS)) >> + BME280_SHIFT_BIT_POSITION_BY_07_BITS) * + ((s32)p_bme280->cal_param.dig_H1)) >> + BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + v_x1_u32 = (v_x1_u32 < 0 ? 0 : v_x1_u32); + v_x1_u32 = (v_x1_u32 > 419430400 ? 419430400 : v_x1_u32); + return (u32)(v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_12_BITS); +} +/*! + * @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_s32: value of uncompensated humidity + * + * + * @return Return the actual relative humidity output as u16 + * + */ +u16 bme280_compensate_humidity_int32_sixteen_bit_output( + s32 v_uncomp_humidity_s32) +{ + u32 v_x1_u32 = BME280_INIT_VALUE; + u16 v_x2_u32 = BME280_INIT_VALUE; + + v_x1_u32 = bme280_compensate_humidity_int32(v_uncomp_humidity_s32); + v_x2_u32 = (u16)(v_x1_u32 >> BME280_SHIFT_BIT_POSITION_BY_01_BIT); + return v_x2_u32; +} +/*! + * @brief This API used to read uncompensated + * pressure,temperature and humidity + * + * + * + * + * @param v_uncomp_pressure_s32: The value of uncompensated pressure. + * @param v_uncomp_temperature_s32: The value of uncompensated temperature + * @param v_uncomp_humidity_s32: The value of uncompensated humidity. + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_pressure_temperature_humidity( + s32 *v_uncomp_pressure_s32, + s32 *v_uncomp_temperature_s32, s32 *v_uncomp_humidity_s32) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + /* Array holding the MSB and LSb value of + a_data_u8[0] - Pressure MSB + a_data_u8[1] - Pressure LSB + a_data_u8[1] - Pressure LSB + a_data_u8[1] - Temperature MSB + a_data_u8[1] - Temperature LSB + a_data_u8[1] - Temperature LSB + a_data_u8[1] - Humidity MSB + a_data_u8[1] - Humidity LSB + */ + u8 a_data_u8[BME280_DATA_FRAME_SIZE] = { + BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE}; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_PRESSURE_MSB_REG, + a_data_u8, BME280_ALL_DATA_FRAME_LENGTH); + /*Pressure*/ + *v_uncomp_pressure_s32 = (s32)(( + ((u32)(a_data_u8[BME280_DATA_FRAME_PRESSURE_MSB_BYTE])) + << BME280_SHIFT_BIT_POSITION_BY_12_BITS) | + (((u32)(a_data_u8[BME280_DATA_FRAME_PRESSURE_LSB_BYTE])) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS) | + ((u32)a_data_u8[BME280_DATA_FRAME_PRESSURE_XLSB_BYTE] >> + BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + + /* Temperature */ + *v_uncomp_temperature_s32 = (s32)((( + (u32)(a_data_u8[BME280_DATA_FRAME_TEMPERATURE_MSB_BYTE])) + << BME280_SHIFT_BIT_POSITION_BY_12_BITS) | + (((u32)(a_data_u8[BME280_DATA_FRAME_TEMPERATURE_LSB_BYTE])) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS) | + ((u32)a_data_u8[BME280_DATA_FRAME_TEMPERATURE_XLSB_BYTE] >> BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + + /*Humidity*/ + *v_uncomp_humidity_s32 = (s32)(( + ((u32)(a_data_u8[BME280_DATA_FRAME_HUMIDITY_MSB_BYTE])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + ((u32)(a_data_u8[BME280_DATA_FRAME_HUMIDITY_LSB_BYTE]))); + } + return com_rslt; +} +/*! + * @brief This API used to read true pressure, temperature and humidity + * + * + * + * + * @param v_pressure_u32 : The value of compensated pressure. + * @param v_temperature_s32 : The value of compensated temperature. + * @param v_humidity_u32 : The value of compensated humidity. + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_pressure_temperature_humidity( + u32 *v_pressure_u32, s32 *v_temperature_s32, u32 *v_humidity_u32) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + s32 v_uncomp_pressure_s32 = BME280_INIT_VALUE; + s32 v_uncom_temperature_s32 = BME280_INIT_VALUE; + s32 v_uncom_humidity_s32 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + /* read the uncompensated pressure, + temperature and humidity*/ + com_rslt = + bme280_read_uncomp_pressure_temperature_humidity( + &v_uncomp_pressure_s32, &v_uncom_temperature_s32, + &v_uncom_humidity_s32); + /* read the true pressure, temperature and humidity*/ + *v_temperature_s32 = + bme280_compensate_temperature_int32( + v_uncom_temperature_s32); + *v_pressure_u32 = bme280_compensate_pressure_int32( + v_uncomp_pressure_s32); + *v_humidity_u32 = bme280_compensate_humidity_int32( + v_uncom_humidity_s32); + } + return com_rslt; +} +/*! + * @brief This API is used to + * calibration parameters used for calculation in the registers + * + * parameter | Register address | bit + *------------|------------------|---------------- + * dig_T1 | 0x88 and 0x89 | from 0 : 7 to 8: 15 + * dig_T2 | 0x8A and 0x8B | from 0 : 7 to 8: 15 + * dig_T3 | 0x8C and 0x8D | from 0 : 7 to 8: 15 + * dig_P1 | 0x8E and 0x8F | from 0 : 7 to 8: 15 + * dig_P2 | 0x90 and 0x91 | from 0 : 7 to 8: 15 + * dig_P3 | 0x92 and 0x93 | from 0 : 7 to 8: 15 + * dig_P4 | 0x94 and 0x95 | from 0 : 7 to 8: 15 + * dig_P5 | 0x96 and 0x97 | from 0 : 7 to 8: 15 + * dig_P6 | 0x98 and 0x99 | from 0 : 7 to 8: 15 + * dig_P7 | 0x9A and 0x9B | from 0 : 7 to 8: 15 + * dig_P8 | 0x9C and 0x9D | from 0 : 7 to 8: 15 + * dig_P9 | 0x9E and 0x9F | from 0 : 7 to 8: 15 + * dig_H1 | 0xA1 | from 0 to 7 + * dig_H2 | 0xE1 and 0xE2 | from 0 : 7 to 8: 15 + * dig_H3 | 0xE3 | from 0 to 7 + * dig_H4 | 0xE4 and 0xE5 | from 4 : 11 to 0: 3 + * dig_H5 | 0xE5 and 0xE6 | from 0 : 3 to 4: 11 + * dig_H6 | 0xE7 | from 0 to 7 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_calib_param(void) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 a_data_u8[BME280_CALIB_DATA_SIZE] = { + BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE, + BME280_INIT_VALUE, BME280_INIT_VALUE, BME280_INIT_VALUE}; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_TEMPERATURE_CALIB_DIG_T1_LSB_REG, + a_data_u8, + BME280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH); + + p_bme280->cal_param.dig_T1 = (u16)((( + (u16)((u8)a_data_u8[BME280_TEMPERATURE_CALIB_DIG_T1_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_TEMPERATURE_CALIB_DIG_T1_LSB]); + p_bme280->cal_param.dig_T2 = (s16)((( + (s16)((s8)a_data_u8[BME280_TEMPERATURE_CALIB_DIG_T2_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_TEMPERATURE_CALIB_DIG_T2_LSB]); + p_bme280->cal_param.dig_T3 = (s16)((( + (s16)((s8)a_data_u8[BME280_TEMPERATURE_CALIB_DIG_T3_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_TEMPERATURE_CALIB_DIG_T3_LSB]); + p_bme280->cal_param.dig_P1 = (u16)((( + (u16)((u8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P1_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P1_LSB]); + p_bme280->cal_param.dig_P2 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P2_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P2_LSB]); + p_bme280->cal_param.dig_P3 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P3_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P3_LSB]); + p_bme280->cal_param.dig_P4 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P4_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P4_LSB]); + p_bme280->cal_param.dig_P5 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P5_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P5_LSB]); + p_bme280->cal_param.dig_P6 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P6_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P6_LSB]); + p_bme280->cal_param.dig_P7 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P7_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P7_LSB]); + p_bme280->cal_param.dig_P8 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P8_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P8_LSB]); + p_bme280->cal_param.dig_P9 = (s16)((( + (s16)((s8)a_data_u8[BME280_PRESSURE_CALIB_DIG_P9_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_PRESSURE_CALIB_DIG_P9_LSB]); + p_bme280->cal_param.dig_H1 = + a_data_u8[BME280_HUMIDITY_CALIB_DIG_H1]; + com_rslt += p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_HUMIDITY_CALIB_DIG_H2_LSB_REG, a_data_u8, + BME280_HUMIDITY_CALIB_DATA_LENGTH); + p_bme280->cal_param.dig_H2 = (s16)((( + (s16)((s8)a_data_u8[BME280_HUMIDITY_CALIB_DIG_H2_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_08_BITS) | + a_data_u8[BME280_HUMIDITY_CALIB_DIG_H2_LSB]); + p_bme280->cal_param.dig_H3 = + a_data_u8[BME280_HUMIDITY_CALIB_DIG_H3]; + p_bme280->cal_param.dig_H4 = (s16)((( + (s16)((s8)a_data_u8[BME280_HUMIDITY_CALIB_DIG_H4_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS) | + (((u8)BME280_MASK_DIG_H4) & + a_data_u8[BME280_HUMIDITY_CALIB_DIG_H4_LSB])); + p_bme280->cal_param.dig_H5 = (s16)((( + (s16)((s8)a_data_u8[BME280_HUMIDITY_CALIB_DIG_H5_MSB])) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS) | + (a_data_u8[BME280_HUMIDITY_CALIB_DIG_H4_LSB] >> + BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + p_bme280->cal_param.dig_H6 = + (s8)a_data_u8[BME280_HUMIDITY_CALIB_DIG_H6]; + } + return com_rslt; +} +/*! + * @brief This API is used to get + * the temperature oversampling setting in the register 0xF4 + * bits from 5 to 7 + * + * value | Temperature oversampling + * ---------------------|--------------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of temperature over sampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_oversamp_temperature( + u8 *v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_value_u8 = BME280_GET_BITSLICE(v_data_u8, + BME280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE); + + p_bme280->oversamp_temperature = *v_value_u8; + } + return com_rslt; +} +/*! + * @brief This API is used to set + * the temperature oversampling setting in the register 0xF4 + * bits from 5 to 7 + * + * value | Temperature oversampling + * ---------------------|--------------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of temperature over sampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_oversamp_temperature( + u8 v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + u8 v_pre_config_value_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + v_data_u8 = p_bme280->ctrl_meas_reg; + v_data_u8 = + BME280_SET_BITSLICE(v_data_u8, + BME280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE, v_value_u8); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous value + of configuration register*/ + v_pre_config_value_u8 = p_bme280->config_reg; + com_rslt += bme280_write_register( + BME280_CONFIG_REG, + &v_pre_config_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value + of humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous and updated value + of configuration register*/ + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt = p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + p_bme280->oversamp_temperature = v_value_u8; + /* read the control measurement register value*/ + com_rslt = bme280_read_register( + BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the control + configuration register value*/ + com_rslt += bme280_read_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + return com_rslt; +} +/*! + * @brief This API is used to get + * the pressure oversampling setting in the register 0xF4 + * bits from 2 to 4 + * + * value | Pressure oversampling + * --------------------|-------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of pressure oversampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_oversamp_pressure( + u8 *v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_value_u8 = BME280_GET_BITSLICE( + v_data_u8, + BME280_CTRL_MEAS_REG_OVERSAMP_PRESSURE); + + p_bme280->oversamp_pressure = *v_value_u8; + } + return com_rslt; +} +/*! + * @brief This API is used to set + * the pressure oversampling setting in the register 0xF4 + * bits from 2 to 4 + * + * value | Pressure oversampling + * --------------------|-------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of pressure oversampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_oversamp_pressure( + u8 v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + u8 v_pre_config_value_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + v_data_u8 = p_bme280->ctrl_meas_reg; + v_data_u8 = + BME280_SET_BITSLICE(v_data_u8, + BME280_CTRL_MEAS_REG_OVERSAMP_PRESSURE, v_value_u8); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous value of + configuration register*/ + v_pre_config_value_u8 = p_bme280->config_reg; + com_rslt = bme280_write_register( + BME280_CONFIG_REG, + &v_pre_config_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous and updated value of + control measurement register*/ + bme280_write_register( + BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt = p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + p_bme280->oversamp_pressure = v_value_u8; + /* read the control measurement register value*/ + com_rslt = bme280_read_register( + BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the control + configuration register value*/ + com_rslt += bme280_read_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + return com_rslt; +} +/*! + * @brief This API is used to get + * the humidity oversampling setting in the register 0xF2 + * bits from 0 to 2 + * + * value | Humidity oversampling + * ---------------------|------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of humidity over sampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_oversamp_humidity( + u8 *v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_value_u8 = BME280_GET_BITSLICE( + v_data_u8, + BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY); + + p_bme280->oversamp_humidity = *v_value_u8; + } + return com_rslt; +} +/*! + * @brief This API is used to set + * the humidity oversampling setting in the register 0xF2 + * bits from 0 to 2 + * + * value | Humidity oversampling + * ---------------------|------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of humidity over sampling + * + * + * + * @note The "BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY" + * register sets the humidity + * data acquisition options of the device. + * @note changes to this registers only become + * effective after a write operation to + * "BME280_CTRL_MEAS_REG" register. + * @note In the code automated reading and writing of + * "BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY" + * @note register first set the + * "BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY" + * and then read and write + * the "BME280_CTRL_MEAS_REG" register in the function. + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_oversamp_humidity( + u8 v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 pre_ctrl_meas_value = BME280_INIT_VALUE; + u8 v_pre_config_value_u8 = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + /* write humidity oversampling*/ + v_data_u8 = p_bme280->ctrl_hum_reg; + v_data_u8 = + BME280_SET_BITSLICE(v_data_u8, + BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY, v_value_u8); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous value of + configuration register*/ + v_pre_config_value_u8 = p_bme280->config_reg; + com_rslt += bme280_write_register( + BME280_CONFIG_REG, + &v_pre_config_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write the value of control humidity*/ + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + control measurement register*/ + pre_ctrl_meas_value = + p_bme280->ctrl_meas_reg; + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &pre_ctrl_meas_value, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt += + p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + /* Control humidity write will effective only + after the control measurement register*/ + pre_ctrl_meas_value = + p_bme280->ctrl_meas_reg; + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &pre_ctrl_meas_value, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + p_bme280->oversamp_humidity = v_value_u8; + /* read the control measurement register value*/ + com_rslt += bme280_read_register(BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the control configuration register value*/ + com_rslt += bme280_read_register(BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + return com_rslt; +} +/*! + * @brief This API used to get the + * Operational Mode from the sensor in the register 0xF4 bit 0 and 1 + * + * + * + * @param v_power_mode_u8 : The value of power mode + * value | mode + * -----------------|------------------ + * 0x00 | BME280_SLEEP_MODE + * 0x01 and 0x02 | BME280_FORCED_MODE + * 0x03 | BME280_NORMAL_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_power_mode(u8 *v_power_mode_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_mode_u8r = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CTRL_MEAS_REG_POWER_MODE__REG, + &v_mode_u8r, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_power_mode_u8 = BME280_GET_BITSLICE(v_mode_u8r, + BME280_CTRL_MEAS_REG_POWER_MODE); + } + return com_rslt; +} +/*! + * @brief This API used to set the + * Operational Mode from the sensor in the register 0xF4 bit 0 and 1 + * + * + * + * @param v_power_mode_u8 : The value of power mode + * value | mode + * -----------------|------------------ + * 0x00 | BME280_SLEEP_MODE + * 0x01 and 0x02 | BME280_FORCED_MODE + * 0x03 | BME280_NORMAL_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_power_mode(u8 v_power_mode_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_mode_u8r = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + u8 v_pre_config_value_u8 = BME280_INIT_VALUE; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + if (v_power_mode_u8 <= BME280_NORMAL_MODE) + { + v_mode_u8r = p_bme280->ctrl_meas_reg; + v_mode_u8r = + BME280_SET_BITSLICE(v_mode_u8r, + BME280_CTRL_MEAS_REG_POWER_MODE, + v_power_mode_u8); + com_rslt = bme280_get_power_mode( + &v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous value of + configuration register*/ + v_pre_config_value_u8 = + p_bme280->config_reg; + com_rslt = bme280_write_register( + BME280_CONFIG_REG, + &v_pre_config_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous and updated value of + control measurement register*/ + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &v_mode_u8r, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt = + p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CTRL_MEAS_REG_POWER_MODE__REG, + &v_mode_u8r, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + /* read the control measurement register value*/ + com_rslt = bme280_read_register( + BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the config register value*/ + com_rslt += bme280_read_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + else + { + com_rslt = E_BME280_OUT_OF_RANGE; + } + } + return com_rslt; +} +/*! + * @brief Used to reset the sensor + * The value 0xB6 is written to the 0xE0 + * register the device is reset using the + * complete power-on-reset procedure. + * @note Soft reset can be easily set using bme280_set_softreset(). + * @note Usage Hint : bme280_set_softreset() + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_soft_rst(void) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_SOFT_RESET_CODE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_RST_REG, &v_data_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + return com_rslt; +} +/*! + * @brief This API used to get the sensor + * SPI mode(communication type) in the register 0xF5 bit 0 + * + * + * + * @param v_enable_disable_u8 : The value of SPI enable + * value | Description + * --------|-------------- + * 0 | Disable + * 1 | Enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_spi3(u8 *v_enable_disable_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CONFIG_REG_SPI3_ENABLE__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_enable_disable_u8 = BME280_GET_BITSLICE( + v_data_u8, + BME280_CONFIG_REG_SPI3_ENABLE); + } + return com_rslt; +} +/*! + * @brief This API used to set the sensor + * SPI mode(communication type) in the register 0xF5 bit 0 + * + * + * + * @param v_enable_disable_u8 : The value of SPI enable + * value | Description + * --------|-------------- + * 0 | Disable + * 1 | Enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_spi3(u8 v_enable_disable_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 pre_ctrl_meas_value = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + v_data_u8 = p_bme280->config_reg; + v_data_u8 = + BME280_SET_BITSLICE(v_data_u8, + BME280_CONFIG_REG_SPI3_ENABLE, v_enable_disable_u8); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous and updated value of + configuration register*/ + com_rslt += bme280_write_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + control measurement register*/ + pre_ctrl_meas_value = + p_bme280->ctrl_meas_reg; + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &pre_ctrl_meas_value, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt = + p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CONFIG_REG_SPI3_ENABLE__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + /* read the control measurement register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the control configuration register value*/ + com_rslt += bme280_read_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + return com_rslt; +} +/*! + * @brief This API is used to reads filter setting + * in the register 0xF5 bit 3 and 4 + * + * + * + * @param v_value_u8 : The value of IIR filter coefficient + * + * value | Filter coefficient + * -------------|------------------------- + * 0x00 | BME280_FILTER_COEFF_OFF + * 0x01 | BME280_FILTER_COEFF_2 + * 0x02 | BME280_FILTER_COEFF_4 + * 0x03 | BME280_FILTER_COEFF_8 + * 0x04 | BME280_FILTER_COEFF_16 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_filter(u8 *v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CONFIG_REG_FILTER__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_value_u8 = BME280_GET_BITSLICE(v_data_u8, + BME280_CONFIG_REG_FILTER); + } + return com_rslt; +} +/*! + * @brief This API is used to write filter setting + * in the register 0xF5 bit 3 and 4 + * + * + * + * @param v_value_u8 : The value of IIR filter coefficient + * + * value | Filter coefficient + * -------------|------------------------- + * 0x00 | BME280_FILTER_COEFF_OFF + * 0x01 | BME280_FILTER_COEFF_2 + * 0x02 | BME280_FILTER_COEFF_4 + * 0x03 | BME280_FILTER_COEFF_8 + * 0x04 | BME280_FILTER_COEFF_16 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_filter(u8 v_value_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 pre_ctrl_meas_value = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + v_data_u8 = p_bme280->config_reg; + v_data_u8 = + BME280_SET_BITSLICE(v_data_u8, + BME280_CONFIG_REG_FILTER, v_value_u8); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous and updated value of + configuration register*/ + com_rslt += bme280_write_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + control measurement register*/ + pre_ctrl_meas_value = + p_bme280->ctrl_meas_reg; + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &pre_ctrl_meas_value, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt = + p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CONFIG_REG_FILTER__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + /* read the control measurement register value*/ + com_rslt += bme280_read_register(BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the configuration register value*/ + com_rslt += bme280_read_register(BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + return com_rslt; +} +/*! + * @brief This API used to Read the + * standby duration time from the sensor in the register 0xF5 bit 5 to 7 + * + * @param v_standby_durn_u8 : The value of standby duration time value. + * value | standby duration + * -------------|----------------------- + * 0x00 | BME280_STANDBY_TIME_1_MS + * 0x01 | BME280_STANDBY_TIME_63_MS + * 0x02 | BME280_STANDBY_TIME_125_MS + * 0x03 | BME280_STANDBY_TIME_250_MS + * 0x04 | BME280_STANDBY_TIME_500_MS + * 0x05 | BME280_STANDBY_TIME_1000_MS + * 0x06 | BME280_STANDBY_TIME_2000_MS + * 0x07 | BME280_STANDBY_TIME_4000_MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_get_standby_durn(u8 *v_standby_durn_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + BME280_CONFIG_REG_TSB__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + *v_standby_durn_u8 = BME280_GET_BITSLICE( + v_data_u8, BME280_CONFIG_REG_TSB); + } + return com_rslt; +} +/*! + * @brief This API used to write the + * standby duration time from the sensor in the register 0xF5 bit 5 to 7 + * + * @param v_standby_durn_u8 : The value of standby duration time value. + * value | standby duration + * -------------|----------------------- + * 0x00 | BME280_STANDBY_TIME_1_MS + * 0x01 | BME280_STANDBY_TIME_63_MS + * 0x02 | BME280_STANDBY_TIME_125_MS + * 0x03 | BME280_STANDBY_TIME_250_MS + * 0x04 | BME280_STANDBY_TIME_500_MS + * 0x05 | BME280_STANDBY_TIME_1000_MS + * 0x06 | BME280_STANDBY_TIME_2000_MS + * 0x07 | BME280_STANDBY_TIME_4000_MS + * + * @note Normal mode comprises an automated perpetual + * cycling between an (active) + * Measurement period and an (inactive) standby period. + * @note The standby time is determined by + * the contents of the register t_sb. + * Standby time can be set using BME280_STANDBY_TIME_125_MS. + * + * @note Usage Hint : bme280_set_standby_durn(BME280_STANDBY_TIME_125_MS) + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_set_standby_durn(u8 v_standby_durn_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 pre_ctrl_meas_value = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + v_data_u8 = p_bme280->config_reg; + v_data_u8 = + BME280_SET_BITSLICE(v_data_u8, + BME280_CONFIG_REG_TSB, v_standby_durn_u8); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous and updated value of + configuration register*/ + com_rslt += bme280_write_register( + BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of control + measurement register*/ + pre_ctrl_meas_value = + p_bme280->ctrl_meas_reg; + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &pre_ctrl_meas_value, + BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + com_rslt = + p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + BME280_CONFIG_REG_TSB__REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + /* read the control measurement register value*/ + com_rslt += bme280_read_register(BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the configuration register value*/ + com_rslt += bme280_read_register(BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + } + return com_rslt; +} +/* + * @brief Writes the working mode to the sensor + * + * + * + * + * @param v_work_mode_u8 : Mode to be set + * value | Working mode + * ----------|-------------------- + * 0 | BME280_ULTRALOWPOWER_MODE + * 1 | BME280_LOWPOWER_MODE + * 2 | BME280_STANDARDRESOLUTION_MODE + * 3 | BME280_HIGHRESOLUTION_MODE + * 4 | BME280_ULTRAHIGHRESOLUTION_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +/*BME280_RETURN_FUNCTION_TYPE bme280_set_work_mode(u8 v_work_mode_u8) +{ +BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; +u8 v_data_u8 = BME280_INIT_VALUE; +if (p_bme280 == BME280_NULL) { + return E_BME280_NULL_PTR; +} else { + if (v_work_mode_u8 <= BME280_ULTRAHIGHRESOLUTION_MODE) { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + if (com_rslt == SUCCESS) { + switch (v_work_mode_u8) { + case BME280_ULTRALOWPOWER_MODE: + p_bme280->oversamp_temperature = + BME280_ULTRALOWPOWER_OSRS_T; + p_bme280->osrs_p = + BME280_ULTRALOWPOWER_OSRS_P; + break; + case BME280_LOWPOWER_MODE: + p_bme280->oversamp_temperature = + BME280_LOWPOWER_OSRS_T; + p_bme280->osrs_p = BME280_LOWPOWER_OSRS_P; + break; + case BME280_STANDARDRESOLUTION_MODE: + p_bme280->oversamp_temperature = + BME280_STANDARDRESOLUTION_OSRS_T; + p_bme280->osrs_p = + BME280_STANDARDRESOLUTION_OSRS_P; + break; + case BME280_HIGHRESOLUTION_MODE: + p_bme280->oversamp_temperature = + BME280_HIGHRESOLUTION_OSRS_T; + p_bme280->osrs_p = BME280_HIGHRESOLUTION_OSRS_P; + break; + case BME280_ULTRAHIGHRESOLUTION_MODE: + p_bme280->oversamp_temperature = + BME280_ULTRAHIGHRESOLUTION_OSRS_T; + p_bme280->osrs_p = + BME280_ULTRAHIGHRESOLUTION_OSRS_P; + break; + } + v_data_u8 = BME280_SET_BITSLICE(v_data_u8, + BME280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE, + p_bme280->oversamp_temperature); + v_data_u8 = BME280_SET_BITSLICE(v_data_u8, + BME280_CTRL_MEAS_REG_OVERSAMP_PRESSURE, + p_bme280->osrs_p); + com_rslt += p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + } else { + com_rslt = E_BME280_OUT_OF_RANGE; + } +} +return com_rslt; +}*/ +/*! + * @brief This API used to read uncompensated + * temperature,pressure and humidity in forced mode + * + * + * @param v_uncom_pressure_s32: The value of uncompensated pressure + * @param v_uncom_temperature_s32: The value of uncompensated temperature + * @param v_uncom_humidity_s32: The value of uncompensated humidity + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE +bme280_get_forced_uncomp_pressure_temperature_humidity( + s32 *v_uncom_pressure_s32, + s32 *v_uncom_temperature_s32, s32 *v_uncom_humidity_s32) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + u8 v_data_u8 = BME280_INIT_VALUE; + u8 v_waittime_u8 = BME280_INIT_VALUE; + u8 v_prev_pow_mode_u8 = BME280_INIT_VALUE; + u8 v_mode_u8r = BME280_INIT_VALUE; + u8 pre_ctrl_config_value = BME280_INIT_VALUE; + u8 v_pre_ctrl_hum_value_u8 = BME280_INIT_VALUE; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + v_mode_u8r = p_bme280->ctrl_meas_reg; + v_mode_u8r = + BME280_SET_BITSLICE(v_mode_u8r, + BME280_CTRL_MEAS_REG_POWER_MODE, BME280_FORCED_MODE); + com_rslt = bme280_get_power_mode(&v_prev_pow_mode_u8); + if (v_prev_pow_mode_u8 != BME280_SLEEP_MODE) + { + com_rslt += bme280_set_soft_rst(); + p_bme280->delay_msec(BME280_3MS_DELAY); + /* write previous and updated value of + configuration register*/ + pre_ctrl_config_value = p_bme280->config_reg; + com_rslt += bme280_write_register( + BME280_CONFIG_REG, + &pre_ctrl_config_value, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write the force mode */ + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &v_mode_u8r, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + else + { + /* write previous value of + humidity oversampling*/ + v_pre_ctrl_hum_value_u8 = + p_bme280->ctrl_hum_reg; + com_rslt += bme280_write_register( + BME280_CTRL_HUMIDITY_REG, + &v_pre_ctrl_hum_value_u8, + BME280_GEN_READ_WRITE_DATA_LENGTH); + /* write the force mode */ + com_rslt += bme280_write_register( + BME280_CTRL_MEAS_REG, + &v_mode_u8r, BME280_GEN_READ_WRITE_DATA_LENGTH); + } + bme280_compute_wait_time(&v_waittime_u8); + p_bme280->delay_msec(v_waittime_u8); + /* read the force-mode value of pressure + temperature and humidity*/ + com_rslt += + bme280_read_uncomp_pressure_temperature_humidity( + v_uncom_pressure_s32, v_uncom_temperature_s32, + v_uncom_humidity_s32); + + /* read the control humidity register value*/ + com_rslt += bme280_read_register( + BME280_CTRL_HUMIDITY_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_hum_reg = v_data_u8; + /* read the configuration register value*/ + com_rslt += bme280_read_register(BME280_CONFIG_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->config_reg = v_data_u8; + + /* read the control measurement register value*/ + com_rslt += bme280_read_register(BME280_CTRL_MEAS_REG, + &v_data_u8, BME280_GEN_READ_WRITE_DATA_LENGTH); + p_bme280->ctrl_meas_reg = v_data_u8; + } + return com_rslt; +} +/*! + * @brief + * This API write the data to + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_write_register(u8 v_addr_u8, + u8 *v_data_u8, u8 v_len_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_WRITE_FUNC( + p_bme280->dev_addr, + v_addr_u8, v_data_u8, v_len_u8); + } + return com_rslt; +} +/*! + * @brief + * This API reads the data from + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_register(u8 v_addr_u8, + u8 *v_data_u8, u8 v_len_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = ERROR; + /* check the p_bme280 structure pointer as NULL*/ + if (p_bme280 == BME280_NULL) + { + return E_BME280_NULL_PTR; + } + else + { + com_rslt = p_bme280->BME280_BUS_READ_FUNC( + p_bme280->dev_addr, + v_addr_u8, v_data_u8, v_len_u8); + } + return com_rslt; +} +#ifdef BME280_ENABLE_FLOAT +/*! + * @brief Reads actual temperature from uncompensated temperature + * @note returns the value in Degree centigrade + * @note Output value of "51.23" equals 51.23 DegC. + * + * + * + * @param v_uncom_temperature_s32 : value of uncompensated temperature + * + * + * + * @return Return the actual temperature in floating point + * + */ +double bme280_compensate_temperature_double(s32 v_uncom_temperature_s32) +{ + double v_x1_u32 = BME280_INIT_VALUE; + double v_x2_u32 = BME280_INIT_VALUE; + double temperature = BME280_INIT_VALUE; + + v_x1_u32 = (((double)v_uncom_temperature_s32) / 16384.0 - + ((double)p_bme280->cal_param.dig_T1) / 1024.0) * + ((double)p_bme280->cal_param.dig_T2); + v_x2_u32 = ((((double)v_uncom_temperature_s32) / 131072.0 - + ((double)p_bme280->cal_param.dig_T1) / 8192.0) * + (((double)v_uncom_temperature_s32) / 131072.0 - + ((double)p_bme280->cal_param.dig_T1) / 8192.0)) * + ((double)p_bme280->cal_param.dig_T3); + p_bme280->cal_param.t_fine = (s32)(v_x1_u32 + v_x2_u32); + temperature = (v_x1_u32 + v_x2_u32) / 5120.0; + + return temperature; +} +/*! + * @brief Reads actual pressure from uncompensated pressure + * @note Returns pressure in Pa as double. + * @note Output value of "96386.2" + * equals 96386.2 Pa = 963.862 hPa. + * + * + * @param v_uncom_pressure_s32 : value of uncompensated pressure + * + * + * @return Return the actual pressure in floating point + * + */ +double bme280_compensate_pressure_double(s32 v_uncom_pressure_s32) +{ + double v_x1_u32 = BME280_INIT_VALUE; + double v_x2_u32 = BME280_INIT_VALUE; + double pressure = BME280_INIT_VALUE; + + v_x1_u32 = ((double)p_bme280->cal_param.t_fine / + 2.0) - + 64000.0; + v_x2_u32 = v_x1_u32 * v_x1_u32 * + ((double)p_bme280->cal_param.dig_P6) / 32768.0; + v_x2_u32 = v_x2_u32 + v_x1_u32 * + ((double)p_bme280->cal_param.dig_P5) * 2.0; + v_x2_u32 = (v_x2_u32 / 4.0) + + (((double)p_bme280->cal_param.dig_P4) * 65536.0); + v_x1_u32 = (((double)p_bme280->cal_param.dig_P3) * + v_x1_u32 * v_x1_u32 / 524288.0 + + ((double)p_bme280->cal_param.dig_P2) * v_x1_u32) / + 524288.0; + v_x1_u32 = (1.0 + v_x1_u32 / 32768.0) * + ((double)p_bme280->cal_param.dig_P1); + pressure = 1048576.0 - (double)v_uncom_pressure_s32; + /* Avoid exception caused by division by zero */ + if ((v_x1_u32 > 0) || (v_x1_u32 < 0)) + pressure = (pressure - (v_x2_u32 / 4096.0)) * 6250.0 / v_x1_u32; + else + return BME280_INVALID_DATA; + v_x1_u32 = ((double)p_bme280->cal_param.dig_P9) * + pressure * pressure / 2147483648.0; + v_x2_u32 = pressure * ((double)p_bme280->cal_param.dig_P8) / 32768.0; + pressure = pressure + (v_x1_u32 + v_x2_u32 + + ((double)p_bme280->cal_param.dig_P7)) / + 16.0; + + return pressure; +} +/*! + * @brief Reads actual humidity from uncompensated humidity + * @note returns the value in relative humidity (%rH) + * @note Output value of "42.12" equals 42.12 %rH + * + * @param v_uncom_humidity_s32 : value of uncompensated humidity + * + * + * + * @return Return the actual humidity in floating point + * + */ +double bme280_compensate_humidity_double(s32 v_uncom_humidity_s32) +{ + double var_h = BME280_INIT_VALUE; + + var_h = (((double)p_bme280->cal_param.t_fine) - 76800.0); + if ((var_h > 0) || (var_h < 0)) + var_h = (v_uncom_humidity_s32 - + (((double)p_bme280->cal_param.dig_H4) * 64.0 + + ((double)p_bme280->cal_param.dig_H5) / 16384.0 * var_h)) * + (((double)p_bme280->cal_param.dig_H2) / 65536.0 * + (1.0 + ((double)p_bme280->cal_param.dig_H6) / 67108864.0 * var_h * (1.0 + ((double)p_bme280->cal_param.dig_H3) / 67108864.0 * var_h))); + else + return BME280_INVALID_DATA; + var_h = var_h * (1.0 - ((double) + p_bme280->cal_param.dig_H1) * + var_h / 524288.0); + if (var_h > 100.0) + var_h = 100.0; + else if (var_h < 0.0) + var_h = 0.0; + return var_h; +} +#endif +#if defined(BME280_ENABLE_INT64) && defined(BME280_64BITSUPPORT_PRESENT) +/*! + * @brief Reads actual pressure from uncompensated pressure + * @note Returns the value in Pa as unsigned 32 bit + * integer in Q24.8 format (24 integer bits and + * 8 fractional bits). + * @note Output value of "24674867" + * represents 24674867 / 256 = 96386.2 Pa = 963.862 hPa + * + * + * + * @param v_uncom_pressure_s32 : value of uncompensated temperature + * + * + * @return Return the actual pressure in u32 + * + */ +u32 bme280_compensate_pressure_int64(s32 v_uncom_pressure_s32) +{ + s64 v_x1_s64r = BME280_INIT_VALUE; + s64 v_x2_s64r = BME280_INIT_VALUE; + s64 pressure = BME280_INIT_VALUE; + + v_x1_s64r = ((s64)p_bme280->cal_param.t_fine) - 128000; + v_x2_s64r = v_x1_s64r * v_x1_s64r * + (s64)p_bme280->cal_param.dig_P6; + v_x2_s64r = v_x2_s64r + ((v_x1_s64r * + (s64)p_bme280->cal_param.dig_P5) + << BME280_SHIFT_BIT_POSITION_BY_17_BITS); + v_x2_s64r = v_x2_s64r + + (((s64)p_bme280->cal_param.dig_P4) + << BME280_SHIFT_BIT_POSITION_BY_35_BITS); + v_x1_s64r = ((v_x1_s64r * v_x1_s64r * + (s64)p_bme280->cal_param.dig_P3) >> + BME280_SHIFT_BIT_POSITION_BY_08_BITS) + + ((v_x1_s64r * (s64)p_bme280->cal_param.dig_P2) + << BME280_SHIFT_BIT_POSITION_BY_12_BITS); + v_x1_s64r = (((((s64)1) + << BME280_SHIFT_BIT_POSITION_BY_47_BITS) + + v_x1_s64r)) * + ((s64)p_bme280->cal_param.dig_P1) >> + BME280_SHIFT_BIT_POSITION_BY_33_BITS; + pressure = 1048576 - v_uncom_pressure_s32; + /* Avoid exception caused by division by zero */ + if (v_x1_s64r != BME280_INIT_VALUE) +#if defined __KERNEL__ + pressure = div64_s64((((pressure + << BME280_SHIFT_BIT_POSITION_BY_31_BITS) - + v_x2_s64r) * + 3125), + v_x1_s64r); +#else + pressure = (((pressure + << BME280_SHIFT_BIT_POSITION_BY_31_BITS) - + v_x2_s64r) * + 3125) / + v_x1_s64r; +#endif + else + return BME280_INVALID_DATA; + v_x1_s64r = (((s64)p_bme280->cal_param.dig_P9) * + (pressure >> BME280_SHIFT_BIT_POSITION_BY_13_BITS) * + (pressure >> BME280_SHIFT_BIT_POSITION_BY_13_BITS)) >> + BME280_SHIFT_BIT_POSITION_BY_25_BITS; + v_x2_s64r = (((s64)p_bme280->cal_param.dig_P8) * + pressure) >> + BME280_SHIFT_BIT_POSITION_BY_19_BITS; + pressure = (((pressure + v_x1_s64r + + v_x2_s64r) >> + BME280_SHIFT_BIT_POSITION_BY_08_BITS) + + (((s64)p_bme280->cal_param.dig_P7) + << BME280_SHIFT_BIT_POSITION_BY_04_BITS)); + + return (u32)pressure; +} +/*! + * @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_uncom_pressure_s32 : value of uncompensated pressure + * + * + * @return the actual pressure in u32 + * + */ +u32 bme280_compensate_pressure_int64_twentyfour_bit_output( + s32 v_uncom_pressure_s32) +{ + u32 pressure = BME280_INIT_VALUE; + + pressure = bme280_compensate_pressure_int64( + v_uncom_pressure_s32); + pressure = (u32)(pressure >> BME280_SHIFT_BIT_POSITION_BY_01_BIT); + return pressure; +} +#endif +/*! + * @brief Computing waiting time for sensor data read + * + * + * + * + * @param v_delaytime_u8 : The value of delay time for force mode + * + * + * @retval 0 -> Success + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_compute_wait_time(u8 + *v_delaytime_u8) +{ + /* used to return the communication result*/ + BME280_RETURN_FUNCTION_TYPE com_rslt = SUCCESS; + + *v_delaytime_u8 = (T_INIT_MAX + + T_MEASURE_PER_OSRS_MAX * + (((1 << p_bme280->oversamp_temperature) >> BME280_SHIFT_BIT_POSITION_BY_01_BIT) + ((1 << p_bme280->oversamp_pressure) >> BME280_SHIFT_BIT_POSITION_BY_01_BIT) + + ((1 << p_bme280->oversamp_humidity) >> BME280_SHIFT_BIT_POSITION_BY_01_BIT)) + + ((p_bme280->oversamp_pressure > 0) ? T_SETUP_PRESSURE_MAX : 0) + + ((p_bme280->oversamp_humidity > 0) ? T_SETUP_HUMIDITY_MAX : 0) + 15) / + 16; + return com_rslt; +} \ No newline at end of file diff --git a/bme280.h b/bme280.h new file mode 100644 index 0000000..76ee8b6 --- /dev/null +++ b/bme280.h @@ -0,0 +1,1695 @@ +/** \mainpage +* +**************************************************************************** +* Copyright (C) 2015 - 2016 Bosch Sensortec GmbH +* +* File : bme280.h +* +* Date : 2016/07/04 +* +* Revision : 2.0.5(Pressure and Temperature compensation code revision is 1.1 +* and Humidity compensation code revision is 1.0) +* +* Usage: Sensor Driver for BME280 sensor +* +**************************************************************************** +* +* \section License +* +* 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 bme280.h + \brief BME280 Sensor Driver Support Header File */ +#ifndef __BME280_H__ +#define __BME280_H__ + + +/*! +* @brief The following definition uses for define 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 +#define BME280_64BITSUPPORT_PRESENT +/* 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 */ + + + +#else /* ! __KERNEL__ */ +/********************************************************** +* These definition uses for 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 */ +#define BME280_64BITSUPPORT_PRESENT +/************************************************ + * 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 */ +#define BME280_64BITSUPPORT_PRESENT +/************************************************ + * 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 */ +#define BME280_64BITSUPPORT_PRESENT +#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 */ +#define BME280_64BITSUPPORT_PRESENT +#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 The API will only offer 32 bit pressure calculation.This will \ +slightly impede accuracy(noise of ~1 pascal RMS will be added to output). +#warning If 64 bit integers are supported on your platform, \ +please set s64 manually and "#define(BME280_64BITSUPPORT_PRESENT)" manually. +#endif + +/*unsigned integer types*/ +typedef unsigned char u8;/**< used for unsigned 8bit */ +typedef unsigned short int u16;/**< used for unsigned 16bit */ +typedef unsigned long 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 */ +/*! @brief + * If your machine support 64 bit + * define the MACHINE_64_BIT + */ +#define BME280_64BITSUPPORT_PRESENT + +/* 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 */ +#define BME280_64BITSUPPORT_PRESENT + +#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 */ +#define BME280_64BITSUPPORT_PRESENT +#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 */ +#define BME280_64BITSUPPORT_PRESENT +#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 The API will only offer 32 bit pressure calculation.This will \ +slightly impede accuracy(noise of ~1 pascal RMS will be added to output). +#warning If 64 bit integers are supported on your platform, \ +please set s64 manually and "#define(BME280_64BITSUPPORT_PRESENT)" manually. +#endif + +/*unsigned integer types*/ +typedef unsigned char u8;/**< used for unsigned 8bit */ +typedef unsigned short int u16;/**< used for unsigned 16bit */ +typedef unsigned long 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 */ +typedef unsigned long long int u64;/**< used for unsigned 64bit */ +#define BME280_64BITSUPPORT_PRESENT + +/* 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 */ +#define BME280_64BITSUPPORT_PRESENT + +#else +#warning The data types defined above which not supported \ +define the data types manually +#endif +#endif +#endif +/********************************************/ +/**\name ENABLE FLOATING OUTPUT */ +/**************************************/ +/*! +* @brief If the user wants to support floating point calculations, please set + the following define. If floating point + calculation is not wanted or allowed + (e.g. in Linux kernel), please do not set the define. */ +#define BME280_ENABLE_FLOAT +/*! +* @brief If the user wants to support 64 bit integer calculation + (needed for optimal pressure accuracy) please set + the following define. If int64 calculation is not wanted + (e.g. because it would include + large libraries), please do not set the define. */ +#define BME280_ENABLE_INT64 +/***************************************************************/ +/**\name BUS READ AND WRITE FUNCTION POINTERS */ +/***************************************************************/ +/*! + @brief Define the calling convention of YOUR bus communication routine. + @note This includes types of parameters. This example shows the + configuration for an SPI bus link. + If your communication function looks like this: + write_my_bus_xy(u8 device_addr, u8 register_addr, + u8 * data, u8 length); + The BME280_WR_FUNC_PTR would equal: + BME280_WR_FUNC_PTR s8 (* bus_write)(u8, + u8, u8 *, u8) + Parameters can be mixed as needed refer to the + refer BME280_BUS_WRITE_FUNC macro. +*/ +/** defines the return parameter type of the BME280_WR_FUNCTION */ +#define BME280_BUS_WR_RETURN_TYPE s8 + +/* links the order of parameters defined in +BME280_BUS_WR_PARAM_TYPE to function calls used inside the API*/ +#define BME280_BUS_WR_PARAM_TYPES u8, u8,\ + u8 *, u8 + +/* links the order of parameters defined in +BME280_BUS_WR_PARAM_TYPE to function calls used inside the API*/ +#define BME280_BUS_WR_PARAM_ORDER(device_addr, register_addr,\ + register_data, wr_len) + +/* never change this line */ +#define BME280_BUS_WRITE_FUNC(device_addr, register_addr,\ +register_data, wr_len) bus_write(device_addr, register_addr,\ + register_data, wr_len) +/*! + @brief link macro between API function calls and bus read function + @note The bus write function can change since this is a + system dependant issue. + If the bus_read parameter calling order is like: reg_addr, + reg_data, wr_len it would be as it is here. + If the parameters are differently ordered or your communication + function like I2C need to know the device address, + you can change this macro accordingly. + BME280_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, wr_len)\ + bus_read(dev_addr, reg_addr, reg_data, wr_len) + This macro lets all API functions call YOUR communication routine in a + way that equals your definition in the + refer BME280_WR_FUNC_PTR definition. + @note: this macro also includes the "MSB='1' + for reading BME280 addresses. +*/ +/*defines the return parameter type of the BME280_RD_FUNCTION +*/ +#define BME280_BUS_RD_RETURN_TYPE s8 + +/**\brief defines the calling parameter types of the BME280_RD_FUNCTION +*/ +#define BME280_BUS_RD_PARAM_TYPES (u8, u8,\ + u8 *, u8) + +/* links the order of parameters defined in \ +BME280_BUS_RD_PARAM_TYPE to function calls used inside the API +*/ +#define BME280_BUS_RD_PARAM_ORDER (device_addr, register_addr,\ + register_data) + +/* never change this line */ +#define BME280_BUS_READ_FUNC(device_addr, register_addr,\ + register_data, rd_len)bus_read(device_addr, register_addr,\ + register_data, rd_len) +/****************************************/ +/**\name DELAY */ +/****************************************/ +/* defines the return parameter type of the BME280_DELAY_FUNCTION +*/ +#define BME280_DELAY_RETURN_TYPE void + +/* defines the calling parameter types of the BME280_DELAY_FUNCTION +*/ +#define BME280_DELAY_PARAM_TYPES u16 +/***************************************************************/ +/**\name GET AND SET BITSLICE FUNCTIONS */ +/***************************************************************/ +/* never change this line */ +#define BME280_DELAY_FUNC(delay_in_msec)\ + delay_func(delay_in_msec) + +#define BME280_GET_BITSLICE(regvar, bitname)\ + ((regvar & bitname##__MSK) >> bitname##__POS) + +#define BME280_SET_BITSLICE(regvar, bitname, val)\ +((regvar & ~bitname##__MSK) | ((val< Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_init(struct bme280_t *bme280); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION UNCOMPENSATED TEMPERATURE */ +/**************************************************************/ +/*! + * @brief This API is used to read uncompensated temperature + * in the registers 0xFA, 0xFB and 0xFC + * @note 0xFA -> MSB -> bit from 0 to 7 + * @note 0xFB -> LSB -> bit from 0 to 7 + * @note 0xFC -> LSB -> bit from 4 to 7 + * + * @param v_uncomp_temperature_s32 : The value of uncompensated temperature + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_temperature( +s32 *v_uncomp_temperature_s32); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION TRUE TEMPERATURE */ +/**************************************************************/ +/*! + * @brief Reads actual temperature from uncompensated temperature + * @note Returns the value in 0.01 degree Centigrade + * Output value of "5123" equals 51.23 DegC. + * + * + * + * @param v_uncomp_temperature_s32 : value of uncompensated temperature + * + * + * @return Returns the actual temperature + * +*/ +s32 bme280_compensate_temperature_int32(s32 v_uncomp_temperature_s32); +/*! + * @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_s32: value of uncompensated temperature + * + * + * + * @return Return the actual temperature as s16 output + * +*/ +s16 bme280_compensate_temperature_int32_sixteen_bit_output( +s32 v_uncomp_temperature_s32); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION UNCOMPENSATED PRESSURE */ +/**************************************************************/ +/*! + * @brief This API is used to read uncompensated pressure. + * in the registers 0xF7, 0xF8 and 0xF9 + * @note 0xF7 -> MSB -> bit from 0 to 7 + * @note 0xF8 -> LSB -> bit from 0 to 7 + * @note 0xF9 -> LSB -> bit from 4 to 7 + * + * + * + * @param v_uncomp_pressure_s32 : The value of uncompensated pressure + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_pressure( +s32 *v_uncomp_pressure_s32); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION TRUE PRESSURE */ +/**************************************************************/ +/*! + * @brief Reads actual pressure from uncompensated pressure + * @note Returns the value in Pascal(Pa) + * Output value of "96386" equals 96386 Pa = + * 963.86 hPa = 963.86 millibar + * + * + * + * @param v_uncomp_pressure_s32 : value of uncompensated pressure + * + * + * + * @return Return the actual pressure output as u32 + * +*/ +u32 bme280_compensate_pressure_int32(s32 v_uncomp_pressure_s32); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION UNCOMPENSATED HUMIDITY */ +/**************************************************************/ +/*! + * @brief This API is used to read uncompensated humidity. + * in the registers 0xF7, 0xF8 and 0xF9 + * @note 0xFD -> MSB -> bit from 0 to 7 + * @note 0xFE -> LSB -> bit from 0 to 7 + * + * + * + * @param v_uncomp_humidity_s32 : The value of uncompensated humidity + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_humidity( +s32 *v_uncomp_humidity_s32); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION RELATIVE HUMIDITY */ +/**************************************************************/ +/*! + * @brief Reads actual humidity from uncompensated humidity + * @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_s32: value of uncompensated humidity + * + * @return Return the actual relative humidity output as u32 + * +*/ +u32 bme280_compensate_humidity_int32(s32 v_uncomp_humidity_s32); +/*! + * @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_s32: value of uncompensated humidity + * + * + * @return Return the actual relative humidity output as u16 + * +*/ +u16 bme280_compensate_humidity_int32_sixteen_bit_output( +s32 v_uncomp_humidity_s32); +/**************************************************************/ +/**\name FUNCTION FOR INTIALIZATION UNCOMPENSATED PRESSURE, + TEMPERATURE AND HUMIDITY */ +/**************************************************************/ +/*! + * @brief This API used to read uncompensated + * pressure,temperature and humidity + * + * + * + * + * @param v_uncomp_pressure_s32: The value of uncompensated pressure. + * @param v_uncomp_temperature_s32: The value of uncompensated temperature + * @param v_uncomp_humidity_s32: The value of uncompensated humidity. + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_read_uncomp_pressure_temperature_humidity( +s32 *v_uncomp_pressure_s32, +s32 *v_uncomp_temperature_s32, s32 *v_uncomp_humidity_s32); +/**************************************************************/ +/**\name FUNCTION FOR TRUE UNCOMPENSATED PRESSURE, + TEMPERATURE AND HUMIDITY */ +/**************************************************************/ +/*! + * @brief This API used to read true pressure, temperature and humidity + * + * + * + * + * @param v_pressure_u32 : The value of compensated pressure. + * @param v_temperature_s32 : The value of compensated temperature. + * @param v_humidity_u32 : The value of compensated humidity. + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_read_pressure_temperature_humidity( +u32 *v_pressure_u32, s32 *v_temperature_s32, u32 *v_humidity_u32); +/**************************************************************/ +/**\name FUNCTION FOR CALIBRATION */ +/**************************************************************/ +/*! + * @brief This API is used to + * calibration parameters used for calculation in the registers + * + * parameter | Register address | bit + *------------|------------------|---------------- + * dig_T1 | 0x88 and 0x89 | from 0 : 7 to 8: 15 + * dig_T2 | 0x8A and 0x8B | from 0 : 7 to 8: 15 + * dig_T3 | 0x8C and 0x8D | from 0 : 7 to 8: 15 + * dig_P1 | 0x8E and 0x8F | from 0 : 7 to 8: 15 + * dig_P2 | 0x90 and 0x91 | from 0 : 7 to 8: 15 + * dig_P3 | 0x92 and 0x93 | from 0 : 7 to 8: 15 + * dig_P4 | 0x94 and 0x95 | from 0 : 7 to 8: 15 + * dig_P5 | 0x96 and 0x97 | from 0 : 7 to 8: 15 + * dig_P6 | 0x98 and 0x99 | from 0 : 7 to 8: 15 + * dig_P7 | 0x9A and 0x9B | from 0 : 7 to 8: 15 + * dig_P8 | 0x9C and 0x9D | from 0 : 7 to 8: 15 + * dig_P9 | 0x9E and 0x9F | from 0 : 7 to 8: 15 + * dig_H1 | 0xA1 | from 0 to 7 + * dig_H2 | 0xE1 and 0xE2 | from 0 : 7 to 8: 15 + * dig_H3 | 0xE3 | from 0 to 7 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_calib_param(void); +/**************************************************************/ +/**\name FUNCTION FOR TEMPERATURE OVER SAMPLING */ +/**************************************************************/ +/*! + * @brief This API is used to get + * the temperature oversampling setting in the register 0xF4 + * bits from 5 to 7 + * + * value | Temperature oversampling + * ---------------------|--------------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of temperature over sampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_oversamp_temperature( +u8 *v_value_u8); +/*! + * @brief This API is used to set + * the temperature oversampling setting in the register 0xF4 + * bits from 5 to 7 + * + * value | Temperature oversampling + * ---------------------|--------------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of temperature over sampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_oversamp_temperature( +u8 v_value_u8); +/**************************************************************/ +/**\name FUNCTION FOR PRESSURE OVER SAMPLING */ +/**************************************************************/ +/*! + * @brief This API is used to get + * the pressure oversampling setting in the register 0xF4 + * bits from 2 to 4 + * + * value | Pressure oversampling + * --------------------|-------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of pressure oversampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_oversamp_pressure( +u8 *v_value_u8); +/*! + * @brief This API is used to set + * the pressure oversampling setting in the register 0xF4 + * bits from 2 to 4 + * + * value | Pressure oversampling + * --------------------|-------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of pressure oversampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_oversamp_pressure( +u8 v_value_u8); +/**************************************************************/ +/**\name FUNCTION FOR HUMIDITY OVER SAMPLING */ +/**************************************************************/ +/*! + * @brief This API is used to get + * the humidity oversampling setting in the register 0xF2 + * bits from 0 to 2 + * + * value | Humidity oversampling + * ---------------------|------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of humidity over sampling + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_oversamp_humidity(u8 *v_value_u8); +/*! + * @brief This API is used to set + * the humidity oversampling setting in the register 0xF2 + * bits from 0 to 2 + * + * value | Humidity oversampling + * ---------------------|------------------------- + * 0x00 | Skipped + * 0x01 | BME280_OVERSAMP_1X + * 0x02 | BME280_OVERSAMP_2X + * 0x03 | BME280_OVERSAMP_4X + * 0x04 | BME280_OVERSAMP_8X + * 0x05,0x06 and 0x07 | BME280_OVERSAMP_16X + * + * + * @param v_value_u8 : The value of humidity over sampling + * + * + * + * @note The "BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY" + * register sets the humidity + * data acquisition options of the device. + * @note changes to this registers only become + * effective after a write operation to + * "BME280_CTRL_MEAS_REG" register. + * @note In the code automated reading and writing of + * "BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY" + * @note register first set the + * "BME280_CTRL_HUMIDITY_REG_OVERSAMP_HUMIDITY" + * and then read and write + * the "BME280_CTRL_MEAS_REG" register in the function. + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_oversamp_humidity( +u8 v_value_u8); +/**************************************************************/ +/**\name FUNCTION FOR POWER MODE*/ +/**************************************************************/ +/*! + * @brief This API used to get the + * Operational Mode from the sensor in the register 0xF4 bit 0 and 1 + * + * + * + * @param v_power_mode_u8 : The value of power mode + * value | mode + * -----------------|------------------ + * 0x00 | BME280_SLEEP_MODE + * 0x01 and 0x02 | BME280_FORCED_MODE + * 0x03 | BME280_NORMAL_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_power_mode(u8 *v_power_mode_u8); +/*! + * @brief This API used to set the + * Operational Mode from the sensor in the register 0xF4 bit 0 and 1 + * + * + * + * @param v_power_mode_u8 : The value of power mode + * value | mode + * -----------------|------------------ + * 0x00 | BME280_SLEEP_MODE + * 0x01 and 0x02 | BME280_FORCED_MODE + * 0x03 | BME280_NORMAL_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_power_mode(u8 v_power_mode_u8); +/**************************************************************/ +/**\name FUNCTION FOR SOFT RESET*/ +/**************************************************************/ +/*! + * @brief Used to reset the sensor + * The value 0xB6 is written to the 0xE0 + * register the device is reset using the + * complete power-on-reset procedure. + * @note Soft reset can be easily set using bme280_set_softreset(). + * @note Usage Hint : bme280_set_softreset() + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_soft_rst(void); +/**************************************************************/ +/**\name FUNCTION FOR SPI ENABLE*/ +/**************************************************************/ +/*! + * @brief This API used to get the sensor + * SPI mode(communication type) in the register 0xF5 bit 0 + * + * + * + * @param v_enable_disable_u8 : The value of SPI enable + * value | Description + * --------|-------------- + * 0 | Disable + * 1 | Enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_spi3(u8 *v_enable_disable_u8); +/*! + * @brief This API used to set the sensor + * SPI mode(communication type) in the register 0xF5 bit 0 + * + * + * + * @param v_enable_disable_u8 : The value of SPI enable + * value | Description + * --------|-------------- + * 0 | Disable + * 1 | Enable + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_spi3(u8 v_enable_disable_u8); +/**************************************************************/ +/**\name FUNCTION FOR IIR FILTER*/ +/**************************************************************/ +/*! + * @brief This API is used to reads filter setting + * in the register 0xF5 bit 3 and 4 + * + * + * + * @param v_value_u8 : The value of IIR filter coefficient + * + * value | Filter coefficient + * -------------|------------------------- + * 0x00 | BME280_FILTER_COEFF_OFF + * 0x01 | BME280_FILTER_COEFF_2 + * 0x02 | BME280_FILTER_COEFF_4 + * 0x03 | BME280_FILTER_COEFF_8 + * 0x04 | BME280_FILTER_COEFF_16 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_filter(u8 *v_value_u8); +/*! + * @brief This API is used to write filter setting + * in the register 0xF5 bit 3 and 4 + * + * + * + * @param v_value_u8 : The value of IIR filter coefficient + * + * value | Filter coefficient + * -------------|------------------------- + * 0x00 | BME280_FILTER_COEFF_OFF + * 0x01 | BME280_FILTER_COEFF_2 + * 0x02 | BME280_FILTER_COEFF_4 + * 0x03 | BME280_FILTER_COEFF_8 + * 0x04 | BME280_FILTER_COEFF_16 + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_filter(u8 v_value_u8); +/**************************************************************/ +/**\name FUNCTION FOR STANDBY DURATION*/ +/**************************************************************/ +/*! + * @brief This API used to Read the + * standby duration time from the sensor in the register 0xF5 bit 5 to 7 + * + * @param v_standby_durn_u8 : The value of standby duration time value. + * value | standby duration + * -------------|----------------------- + * 0x00 | BME280_STANDBY_TIME_1_MS + * 0x01 | BME280_STANDBY_TIME_63_MS + * 0x02 | BME280_STANDBY_TIME_125_MS + * 0x03 | BME280_STANDBY_TIME_250_MS + * 0x04 | BME280_STANDBY_TIME_500_MS + * 0x05 | BME280_STANDBY_TIME_1000_MS + * 0x06 | BME280_STANDBY_TIME_2000_MS + * 0x07 | BME280_STANDBY_TIME_4000_MS + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_get_standby_durn(u8 *v_standby_durn_u8); +/*! + * @brief This API used to write the + * standby duration time from the sensor in the register 0xF5 bit 5 to 7 + * + * @param v_standby_durn_u8 : The value of standby duration time value. + * value | standby duration + * -------------|----------------------- + * 0x00 | BME280_STANDBY_TIME_1_MS + * 0x01 | BME280_STANDBY_TIME_63_MS + * 0x02 | BME280_STANDBY_TIME_125_MS + * 0x03 | BME280_STANDBY_TIME_250_MS + * 0x04 | BME280_STANDBY_TIME_500_MS + * 0x05 | BME280_STANDBY_TIME_1000_MS + * 0x06 | BME280_STANDBY_TIME_2000_MS + * 0x07 | BME280_STANDBY_TIME_4000_MS + * + * @note Normal mode comprises an automated perpetual + * cycling between an (active) + * Measurement period and an (inactive) standby period. + * @note The standby time is determined by + * the contents of the register t_sb. + * Standby time can be set using BME280_STANDBY_TIME_125_MS. + * + * @note Usage Hint : bme280_set_standby_durn(BME280_STANDBY_TIME_125_MS) + * + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE bme280_set_standby_durn(u8 v_standby_durn_u8); +/**************************************************************/ +/**\name FUNCTION FOR WORK MODE*/ +/**************************************************************/ +/* + * @brief Writes the working mode to the sensor + * + * + * + * + * @param v_work_mode_u8 : Mode to be set + * value | Working mode + * ----------|-------------------- + * 0 | BME280_ULTRALOWPOWER_MODE + * 1 | BME280_LOWPOWER_MODE + * 2 | BME280_STANDARDRESOLUTION_MODE + * 3 | BME280_HIGHRESOLUTION_MODE + * 4 | BME280_ULTRAHIGHRESOLUTION_MODE + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +/*BME280_RETURN_FUNCTION_TYPE bme280_set_work_mode(u8 v_work_mode_u8);*/ +/**************************************************************/ +/**\name FUNCTION FOR FORCE MODE DATA READ*/ +/**************************************************************/ +/*! + * @brief This API used to read uncompensated + * temperature,pressure and humidity in forced mode + * + * + * @param v_uncom_pressure_s32: The value of uncompensated pressure + * @param v_uncom_temperature_s32: The value of uncompensated temperature + * @param v_uncom_humidity_s32: The value of uncompensated humidity + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * +*/ +BME280_RETURN_FUNCTION_TYPE +bme280_get_forced_uncomp_pressure_temperature_humidity( +s32 *v_uncom_pressure_s32, +s32 *v_uncom_temperature_s32, s32 *v_uncom_humidity_s32); +/**************************************************************/ +/**\name FUNCTION FOR COMMON READ AND WRITE */ +/**************************************************************/ +/*! + * @brief + * This API write the data to + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_write_register(u8 v_addr_u8, +u8 *v_data_u8, u8 v_len_u8); +/*! + * @brief + * This API reads the data from + * the given register + * + * + * @param v_addr_u8 -> Address of the register + * @param v_data_u8 -> The data from the register + * @param v_len_u8 -> no of bytes to read + * + * + * @return results of bus communication function + * @retval 0 -> Success + * @retval -1 -> Error + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_read_register(u8 v_addr_u8, +u8 *v_data_u8, u8 v_len_u8); +/**************************************************************/ +/**\name FUNCTION FOR FLOAT OUTPUT TEMPERATURE*/ +/**************************************************************/ +#ifdef BME280_ENABLE_FLOAT +/*! + * @brief Reads actual temperature from uncompensated temperature + * @note returns the value in Degree centigrade + * @note Output value of "51.23" equals 51.23 DegC. + * + * + * + * @param v_uncom_temperature_s32 : value of uncompensated temperature + * + * + * + * @return Return the actual temperature in floating point + * +*/ +double bme280_compensate_temperature_double( +s32 v_uncom_temperature_s32); +/**************************************************************/ +/**\name FUNCTION FOR FLOAT OUTPUT PRESSURE*/ +/**************************************************************/ +/*! + * @brief Reads actual pressure from uncompensated pressure + * @note Returns pressure in Pa as double. + * @note Output value of "96386.2" + * equals 96386.2 Pa = 963.862 hPa. + * + * + * @param v_uncom_pressure_s32 : value of uncompensated pressure + * + * + * @return Return the actual pressure in floating point + * +*/ +double bme280_compensate_pressure_double(s32 v_uncom_pressure_s32); +/**************************************************************/ +/**\name FUNCTION FOR FLOAT OUTPUT HUMIDITY*/ +/**************************************************************/ +/*! + * @brief Reads actual humidity from uncompensated humidity + * @note returns the value in relative humidity (%rH) + * @note Output value of "42.12" equals 42.12 %rH + * + * @param v_uncom_humidity_s32 : value of uncompensated humidity + * + * + * + * @return Return the actual humidity in floating point + * +*/ +double bme280_compensate_humidity_double(s32 v_uncom_humidity_s32); +#endif +/**************************************************************/ +/**\name FUNCTION FOR 64BIT OUTPUT PRESSURE*/ +/**************************************************************/ +#if defined(BME280_ENABLE_INT64) && defined(BME280_64BITSUPPORT_PRESENT) +/*! + * @brief Reads actual pressure from uncompensated pressure + * @note Returns the value in Pa as unsigned 32 bit + * integer in Q24.8 format (24 integer bits and + * 8 fractional bits). + * @note Output value of "24674867" + * represents 24674867 / 256 = 96386.2 Pa = 963.862 hPa + * + * + * + * @param v_uncom_pressure_s32 : value of uncompensated temperature + * + * + * @return Return the actual pressure in u32 + * +*/ +u32 bme280_compensate_pressure_int64(s32 v_uncom_pressure_s32); +/**************************************************************/ +/**\name FUNCTION FOR 24BIT OUTPUT PRESSURE*/ +/**************************************************************/ +/*! + * @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_uncom_pressure_s32 : value of uncompensated pressure + * + * + * @return the actual pressure in u32 + * +*/ +u32 bme280_compensate_pressure_int64_twentyfour_bit_output( +s32 v_uncom_pressure_s32); +#endif +/**************************************************************/ +/**\name FUNCTION FOR WAIT PERIOD*/ +/**************************************************************/ +/*! + * @brief Computing waiting time for sensor data read + * + * + * + * + * @param v_delaytime_u8 : The value of delay time for force mode + * + * + * @retval 0 -> Success + * + * + */ +BME280_RETURN_FUNCTION_TYPE bme280_compute_wait_time(u8 +*v_delaytime_u8); +#endif \ No newline at end of file diff --git a/proj5.c b/proj5.c new file mode 100644 index 0000000..210d95a --- /dev/null +++ b/proj5.c @@ -0,0 +1,207 @@ +// I2C BME280 sensor - Temperature read +// Example: https://github.com/ESP32Tutorials/esp32-esp-idf-mqtt-bme280/tree/main/components/bme280 +// Tutorial: https://esp32tutorials.com/esp32-mqtt-publish-bme280-node-red-esp-idf/#more-2125 + +#include +#include +#include +#include +#include "esp_system.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_netif.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" + +#include "lwip/sockets.h" +#include "lwip/dns.h" +#include "lwip/netdb.h" + +#include "esp_log.h" + +#include "driver/gpio.h" +#include "driver/i2c.h" +#include "esp_err.h" + +#include "bme280.h" + +#define TAG_BME280 "BME280" + +#define SDA_PIN GPIO_NUM_21 +#define SCL_PIN GPIO_NUM_22 + +#define I2C_MASTER_ACK 0 +#define I2C_MASTER_NACK 1 + +// Initialize I2C communication parameters +void i2c_master_init() +{ + i2c_config_t i2c_config = { + .mode = I2C_MODE_MASTER, + .sda_io_num = SDA_PIN, + .scl_io_num = SCL_PIN, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = 1000000}; + i2c_param_config(I2C_NUM_0, &i2c_config); + i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0); +} + +// BME280 I2C write function +s8 BME280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt) +{ + s32 iError = BME280_INIT_VALUE; + + esp_err_t espRc; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true); + + i2c_master_write_byte(cmd, reg_addr, true); + i2c_master_write(cmd, reg_data, cnt, true); + i2c_master_stop(cmd); + + espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); + if (espRc == ESP_OK) + { + iError = SUCCESS; + } + else + { + iError = FAIL; + } + i2c_cmd_link_delete(cmd); + + return (s8)iError; +} + +// BME280 I2C read function +s8 BME280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt) +{ + s32 iError = BME280_INIT_VALUE; + esp_err_t espRc; + + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg_addr, true); + + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_READ, true); + + if (cnt > 1) + { + i2c_master_read(cmd, reg_data, cnt - 1, I2C_MASTER_ACK); + } + i2c_master_read_byte(cmd, reg_data + cnt - 1, I2C_MASTER_NACK); + i2c_master_stop(cmd); + + espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); + if (espRc == ESP_OK) + { + iError = SUCCESS; + } + else + { + iError = FAIL; + } + + i2c_cmd_link_delete(cmd); + + return (s8)iError; +} + +// BME280 I2C delay function +void BME280_delay_msek(u32 msek) +{ + vTaskDelay(msek / portTICK_PERIOD_MS); +} + +// BME280 I2C task +void Publisher_Task(void *params) +{ + // BME280 I2C communication structure + struct bme280_t bme280 = { + .bus_write = BME280_I2C_bus_write, + .bus_read = BME280_I2C_bus_read, + .dev_addr = BME280_I2C_ADDRESS1, + .delay_msec = BME280_delay_msek}; + + s32 com_rslt; + s32 v_uncomp_pressure_s32; + s32 v_uncomp_temperature_s32; + s32 v_uncomp_humidity_s32; + + // Initialize BME280 sensor and set internal parameters + com_rslt = bme280_init(&bme280); + printf("com_rslt %d\n", com_rslt); + + com_rslt += bme280_set_oversamp_pressure(BME280_OVERSAMP_16X); + com_rslt += bme280_set_oversamp_temperature(BME280_OVERSAMP_2X); + com_rslt += bme280_set_oversamp_humidity(BME280_OVERSAMP_1X); + + com_rslt += bme280_set_standby_durn(BME280_STANDBY_TIME_1_MS); + com_rslt += bme280_set_filter(BME280_FILTER_COEFF_16); + + com_rslt += bme280_set_power_mode(BME280_NORMAL_MODE); + if (com_rslt == SUCCESS) + { + while (true) + { + vTaskDelay(1000 / portTICK_PERIOD_MS); + + // Read BME280 data + com_rslt = bme280_read_uncomp_pressure_temperature_humidity( + &v_uncomp_pressure_s32, &v_uncomp_temperature_s32, &v_uncomp_humidity_s32); + + double temp = bme280_compensate_temperature_double(v_uncomp_temperature_s32); + char temperature[12]; + sprintf(temperature, "%.2f degC", temp); + + double press = bme280_compensate_pressure_double(v_uncomp_pressure_s32) / 100; // Pa -> hPa + char pressure[10]; + sprintf(pressure, "%.2f hPa", press); + + double hum = bme280_compensate_humidity_double(v_uncomp_humidity_s32); + char humidity[10]; + sprintf(humidity, "%.2f %%", hum); + + // Print BME data + if (com_rslt == SUCCESS) + { + printf("Temperature %s\n",temperature); + } + else + { + ESP_LOGE(TAG_BME280, "measure error. code: %d", com_rslt); + } + } + } + else + { + ESP_LOGE(TAG_BME280, "init or setting error. code: %d", com_rslt); + } +} + +void app_main(void) +{ + // Initialize memory + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + // Initialize I2C parameters + i2c_master_init(); + + // Read the data from BME280 sensor + xTaskCreate(Publisher_Task, "Publisher_Task", 1024 * 5, NULL, 5, NULL); +}