commit 71381bb4678af92893c484b316d0503a2549cd33 Author: Artur Gurgul Date: Tue Sep 16 07:23:00 2025 -0500 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..482755d --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +# Help tools that honor '.gitignore' (redundant for Git itself). +/.git + +/CMakeUserPresets.json + +# Common build directories +/build*/ + +/main/build/ +/components/bme68x/build/ + +# CI jobs that run in symlinked trees produce these artifacts. +/real_work/ +/work + +# MacOS Finder files. +.DS_Store + +# Python compile output. +*.pyc + +# See Utilities/Sphinx/tutorial_archive.cmake +/Help/_generated + +# CLion work directory +/.idea/ +# CLion build directories +/cmake-build-*/ + +# QtCreator files. +/CMakeLists.txt.user* + +# Visual Studio Code +/.vscode/ +/.cache/ + +# Visual Studio work directory +/.vs/ +# Visual Studio build directory +/out/ + +# clang-tidy output +/clang-tidy-fixes.patch + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..39e41a5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/components") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(bme680_esp8266) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d19ebda --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ + + +clean: + idf.py fullclean + rm -rf ./main/build + rm -rf ./components/bme68x/build + rm -rf ./build + diff --git a/components/bme68x/CMakeLists.txt b/components/bme68x/CMakeLists.txt new file mode 100644 index 0000000..520ce78 --- /dev/null +++ b/components/bme68x/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "bme68x.c" INCLUDE_DIRS ".") + diff --git a/components/bme68x/bme68x.c b/components/bme68x/bme68x.c new file mode 100644 index 0000000..cd6965b --- /dev/null +++ b/components/bme68x/bme68x.c @@ -0,0 +1,1857 @@ +/** +* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder nor the names of its +* 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 THE +* 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. +* +* @file bme68x.c +* @date 2023-02-07 +* @version v4.4.8 +* +*/ + +#include "bme68x.h" +#include + +/* This internal API is used to read the calibration coefficients */ +static int8_t get_calib_data(struct bme68x_dev *dev); + +/* This internal API is used to read variant ID information register status */ +static int8_t read_variant_id(struct bme68x_dev *dev); + +/* This internal API is used to calculate the gas wait */ +static uint8_t calc_gas_wait(uint16_t dur); + +#ifndef BME68X_USE_FPU + +/* This internal API is used to calculate the temperature in integer */ +static int16_t calc_temperature(uint32_t temp_adc, struct bme68x_dev *dev); + +/* This internal API is used to calculate the pressure in integer */ +static uint32_t calc_pressure(uint32_t pres_adc, const struct bme68x_dev *dev); + +/* This internal API is used to calculate the humidity in integer */ +static uint32_t calc_humidity(uint16_t hum_adc, const struct bme68x_dev *dev); + +/* This internal API is used to calculate the gas resistance high */ +static uint32_t calc_gas_resistance_high(uint16_t gas_res_adc, uint8_t gas_range); + +/* This internal API is used to calculate the gas resistance low */ +static uint32_t calc_gas_resistance_low(uint16_t gas_res_adc, uint8_t gas_range, const struct bme68x_dev *dev); + +/* This internal API is used to calculate the heater resistance using integer */ +static uint8_t calc_res_heat(uint16_t temp, const struct bme68x_dev *dev); + +#else + +/* This internal API is used to calculate the temperature value in float */ +static float calc_temperature(uint32_t temp_adc, struct bme68x_dev *dev); + +/* This internal API is used to calculate the pressure value in float */ +static float calc_pressure(uint32_t pres_adc, const struct bme68x_dev *dev); + +/* This internal API is used to calculate the humidity value in float */ +static float calc_humidity(uint16_t hum_adc, const struct bme68x_dev *dev); + +/* This internal API is used to calculate the gas resistance high value in float */ +static float calc_gas_resistance_high(uint16_t gas_res_adc, uint8_t gas_range); + +/* This internal API is used to calculate the gas resistance low value in float */ +static float calc_gas_resistance_low(uint16_t gas_res_adc, uint8_t gas_range, const struct bme68x_dev *dev); + +/* This internal API is used to calculate the heater resistance value using float */ +static uint8_t calc_res_heat(uint16_t temp, const struct bme68x_dev *dev); + +#endif + +/* This internal API is used to read a single data of the sensor */ +static int8_t read_field_data(uint8_t index, struct bme68x_data *data, struct bme68x_dev *dev); + +/* This internal API is used to read all data fields of the sensor */ +static int8_t read_all_field_data(struct bme68x_data * const data[], struct bme68x_dev *dev); + +/* This internal API is used to switch between SPI memory pages */ +static int8_t set_mem_page(uint8_t reg_addr, struct bme68x_dev *dev); + +/* This internal API is used to get the current SPI memory page */ +static int8_t get_mem_page(struct bme68x_dev *dev); + +/* This internal API is used to check the bme68x_dev for null pointers */ +static int8_t null_ptr_check(const struct bme68x_dev *dev); + +/* This internal API is used to set heater configurations */ +static int8_t set_conf(const struct bme68x_heatr_conf *conf, uint8_t op_mode, uint8_t *nb_conv, struct bme68x_dev *dev); + +/* This internal API is used to limit the max value of a parameter */ +static int8_t boundary_check(uint8_t *value, uint8_t max, struct bme68x_dev *dev); + +/* This internal API is used to calculate the register value for + * shared heater duration */ +static uint8_t calc_heatr_dur_shared(uint16_t dur); + +/* This internal API is used to swap two fields */ +static void swap_fields(uint8_t index1, uint8_t index2, struct bme68x_data *field[]); + +/* This internal API is used sort the sensor data */ +static void sort_sensor_data(uint8_t low_index, uint8_t high_index, struct bme68x_data *field[]); + +/* + * @brief Function to analyze the sensor data + * + * @param[in] data Array of measurement data + * @param[in] n_meas Number of measurements + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +static int8_t analyze_sensor_data(const struct bme68x_data *data, uint8_t n_meas); + +/******************************************************************************************/ +/* Global API definitions */ +/******************************************************************************************/ + +/* @brief This API reads the chip-id of the sensor which is the first step to +* verify the sensor and also calibrates the sensor +* As this API is the entry point, call this API before using other APIs. +*/ +int8_t bme68x_init(struct bme68x_dev *dev) +{ + int8_t rslt; + + (void) bme68x_soft_reset(dev); + + rslt = bme68x_get_regs(BME68X_REG_CHIP_ID, &dev->chip_id, 1, dev); + + if (rslt == BME68X_OK) + { + if (dev->chip_id == BME68X_CHIP_ID) + { + /* Read Variant ID */ + rslt = read_variant_id(dev); + + if (rslt == BME68X_OK) + { + /* Get the Calibration data */ + rslt = get_calib_data(dev); + } + } + else + { + rslt = BME68X_E_DEV_NOT_FOUND; + } + } + + return rslt; +} + +/* + * @brief This API writes the given data to the register address of the sensor + */ +int8_t bme68x_set_regs(const uint8_t *reg_addr, const uint8_t *reg_data, uint32_t len, struct bme68x_dev *dev) +{ + int8_t rslt; + + /* Length of the temporary buffer is 2*(length of register)*/ + uint8_t tmp_buff[BME68X_LEN_INTERLEAVE_BUFF] = { 0 }; + uint16_t index; + + /* Check for null pointer in the device structure*/ + rslt = null_ptr_check(dev); + if ((rslt == BME68X_OK) && reg_addr && reg_data) + { + if ((len > 0) && (len <= (BME68X_LEN_INTERLEAVE_BUFF / 2))) + { + /* Interleave the 2 arrays */ + for (index = 0; index < len; index++) + { + if (dev->intf == BME68X_SPI_INTF) + { + /* Set the memory page */ + rslt = set_mem_page(reg_addr[index], dev); + tmp_buff[(2 * index)] = reg_addr[index] & BME68X_SPI_WR_MSK; + } + else + { + tmp_buff[(2 * index)] = reg_addr[index]; + } + + tmp_buff[(2 * index) + 1] = reg_data[index]; + } + + /* Write the interleaved array */ + if (rslt == BME68X_OK) + { + dev->intf_rslt = dev->write(tmp_buff[0], &tmp_buff[1], (2 * len) - 1, dev->intf_ptr); + if (dev->intf_rslt != 0) + { + rslt = BME68X_E_COM_FAIL; + } + } + } + else + { + rslt = BME68X_E_INVALID_LENGTH; + } + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* + * @brief This API reads the data from the given register address of sensor. + */ +int8_t bme68x_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, struct bme68x_dev *dev) +{ + int8_t rslt; + + /* Check for null pointer in the device structure*/ + rslt = null_ptr_check(dev); + if ((rslt == BME68X_OK) && reg_data) + { + if (dev->intf == BME68X_SPI_INTF) + { + /* Set the memory page */ + rslt = set_mem_page(reg_addr, dev); + if (rslt == BME68X_OK) + { + reg_addr = reg_addr | BME68X_SPI_RD_MSK; + } + } + + dev->intf_rslt = dev->read(reg_addr, reg_data, len, dev->intf_ptr); + if (dev->intf_rslt != 0) + { + rslt = BME68X_E_COM_FAIL; + } + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* + * @brief This API soft-resets the sensor. + */ +int8_t bme68x_soft_reset(struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t reg_addr = BME68X_REG_SOFT_RESET; + + /* 0xb6 is the soft reset command */ + uint8_t soft_rst_cmd = BME68X_SOFT_RESET_CMD; + + /* Check for null pointer in the device structure*/ + rslt = null_ptr_check(dev); + if (rslt == BME68X_OK) + { + if (dev->intf == BME68X_SPI_INTF) + { + rslt = get_mem_page(dev); + } + + /* Reset the device */ + if (rslt == BME68X_OK) + { + rslt = bme68x_set_regs(®_addr, &soft_rst_cmd, 1, dev); + + if (rslt == BME68X_OK) + { + /* Wait for 5ms */ + dev->delay_us(BME68X_PERIOD_RESET, dev->intf_ptr); + + /* After reset get the memory page */ + if (dev->intf == BME68X_SPI_INTF) + { + rslt = get_mem_page(dev); + } + } + } + } + + return rslt; +} + +/* + * @brief This API is used to set the oversampling, filter and odr configuration + */ +int8_t bme68x_set_conf(struct bme68x_conf *conf, struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t odr20 = 0, odr3 = 1; + uint8_t current_op_mode; + + /* Register data starting from BME68X_REG_CTRL_GAS_1(0x71) up to BME68X_REG_CONFIG(0x75) */ + uint8_t reg_array[BME68X_LEN_CONFIG] = { 0x71, 0x72, 0x73, 0x74, 0x75 }; + uint8_t data_array[BME68X_LEN_CONFIG] = { 0 }; + + rslt = bme68x_get_op_mode(¤t_op_mode, dev); + if (rslt == BME68X_OK) + { + /* Configure only in the sleep mode */ + rslt = bme68x_set_op_mode(BME68X_SLEEP_MODE, dev); + } + + if (conf == NULL) + { + rslt = BME68X_E_NULL_PTR; + } + else if (rslt == BME68X_OK) + { + /* Read the whole configuration and write it back once later */ + rslt = bme68x_get_regs(reg_array[0], data_array, BME68X_LEN_CONFIG, dev); + dev->info_msg = BME68X_OK; + if (rslt == BME68X_OK) + { + rslt = boundary_check(&conf->filter, BME68X_FILTER_SIZE_127, dev); + } + + if (rslt == BME68X_OK) + { + rslt = boundary_check(&conf->os_temp, BME68X_OS_16X, dev); + } + + if (rslt == BME68X_OK) + { + rslt = boundary_check(&conf->os_pres, BME68X_OS_16X, dev); + } + + if (rslt == BME68X_OK) + { + rslt = boundary_check(&conf->os_hum, BME68X_OS_16X, dev); + } + + if (rslt == BME68X_OK) + { + rslt = boundary_check(&conf->odr, BME68X_ODR_NONE, dev); + } + + if (rslt == BME68X_OK) + { + data_array[4] = BME68X_SET_BITS(data_array[4], BME68X_FILTER, conf->filter); + data_array[3] = BME68X_SET_BITS(data_array[3], BME68X_OST, conf->os_temp); + data_array[3] = BME68X_SET_BITS(data_array[3], BME68X_OSP, conf->os_pres); + data_array[1] = BME68X_SET_BITS_POS_0(data_array[1], BME68X_OSH, conf->os_hum); + if (conf->odr != BME68X_ODR_NONE) + { + odr20 = conf->odr; + odr3 = 0; + } + + data_array[4] = BME68X_SET_BITS(data_array[4], BME68X_ODR20, odr20); + data_array[0] = BME68X_SET_BITS(data_array[0], BME68X_ODR3, odr3); + } + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_set_regs(reg_array, data_array, BME68X_LEN_CONFIG, dev); + } + + if ((current_op_mode != BME68X_SLEEP_MODE) && (rslt == BME68X_OK)) + { + rslt = bme68x_set_op_mode(current_op_mode, dev); + } + + return rslt; +} + +/* + * @brief This API is used to get the oversampling, filter and odr + */ +int8_t bme68x_get_conf(struct bme68x_conf *conf, struct bme68x_dev *dev) +{ + int8_t rslt; + + /* starting address of the register array for burst read*/ + uint8_t reg_addr = BME68X_REG_CTRL_GAS_1; + uint8_t data_array[BME68X_LEN_CONFIG]; + + rslt = bme68x_get_regs(reg_addr, data_array, 5, dev); + if (!conf) + { + rslt = BME68X_E_NULL_PTR; + } + else if (rslt == BME68X_OK) + { + conf->os_hum = BME68X_GET_BITS_POS_0(data_array[1], BME68X_OSH); + conf->filter = BME68X_GET_BITS(data_array[4], BME68X_FILTER); + conf->os_temp = BME68X_GET_BITS(data_array[3], BME68X_OST); + conf->os_pres = BME68X_GET_BITS(data_array[3], BME68X_OSP); + if (BME68X_GET_BITS(data_array[0], BME68X_ODR3)) + { + conf->odr = BME68X_ODR_NONE; + } + else + { + conf->odr = BME68X_GET_BITS(data_array[4], BME68X_ODR20); + } + } + + return rslt; +} + +/* + * @brief This API is used to set the operation mode of the sensor + */ +int8_t bme68x_set_op_mode(const uint8_t op_mode, struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t tmp_pow_mode; + uint8_t pow_mode = 0; + uint8_t reg_addr = BME68X_REG_CTRL_MEAS; + + /* Call until in sleep */ + do + { + rslt = bme68x_get_regs(BME68X_REG_CTRL_MEAS, &tmp_pow_mode, 1, dev); + if (rslt == BME68X_OK) + { + /* Put to sleep before changing mode */ + pow_mode = (tmp_pow_mode & BME68X_MODE_MSK); + if (pow_mode != BME68X_SLEEP_MODE) + { + tmp_pow_mode &= ~BME68X_MODE_MSK; /* Set to sleep */ + rslt = bme68x_set_regs(®_addr, &tmp_pow_mode, 1, dev); + dev->delay_us(BME68X_PERIOD_POLL, dev->intf_ptr); + } + } + } while ((pow_mode != BME68X_SLEEP_MODE) && (rslt == BME68X_OK)); + + /* Already in sleep */ + if ((op_mode != BME68X_SLEEP_MODE) && (rslt == BME68X_OK)) + { + tmp_pow_mode = (tmp_pow_mode & ~BME68X_MODE_MSK) | (op_mode & BME68X_MODE_MSK); + rslt = bme68x_set_regs(®_addr, &tmp_pow_mode, 1, dev); + } + + return rslt; +} + +/* + * @brief This API is used to get the operation mode of the sensor. + */ +int8_t bme68x_get_op_mode(uint8_t *op_mode, struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t mode; + + if (op_mode) + { + rslt = bme68x_get_regs(BME68X_REG_CTRL_MEAS, &mode, 1, dev); + + /* Masking the other register bit info*/ + *op_mode = mode & BME68X_MODE_MSK; + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* + * @brief This API is used to get the remaining duration that can be used for heating. + */ +uint32_t bme68x_get_meas_dur(const uint8_t op_mode, struct bme68x_conf *conf, struct bme68x_dev *dev) +{ + int8_t rslt; + uint32_t meas_dur = 0; /* Calculate in us */ + uint32_t meas_cycles; + uint8_t os_to_meas_cycles[6] = { 0, 1, 2, 4, 8, 16 }; + + if (conf != NULL) + { + /* Boundary check for temperature oversampling */ + rslt = boundary_check(&conf->os_temp, BME68X_OS_16X, dev); + + if (rslt == BME68X_OK) + { + /* Boundary check for pressure oversampling */ + rslt = boundary_check(&conf->os_pres, BME68X_OS_16X, dev); + } + + if (rslt == BME68X_OK) + { + /* Boundary check for humidity oversampling */ + rslt = boundary_check(&conf->os_hum, BME68X_OS_16X, dev); + } + + if (rslt == BME68X_OK) + { + meas_cycles = os_to_meas_cycles[conf->os_temp]; + meas_cycles += os_to_meas_cycles[conf->os_pres]; + meas_cycles += os_to_meas_cycles[conf->os_hum]; + + /* TPH measurement duration */ + meas_dur = meas_cycles * UINT32_C(1963); + meas_dur += UINT32_C(477 * 4); /* TPH switching duration */ + meas_dur += UINT32_C(477 * 5); /* Gas measurement duration */ + + if (op_mode != BME68X_PARALLEL_MODE) + { + meas_dur += UINT32_C(1000); /* Wake up duration of 1ms */ + } + } + } + + return meas_dur; +} + +/* + * @brief This API reads the pressure, temperature and humidity and gas data + * from the sensor, compensates the data and store it in the bme68x_data + * structure instance passed by the user. + */ +int8_t bme68x_get_data(uint8_t op_mode, struct bme68x_data *data, uint8_t *n_data, struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t i = 0, j = 0, new_fields = 0; + struct bme68x_data *field_ptr[3] = { 0 }; + struct bme68x_data field_data[3] = { { 0 } }; + + field_ptr[0] = &field_data[0]; + field_ptr[1] = &field_data[1]; + field_ptr[2] = &field_data[2]; + + rslt = null_ptr_check(dev); + if ((rslt == BME68X_OK) && (data != NULL)) + { + /* Reading the sensor data in forced mode only */ + if (op_mode == BME68X_FORCED_MODE) + { + rslt = read_field_data(0, data, dev); + if (rslt == BME68X_OK) + { + if (data->status & BME68X_NEW_DATA_MSK) + { + new_fields = 1; + } + else + { + new_fields = 0; + rslt = BME68X_W_NO_NEW_DATA; + } + } + } + else if ((op_mode == BME68X_PARALLEL_MODE) || (op_mode == BME68X_SEQUENTIAL_MODE)) + { + /* Read the 3 fields and count the number of new data fields */ + rslt = read_all_field_data(field_ptr, dev); + + new_fields = 0; + for (i = 0; (i < 3) && (rslt == BME68X_OK); i++) + { + if (field_ptr[i]->status & BME68X_NEW_DATA_MSK) + { + new_fields++; + } + } + + /* Sort the sensor data in parallel & sequential modes*/ + for (i = 0; (i < 2) && (rslt == BME68X_OK); i++) + { + for (j = i + 1; j < 3; j++) + { + sort_sensor_data(i, j, field_ptr); + } + } + + /* Copy the sorted data */ + for (i = 0; ((i < 3) && (rslt == BME68X_OK)); i++) + { + data[i] = *field_ptr[i]; + } + + if (new_fields == 0) + { + rslt = BME68X_W_NO_NEW_DATA; + } + } + else + { + rslt = BME68X_W_DEFINE_OP_MODE; + } + + if (n_data == NULL) + { + rslt = BME68X_E_NULL_PTR; + } + else + { + *n_data = new_fields; + } + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* + * @brief This API is used to set the gas configuration of the sensor. + */ +int8_t bme68x_set_heatr_conf(uint8_t op_mode, const struct bme68x_heatr_conf *conf, struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t nb_conv = 0; + uint8_t hctrl, run_gas = 0; + uint8_t ctrl_gas_data[2]; + uint8_t ctrl_gas_addr[2] = { BME68X_REG_CTRL_GAS_0, BME68X_REG_CTRL_GAS_1 }; + + if (conf != NULL) + { + rslt = bme68x_set_op_mode(BME68X_SLEEP_MODE, dev); + if (rslt == BME68X_OK) + { + rslt = set_conf(conf, op_mode, &nb_conv, dev); + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_CTRL_GAS_0, ctrl_gas_data, 2, dev); + if (rslt == BME68X_OK) + { + if (conf->enable == BME68X_ENABLE) + { + hctrl = BME68X_ENABLE_HEATER; + if (dev->variant_id == BME68X_VARIANT_GAS_HIGH) + { + run_gas = BME68X_ENABLE_GAS_MEAS_H; + } + else + { + run_gas = BME68X_ENABLE_GAS_MEAS_L; + } + } + else + { + hctrl = BME68X_DISABLE_HEATER; + run_gas = BME68X_DISABLE_GAS_MEAS; + } + + ctrl_gas_data[0] = BME68X_SET_BITS(ctrl_gas_data[0], BME68X_HCTRL, hctrl); + ctrl_gas_data[1] = BME68X_SET_BITS_POS_0(ctrl_gas_data[1], BME68X_NBCONV, nb_conv); + ctrl_gas_data[1] = BME68X_SET_BITS(ctrl_gas_data[1], BME68X_RUN_GAS, run_gas); + rslt = bme68x_set_regs(ctrl_gas_addr, ctrl_gas_data, 2, dev); + } + } + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to get the gas configuration of the sensor. + */ +int8_t bme68x_get_heatr_conf(const struct bme68x_heatr_conf *conf, struct bme68x_dev *dev) +{ + int8_t rslt = BME68X_OK; + uint8_t data_array[10] = { 0 }; + uint8_t i; + + if ((conf != NULL) && (conf->heatr_dur_prof != NULL) && (conf->heatr_temp_prof != NULL)) + { + /* FIXME: Add conversion to deg C and ms and add the other parameters */ + rslt = bme68x_get_regs(BME68X_REG_RES_HEAT0, data_array, 10, dev); + + if (rslt == BME68X_OK) + { + for (i = 0; i < conf->profile_len; i++) + { + conf->heatr_temp_prof[i] = data_array[i]; + } + + rslt = bme68x_get_regs(BME68X_REG_GAS_WAIT0, data_array, 10, dev); + + if (rslt == BME68X_OK) + { + for (i = 0; i < conf->profile_len; i++) + { + conf->heatr_dur_prof[i] = data_array[i]; + } + } + } + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* + * @brief This API performs Self-test of low and high gas variants of BME68X + */ +int8_t bme68x_selftest_check(const struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t n_fields; + uint8_t i = 0; + struct bme68x_data data[BME68X_N_MEAS] = { { 0 } }; + struct bme68x_dev t_dev; + struct bme68x_conf conf; + struct bme68x_heatr_conf heatr_conf; + + rslt = null_ptr_check(dev); + + if (rslt == BME68X_OK) + { + /* Copy required parameters from reference bme68x_dev struct */ + t_dev.amb_temp = 25; + t_dev.read = dev->read; + t_dev.write = dev->write; + t_dev.intf = dev->intf; + t_dev.delay_us = dev->delay_us; + t_dev.intf_ptr = dev->intf_ptr; + + rslt = bme68x_init(&t_dev); + } + + if (rslt == BME68X_OK) + { + /* Set the temperature, pressure and humidity & filter settings */ + conf.os_hum = BME68X_OS_1X; + conf.os_pres = BME68X_OS_16X; + conf.os_temp = BME68X_OS_2X; + + /* Set the remaining gas sensor settings and link the heating profile */ + heatr_conf.enable = BME68X_ENABLE; + heatr_conf.heatr_dur = BME68X_HEATR_DUR1; + heatr_conf.heatr_temp = BME68X_HIGH_TEMP; + rslt = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &heatr_conf, &t_dev); + if (rslt == BME68X_OK) + { + rslt = bme68x_set_conf(&conf, &t_dev); + if (rslt == BME68X_OK) + { + rslt = bme68x_set_op_mode(BME68X_FORCED_MODE, &t_dev); /* Trigger a measurement */ + if (rslt == BME68X_OK) + { + /* Wait for the measurement to complete */ + t_dev.delay_us(BME68X_HEATR_DUR1_DELAY, t_dev.intf_ptr); + rslt = bme68x_get_data(BME68X_FORCED_MODE, &data[0], &n_fields, &t_dev); + if (rslt == BME68X_OK) + { + if ((data[0].idac != 0x00) && (data[0].idac != 0xFF) && + (data[0].status & BME68X_GASM_VALID_MSK)) + { + rslt = BME68X_OK; + } + else + { + rslt = BME68X_E_SELF_TEST; + } + } + } + } + } + + heatr_conf.heatr_dur = BME68X_HEATR_DUR2; + while ((rslt == BME68X_OK) && (i < BME68X_N_MEAS)) + { + if (i % 2 == 0) + { + heatr_conf.heatr_temp = BME68X_HIGH_TEMP; /* Higher temperature */ + } + else + { + heatr_conf.heatr_temp = BME68X_LOW_TEMP; /* Lower temperature */ + } + + rslt = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &heatr_conf, &t_dev); + if (rslt == BME68X_OK) + { + rslt = bme68x_set_conf(&conf, &t_dev); + if (rslt == BME68X_OK) + { + rslt = bme68x_set_op_mode(BME68X_FORCED_MODE, &t_dev); /* Trigger a measurement */ + if (rslt == BME68X_OK) + { + /* Wait for the measurement to complete */ + t_dev.delay_us(BME68X_HEATR_DUR2_DELAY, t_dev.intf_ptr); + rslt = bme68x_get_data(BME68X_FORCED_MODE, &data[i], &n_fields, &t_dev); + } + } + } + + i++; + } + + if (rslt == BME68X_OK) + { + rslt = analyze_sensor_data(data, BME68X_N_MEAS); + } + } + + return rslt; +} + +/*****************************INTERNAL APIs***********************************************/ +#ifndef BME68X_USE_FPU + +/* @brief This internal API is used to calculate the temperature value. */ +static int16_t calc_temperature(uint32_t temp_adc, struct bme68x_dev *dev) +{ + int64_t var1; + int64_t var2; + int64_t var3; + int16_t calc_temp; + + /*lint -save -e701 -e702 -e704 */ + var1 = ((int32_t)temp_adc >> 3) - ((int32_t)dev->calib.par_t1 << 1); + var2 = (var1 * (int32_t)dev->calib.par_t2) >> 11; + var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; + var3 = ((var3) * ((int32_t)dev->calib.par_t3 << 4)) >> 14; + dev->calib.t_fine = (int32_t)(var2 + var3); + calc_temp = (int16_t)(((dev->calib.t_fine * 5) + 128) >> 8); + + /*lint -restore */ + return calc_temp; +} + +/* @brief This internal API is used to calculate the pressure value. */ +static uint32_t calc_pressure(uint32_t pres_adc, const struct bme68x_dev *dev) +{ + int32_t var1; + int32_t var2; + int32_t var3; + int32_t pressure_comp; + + /* This value is used to check precedence to multiplication or division + * in the pressure compensation equation to achieve least loss of precision and + * avoiding overflows. + * i.e Comparing value, pres_ovf_check = (1 << 31) >> 1 + */ + const int32_t pres_ovf_check = INT32_C(0x40000000); + + /*lint -save -e701 -e702 -e713 */ + var1 = (((int32_t)dev->calib.t_fine) >> 1) - 64000; + var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)dev->calib.par_p6) >> 2; + var2 = var2 + ((var1 * (int32_t)dev->calib.par_p5) << 1); + var2 = (var2 >> 2) + ((int32_t)dev->calib.par_p4 << 16); + var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * ((int32_t)dev->calib.par_p3 << 5)) >> 3) + + (((int32_t)dev->calib.par_p2 * var1) >> 1); + var1 = var1 >> 18; + var1 = ((32768 + var1) * (int32_t)dev->calib.par_p1) >> 15; + pressure_comp = 1048576 - pres_adc; + pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125)); + if (pressure_comp >= pres_ovf_check) + { + pressure_comp = ((pressure_comp / var1) << 1); + } + else + { + pressure_comp = ((pressure_comp << 1) / var1); + } + + var1 = ((int32_t)dev->calib.par_p9 * (int32_t)(((pressure_comp >> 3) * (pressure_comp >> 3)) >> 13)) >> 12; + var2 = ((int32_t)(pressure_comp >> 2) * (int32_t)dev->calib.par_p8) >> 13; + var3 = + ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) * + (int32_t)dev->calib.par_p10) >> 17; + pressure_comp = (int32_t)(pressure_comp) + ((var1 + var2 + var3 + ((int32_t)dev->calib.par_p7 << 7)) >> 4); + + /*lint -restore */ + return (uint32_t)pressure_comp; +} + +/* This internal API is used to calculate the humidity in integer */ +static uint32_t calc_humidity(uint16_t hum_adc, const struct bme68x_dev *dev) +{ + int32_t var1; + int32_t var2; + int32_t var3; + int32_t var4; + int32_t var5; + int32_t var6; + int32_t temp_scaled; + int32_t calc_hum; + + /*lint -save -e702 -e704 */ + temp_scaled = (((int32_t)dev->calib.t_fine * 5) + 128) >> 8; + var1 = (int32_t)(hum_adc - ((int32_t)((int32_t)dev->calib.par_h1 * 16))) - + (((temp_scaled * (int32_t)dev->calib.par_h3) / ((int32_t)100)) >> 1); + var2 = + ((int32_t)dev->calib.par_h2 * + (((temp_scaled * (int32_t)dev->calib.par_h4) / ((int32_t)100)) + + (((temp_scaled * ((temp_scaled * (int32_t)dev->calib.par_h5) / ((int32_t)100))) >> 6) / ((int32_t)100)) + + (int32_t)(1 << 14))) >> 10; + var3 = var1 * var2; + var4 = (int32_t)dev->calib.par_h6 << 7; + var4 = ((var4) + ((temp_scaled * (int32_t)dev->calib.par_h7) / ((int32_t)100))) >> 4; + var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; + var6 = (var4 * var5) >> 1; + calc_hum = (((var3 + var6) >> 10) * ((int32_t)1000)) >> 12; + if (calc_hum > 100000) /* Cap at 100%rH */ + { + calc_hum = 100000; + } + else if (calc_hum < 0) + { + calc_hum = 0; + } + + /*lint -restore */ + return (uint32_t)calc_hum; +} + +/* This internal API is used to calculate the gas resistance low */ +static uint32_t calc_gas_resistance_low(uint16_t gas_res_adc, uint8_t gas_range, const struct bme68x_dev *dev) +{ + int64_t var1; + uint64_t var2; + int64_t var3; + uint32_t calc_gas_res; + uint32_t lookup_table1[16] = { + UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647), UINT32_C(2147483647), + UINT32_C(2126008810), UINT32_C(2147483647), UINT32_C(2130303777), UINT32_C(2147483647), UINT32_C(2147483647), + UINT32_C(2143188679), UINT32_C(2136746228), UINT32_C(2147483647), UINT32_C(2126008810), UINT32_C(2147483647), + UINT32_C(2147483647) + }; + uint32_t lookup_table2[16] = { + UINT32_C(4096000000), UINT32_C(2048000000), UINT32_C(1024000000), UINT32_C(512000000), UINT32_C(255744255), + UINT32_C(127110228), UINT32_C(64000000), UINT32_C(32258064), UINT32_C(16016016), UINT32_C(8000000), UINT32_C( + 4000000), UINT32_C(2000000), UINT32_C(1000000), UINT32_C(500000), UINT32_C(250000), UINT32_C(125000) + }; + + /*lint -save -e704 */ + var1 = (int64_t)((1340 + (5 * (int64_t)dev->calib.range_sw_err)) * ((int64_t)lookup_table1[gas_range])) >> 16; + var2 = (((int64_t)((int64_t)gas_res_adc << 15) - (int64_t)(16777216)) + var1); + var3 = (((int64_t)lookup_table2[gas_range] * (int64_t)var1) >> 9); + calc_gas_res = (uint32_t)((var3 + ((int64_t)var2 >> 1)) / (int64_t)var2); + + /*lint -restore */ + return calc_gas_res; +} + +/* This internal API is used to calculate the gas resistance */ +static uint32_t calc_gas_resistance_high(uint16_t gas_res_adc, uint8_t gas_range) +{ + uint32_t calc_gas_res; + uint32_t var1 = UINT32_C(262144) >> gas_range; + int32_t var2 = (int32_t)gas_res_adc - INT32_C(512); + + var2 *= INT32_C(3); + var2 = INT32_C(4096) + var2; + + /* multiplying 10000 then dividing then multiplying by 100 instead of multiplying by 1000000 to prevent overflow */ + calc_gas_res = (UINT32_C(10000) * var1) / (uint32_t)var2; + calc_gas_res = calc_gas_res * 100; + + return calc_gas_res; +} + +/* This internal API is used to calculate the heater resistance value using integer */ +static uint8_t calc_res_heat(uint16_t temp, const struct bme68x_dev *dev) +{ + uint8_t heatr_res; + int32_t var1; + int32_t var2; + int32_t var3; + int32_t var4; + int32_t var5; + int32_t heatr_res_x100; + + if (temp > 400) /* Cap temperature */ + { + temp = 400; + } + + var1 = (((int32_t)dev->amb_temp * dev->calib.par_gh3) / 1000) * 256; + var2 = (dev->calib.par_gh1 + 784) * (((((dev->calib.par_gh2 + 154009) * temp * 5) / 100) + 3276800) / 10); + var3 = var1 + (var2 / 2); + var4 = (var3 / (dev->calib.res_heat_range + 4)); + var5 = (131 * dev->calib.res_heat_val) + 65536; + heatr_res_x100 = (int32_t)(((var4 / var5) - 250) * 34); + heatr_res = (uint8_t)((heatr_res_x100 + 50) / 100); + + return heatr_res; +} + +#else + +/* @brief This internal API is used to calculate the temperature value. */ +static float calc_temperature(uint32_t temp_adc, struct bme68x_dev *dev) +{ + float var1; + float var2; + float calc_temp; + + /* calculate var1 data */ + var1 = ((((float)temp_adc / 16384.0f) - ((float)dev->calib.par_t1 / 1024.0f)) * ((float)dev->calib.par_t2)); + + /* calculate var2 data */ + var2 = + (((((float)temp_adc / 131072.0f) - ((float)dev->calib.par_t1 / 8192.0f)) * + (((float)temp_adc / 131072.0f) - ((float)dev->calib.par_t1 / 8192.0f))) * ((float)dev->calib.par_t3 * 16.0f)); + + /* t_fine value*/ + dev->calib.t_fine = (var1 + var2); + + /* compensated temperature data*/ + calc_temp = ((dev->calib.t_fine) / 5120.0f); + + return calc_temp; +} + +/* @brief This internal API is used to calculate the pressure value. */ +static float calc_pressure(uint32_t pres_adc, const struct bme68x_dev *dev) +{ + float var1; + float var2; + float var3; + float calc_pres; + + var1 = (((float)dev->calib.t_fine / 2.0f) - 64000.0f); + var2 = var1 * var1 * (((float)dev->calib.par_p6) / (131072.0f)); + var2 = var2 + (var1 * ((float)dev->calib.par_p5) * 2.0f); + var2 = (var2 / 4.0f) + (((float)dev->calib.par_p4) * 65536.0f); + var1 = (((((float)dev->calib.par_p3 * var1 * var1) / 16384.0f) + ((float)dev->calib.par_p2 * var1)) / 524288.0f); + var1 = ((1.0f + (var1 / 32768.0f)) * ((float)dev->calib.par_p1)); + calc_pres = (1048576.0f - ((float)pres_adc)); + + /* Avoid exception caused by division by zero */ + if ((int)var1 != 0) + { + calc_pres = (((calc_pres - (var2 / 4096.0f)) * 6250.0f) / var1); + var1 = (((float)dev->calib.par_p9) * calc_pres * calc_pres) / 2147483648.0f; + var2 = calc_pres * (((float)dev->calib.par_p8) / 32768.0f); + var3 = ((calc_pres / 256.0f) * (calc_pres / 256.0f) * (calc_pres / 256.0f) * (dev->calib.par_p10 / 131072.0f)); + calc_pres = (calc_pres + (var1 + var2 + var3 + ((float)dev->calib.par_p7 * 128.0f)) / 16.0f); + } + else + { + calc_pres = 0; + } + + return calc_pres; +} + +/* This internal API is used to calculate the humidity in integer */ +static float calc_humidity(uint16_t hum_adc, const struct bme68x_dev *dev) +{ + float calc_hum; + float var1; + float var2; + float var3; + float var4; + float temp_comp; + + /* compensated temperature data*/ + temp_comp = ((dev->calib.t_fine) / 5120.0f); + var1 = (float)((float)hum_adc) - + (((float)dev->calib.par_h1 * 16.0f) + (((float)dev->calib.par_h3 / 2.0f) * temp_comp)); + var2 = var1 * + ((float)(((float)dev->calib.par_h2 / 262144.0f) * + (1.0f + (((float)dev->calib.par_h4 / 16384.0f) * temp_comp) + + (((float)dev->calib.par_h5 / 1048576.0f) * temp_comp * temp_comp)))); + var3 = (float)dev->calib.par_h6 / 16384.0f; + var4 = (float)dev->calib.par_h7 / 2097152.0f; + calc_hum = var2 + ((var3 + (var4 * temp_comp)) * var2 * var2); + if (calc_hum > 100.0f) + { + calc_hum = 100.0f; + } + else if (calc_hum < 0.0f) + { + calc_hum = 0.0f; + } + + return calc_hum; +} + +/* This internal API is used to calculate the gas resistance low value in float */ +static float calc_gas_resistance_low(uint16_t gas_res_adc, uint8_t gas_range, const struct bme68x_dev *dev) +{ + float calc_gas_res; + float var1; + float var2; + float var3; + float gas_res_f = gas_res_adc; + float gas_range_f = (1U << gas_range); /*lint !e790 / Suspicious truncation, integral to float */ + const float lookup_k1_range[16] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, -0.8f, 0.0f, 0.0f, -0.2f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f + }; + const float lookup_k2_range[16] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.7f, 0.0f, -0.8f, -0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f + }; + + var1 = (1340.0f + (5.0f * dev->calib.range_sw_err)); + var2 = (var1) * (1.0f + lookup_k1_range[gas_range] / 100.0f); + var3 = 1.0f + (lookup_k2_range[gas_range] / 100.0f); + calc_gas_res = 1.0f / (float)(var3 * (0.000000125f) * gas_range_f * (((gas_res_f - 512.0f) / var2) + 1.0f)); + + return calc_gas_res; +} + +/* This internal API is used to calculate the gas resistance value in float */ +static float calc_gas_resistance_high(uint16_t gas_res_adc, uint8_t gas_range) +{ + float calc_gas_res; + uint32_t var1 = UINT32_C(262144) >> gas_range; + int32_t var2 = (int32_t)gas_res_adc - INT32_C(512); + + var2 *= INT32_C(3); + var2 = INT32_C(4096) + var2; + + calc_gas_res = 1000000.0f * (float)var1 / (float)var2; + + return calc_gas_res; +} + +/* This internal API is used to calculate the heater resistance value using float */ +static uint8_t calc_res_heat(uint16_t temp, const struct bme68x_dev *dev) +{ + float var1; + float var2; + float var3; + float var4; + float var5; + uint8_t res_heat; + + if (temp > 400) /* Cap temperature */ + { + temp = 400; + } + + var1 = (((float)dev->calib.par_gh1 / (16.0f)) + 49.0f); + var2 = ((((float)dev->calib.par_gh2 / (32768.0f)) * (0.0005f)) + 0.00235f); + var3 = ((float)dev->calib.par_gh3 / (1024.0f)); + var4 = (var1 * (1.0f + (var2 * (float)temp))); + var5 = (var4 + (var3 * (float)dev->amb_temp)); + res_heat = + (uint8_t)(3.4f * + ((var5 * (4 / (4 + (float)dev->calib.res_heat_range)) * + (1 / (1 + ((float)dev->calib.res_heat_val * 0.002f)))) - + 25)); + + return res_heat; +} + +#endif + +/* This internal API is used to calculate the gas wait */ +static uint8_t calc_gas_wait(uint16_t dur) +{ + uint8_t factor = 0; + uint8_t durval; + + if (dur >= 0xfc0) + { + durval = 0xff; /* Max duration*/ + } + else + { + while (dur > 0x3F) + { + dur = dur / 4; + factor += 1; + } + + durval = (uint8_t)(dur + (factor * 64)); + } + + return durval; +} + +/* This internal API is used to read a single data of the sensor */ +static int8_t read_field_data(uint8_t index, struct bme68x_data *data, struct bme68x_dev *dev) +{ + int8_t rslt = BME68X_OK; + uint8_t buff[BME68X_LEN_FIELD] = { 0 }; + uint8_t gas_range_l, gas_range_h; + uint32_t adc_temp; + uint32_t adc_pres; + uint16_t adc_hum; + uint16_t adc_gas_res_low, adc_gas_res_high; + uint8_t tries = 5; + + while ((tries) && (rslt == BME68X_OK)) + { + rslt = bme68x_get_regs(((uint8_t)(BME68X_REG_FIELD0 + (index * BME68X_LEN_FIELD_OFFSET))), + buff, + (uint16_t)BME68X_LEN_FIELD, + dev); + if (!data) + { + rslt = BME68X_E_NULL_PTR; + break; + } + + data->status = buff[0] & BME68X_NEW_DATA_MSK; + data->gas_index = buff[0] & BME68X_GAS_INDEX_MSK; + data->meas_index = buff[1]; + + /* read the raw data from the sensor */ + adc_pres = (uint32_t)(((uint32_t)buff[2] * 4096) | ((uint32_t)buff[3] * 16) | ((uint32_t)buff[4] / 16)); + adc_temp = (uint32_t)(((uint32_t)buff[5] * 4096) | ((uint32_t)buff[6] * 16) | ((uint32_t)buff[7] / 16)); + adc_hum = (uint16_t)(((uint32_t)buff[8] * 256) | (uint32_t)buff[9]); + adc_gas_res_low = (uint16_t)((uint32_t)buff[13] * 4 | (((uint32_t)buff[14]) / 64)); + adc_gas_res_high = (uint16_t)((uint32_t)buff[15] * 4 | (((uint32_t)buff[16]) / 64)); + gas_range_l = buff[14] & BME68X_GAS_RANGE_MSK; + gas_range_h = buff[16] & BME68X_GAS_RANGE_MSK; + if (dev->variant_id == BME68X_VARIANT_GAS_HIGH) + { + data->status |= buff[16] & BME68X_GASM_VALID_MSK; + data->status |= buff[16] & BME68X_HEAT_STAB_MSK; + } + else + { + data->status |= buff[14] & BME68X_GASM_VALID_MSK; + data->status |= buff[14] & BME68X_HEAT_STAB_MSK; + } + + if ((data->status & BME68X_NEW_DATA_MSK) && (rslt == BME68X_OK)) + { + rslt = bme68x_get_regs(BME68X_REG_RES_HEAT0 + data->gas_index, &data->res_heat, 1, dev); + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_IDAC_HEAT0 + data->gas_index, &data->idac, 1, dev); + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_GAS_WAIT0 + data->gas_index, &data->gas_wait, 1, dev); + } + + if (rslt == BME68X_OK) + { + data->temperature = calc_temperature(adc_temp, dev); + data->pressure = calc_pressure(adc_pres, dev); + data->humidity = calc_humidity(adc_hum, dev); + if (dev->variant_id == BME68X_VARIANT_GAS_HIGH) + { + data->gas_resistance = calc_gas_resistance_high(adc_gas_res_high, gas_range_h); + } + else + { + data->gas_resistance = calc_gas_resistance_low(adc_gas_res_low, gas_range_l, dev); + } + + break; + } + } + + if (rslt == BME68X_OK) + { + dev->delay_us(BME68X_PERIOD_POLL, dev->intf_ptr); + } + + tries--; + } + + return rslt; +} + +/* This internal API is used to read all data fields of the sensor */ +static int8_t read_all_field_data(struct bme68x_data * const data[], struct bme68x_dev *dev) +{ + int8_t rslt = BME68X_OK; + uint8_t buff[BME68X_LEN_FIELD * 3] = { 0 }; + uint8_t gas_range_l, gas_range_h; + uint32_t adc_temp; + uint32_t adc_pres; + uint16_t adc_hum; + uint16_t adc_gas_res_low, adc_gas_res_high; + uint8_t off; + uint8_t set_val[30] = { 0 }; /* idac, res_heat, gas_wait */ + uint8_t i; + + if (!data[0] && !data[1] && !data[2]) + { + rslt = BME68X_E_NULL_PTR; + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_FIELD0, buff, (uint32_t) BME68X_LEN_FIELD * 3, dev); + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_IDAC_HEAT0, set_val, 30, dev); + } + + for (i = 0; ((i < 3) && (rslt == BME68X_OK)); i++) + { + off = (uint8_t)(i * BME68X_LEN_FIELD); + data[i]->status = buff[off] & BME68X_NEW_DATA_MSK; + data[i]->gas_index = buff[off] & BME68X_GAS_INDEX_MSK; + data[i]->meas_index = buff[off + 1]; + + /* read the raw data from the sensor */ + adc_pres = + (uint32_t) (((uint32_t) buff[off + 2] * 4096) | ((uint32_t) buff[off + 3] * 16) | + ((uint32_t) buff[off + 4] / 16)); + adc_temp = + (uint32_t) (((uint32_t) buff[off + 5] * 4096) | ((uint32_t) buff[off + 6] * 16) | + ((uint32_t) buff[off + 7] / 16)); + adc_hum = (uint16_t) (((uint32_t) buff[off + 8] * 256) | (uint32_t) buff[off + 9]); + adc_gas_res_low = (uint16_t) ((uint32_t) buff[off + 13] * 4 | (((uint32_t) buff[off + 14]) / 64)); + adc_gas_res_high = (uint16_t) ((uint32_t) buff[off + 15] * 4 | (((uint32_t) buff[off + 16]) / 64)); + gas_range_l = buff[off + 14] & BME68X_GAS_RANGE_MSK; + gas_range_h = buff[off + 16] & BME68X_GAS_RANGE_MSK; + if (dev->variant_id == BME68X_VARIANT_GAS_HIGH) + { + data[i]->status |= buff[off + 16] & BME68X_GASM_VALID_MSK; + data[i]->status |= buff[off + 16] & BME68X_HEAT_STAB_MSK; + } + else + { + data[i]->status |= buff[off + 14] & BME68X_GASM_VALID_MSK; + data[i]->status |= buff[off + 14] & BME68X_HEAT_STAB_MSK; + } + + data[i]->idac = set_val[data[i]->gas_index]; + data[i]->res_heat = set_val[10 + data[i]->gas_index]; + data[i]->gas_wait = set_val[20 + data[i]->gas_index]; + data[i]->temperature = calc_temperature(adc_temp, dev); + data[i]->pressure = calc_pressure(adc_pres, dev); + data[i]->humidity = calc_humidity(adc_hum, dev); + if (dev->variant_id == BME68X_VARIANT_GAS_HIGH) + { + data[i]->gas_resistance = calc_gas_resistance_high(adc_gas_res_high, gas_range_h); + } + else + { + data[i]->gas_resistance = calc_gas_resistance_low(adc_gas_res_low, gas_range_l, dev); + } + } + + return rslt; +} + +/* This internal API is used to switch between SPI memory pages */ +static int8_t set_mem_page(uint8_t reg_addr, struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t reg; + uint8_t mem_page; + + /* Check for null pointers in the device structure*/ + rslt = null_ptr_check(dev); + if (rslt == BME68X_OK) + { + if (reg_addr > 0x7f) + { + mem_page = BME68X_MEM_PAGE1; + } + else + { + mem_page = BME68X_MEM_PAGE0; + } + + if (mem_page != dev->mem_page) + { + dev->mem_page = mem_page; + dev->intf_rslt = dev->read(BME68X_REG_MEM_PAGE | BME68X_SPI_RD_MSK, ®, 1, dev->intf_ptr); + if (dev->intf_rslt != 0) + { + rslt = BME68X_E_COM_FAIL; + } + + if (rslt == BME68X_OK) + { + reg = reg & (~BME68X_MEM_PAGE_MSK); + reg = reg | (dev->mem_page & BME68X_MEM_PAGE_MSK); + dev->intf_rslt = dev->write(BME68X_REG_MEM_PAGE & BME68X_SPI_WR_MSK, ®, 1, dev->intf_ptr); + if (dev->intf_rslt != 0) + { + rslt = BME68X_E_COM_FAIL; + } + } + } + } + + return rslt; +} + +/* This internal API is used to get the current SPI memory page */ +static int8_t get_mem_page(struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t reg; + + /* Check for null pointer in the device structure*/ + rslt = null_ptr_check(dev); + if (rslt == BME68X_OK) + { + dev->intf_rslt = dev->read(BME68X_REG_MEM_PAGE | BME68X_SPI_RD_MSK, ®, 1, dev->intf_ptr); + if (dev->intf_rslt != 0) + { + rslt = BME68X_E_COM_FAIL; + } + else + { + dev->mem_page = reg & BME68X_MEM_PAGE_MSK; + } + } + + return rslt; +} + +/* This internal API is used to limit the max value of a parameter */ +static int8_t boundary_check(uint8_t *value, uint8_t max, struct bme68x_dev *dev) +{ + int8_t rslt; + + rslt = null_ptr_check(dev); + if ((value != NULL) && (rslt == BME68X_OK)) + { + /* Check if value is above maximum value */ + if (*value > max) + { + /* Auto correct the invalid value to maximum value */ + *value = max; + dev->info_msg |= BME68X_I_PARAM_CORR; + } + } + else + { + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* This internal API is used to check the bme68x_dev for null pointers */ +static int8_t null_ptr_check(const struct bme68x_dev *dev) +{ + int8_t rslt = BME68X_OK; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + { + /* Device structure pointer is not valid */ + rslt = BME68X_E_NULL_PTR; + } + + return rslt; +} + +/* This internal API is used to set heater configurations */ +static int8_t set_conf(const struct bme68x_heatr_conf *conf, uint8_t op_mode, uint8_t *nb_conv, struct bme68x_dev *dev) +{ + int8_t rslt = BME68X_OK; + uint8_t i; + uint8_t shared_dur; + uint8_t write_len = 0; + uint8_t heater_dur_shared_addr = BME68X_REG_SHD_HEATR_DUR; + uint8_t rh_reg_addr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t rh_reg_data[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t gw_reg_addr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t gw_reg_data[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + switch (op_mode) + { + case BME68X_FORCED_MODE: + rh_reg_addr[0] = BME68X_REG_RES_HEAT0; + rh_reg_data[0] = calc_res_heat(conf->heatr_temp, dev); + gw_reg_addr[0] = BME68X_REG_GAS_WAIT0; + gw_reg_data[0] = calc_gas_wait(conf->heatr_dur); + (*nb_conv) = 0; + write_len = 1; + break; + case BME68X_SEQUENTIAL_MODE: + if ((!conf->heatr_dur_prof) || (!conf->heatr_temp_prof)) + { + rslt = BME68X_E_NULL_PTR; + break; + } + + for (i = 0; i < conf->profile_len; i++) + { + rh_reg_addr[i] = BME68X_REG_RES_HEAT0 + i; + rh_reg_data[i] = calc_res_heat(conf->heatr_temp_prof[i], dev); + gw_reg_addr[i] = BME68X_REG_GAS_WAIT0 + i; + gw_reg_data[i] = calc_gas_wait(conf->heatr_dur_prof[i]); + } + + (*nb_conv) = conf->profile_len; + write_len = conf->profile_len; + break; + case BME68X_PARALLEL_MODE: + if ((!conf->heatr_dur_prof) || (!conf->heatr_temp_prof)) + { + rslt = BME68X_E_NULL_PTR; + break; + } + + if (conf->shared_heatr_dur == 0) + { + rslt = BME68X_W_DEFINE_SHD_HEATR_DUR; + } + + for (i = 0; i < conf->profile_len; i++) + { + rh_reg_addr[i] = BME68X_REG_RES_HEAT0 + i; + rh_reg_data[i] = calc_res_heat(conf->heatr_temp_prof[i], dev); + gw_reg_addr[i] = BME68X_REG_GAS_WAIT0 + i; + gw_reg_data[i] = (uint8_t) conf->heatr_dur_prof[i]; + } + + (*nb_conv) = conf->profile_len; + write_len = conf->profile_len; + shared_dur = calc_heatr_dur_shared(conf->shared_heatr_dur); + if (rslt == BME68X_OK) + { + rslt = bme68x_set_regs(&heater_dur_shared_addr, &shared_dur, 1, dev); + } + + break; + default: + rslt = BME68X_W_DEFINE_OP_MODE; + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_set_regs(rh_reg_addr, rh_reg_data, write_len, dev); + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_set_regs(gw_reg_addr, gw_reg_data, write_len, dev); + } + + return rslt; +} + +/* This internal API is used to calculate the register value for + * shared heater duration */ +static uint8_t calc_heatr_dur_shared(uint16_t dur) +{ + uint8_t factor = 0; + uint8_t heatdurval; + + if (dur >= 0x783) + { + heatdurval = 0xff; /* Max duration */ + } + else + { + /* Step size of 0.477ms */ + dur = (uint16_t)(((uint32_t)dur * 1000) / 477); + while (dur > 0x3F) + { + dur = dur >> 2; + factor += 1; + } + + heatdurval = (uint8_t)(dur + (factor * 64)); + } + + return heatdurval; +} + +/* This internal API is used sort the sensor data */ +static void sort_sensor_data(uint8_t low_index, uint8_t high_index, struct bme68x_data *field[]) +{ + int16_t meas_index1; + int16_t meas_index2; + + meas_index1 = (int16_t)field[low_index]->meas_index; + meas_index2 = (int16_t)field[high_index]->meas_index; + if ((field[low_index]->status & BME68X_NEW_DATA_MSK) && (field[high_index]->status & BME68X_NEW_DATA_MSK)) + { + int16_t diff = meas_index2 - meas_index1; + if (((diff > -3) && (diff < 0)) || (diff > 2)) + { + swap_fields(low_index, high_index, field); + } + } + else if (field[high_index]->status & BME68X_NEW_DATA_MSK) + { + swap_fields(low_index, high_index, field); + } + + /* Sorting field data + * + * The 3 fields are filled in a fixed order with data in an incrementing + * 8-bit sub-measurement index which looks like + * Field index | Sub-meas index + * 0 | 0 + * 1 | 1 + * 2 | 2 + * 0 | 3 + * 1 | 4 + * 2 | 5 + * ... + * 0 | 252 + * 1 | 253 + * 2 | 254 + * 0 | 255 + * 1 | 0 + * 2 | 1 + * + * The fields are sorted in a way so as to always deal with only a snapshot + * of comparing 2 fields at a time. The order being + * field0 & field1 + * field0 & field2 + * field1 & field2 + * Here the oldest data should be in field0 while the newest is in field2. + * In the following documentation, field0's position would referred to as + * the lowest and field2 as the highest. + * + * In order to sort we have to consider the following cases, + * + * Case A: No fields have new data + * Then do not sort, as this data has already been read. + * + * Case B: Higher field has new data + * Then the new field get's the lowest position. + * + * Case C: Both fields have new data + * We have to put the oldest sample in the lowest position. Since the + * sub-meas index contains in essence the age of the sample, we calculate + * the difference between the higher field and the lower field. + * Here we have 3 sub-cases, + * Case 1: Regular read without overwrite + * Field index | Sub-meas index + * 0 | 3 + * 1 | 4 + * + * Field index | Sub-meas index + * 0 | 3 + * 2 | 5 + * + * The difference is always <= 2. There is no need to swap as the + * oldest sample is already in the lowest position. + * + * Case 2: Regular read with an overflow and without an overwrite + * Field index | Sub-meas index + * 0 | 255 + * 1 | 0 + * + * Field index | Sub-meas index + * 0 | 254 + * 2 | 0 + * + * The difference is always <= -3. There is no need to swap as the + * oldest sample is already in the lowest position. + * + * Case 3: Regular read with overwrite + * Field index | Sub-meas index + * 0 | 6 + * 1 | 4 + * + * Field index | Sub-meas index + * 0 | 6 + * 2 | 5 + * + * The difference is always > -3. There is a need to swap as the + * oldest sample is not in the lowest position. + * + * Case 4: Regular read with overwrite and overflow + * Field index | Sub-meas index + * 0 | 0 + * 1 | 254 + * + * Field index | Sub-meas index + * 0 | 0 + * 2 | 255 + * + * The difference is always > 2. There is a need to swap as the + * oldest sample is not in the lowest position. + * + * To summarize, we have to swap when + * - The higher field has new data and the lower field does not. + * - If both fields have new data, then the difference of sub-meas index + * between the higher field and the lower field creates the + * following condition for swapping. + * - (diff > -3) && (diff < 0), combination of cases 1, 2, and 3. + * - diff > 2, case 4. + * + * Here the limits of -3 and 2 derive from the fact that there are 3 fields. + * These values decrease or increase respectively if the number of fields increases. + */ +} + +/* This internal API is used sort the sensor data */ +static void swap_fields(uint8_t index1, uint8_t index2, struct bme68x_data *field[]) +{ + struct bme68x_data *temp; + + temp = field[index1]; + field[index1] = field[index2]; + field[index2] = temp; +} + +/* This Function is to analyze the sensor data */ +static int8_t analyze_sensor_data(const struct bme68x_data *data, uint8_t n_meas) +{ + int8_t rslt = BME68X_OK; + uint8_t self_test_failed = 0, i; + uint32_t cent_res = 0; + + if ((data[0].temperature < BME68X_MIN_TEMPERATURE) || (data[0].temperature > BME68X_MAX_TEMPERATURE)) + { + self_test_failed++; + } + + if ((data[0].pressure < BME68X_MIN_PRESSURE) || (data[0].pressure > BME68X_MAX_PRESSURE)) + { + self_test_failed++; + } + + if ((data[0].humidity < BME68X_MIN_HUMIDITY) || (data[0].humidity > BME68X_MAX_HUMIDITY)) + { + self_test_failed++; + } + + for (i = 0; i < n_meas; i++) /* Every gas measurement should be valid */ + { + if (!(data[i].status & BME68X_GASM_VALID_MSK)) + { + self_test_failed++; + } + } + + if (n_meas >= 6) + { + cent_res = (uint32_t)((5 * (data[3].gas_resistance + data[5].gas_resistance)) / (2 * data[4].gas_resistance)); + } + + if (cent_res < 6) + { + self_test_failed++; + } + + if (self_test_failed) + { + rslt = BME68X_E_SELF_TEST; + } + + return rslt; +} + +/* This internal API is used to read the calibration coefficients */ +static int8_t get_calib_data(struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t coeff_array[BME68X_LEN_COEFF_ALL]; + + rslt = bme68x_get_regs(BME68X_REG_COEFF1, coeff_array, BME68X_LEN_COEFF1, dev); + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_COEFF2, &coeff_array[BME68X_LEN_COEFF1], BME68X_LEN_COEFF2, dev); + } + + if (rslt == BME68X_OK) + { + rslt = bme68x_get_regs(BME68X_REG_COEFF3, + &coeff_array[BME68X_LEN_COEFF1 + BME68X_LEN_COEFF2], + BME68X_LEN_COEFF3, + dev); + } + + if (rslt == BME68X_OK) + { + /* Temperature related coefficients */ + dev->calib.par_t1 = + (uint16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_T1_MSB], coeff_array[BME68X_IDX_T1_LSB])); + dev->calib.par_t2 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_T2_MSB], coeff_array[BME68X_IDX_T2_LSB])); + dev->calib.par_t3 = (int8_t)(coeff_array[BME68X_IDX_T3]); + + /* Pressure related coefficients */ + dev->calib.par_p1 = + (uint16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P1_MSB], coeff_array[BME68X_IDX_P1_LSB])); + dev->calib.par_p2 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P2_MSB], coeff_array[BME68X_IDX_P2_LSB])); + dev->calib.par_p3 = (int8_t)coeff_array[BME68X_IDX_P3]; + dev->calib.par_p4 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P4_MSB], coeff_array[BME68X_IDX_P4_LSB])); + dev->calib.par_p5 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P5_MSB], coeff_array[BME68X_IDX_P5_LSB])); + dev->calib.par_p6 = (int8_t)(coeff_array[BME68X_IDX_P6]); + dev->calib.par_p7 = (int8_t)(coeff_array[BME68X_IDX_P7]); + dev->calib.par_p8 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P8_MSB], coeff_array[BME68X_IDX_P8_LSB])); + dev->calib.par_p9 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_P9_MSB], coeff_array[BME68X_IDX_P9_LSB])); + dev->calib.par_p10 = (uint8_t)(coeff_array[BME68X_IDX_P10]); + + /* Humidity related coefficients */ + dev->calib.par_h1 = + (uint16_t)(((uint16_t)coeff_array[BME68X_IDX_H1_MSB] << 4) | + (coeff_array[BME68X_IDX_H1_LSB] & BME68X_BIT_H1_DATA_MSK)); + dev->calib.par_h2 = + (uint16_t)(((uint16_t)coeff_array[BME68X_IDX_H2_MSB] << 4) | ((coeff_array[BME68X_IDX_H2_LSB]) >> 4)); + dev->calib.par_h3 = (int8_t)coeff_array[BME68X_IDX_H3]; + dev->calib.par_h4 = (int8_t)coeff_array[BME68X_IDX_H4]; + dev->calib.par_h5 = (int8_t)coeff_array[BME68X_IDX_H5]; + dev->calib.par_h6 = (uint8_t)coeff_array[BME68X_IDX_H6]; + dev->calib.par_h7 = (int8_t)coeff_array[BME68X_IDX_H7]; + + /* Gas heater related coefficients */ + dev->calib.par_gh1 = (int8_t)coeff_array[BME68X_IDX_GH1]; + dev->calib.par_gh2 = + (int16_t)(BME68X_CONCAT_BYTES(coeff_array[BME68X_IDX_GH2_MSB], coeff_array[BME68X_IDX_GH2_LSB])); + dev->calib.par_gh3 = (int8_t)coeff_array[BME68X_IDX_GH3]; + + /* Other coefficients */ + dev->calib.res_heat_range = ((coeff_array[BME68X_IDX_RES_HEAT_RANGE] & BME68X_RHRANGE_MSK) / 16); + dev->calib.res_heat_val = (int8_t)coeff_array[BME68X_IDX_RES_HEAT_VAL]; + dev->calib.range_sw_err = ((int8_t)(coeff_array[BME68X_IDX_RANGE_SW_ERR] & BME68X_RSERROR_MSK)) / 16; + } + + return rslt; +} + +/* This internal API is used to read variant ID information from the register */ +static int8_t read_variant_id(struct bme68x_dev *dev) +{ + int8_t rslt; + uint8_t reg_data = 0; + + /* Read variant ID information register */ + rslt = bme68x_get_regs(BME68X_REG_VARIANT_ID, ®_data, 1, dev); + + if (rslt == BME68X_OK) + { + dev->variant_id = reg_data; + } + + return rslt; +} diff --git a/components/bme68x/bme68x.h b/components/bme68x/bme68x.h new file mode 100644 index 0000000..89b58ed --- /dev/null +++ b/components/bme68x/bme68x.h @@ -0,0 +1,323 @@ +/** +* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder nor the names of its +* 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 THE +* 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. +* +* @file bme68x.h +* @date 2023-02-07 +* @version v4.4.8 +* +*/ + +/*! + * @defgroup bme68x BME68X + * @brief Product Overview + * and Sensor API Source Code + */ + +#ifndef BME68X_H_ +#define BME68X_H_ + +#include "bme68x_defs.h" + +/* CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup bme68x + * \defgroup bme68xApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bme68xApiInit + * \page bme68x_api_bme68x_init bme68x_init + * \code + * int8_t bme68x_init(struct bme68x_dev *dev); + * \endcode + * @details This API reads the chip-id of the sensor which is the first step to + * verify the sensor and also calibrates the sensor + * As this API is the entry point, call this API before using other APIs. + * + * @param[in,out] dev : Structure instance of bme68x_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_init(struct bme68x_dev *dev); + +/** + * \ingroup bme68x + * \defgroup bme68xApiRegister Registers + * @brief Generic API for accessing sensor registers + */ + +/*! + * \ingroup bme68xApiRegister + * \page bme68x_api_bme68x_set_regs bme68x_set_regs + * \code + * int8_t bme68x_set_regs(const uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, struct bme68x_dev *dev) + * \endcode + * @details This API writes the given data to the register address of the sensor + * + * @param[in] reg_addr : Register addresses to where the data is to be written + * @param[in] reg_data : Pointer to data buffer which is to be written + * in the reg_addr of sensor. + * @param[in] len : No of bytes of data to write + * @param[in,out] dev : Structure instance of bme68x_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_set_regs(const uint8_t *reg_addr, const uint8_t *reg_data, uint32_t len, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiRegister + * \page bme68x_api_bme68x_get_regs bme68x_get_regs + * \code + * int8_t bme68x_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, struct bme68x_dev *dev) + * \endcode + * @details This API reads the data from the given register address of sensor. + * + * @param[in] reg_addr : Register address from where the data to be read + * @param[out] reg_data : Pointer to data buffer to store the read data. + * @param[in] len : No of bytes of data to be read. + * @param[in,out] dev : Structure instance of bme68x_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, struct bme68x_dev *dev); + +/** + * \ingroup bme68x + * \defgroup bme68xApiSystem System + * @brief API that performs system-level operations + */ + +/*! + * \ingroup bme68xApiSystem + * \page bme68x_api_bme68x_soft_reset bme68x_soft_reset + * \code + * int8_t bme68x_soft_reset(struct bme68x_dev *dev); + * \endcode + * @details This API soft-resets the sensor. + * + * @param[in,out] dev : Structure instance of bme68x_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_soft_reset(struct bme68x_dev *dev); + +/** + * \ingroup bme68x + * \defgroup bme68xApiOm Operation mode + * @brief API to configure operation mode + */ + +/*! + * \ingroup bme68xApiOm + * \page bme68x_api_bme68x_set_op_mode bme68x_set_op_mode + * \code + * int8_t bme68x_set_op_mode(const uint8_t op_mode, struct bme68x_dev *dev); + * \endcode + * @details This API is used to set the operation mode of the sensor + * @param[in] op_mode : Desired operation mode. + * @param[in] dev : Structure instance of bme68x_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_set_op_mode(const uint8_t op_mode, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiOm + * \page bme68x_api_bme68x_get_op_mode bme68x_get_op_mode + * \code + * int8_t bme68x_get_op_mode(uint8_t *op_mode, struct bme68x_dev *dev); + * \endcode + * @details This API is used to get the operation mode of the sensor. + * + * @param[out] op_mode : Desired operation mode. + * @param[in,out] dev : Structure instance of bme68x_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_get_op_mode(uint8_t *op_mode, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiConfig + * \page bme68x_api_bme68x_get_meas_dur bme68x_get_meas_dur + * \code + * uint32_t bme68x_get_meas_dur(const uint8_t op_mode, struct bme68x_conf *conf, struct bme68x_dev *dev); + * \endcode + * @details This API is used to get the remaining duration that can be used for heating. + * + * @param[in] op_mode : Desired operation mode. + * @param[in] conf : Desired sensor configuration. + * @param[in] dev : Structure instance of bme68x_dev + * + * @return Measurement duration calculated in microseconds + */ +uint32_t bme68x_get_meas_dur(const uint8_t op_mode, struct bme68x_conf *conf, struct bme68x_dev *dev); + +/** + * \ingroup bme68x + * \defgroup bme68xApiData Data Read out + * @brief Read our data from the sensor + */ + +/*! + * \ingroup bme68xApiData + * \page bme68x_api_bme68x_get_data bme68x_get_data + * \code + * int8_t bme68x_get_data(uint8_t op_mode, struct bme68x_data *data, uint8_t *n_data, struct bme68x_dev *dev); + * \endcode + * @details This API reads the pressure, temperature and humidity and gas data + * from the sensor, compensates the data and store it in the bme68x_data + * structure instance passed by the user. + * + * @param[in] op_mode : Expected operation mode. + * @param[out] data : Structure instance to hold the data. + * @param[out] n_data : Number of data instances available. + * @param[in,out] dev : Structure instance of bme68x_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_get_data(uint8_t op_mode, struct bme68x_data *data, uint8_t *n_data, struct bme68x_dev *dev); + +/** + * \ingroup bme68x + * \defgroup bme68xApiConfig Configuration + * @brief Configuration API of sensor + */ + +/*! + * \ingroup bme68xApiConfig + * \page bme68x_api_bme68x_set_conf bme68x_set_conf + * \code + * int8_t bme68x_set_conf(struct bme68x_conf *conf, struct bme68x_dev *dev); + * \endcode + * @details This API is used to set the oversampling, filter and odr configuration + * + * @param[in] conf : Desired sensor configuration. + * @param[in,out] dev : Structure instance of bme68x_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_set_conf(struct bme68x_conf *conf, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiConfig + * \page bme68x_api_bme68x_get_conf bme68x_get_conf + * \code + * int8_t bme68x_get_conf(struct bme68x_conf *conf, struct bme68x_dev *dev); + * \endcode + * @details This API is used to get the oversampling, filter and odr + * configuration + * + * @param[out] conf : Present sensor configuration. + * @param[in,out] dev : Structure instance of bme68x_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_get_conf(struct bme68x_conf *conf, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiConfig + * \page bme68x_api_bme68x_set_heatr_conf bme68x_set_heatr_conf + * \code + * int8_t bme68x_set_heatr_conf(uint8_t op_mode, const struct bme68x_heatr_conf *conf, struct bme68x_dev *dev); + * \endcode + * @details This API is used to set the gas configuration of the sensor. + * + * @param[in] op_mode : Expected operation mode of the sensor. + * @param[in] conf : Desired heating configuration. + * @param[in,out] dev : Structure instance of bme68x_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_set_heatr_conf(uint8_t op_mode, const struct bme68x_heatr_conf *conf, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiConfig + * \page bme68x_api_bme68x_get_heatr_conf bme68x_get_heatr_conf + * \code + * int8_t bme68x_get_heatr_conf(const struct bme68x_heatr_conf *conf, struct bme68x_dev *dev); + * \endcode + * @details This API is used to get the gas configuration of the sensor. + * + * @param[out] conf : Current configurations of the gas sensor. + * @param[in,out] dev : Structure instance of bme68x_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_get_heatr_conf(const struct bme68x_heatr_conf *conf, struct bme68x_dev *dev); + +/*! + * \ingroup bme68xApiSystem + * \page bme68x_api_bme68x_selftest_check bme68x_selftest_check + * \code + * int8_t bme68x_selftest_check(const struct bme68x_dev *dev); + * \endcode + * @details This API performs Self-test of low gas variant of BME68X + * + * @param[in, out] dev : Structure instance of bme68x_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval < 0 -> Fail + */ +int8_t bme68x_selftest_check(const struct bme68x_dev *dev); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ +#endif /* BME68X_H_ */ diff --git a/components/bme68x/bme68x_defs.h b/components/bme68x/bme68x_defs.h new file mode 100644 index 0000000..1ad1584 --- /dev/null +++ b/components/bme68x/bme68x_defs.h @@ -0,0 +1,972 @@ +/** +* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder nor the names of its +* 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 THE +* 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. +* +* @file bme68x_defs.h +* @date 2023-02-07 +* @version v4.4.8 +* +*/ + +/*! @cond DOXYGEN_SUPRESS */ + +#ifndef BME68X_DEFS_H_ +#define BME68X_DEFS_H_ + +/********************************************************* */ +/*! Header includes */ +/********************************************************* */ +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +/********************************************************* */ +/*! Common Macros */ +/********************************************************* */ +#ifdef __KERNEL__ +#if !defined(UINT8_C) && !defined(INT8_C) +#define INT8_C(x) S8_C(x) +#define UINT8_C(x) U8_C(x) +#endif + +#if !defined(UINT16_C) && !defined(INT16_C) +#define INT16_C(x) S16_C(x) +#define UINT16_C(x) U16_C(x) +#endif + +#if !defined(INT32_C) && !defined(UINT32_C) +#define INT32_C(x) S32_C(x) +#define UINT32_C(x) U32_C(x) +#endif + +#if !defined(INT64_C) && !defined(UINT64_C) +#define INT64_C(x) S64_C(x) +#define UINT64_C(x) U64_C(x) +#endif +#endif + +/*! C standard macros */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +#ifndef BME68X_DO_NOT_USE_FPU + +/* Comment or un-comment the macro to provide floating point data output */ +#define BME68X_USE_FPU +#endif + +/* Period between two polls (value can be given by user) */ +#ifndef BME68X_PERIOD_POLL +#define BME68X_PERIOD_POLL UINT32_C(10000) +#endif + +/* BME68X unique chip identifier */ +#define BME68X_CHIP_ID UINT8_C(0x61) + +/* Period for a soft reset */ +#define BME68X_PERIOD_RESET UINT32_C(10000) + +/* BME68X lower I2C address */ +#define BME68X_I2C_ADDR_LOW UINT8_C(0x76) + +/* BME68X higher I2C address */ +#define BME68X_I2C_ADDR_HIGH UINT8_C(0x77) + +/* Soft reset command */ +#define BME68X_SOFT_RESET_CMD UINT8_C(0xb6) + +/* Return code definitions */ +/* Success */ +#define BME68X_OK INT8_C(0) + +/* Errors */ +/* Null pointer passed */ +#define BME68X_E_NULL_PTR INT8_C(-1) + +/* Communication failure */ +#define BME68X_E_COM_FAIL INT8_C(-2) + +/* Sensor not found */ +#define BME68X_E_DEV_NOT_FOUND INT8_C(-3) + +/* Incorrect length parameter */ +#define BME68X_E_INVALID_LENGTH INT8_C(-4) + +/* Self test fail error */ +#define BME68X_E_SELF_TEST INT8_C(-5) + +/* Warnings */ +/* Define a valid operation mode */ +#define BME68X_W_DEFINE_OP_MODE INT8_C(1) + +/* No new data was found */ +#define BME68X_W_NO_NEW_DATA INT8_C(2) + +/* Define the shared heating duration */ +#define BME68X_W_DEFINE_SHD_HEATR_DUR INT8_C(3) + +/* Information - only available via bme68x_dev.info_msg */ +#define BME68X_I_PARAM_CORR UINT8_C(1) + +/* Register map addresses in I2C */ +/* Register for 3rd group of coefficients */ +#define BME68X_REG_COEFF3 UINT8_C(0x00) + +/* 0th Field address*/ +#define BME68X_REG_FIELD0 UINT8_C(0x1d) + +/* 0th Current DAC address*/ +#define BME68X_REG_IDAC_HEAT0 UINT8_C(0x50) + +/* 0th Res heat address */ +#define BME68X_REG_RES_HEAT0 UINT8_C(0x5a) + +/* 0th Gas wait address */ +#define BME68X_REG_GAS_WAIT0 UINT8_C(0x64) + +/* Shared heating duration address */ +#define BME68X_REG_SHD_HEATR_DUR UINT8_C(0x6E) + +/* CTRL_GAS_0 address */ +#define BME68X_REG_CTRL_GAS_0 UINT8_C(0x70) + +/* CTRL_GAS_1 address */ +#define BME68X_REG_CTRL_GAS_1 UINT8_C(0x71) + +/* CTRL_HUM address */ +#define BME68X_REG_CTRL_HUM UINT8_C(0x72) + +/* CTRL_MEAS address */ +#define BME68X_REG_CTRL_MEAS UINT8_C(0x74) + +/* CONFIG address */ +#define BME68X_REG_CONFIG UINT8_C(0x75) + +/* MEM_PAGE address */ +#define BME68X_REG_MEM_PAGE UINT8_C(0xf3) + +/* Unique ID address */ +#define BME68X_REG_UNIQUE_ID UINT8_C(0x83) + +/* Register for 1st group of coefficients */ +#define BME68X_REG_COEFF1 UINT8_C(0x8a) + +/* Chip ID address */ +#define BME68X_REG_CHIP_ID UINT8_C(0xd0) + +/* Soft reset address */ +#define BME68X_REG_SOFT_RESET UINT8_C(0xe0) + +/* Register for 2nd group of coefficients */ +#define BME68X_REG_COEFF2 UINT8_C(0xe1) + +/* Variant ID Register */ +#define BME68X_REG_VARIANT_ID UINT8_C(0xF0) + +/* Enable/Disable macros */ + +/* Enable */ +#define BME68X_ENABLE UINT8_C(0x01) + +/* Disable */ +#define BME68X_DISABLE UINT8_C(0x00) + +/* Variant ID macros */ + +/* Low Gas variant */ +#define BME68X_VARIANT_GAS_LOW UINT8_C(0x00) + +/* High Gas variant */ +#define BME68X_VARIANT_GAS_HIGH UINT8_C(0x01) + +/* Oversampling setting macros */ + +/* Switch off measurement */ +#define BME68X_OS_NONE UINT8_C(0) + +/* Perform 1 measurement */ +#define BME68X_OS_1X UINT8_C(1) + +/* Perform 2 measurements */ +#define BME68X_OS_2X UINT8_C(2) + +/* Perform 4 measurements */ +#define BME68X_OS_4X UINT8_C(3) + +/* Perform 8 measurements */ +#define BME68X_OS_8X UINT8_C(4) + +/* Perform 16 measurements */ +#define BME68X_OS_16X UINT8_C(5) + +/* IIR Filter settings */ + +/* Switch off the filter */ +#define BME68X_FILTER_OFF UINT8_C(0) + +/* Filter coefficient of 2 */ +#define BME68X_FILTER_SIZE_1 UINT8_C(1) + +/* Filter coefficient of 4 */ +#define BME68X_FILTER_SIZE_3 UINT8_C(2) + +/* Filter coefficient of 8 */ +#define BME68X_FILTER_SIZE_7 UINT8_C(3) + +/* Filter coefficient of 16 */ +#define BME68X_FILTER_SIZE_15 UINT8_C(4) + +/* Filter coefficient of 32 */ +#define BME68X_FILTER_SIZE_31 UINT8_C(5) + +/* Filter coefficient of 64 */ +#define BME68X_FILTER_SIZE_63 UINT8_C(6) + +/* Filter coefficient of 128 */ +#define BME68X_FILTER_SIZE_127 UINT8_C(7) + +/* ODR/Standby time macros */ + +/* Standby time of 0.59ms */ +#define BME68X_ODR_0_59_MS UINT8_C(0) + +/* Standby time of 62.5ms */ +#define BME68X_ODR_62_5_MS UINT8_C(1) + +/* Standby time of 125ms */ +#define BME68X_ODR_125_MS UINT8_C(2) + +/* Standby time of 250ms */ +#define BME68X_ODR_250_MS UINT8_C(3) + +/* Standby time of 500ms */ +#define BME68X_ODR_500_MS UINT8_C(4) + +/* Standby time of 1s */ +#define BME68X_ODR_1000_MS UINT8_C(5) + +/* Standby time of 10ms */ +#define BME68X_ODR_10_MS UINT8_C(6) + +/* Standby time of 20ms */ +#define BME68X_ODR_20_MS UINT8_C(7) + +/* No standby time */ +#define BME68X_ODR_NONE UINT8_C(8) + +/* Operating mode macros */ + +/* Sleep operation mode */ +#define BME68X_SLEEP_MODE UINT8_C(0) + +/* Forced operation mode */ +#define BME68X_FORCED_MODE UINT8_C(1) + +/* Parallel operation mode */ +#define BME68X_PARALLEL_MODE UINT8_C(2) + +/* Sequential operation mode */ +#define BME68X_SEQUENTIAL_MODE UINT8_C(3) + +/* SPI page macros */ + +/* SPI memory page 0 */ +#define BME68X_MEM_PAGE0 UINT8_C(0x10) + +/* SPI memory page 1 */ +#define BME68X_MEM_PAGE1 UINT8_C(0x00) + +/* Coefficient index macros */ + +/* Length for all coefficients */ +#define BME68X_LEN_COEFF_ALL UINT8_C(42) + +/* Length for 1st group of coefficients */ +#define BME68X_LEN_COEFF1 UINT8_C(23) + +/* Length for 2nd group of coefficients */ +#define BME68X_LEN_COEFF2 UINT8_C(14) + +/* Length for 3rd group of coefficients */ +#define BME68X_LEN_COEFF3 UINT8_C(5) + +/* Length of the field */ +#define BME68X_LEN_FIELD UINT8_C(17) + +/* Length between two fields */ +#define BME68X_LEN_FIELD_OFFSET UINT8_C(17) + +/* Length of the configuration register */ +#define BME68X_LEN_CONFIG UINT8_C(5) + +/* Length of the interleaved buffer */ +#define BME68X_LEN_INTERLEAVE_BUFF UINT8_C(20) + +/* Coefficient index macros */ + +/* Coefficient T2 LSB position */ +#define BME68X_IDX_T2_LSB (0) + +/* Coefficient T2 MSB position */ +#define BME68X_IDX_T2_MSB (1) + +/* Coefficient T3 position */ +#define BME68X_IDX_T3 (2) + +/* Coefficient P1 LSB position */ +#define BME68X_IDX_P1_LSB (4) + +/* Coefficient P1 MSB position */ +#define BME68X_IDX_P1_MSB (5) + +/* Coefficient P2 LSB position */ +#define BME68X_IDX_P2_LSB (6) + +/* Coefficient P2 MSB position */ +#define BME68X_IDX_P2_MSB (7) + +/* Coefficient P3 position */ +#define BME68X_IDX_P3 (8) + +/* Coefficient P4 LSB position */ +#define BME68X_IDX_P4_LSB (10) + +/* Coefficient P4 MSB position */ +#define BME68X_IDX_P4_MSB (11) + +/* Coefficient P5 LSB position */ +#define BME68X_IDX_P5_LSB (12) + +/* Coefficient P5 MSB position */ +#define BME68X_IDX_P5_MSB (13) + +/* Coefficient P7 position */ +#define BME68X_IDX_P7 (14) + +/* Coefficient P6 position */ +#define BME68X_IDX_P6 (15) + +/* Coefficient P8 LSB position */ +#define BME68X_IDX_P8_LSB (18) + +/* Coefficient P8 MSB position */ +#define BME68X_IDX_P8_MSB (19) + +/* Coefficient P9 LSB position */ +#define BME68X_IDX_P9_LSB (20) + +/* Coefficient P9 MSB position */ +#define BME68X_IDX_P9_MSB (21) + +/* Coefficient P10 position */ +#define BME68X_IDX_P10 (22) + +/* Coefficient H2 MSB position */ +#define BME68X_IDX_H2_MSB (23) + +/* Coefficient H2 LSB position */ +#define BME68X_IDX_H2_LSB (24) + +/* Coefficient H1 LSB position */ +#define BME68X_IDX_H1_LSB (24) + +/* Coefficient H1 MSB position */ +#define BME68X_IDX_H1_MSB (25) + +/* Coefficient H3 position */ +#define BME68X_IDX_H3 (26) + +/* Coefficient H4 position */ +#define BME68X_IDX_H4 (27) + +/* Coefficient H5 position */ +#define BME68X_IDX_H5 (28) + +/* Coefficient H6 position */ +#define BME68X_IDX_H6 (29) + +/* Coefficient H7 position */ +#define BME68X_IDX_H7 (30) + +/* Coefficient T1 LSB position */ +#define BME68X_IDX_T1_LSB (31) + +/* Coefficient T1 MSB position */ +#define BME68X_IDX_T1_MSB (32) + +/* Coefficient GH2 LSB position */ +#define BME68X_IDX_GH2_LSB (33) + +/* Coefficient GH2 MSB position */ +#define BME68X_IDX_GH2_MSB (34) + +/* Coefficient GH1 position */ +#define BME68X_IDX_GH1 (35) + +/* Coefficient GH3 position */ +#define BME68X_IDX_GH3 (36) + +/* Coefficient res heat value position */ +#define BME68X_IDX_RES_HEAT_VAL (37) + +/* Coefficient res heat range position */ +#define BME68X_IDX_RES_HEAT_RANGE (39) + +/* Coefficient range switching error position */ +#define BME68X_IDX_RANGE_SW_ERR (41) + +/* Gas measurement macros */ + +/* Disable gas measurement */ +#define BME68X_DISABLE_GAS_MEAS UINT8_C(0x00) + +/* Enable gas measurement low */ +#define BME68X_ENABLE_GAS_MEAS_L UINT8_C(0x01) + +/* Enable gas measurement high */ +#define BME68X_ENABLE_GAS_MEAS_H UINT8_C(0x02) + +/* Heater control macros */ + +/* Enable heater */ +#define BME68X_ENABLE_HEATER UINT8_C(0x00) + +/* Disable heater */ +#define BME68X_DISABLE_HEATER UINT8_C(0x01) + +#ifdef BME68X_USE_FPU + +/* 0 degree Celsius */ +#define BME68X_MIN_TEMPERATURE INT16_C(0) + +/* 60 degree Celsius */ +#define BME68X_MAX_TEMPERATURE INT16_C(60) + +/* 900 hecto Pascals */ +#define BME68X_MIN_PRESSURE UINT32_C(90000) + +/* 1100 hecto Pascals */ +#define BME68X_MAX_PRESSURE UINT32_C(110000) + +/* 20% relative humidity */ +#define BME68X_MIN_HUMIDITY UINT32_C(20) + +/* 80% relative humidity*/ +#define BME68X_MAX_HUMIDITY UINT32_C(80) +#else + +/* 0 degree Celsius */ +#define BME68X_MIN_TEMPERATURE INT16_C(0) + +/* 60 degree Celsius */ +#define BME68X_MAX_TEMPERATURE INT16_C(6000) + +/* 900 hecto Pascals */ +#define BME68X_MIN_PRESSURE UINT32_C(90000) + +/* 1100 hecto Pascals */ +#define BME68X_MAX_PRESSURE UINT32_C(110000) + +/* 20% relative humidity */ +#define BME68X_MIN_HUMIDITY UINT32_C(20000) + +/* 80% relative humidity*/ +#define BME68X_MAX_HUMIDITY UINT32_C(80000) + +#endif + +#define BME68X_HEATR_DUR1 UINT16_C(1000) +#define BME68X_HEATR_DUR2 UINT16_C(2000) +#define BME68X_HEATR_DUR1_DELAY UINT32_C(1000000) +#define BME68X_HEATR_DUR2_DELAY UINT32_C(2000000) +#define BME68X_N_MEAS UINT8_C(6) +#define BME68X_LOW_TEMP UINT8_C(150) +#define BME68X_HIGH_TEMP UINT16_C(350) + +/* Mask macros */ +/* Mask for number of conversions */ +#define BME68X_NBCONV_MSK UINT8_C(0X0f) + +/* Mask for IIR filter */ +#define BME68X_FILTER_MSK UINT8_C(0X1c) + +/* Mask for ODR[3] */ +#define BME68X_ODR3_MSK UINT8_C(0x80) + +/* Mask for ODR[2:0] */ +#define BME68X_ODR20_MSK UINT8_C(0xe0) + +/* Mask for temperature oversampling */ +#define BME68X_OST_MSK UINT8_C(0Xe0) + +/* Mask for pressure oversampling */ +#define BME68X_OSP_MSK UINT8_C(0X1c) + +/* Mask for humidity oversampling */ +#define BME68X_OSH_MSK UINT8_C(0X07) + +/* Mask for heater control */ +#define BME68X_HCTRL_MSK UINT8_C(0x08) + +/* Mask for run gas */ +#define BME68X_RUN_GAS_MSK UINT8_C(0x30) + +/* Mask for operation mode */ +#define BME68X_MODE_MSK UINT8_C(0x03) + +/* Mask for res heat range */ +#define BME68X_RHRANGE_MSK UINT8_C(0x30) + +/* Mask for range switching error */ +#define BME68X_RSERROR_MSK UINT8_C(0xf0) + +/* Mask for new data */ +#define BME68X_NEW_DATA_MSK UINT8_C(0x80) + +/* Mask for gas index */ +#define BME68X_GAS_INDEX_MSK UINT8_C(0x0f) + +/* Mask for gas range */ +#define BME68X_GAS_RANGE_MSK UINT8_C(0x0f) + +/* Mask for gas measurement valid */ +#define BME68X_GASM_VALID_MSK UINT8_C(0x20) + +/* Mask for heater stability */ +#define BME68X_HEAT_STAB_MSK UINT8_C(0x10) + +/* Mask for SPI memory page */ +#define BME68X_MEM_PAGE_MSK UINT8_C(0x10) + +/* Mask for reading a register in SPI */ +#define BME68X_SPI_RD_MSK UINT8_C(0x80) + +/* Mask for writing a register in SPI */ +#define BME68X_SPI_WR_MSK UINT8_C(0x7f) + +/* Mask for the H1 calibration coefficient */ +#define BME68X_BIT_H1_DATA_MSK UINT8_C(0x0f) + +/* Position macros */ + +/* Filter bit position */ +#define BME68X_FILTER_POS UINT8_C(2) + +/* Temperature oversampling bit position */ +#define BME68X_OST_POS UINT8_C(5) + +/* Pressure oversampling bit position */ +#define BME68X_OSP_POS UINT8_C(2) + +/* ODR[3] bit position */ +#define BME68X_ODR3_POS UINT8_C(7) + +/* ODR[2:0] bit position */ +#define BME68X_ODR20_POS UINT8_C(5) + +/* Run gas bit position */ +#define BME68X_RUN_GAS_POS UINT8_C(4) + +/* Heater control bit position */ +#define BME68X_HCTRL_POS UINT8_C(3) + +/* Macro to combine two 8 bit data's to form a 16 bit data */ +#define BME68X_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb) + +/* Macro to set bits */ +#define BME68X_SET_BITS(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | \ + ((data << bitname##_POS) & bitname##_MSK)) + +/* Macro to get bits */ +#define BME68X_GET_BITS(reg_data, bitname) ((reg_data & (bitname##_MSK)) >> \ + (bitname##_POS)) + +/* Macro to set bits starting from position 0 */ +#define BME68X_SET_BITS_POS_0(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | \ + (data & bitname##_MSK)) + +/* Macro to get bits starting from position 0 */ +#define BME68X_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) + +/** + * BME68X_INTF_RET_TYPE is the read/write interface return type which can be overwritten by the build system. + * The default is set to int8_t. + */ +#ifndef BME68X_INTF_RET_TYPE +#define BME68X_INTF_RET_TYPE int8_t +#endif + +/** + * BME68X_INTF_RET_SUCCESS is the success return value read/write interface return type which can be + * overwritten by the build system. The default is set to 0. It is used to check for a successful + * execution of the read/write functions + */ +#ifndef BME68X_INTF_RET_SUCCESS +#define BME68X_INTF_RET_SUCCESS INT8_C(0) +#endif + +/********************************************************* */ +/*! Function Pointers */ +/********************************************************* */ + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific read functions of the user + * + * @param[in] reg_addr : 8bit register address of the sensor + * @param[out] reg_data : Data from the specified address + * @param[in] length : Length of the reg_data array + * @param[in,out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related callbacks + * @retval 0 for Success + * @retval Non-zero for Failure + */ +typedef BME68X_INTF_RET_TYPE (*bme68x_read_fptr_t)(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, + void *intf_ptr); + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific write functions of the user + * + * @param[in] reg_addr : 8bit register address of the sensor + * @param[out] reg_data : Data to the specified address + * @param[in] length : Length of the reg_data array + * @param[in,out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related callbacks + * @retval 0 for Success + * @retval Non-zero for Failure + * + */ +typedef BME68X_INTF_RET_TYPE (*bme68x_write_fptr_t)(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, + void *intf_ptr); + +/*! + * @brief Delay function pointer which should be mapped to + * delay function of the user + * + * @param period - The time period in microseconds + * @param[in,out] intf_ptr : Void pointer that can enable the linking of descriptors + * for interface related callbacks + */ +typedef void (*bme68x_delay_us_fptr_t)(uint32_t period, void *intf_ptr); + +/* + * @brief Generic communication function pointer + * @param[in] dev_id: Place holder to store the id of the device structure + * Can be used to store the index of the Chip select or + * I2C address of the device. + * @param[in] reg_addr: Used to select the register the where data needs to + * be read from or written to. + * @param[in,out] reg_data: Data array to read/write + * @param[in] len: Length of the data array + */ + +/* + * @brief Interface selection Enumerations + */ +enum bme68x_intf { + /*! SPI interface */ + BME68X_SPI_INTF, + /*! I2C interface */ + BME68X_I2C_INTF +}; + +/* Structure definitions */ + +/* + * @brief Sensor field data structure + */ +struct bme68x_data +{ + /*! Contains new_data, gasm_valid & heat_stab */ + uint8_t status; + + /*! The index of the heater profile used */ + uint8_t gas_index; + + /*! Measurement index to track order */ + uint8_t meas_index; + + /*! Heater resistance */ + uint8_t res_heat; + + /*! Current DAC */ + uint8_t idac; + + /*! Gas wait period */ + uint8_t gas_wait; +#ifndef BME68X_USE_FPU + + /*! Temperature in degree celsius x100 */ + int16_t temperature; + + /*! Pressure in Pascal */ + uint32_t pressure; + + /*! Humidity in % relative humidity x1000 */ + uint32_t humidity; + + /*! Gas resistance in Ohms */ + uint32_t gas_resistance; +#else + + /*! Temperature in degree celsius */ + float temperature; + + /*! Pressure in Pascal */ + float pressure; + + /*! Humidity in % relative humidity x1000 */ + float humidity; + + /*! Gas resistance in Ohms */ + float gas_resistance; + +#endif + +}; + +/* + * @brief Structure to hold the calibration coefficients + */ +struct bme68x_calib_data +{ + /*! Calibration coefficient for the humidity sensor */ + uint16_t par_h1; + + /*! Calibration coefficient for the humidity sensor */ + uint16_t par_h2; + + /*! Calibration coefficient for the humidity sensor */ + int8_t par_h3; + + /*! Calibration coefficient for the humidity sensor */ + int8_t par_h4; + + /*! Calibration coefficient for the humidity sensor */ + int8_t par_h5; + + /*! Calibration coefficient for the humidity sensor */ + uint8_t par_h6; + + /*! Calibration coefficient for the humidity sensor */ + int8_t par_h7; + + /*! Calibration coefficient for the gas sensor */ + int8_t par_gh1; + + /*! Calibration coefficient for the gas sensor */ + int16_t par_gh2; + + /*! Calibration coefficient for the gas sensor */ + int8_t par_gh3; + + /*! Calibration coefficient for the temperature sensor */ + uint16_t par_t1; + + /*! Calibration coefficient for the temperature sensor */ + int16_t par_t2; + + /*! Calibration coefficient for the temperature sensor */ + int8_t par_t3; + + /*! Calibration coefficient for the pressure sensor */ + uint16_t par_p1; + + /*! Calibration coefficient for the pressure sensor */ + int16_t par_p2; + + /*! Calibration coefficient for the pressure sensor */ + int8_t par_p3; + + /*! Calibration coefficient for the pressure sensor */ + int16_t par_p4; + + /*! Calibration coefficient for the pressure sensor */ + int16_t par_p5; + + /*! Calibration coefficient for the pressure sensor */ + int8_t par_p6; + + /*! Calibration coefficient for the pressure sensor */ + int8_t par_p7; + + /*! Calibration coefficient for the pressure sensor */ + int16_t par_p8; + + /*! Calibration coefficient for the pressure sensor */ + int16_t par_p9; + + /*! Calibration coefficient for the pressure sensor */ + uint8_t par_p10; +#ifndef BME68X_USE_FPU + + /*! Variable to store the intermediate temperature coefficient */ + int32_t t_fine; +#else + + /*! Variable to store the intermediate temperature coefficient */ + float t_fine; +#endif + + /*! Heater resistance range coefficient */ + uint8_t res_heat_range; + + /*! Heater resistance value coefficient */ + int8_t res_heat_val; + + /*! Gas resistance range switching error coefficient */ + int8_t range_sw_err; +}; + +/* + * @brief BME68X sensor settings structure which comprises of ODR, + * over-sampling and filter settings. + */ +struct bme68x_conf +{ + /*! Humidity oversampling. Refer @ref osx*/ + uint8_t os_hum; + + /*! Temperature oversampling. Refer @ref osx */ + uint8_t os_temp; + + /*! Pressure oversampling. Refer @ref osx */ + uint8_t os_pres; + + /*! Filter coefficient. Refer @ref filter*/ + uint8_t filter; + + /*! + * Standby time between sequential mode measurement profiles. + * Refer @ref odr + */ + uint8_t odr; +}; + +/* + * @brief BME68X gas heater configuration + */ +struct bme68x_heatr_conf +{ + /*! Enable gas measurement. Refer @ref en_dis */ + uint8_t enable; + + /*! Store the heater temperature for forced mode degree Celsius */ + uint16_t heatr_temp; + + /*! Store the heating duration for forced mode in milliseconds */ + uint16_t heatr_dur; + + /*! Store the heater temperature profile in degree Celsius */ + uint16_t *heatr_temp_prof; + + /*! Store the heating duration profile in milliseconds */ + uint16_t *heatr_dur_prof; + + /*! Variable to store the length of the heating profile */ + uint8_t profile_len; + + /*! + * Variable to store heating duration for parallel mode + * in milliseconds + */ + uint16_t shared_heatr_dur; +}; + +/* + * @brief BME68X device structure + */ +struct bme68x_dev +{ + /*! Chip Id */ + uint8_t chip_id; + + /*! + * The interface pointer is used to enable the user + * to link their interface descriptors for reference during the + * implementation of the read and write interfaces to the + * hardware. + */ + void *intf_ptr; + + /*! + * Variant id + * ---------------------------------------- + * Value | Variant + * ---------------------------------------- + * 0 | BME68X_VARIANT_GAS_LOW + * 1 | BME68X_VARIANT_GAS_HIGH + * ---------------------------------------- + */ + uint32_t variant_id; + + /*! SPI/I2C interface */ + enum bme68x_intf intf; + + /*! Memory page used */ + uint8_t mem_page; + + /*! Ambient temperature in Degree C*/ + int8_t amb_temp; + + /*! Sensor calibration data */ + struct bme68x_calib_data calib; + + /*! Read function pointer */ + bme68x_read_fptr_t read; + + /*! Write function pointer */ + bme68x_write_fptr_t write; + + /*! Delay function pointer */ + bme68x_delay_us_fptr_t delay_us; + + /*! To store interface pointer error */ + BME68X_INTF_RET_TYPE intf_rslt; + + /*! Store the info messages */ + uint8_t info_msg; +}; + +#endif /* BME68X_DEFS_H_ */ +/*! @endcond */ diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..44ffafd --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,10 @@ +#idf_component_register(SRCS "bme680_esp8266.c" +# INCLUDE_DIRS "." +# REQUIRES bme680) + +idf_component_register( + SRCS "bme680_esp8266.c" + INCLUDE_DIRS "." + REQUIRES bme68x esp8266 + # PRIV_REQUIRES driver +) diff --git a/main/bme680_esp8266.c b/main/bme680_esp8266.c new file mode 100644 index 0000000..1348a5a --- /dev/null +++ b/main/bme680_esp8266.c @@ -0,0 +1,129 @@ +// #include + +// void app_main(void) +// { + +// } + + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/i2c.h" +#include "bme680.h" + +#define I2C_PORT I2C_NUM_0 +#define I2C_SDA_PIN 0 // GPIO0 +#define I2C_SCL_PIN 2 // GPIO2 +#define I2C_FREQ_HZ 100000 +#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // 0x76 (SDO=GND) +// #define BME680_ADDR BME680_I2C_ADDR_SECONDARY // 0x77 (SDO=VCC) + +// --- I2C helpers (ESP-IDF style) --- +static int8_t i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg_addr, true); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_READ, true); + if (len > 1) { + i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK); + } + i2c_master_read_byte(cmd, data + len - 1, I2C_MASTER_NACK); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, pdMS_TO_TICKS(1000)); + i2c_cmd_link_delete(cmd); + return (ret == ESP_OK) ? BME680_OK : BME680_E_COM_FAIL; +} + +static int8_t i2c_write(uint8_t dev_id, uint8_t reg_addr, const uint8_t *data, uint16_t len) { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, reg_addr, true); + i2c_master_write(cmd, (uint8_t*)data, len, true); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, pdMS_TO_TICKS(1000)); + i2c_cmd_link_delete(cmd); + return (ret == ESP_OK) ? BME680_OK : BME680_E_COM_FAIL; +} + +static void delay_ms(uint32_t period_ms) { vTaskDelay(pdMS_TO_TICKS(period_ms)); } + +static void i2c_init(void) { + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_SDA_PIN, + .scl_io_num = I2C_SCL_PIN, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_FREQ_HZ, + }; + i2c_param_config(I2C_PORT, &conf); + i2c_driver_install(I2C_PORT, conf.mode, 0, 0, 0); +} + +void app_main(void) { + i2c_init(); + + struct bme680_dev dev = {0}; + dev.dev_id = BME680_ADDR; + dev.intf = BME680_I2C_INTF; + dev.read = i2c_read; + dev.write = i2c_write; + dev.delay_ms = delay_ms; + + if (bme680_init(&dev) != BME680_OK) { + printf("BME680 init failed\n"); + return; + } + + // Oversampling / filter + dev.tph_sett.os_hum = BME680_OS_2X; + dev.tph_sett.os_pres = BME680_OS_4X; + dev.tph_sett.os_temp = BME680_OS_8X; + dev.tph_sett.filter = BME680_FILTER_SIZE_3; + + // Gas sensor + dev.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; + dev.gas_sett.heatr_temp = 320; // °C + dev.gas_sett.heatr_dur = 150; // ms + + uint8_t set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | + BME680_OSH_SEL | BME680_FILTER_SEL | + BME680_GAS_SENSOR_SEL; + + if (bme680_set_sensor_settings(set_required_settings, &dev) != BME680_OK) { + printf("Sensor settings failed\n"); + return; + } + + while (1) { + // Force mode, one-shot + if (bme680_set_sensor_mode(&dev) != BME680_OK) { + printf("Set mode failed\n"); + vTaskDelay(pdMS_TO_TICKS(1000)); + continue; + } + + // Wait for measurement time + uint16_t meas_period; + bme680_get_profile_dur(&meas_period, &dev); + vTaskDelay(pdMS_TO_TICKS(meas_period)); + + struct bme680_field_data data; + if (bme680_get_sensor_data(&data, &dev) == BME680_OK) { + printf("T=%.2f °C RH=%.2f %% P=%.2f hPa Gas=%.2f kΩ\n", + data.temperature / 100.0f, + data.humidity / 1000.0f, + data.pressure / 100.0f, + data.gas_resistance / 1000.0f); + } else { + printf("Read failed\n"); + } + + vTaskDelay(pdMS_TO_TICKS(2000)); + } +} + diff --git a/sdkconfig b/sdkconfig new file mode 100644 index 0000000..ef16411 --- /dev/null +++ b/sdkconfig @@ -0,0 +1,525 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_TARGET_ESP8266=y +CONFIG_IDF_TARGET="esp8266" + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-lx106-elf-" +CONFIG_BOOTLOADER_INIT_SPI_FLASH=y +# CONFIG_BOOTLOADER_DISABLE_JTAG_IO is not set +# CONFIG_BOOTLOADER_FAST_BOOT is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_STORE_OFFSET=0x0 +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" +CONFIG_ESPTOOLPY_BAUD_115200B=y +# CONFIG_ESPTOOLPY_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_BAUD=115200 +CONFIG_ESPTOOLPY_COMPRESSED=y +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_SPI_FLASH_MODE=0x2 +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +CONFIG_SPI_FLASH_FREQ=0x0 +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_SPI_FLASH_SIZE=0x200000 +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_HARD_RESET=y +# CONFIG_ESPTOOLPY_AFTER_SOFT_RESET is not set +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_74880B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=74880 +CONFIG_ESPTOOLPY_MONITOR_BAUD=74880 +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_STACK_CHECK is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_APP_UPDATE_CHECK_APP_SUM=y +# CONFIG_APP_UPDATE_CHECK_APP_HASH is not set +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +# CONFIG_ENABLE_COAP is not set +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USING_WOLFSSL is not set +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# CONFIG_ESP_WOLFSSL_INTERNAL is not set +# CONFIG_WOLFSSL_DEBUG is not set +CONFIG_ESP8266_NMI_WDT=y +# CONFIG_ESP8266_XTAL_FREQ_40 is not set +CONFIG_ESP8266_XTAL_FREQ_26=y +CONFIG_ESP8266_XTAL_FREQ=26 +# CONFIG_ESP8266_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP8266_DEFAULT_CPU_FREQ_160=y +CONFIG_ESP8266_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_ESP_FILENAME_MACRO_NO_PATH=y +# CONFIG_ESP_FILENAME_MACRO_RAW is not set +# CONFIG_ESP_FILENAME_MACRO_NULL is not set +CONFIG_USING_NEW_ETS_VPRINTF=y +# CONFIG_LINK_ETS_PRINTF_TO_IRAM is not set +CONFIG_ETS_PRINTF_EXIT_WHEN_FLASH_RW=y +# CONFIG_SOC_FULL_ICACHE is not set +CONFIG_SOC_IRAM_SIZE=0xC000 +# CONFIG_DISABLE_ROM_UART_PRINT is not set +# CONFIG_ESP_PANIC_PRINT_HALT is not set +CONFIG_ESP_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_PANIC_GDBSTUB is not set +CONFIG_RESET_REASON=y +CONFIG_WIFI_PPT_TASKSTACK_SIZE=5120 +CONFIG_ESP8266_CORE_GLOBAL_DATA_LINK_IRAM=y +# CONFIG_ESP8266_OTA_FROM_OLD is not set +# CONFIG_ESP8266_BOOT_COPY_APP is not set +CONFIG_ESP8266_TIME_SYSCALL_USE_FRC1=y +# CONFIG_ESP8266_TIME_SYSCALL_USE_NONE is not set +# CONFIG_PM_ENABLE is not set +CONFIG_SCAN_AP_MAX=99 +CONFIG_WIFI_TX_RATE_SEQUENCE_FROM_HIGH=y +# CONFIG_ESP8266_WIFI_QOS_ENABLED is not set +# CONFIG_ESP8266_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set +CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=16 +CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=16 +CONFIG_ESP8266_WIFI_RX_PKT_NUM=7 +CONFIG_ESP8266_WIFI_TX_PKT_NUM=6 +CONFIG_ESP8266_WIFI_NVS_ENABLED=y +CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET=y +CONFIG_ESP8266_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP8266_WIFI_DEBUG_LOG_ENABLE is not set +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_INIT_DATA_VDD33_CONST=33 +CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=20 +# CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT is not set +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +# CONFIG_ESP_UART0_SWAP_IO is not set +CONFIG_ESP_TASK_WDT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +# CONFIG_ESP_TASK_WDT_TIMEOUT_13N is not set +# CONFIG_ESP_TASK_WDT_TIMEOUT_14N is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_15N=y +CONFIG_ESP_TASK_WDT_TIMEOUT_S=15 +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +CONFIG_HTTP_BUF_SIZE=512 +CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_OTA_BUF_SIZE=256 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_PORT_TASK_PRIO=10 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_FMB_TIMER_GROUP=0 +CONFIG_FMB_TIMER_INDEX=0 +# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# CONFIG_DISABLE_FREERTOS is not set +CONFIG_FREERTOS_UNICORE=y +# CONFIG_FREERTOS_ENABLE_REENT is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_MAX_HOOK=2 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_EXTENED_HOOKS is not set +CONFIG_FREERTOS_GLOBAL_DATA_LINK_IRAM=y +# CONFIG_FREERTOS_CODE_LINK_TO_IRAM is not set +CONFIG_FREERTOS_TIMER_STACKSIZE=2048 +CONFIG_TASK_SWITCH_FASTER=y +# CONFIG_USE_QUEUE_SETS is not set +# CONFIG_ENABLE_FREERTOS_SLEEP is not set +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +# CONFIG_HEAP_DISABLE_IRAM is not set +# CONFIG_HEAP_TRACING is not set +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +# CONFIG_LOG_COLORS is not set +# CONFIG_LOG_SET_LEVEL is not set +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# CONFIG_LWIP_AUTOIP is not set +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +CONFIG_LWIP_MAX_RAW_PCBS=16 +CONFIG_LWIP_IPV6=y +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_ESP_LWIP_ASSERT=y +# CONFIG_LWIP_DEBUG is not set +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_RIPEMD160_C is not set +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_util_assert is not set +# CONFIG_ESP_SHA is not set +CONFIG_ESP_AES=y +CONFIG_ESP_MD5=y +CONFIG_ESP_ARC4=y +# CONFIG_ENABLE_MDNS is not set +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_NANO_FORMAT is not set +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ASSERT_DO_NOTHING=y +# CONFIG_OPENSSL_ASSERT_EXIT is not set +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# CONFIG_ENABLE_TH25Q16HB_PATCH_0 is not set +CONFIG_SPIFFS_MAX_PARTITIONS=3 +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +CONFIG_IP_LOST_TIMER_INTERVAL=120 +CONFIG_TCPIP_ADAPTER_GLOBAL_DATA_LINK_IRAM=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# CONFIG_ENABLE_UNIFIED_PROVISIONING is not set +CONFIG_LTM_FAST=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_WARS is not set +# CONFIG_WPA_11KV_SUPPORT is not set + +# Deprecated options for backward compatibility +CONFIG_TARGET_PLATFORM="esp8266" +CONFIG_TOOLPREFIX="xtensa-lx106-elf-" +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set +CONFIG_MONITOR_BAUD_74880B=y +# CONFIG_MONITOR_BAUD_115200B is not set +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set +CONFIG_MONITOR_BAUD_OTHER_VAL=74880 +CONFIG_MONITOR_BAUD=74880 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_STACK_CHECK is not set +# CONFIG_WARN_WRITE_STRINGS is not set +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +# CONFIG_UART0_SWAP_IO is not set +CONFIG_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=15 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_MB_TIMER_GROUP=0 +CONFIG_MB_TIMER_INDEX=0 +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_USE_ONLY_LWIP_SELECT is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +# End of deprecated options