diff --git a/.gitignore b/.gitignore index e36e115..2c8dab0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ components/ build/ *.o *.d - +*.log \ No newline at end of file diff --git a/main/APP/app_task_sensors/app_task_sensors.c b/main/APP/app_task_sensors/app_task_sensors.c index 3a11c32..22ab3bc 100644 --- a/main/APP/app_task_sensors/app_task_sensors.c +++ b/main/APP/app_task_sensors/app_task_sensors.c @@ -27,22 +27,30 @@ static i2c_config_t sg_drv_sensor_i2c_conf = { static drv_bmp280_3v3_t* sg_drv_bmp280_handle = NULL; -static uint8_t drv_i2c_read(uint8_t chip_addr, uint8_t reg_addr, uint8_t *data, uint16_t data_len) +static int8_t drv_i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t data_len, void *chip_addr) { - int ret = i2c_master_write_read_device(SENSOR_DRV_I2C_CONTROLLER_PORT, chip_addr , ®_addr, 1, data, data_len, SENSOR_DRV_I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); + int ret = i2c_master_write_read_device(SENSOR_DRV_I2C_CONTROLLER_PORT, *((uint8_t*)chip_addr) , ®_addr, 1, data, data_len, SENSOR_DRV_I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); if (ret) { - printf("I2C read error = %d\r\n", ret); + printf("I2C read error = %d, chip addr = %02x\r\n", ret, *((uint8_t*)chip_addr)); } return 0; } -static uint8_t drv_i2c_write(uint8_t chip_addr, uint8_t reg_addr, uint8_t data) +static int8_t drv_i2c_write(uint8_t reg_addr, const uint8_t *data, uint32_t data_len, void *chip_addr) { - int ret; - uint8_t write_buf[2] = {reg_addr, data}; + int ret, i; + uint8_t write_buf[51] = {0}; //{reg_addr, *data}; - ret = i2c_master_write_to_device(SENSOR_DRV_I2C_CONTROLLER_PORT, chip_addr, write_buf, sizeof(write_buf), SENSOR_DRV_I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); + if (data_len > 50 || data_len == 0) { + return 1; + } + write_buf[0] = reg_addr; + for (i = 0 ; i < data_len; i++) { + write_buf[i+1] = data[i]; + } + + ret = i2c_master_write_to_device(SENSOR_DRV_I2C_CONTROLLER_PORT, *((uint8_t*)chip_addr), write_buf, data_len + 1, SENSOR_DRV_I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); if (ret) { printf("I2C write error = %d\r\n", ret); @@ -50,12 +58,18 @@ static uint8_t drv_i2c_write(uint8_t chip_addr, uint8_t reg_addr, uint8_t data) return 0; } +static void drv_delay_ms_fptr_t(uint32_t period, void *intf_ptr) +{ + vTaskDelay(1); +} + static uint8_t _app_task_sensors_drv_init() { sg_drv_bmp280_handle = malloc(sizeof(drv_bmp280_3v3_t)); memset(sg_drv_bmp280_handle, 0, sizeof(drv_bmp280_3v3_t)); sg_drv_bmp280_handle->drv_i2c_read = drv_i2c_read; sg_drv_bmp280_handle->drv_i2c_write = drv_i2c_write; + sg_drv_bmp280_handle->delay_10ms = drv_delay_ms_fptr_t; drv_bmp280_3v3_init(sg_drv_bmp280_handle); return 0; } @@ -85,16 +99,29 @@ static void _app_task_sensors_run() _app_task_sensors_drv_init(); + double temp = 0; + double pres = 0; + while(1) { - drv_bmp280_3v3_get_pressure(sg_drv_bmp280_handle, &presure); - vTaskDelay(100); + + ret = drv_bmp280_3v3_refresh_data(sg_drv_bmp280_handle); + if (!ret) { + ret = drv_bmp280_3v3_get_tempreture(sg_drv_bmp280_handle, &temp); + // printf("temp = %.4lf\r\n", temp); + ret = drv_bmp280_3v3_get_pressure(sg_drv_bmp280_handle, &pres); + // printf("pres = %.4lf\r\n", pres); + }else { + printf("bmp280 is mesuring\r\n"); + } + + vTaskDelay(500); } } uint8_t app_task_sensors_start() { vTaskDelay(10); - xTaskCreatePinnedToCore(_app_task_sensors_run, "sensor task", 4096, NULL, 7, NULL, tskNO_AFFINITY); + xTaskCreatePinnedToCore(_app_task_sensors_run, "sensor task", 4096, NULL, 4, NULL, tskNO_AFFINITY); return 0; } diff --git a/main/APP/app_task_wifi/app_task_wifi.c b/main/APP/app_task_wifi/app_task_wifi.c index 6130db9..b2144ac 100644 --- a/main/APP/app_task_wifi/app_task_wifi.c +++ b/main/APP/app_task_wifi/app_task_wifi.c @@ -27,8 +27,8 @@ #include /* Set the SSID and Password via project configuration, or can set directly here */ -#define DEFAULT_SSID "IMPRESSIONYANG" -#define DEFAULT_PWD "88888888" +#define DEFAULT_SSID "1022" +#define DEFAULT_PWD "w15077040648" #if CONFIG_EXAMPLE_WIFI_ALL_CHANNEL_SCAN #define DEFAULT_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 010c4d4..d9c1271 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -6,6 +6,7 @@ idf_component_register( "APP/app_task_mqtt" "APP/app_task_sensors" "drivers/drv_bmp280_3v3" + "drivers/drv_bmp280_3v3/bmp2" INCLUDE_DIRS "." "APP/app_task_hello" @@ -13,4 +14,5 @@ idf_component_register( "APP/app_task_mqtt" "APP/app_task_sensors" "drivers/drv_bmp280_3v3" + "drivers/drv_bmp280_3v3/bmp2" ) diff --git a/main/drivers/drv_bmp280_3v3/bmp2/bmp2.c b/main/drivers/drv_bmp280_3v3/bmp2/bmp2.c new file mode 100644 index 0000000..e9917fd --- /dev/null +++ b/main/drivers/drv_bmp280_3v3/bmp2/bmp2.c @@ -0,0 +1,1032 @@ +/** +* Copyright (c) 2021 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 bmp2.c +* @date 2021-05-21 +* @version v1.0.1 +* +*/ + +/*! @file bmp2.c + * @brief Sensor driver for BMP2 sensor + */ + +#include "bmp2.h" + +/********************** Static function declarations ************************/ + +/*! + * @brief This internal API is used to check for null-pointers in the device + * structure. + * + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval <0 -> Fail + */ +static int8_t null_ptr_check(const struct bmp2_dev *dev); + +/*! + * @brief This internal API interleaves the register addresses and respective + * register data for a burst write + * + * @param[in] reg_addr : Register address array + * @param[out] temp_buff : Interleaved register address and data array + * @param[in] reg_data : Register data array + * @param[in] len : Length of the reg_addr and reg_data arrays + * + */ +static void interleave_data(const uint8_t *reg_addr, uint8_t *temp_buff, const uint8_t *reg_data, uint32_t len); + +/*! + * @brief This API is used to read the calibration parameters used + * for calculating the compensated data. + * + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval <0 -> Fail + */ +static int8_t get_calib_param(struct bmp2_dev *dev); + +/*! + * @brief This internal API to reset the sensor, restore/set conf, restore/set mode + * + * @param[in] mode : Desired mode + * @param[in] conf : Desired configuration to the bmp2 + * + * conf->os_mode = BMP2_OS_MODE_ULTRA_LOW_POWER, BMP2_OS_MODE_LOW_POWER, BMP2_OS_MODE_STANDARD_RESOLUTION, + * BMP2_OS_MODE_HIGH_RESOLUTION, BMP2_OS_MODE_ULTRA_HIGH_RESOLUTION + * + * conf->mode = BMP2_POWERMODE_SLEEP, BMP2_POWERMODE_FORCED, BMP2_POWERMODE_NORMAL + * + * conf->odr = BMP2_ODR_0_5_MS, BMP2_ODR_62_5_MS, BMP2_ODR_125_MS, + * BMP2_ODR_250_MS, BMP2_ODR_500_MS, BMP2_ODR_1000_MS, + * BMP2_ODR_2000_MS, BMP2_ODR_4000_MS + * + * conf->filter = BMP2_FILTER_OFF, BMP2_FILTER_COEFF_2, + * BMP2_FILTER_COEFF_4, BMP2_FILTER_COEFF_8, BMP2_FILTER_COEFF_16 + * + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval <0 -> Fail + */ +static int8_t conf_sensor(uint8_t mode, const struct bmp2_config *conf, struct bmp2_dev *dev); + +/*! + * @brief This API is used to set the over-sampling rate of temperature and pressure + * based on the over-sampling mode. + * + * @param[in] reg_data : Contains register data + * @param[out] conf : Desired configuration to the bmp2 + * + */ +static void set_os_mode(uint8_t *reg_data, const struct bmp2_config *conf); + +/*! + * @brief This API is used to parse the pressure and temperature + * data and store it in the bmp2_uncomp_data structure instance. + * + * @param[in] reg_data : Contains register data which needs to be parsed + * @param[out] uncomp_data : Contains the uncompensated pressure, temperature + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval <0 -> Fail + */ +static int8_t parse_sensor_data(const uint8_t *reg_data, struct bmp2_uncomp_data *uncomp_data); + +#ifdef BMP2_DOUBLE_COMPENSATION + +/*! + * @brief This internal API is used to get the compensated temperature from + * uncompensated temperature. This API uses double floating precision. + * + * @param[out] comp_temperature : Compensated temperature data in double. + * @param[in] uncomp_data : Contains the uncompensated temperature data. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval >0 -> Warning + * @retval <0 -> Fail + */ +static int8_t compensate_temperature(double *comp_temperature, + const struct bmp2_uncomp_data *uncomp_data, + struct bmp2_dev *dev); + +/*! + * @brief This internal API is used to get the compensated pressure from + * uncompensated pressure. This API uses double floating precision. + * + * @param[out] comp_pressure : Compensated pressure data in double. + * @param[in] uncomp_data : Contains the uncompensated pressure data. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval >0 -> Warning + * @retval <0 -> Fail + */ +static int8_t compensate_pressure(double *comp_pressure, + const struct bmp2_uncomp_data *uncomp_data, + const struct bmp2_dev *dev); + +#else + +/*! + * @brief This internal API is used to get the compensated temperature from + * uncompensated temperature. This API uses 32bit integer data type. + * + * @param[out] comp_temperature : Compensated temperature data in integer. + * @param[in] uncomp_data : Contains the uncompensated temperature data. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval >0 -> Warning + * @retval <0 -> Fail + */ +static int8_t compensate_temperature(int32_t *comp_temperature, + const struct bmp2_uncomp_data *uncomp_data, + struct bmp2_dev *dev); + +/*! + * @brief This internal API is used to get the compensated pressure from + * uncompensated pressure. This API uses 64bit integer data type. + * + * @param[out] comp_pressure : Compensated pressure data in integer. + * @param[in] uncomp_data : Contains the uncompensated pressure data. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval >0 -> Warning + * @retval <0 -> Fail + */ +static int8_t compensate_pressure(uint32_t *comp_pressure, + const struct bmp2_uncomp_data *uncomp_data, + const struct bmp2_dev *dev); + +#endif + +/*! + * @This internal API checks whether the uncompensated temperature and pressure are within the range + * + * @param[in] utemperature : Uncompensated temperature + * @param[in] upressure : Uncompensated pressure + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval <0 -> Fail + */ +static int8_t st_check_boundaries(int32_t utemperature, int32_t upressure); + +/****************** User Function Definitions *******************************/ + +/*! + * @brief This API is the entry point. + * It reads the chip-id and calibration data from the sensor. + */ +int8_t bmp2_init(struct bmp2_dev *dev) +{ + int8_t rslt; + + rslt = null_ptr_check(dev); + + if (rslt == BMP2_OK) + { + rslt = bmp2_get_regs(BMP2_REG_CHIP_ID, &dev->chip_id, 1, dev); + + /* Check for chip id validity */ + if (rslt == BMP2_OK) + { + if (dev->chip_id == BMP2_CHIP_ID) + { + rslt = get_calib_param(dev); + } + else + { + rslt = BMP2_E_DEV_NOT_FOUND; + } + } + } + + return rslt; +} + +/*! + * @brief This API reads the data from the given register address of the + * sensor. + */ +int8_t bmp2_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, struct bmp2_dev *dev) +{ + int8_t rslt; + + rslt = null_ptr_check(dev); + + if ((rslt == BMP2_OK) && (reg_data != NULL)) + { + /* Mask the register address' MSB if interface selected is SPI */ + if (dev->intf == BMP2_SPI_INTF) + { + reg_addr = reg_addr | BMP2_SPI_RD_MASK; + } + + dev->intf_rslt = dev->read(reg_addr, reg_data, len, dev->intf_ptr); + + /* Check for communication error and mask with an internal error code */ + if (dev->intf_rslt != BMP2_INTF_RET_SUCCESS) + { + rslt = BMP2_E_COM_FAIL; + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API writes the given data to the register addresses + * of the sensor. + */ +int8_t bmp2_set_regs(uint8_t *reg_addr, const uint8_t *reg_data, uint32_t len, struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp_buff[8]; /* Typically not to write more than 4 registers */ + uint32_t temp_len; + uint8_t reg_addr_cnt; + + if (len > BMP2_MAX_LEN) + { + len = BMP2_MAX_LEN; + } + + rslt = null_ptr_check(dev); + + if ((rslt == BMP2_OK) && (reg_addr != NULL) && (reg_data != NULL)) + { + if (len > 0) + { + temp_buff[0] = reg_data[0]; + + /* Mask the register address' MSB if interface selected is SPI */ + if (dev->intf == BMP2_SPI_INTF) + { + /* Converting all the reg address into proper SPI write address + * i.e making MSB(R/`W) bit 0 + */ + for (reg_addr_cnt = 0; reg_addr_cnt < len; reg_addr_cnt++) + { + reg_addr[reg_addr_cnt] = reg_addr[reg_addr_cnt] & BMP2_SPI_WR_MASK; + } + } + + /* Burst write mode */ + if (len > 1) + { + /* Interleave register address w.r.t data for burst write */ + interleave_data(reg_addr, temp_buff, reg_data, len); + temp_len = ((len * 2) - 1); + } + else + { + temp_len = len; + } + + dev->intf_rslt = dev->write(reg_addr[0], temp_buff, temp_len, dev->intf_ptr); + + /* Check for communication error and mask with an internal error code */ + if (dev->intf_rslt != BMP2_INTF_RET_SUCCESS) + { + rslt = BMP2_E_COM_FAIL; + } + } + else + { + rslt = BMP2_E_INVALID_LEN; + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API triggers the soft-reset of the sensor. + */ +int8_t bmp2_soft_reset(struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t reg_addr = BMP2_REG_SOFT_RESET; + uint8_t soft_rst_cmd = BMP2_SOFT_RESET_CMD; + + rslt = bmp2_set_regs(®_addr, &soft_rst_cmd, 1, dev); + + return rslt; +} + +/*! + * @brief This API reads the data from the ctrl_meas register and config + * register. It gives the currently set temperature and pressure over-sampling + * configuration, power mode configuration, sleep duration and + * IIR filter coefficient. + */ +int8_t bmp2_get_config(struct bmp2_config *conf, struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp[2] = { 0, 0 }; + + if (conf != NULL) + { + rslt = bmp2_get_regs(BMP2_REG_CTRL_MEAS, temp, 2, dev); + + if (rslt == BMP2_OK) + { + conf->os_temp = BMP2_GET_BITS(temp[0], BMP2_OS_TEMP); + conf->os_pres = BMP2_GET_BITS(temp[0], BMP2_OS_PRES); + conf->odr = BMP2_GET_BITS(temp[1], BMP2_STANDBY_DURN); + conf->filter = BMP2_GET_BITS(temp[1], BMP2_FILTER); + conf->spi3w_en = BMP2_GET_BITS_POS_0(temp[1], BMP2_SPI3_ENABLE); + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API writes the data to the ctrl_meas register and config register. + * It sets the over-sampling mode, power mode configuration, + * sleep duration and IIR filter coefficient. + */ +int8_t bmp2_set_config(const struct bmp2_config *conf, struct bmp2_dev *dev) +{ + return conf_sensor(BMP2_POWERMODE_SLEEP, conf, dev); +} + +/*! + * @brief This API reads the status register + */ +int8_t bmp2_get_status(struct bmp2_status *status, struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp; + + if (status != NULL) + { + rslt = bmp2_get_regs(BMP2_REG_STATUS, &temp, 1, dev); + + if (rslt == BMP2_OK) + { + status->measuring = BMP2_GET_BITS(temp, BMP2_STATUS_MEAS); + status->im_update = BMP2_GET_BITS_POS_0(temp, BMP2_STATUS_IM_UPDATE); + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API reads the power mode. + */ +int8_t bmp2_get_power_mode(uint8_t *mode, struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp; + + if (mode != NULL) + { + rslt = bmp2_get_regs(BMP2_REG_CTRL_MEAS, &temp, 1, dev); + + *mode = BMP2_GET_BITS_POS_0(temp, BMP2_POWERMODE); + dev->power_mode = *mode; + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API writes the power mode. + */ +int8_t bmp2_set_power_mode(uint8_t mode, const struct bmp2_config *conf, struct bmp2_dev *dev) +{ + int8_t rslt; + + rslt = conf_sensor(mode, conf, dev); + + return rslt; +} + +/*! + * @brief This API reads the pressure and temperature data from the + * sensor, compensates the data and store it in the bmp2_data structure + * instance passed by the user. + */ +int8_t bmp2_get_sensor_data(struct bmp2_data *comp_data, struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp[BMP2_P_T_LEN] = { 0 }; + struct bmp2_uncomp_data uncomp_data = { 0 }; + + if (comp_data != NULL) + { + rslt = bmp2_get_regs(BMP2_REG_PRES_MSB, temp, BMP2_P_T_LEN, dev); + + if (rslt == BMP2_OK) + { + /* Parse the read data from the sensor */ + rslt = parse_sensor_data(temp, &uncomp_data); + + if (rslt == BMP2_OK) + { + /* Compensate the pressure and/or temperature + * data from the sensor + */ + rslt = bmp2_compensate_data(&uncomp_data, comp_data, dev); + } + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API is used to compensate the pressure and + * temperature data. + */ +int8_t bmp2_compensate_data(const struct bmp2_uncomp_data *uncomp_data, + struct bmp2_data *comp_data, + struct bmp2_dev *dev) +{ + int8_t rslt; + + rslt = null_ptr_check(dev); + + if ((rslt == BMP2_OK) && (uncomp_data != NULL) && (comp_data != NULL)) + { + /* Initialize to zero */ + comp_data->temperature = 0; + comp_data->pressure = 0; + + rslt = compensate_temperature(&comp_data->temperature, uncomp_data, dev); + + if (rslt == BMP2_OK) + { + rslt = compensate_pressure(&comp_data->pressure, uncomp_data, dev); + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API computes the measurement time in microseconds for the + * active configuration based on standbytime(conf->odr) and over-sampling mode(conf->os_mode) + */ +int8_t bmp2_compute_meas_time(uint32_t *sampling_time, const struct bmp2_config *conf, const struct bmp2_dev *dev) +{ + int8_t rslt; + + /* Array contains measurement time in microseconds */ + uint32_t measurement_time[] = { 5500, 7500, 11500, 19500, 37500 }; + uint32_t standby_time[] = { 500, 62500, 125000, 250000, 500000, 1000000, 2000000, 4000000 }; + + rslt = null_ptr_check(dev); + + if ((rslt == BMP2_OK) && (conf != NULL)) + { + if (dev->power_mode == BMP2_POWERMODE_NORMAL) + { + /* Time in microseconds */ + (*sampling_time) = measurement_time[conf->os_mode] + standby_time[conf->odr]; + } + else + { + /* Time in microseconds */ + (*sampling_time) = measurement_time[conf->os_mode]; + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/****************** Static Function Definitions *******************************/ + +/*! + * @brief This internal API is used to check for null-pointers in the device + * structure. + */ +static int8_t null_ptr_check(const struct bmp2_dev *dev) +{ + int8_t rslt; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL)) + { + /* Null-pointer found */ + rslt = BMP2_E_NULL_PTR; + } + else + { + rslt = BMP2_OK; + } + + return rslt; +} + +/*! + * @brief This internal API interleaves the register addresses and respective + * register data for a burst write + */ +static void interleave_data(const uint8_t *reg_addr, uint8_t *temp_buff, const uint8_t *reg_data, uint32_t len) +{ + uint32_t index; + + for (index = 1; index < len; index++) + { + temp_buff[(index * 2) - 1] = reg_addr[index]; + temp_buff[index * 2] = reg_data[index]; + } +} + +/*! + * @brief This API is used to read the calibration parameters used + * for calculating the compensated data. + */ +static int8_t get_calib_param(struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp[BMP2_CALIB_DATA_SIZE] = { 0 }; + + rslt = bmp2_get_regs(BMP2_REG_DIG_T1_LSB, temp, BMP2_CALIB_DATA_SIZE, dev); + + if (rslt == BMP2_OK) + { + dev->calib_param.dig_t1 = (uint16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_T1_MSB_POS], temp[BMP2_DIG_T1_LSB_POS])); + dev->calib_param.dig_t2 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_T2_MSB_POS], temp[BMP2_DIG_T2_LSB_POS])); + dev->calib_param.dig_t3 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_T3_MSB_POS], temp[BMP2_DIG_T3_LSB_POS])); + dev->calib_param.dig_p1 = (uint16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P1_MSB_POS], temp[BMP2_DIG_P1_LSB_POS])); + dev->calib_param.dig_p2 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P2_MSB_POS], temp[BMP2_DIG_P2_LSB_POS])); + dev->calib_param.dig_p3 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P3_MSB_POS], temp[BMP2_DIG_P3_LSB_POS])); + dev->calib_param.dig_p4 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P4_MSB_POS], temp[BMP2_DIG_P4_LSB_POS])); + dev->calib_param.dig_p5 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P5_MSB_POS], temp[BMP2_DIG_P5_LSB_POS])); + dev->calib_param.dig_p6 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P6_MSB_POS], temp[BMP2_DIG_P6_LSB_POS])); + dev->calib_param.dig_p7 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P7_MSB_POS], temp[BMP2_DIG_P7_LSB_POS])); + dev->calib_param.dig_p8 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P8_MSB_POS], temp[BMP2_DIG_P8_LSB_POS])); + dev->calib_param.dig_p9 = (int16_t) (BMP2_MSBLSB_TO_U16(temp[BMP2_DIG_P9_MSB_POS], temp[BMP2_DIG_P9_LSB_POS])); + dev->calib_param.dig_p10 = (int8_t) ((uint8_t)(temp[BMP2_DIG_P10_POS])); + } + + return rslt; +} + +/*! + * @brief This internal API to reset the sensor, restore/set conf, restore/set mode + */ +static int8_t conf_sensor(uint8_t mode, const struct bmp2_config *conf, struct bmp2_dev *dev) +{ + int8_t rslt; + uint8_t temp[2] = { 0, 0 }; + uint8_t reg_addr[2] = { BMP2_REG_CTRL_MEAS, BMP2_REG_CONFIG }; + + if (conf != NULL) + { + rslt = bmp2_get_regs(BMP2_REG_CTRL_MEAS, temp, 2, dev); + + if (rslt == BMP2_OK) + { + /* Here the intention is to put the device to sleep + * within the shortest period of time + */ + rslt = bmp2_soft_reset(dev); + + if (rslt == BMP2_OK) + { + set_os_mode(temp, conf); + temp[1] = BMP2_SET_BITS(temp[1], BMP2_STANDBY_DURN, conf->odr); + temp[1] = BMP2_SET_BITS(temp[1], BMP2_FILTER, conf->filter); + temp[1] = BMP2_SET_BITS_POS_0(temp[1], BMP2_SPI3_ENABLE, conf->spi3w_en); + + rslt = bmp2_set_regs(reg_addr, temp, 2, dev); + + if ((rslt == BMP2_OK) && (mode != BMP2_POWERMODE_SLEEP)) + { + dev->power_mode = mode; + + /* Write only the power mode register in a separate write */ + temp[0] = BMP2_SET_BITS_POS_0(temp[0], BMP2_POWERMODE, mode); + rslt = bmp2_set_regs(reg_addr, temp, 1, dev); + } + } + } + } + else + { + rslt = BMP2_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This internal API is used to set the over-sampling rate of temperature and pressure + * based on the over-sampling mode. + */ +static void set_os_mode(uint8_t *reg_data, const struct bmp2_config *conf) +{ + switch (conf->os_mode) + { + case BMP2_OS_MODE_ULTRA_LOW_POWER: + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_TEMP, BMP2_OS_1X); + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_PRES, BMP2_OS_1X); + break; + case BMP2_OS_MODE_LOW_POWER: + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_TEMP, BMP2_OS_1X); + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_PRES, BMP2_OS_2X); + break; + case BMP2_OS_MODE_STANDARD_RESOLUTION: + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_TEMP, BMP2_OS_1X); + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_PRES, BMP2_OS_4X); + break; + case BMP2_OS_MODE_HIGH_RESOLUTION: + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_TEMP, BMP2_OS_1X); + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_PRES, BMP2_OS_8X); + break; + case BMP2_OS_MODE_ULTRA_HIGH_RESOLUTION: + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_TEMP, BMP2_OS_2X); + reg_data[0] = BMP2_SET_BITS(reg_data[0], BMP2_OS_PRES, BMP2_OS_16X); + break; + default: + break; + } +} + +/*! + * @brief This internal API is used to parse the pressure and temperature + * data and store it in the bmp2_uncomp_data structure instance. + */ +static int8_t parse_sensor_data(const uint8_t *reg_data, struct bmp2_uncomp_data *uncomp_data) +{ + int8_t rslt; + + /* Variables to store the sensor data */ + uint32_t data_xlsb; + uint32_t data_lsb; + uint32_t data_msb; + + /* Store the parsed register values for pressure data */ + data_msb = (uint32_t)reg_data[0] << 12; + data_lsb = (uint32_t)reg_data[1] << 4; + data_xlsb = (uint32_t)reg_data[2] >> 4; + uncomp_data->pressure = data_msb | data_lsb | data_xlsb; + + /* Store the parsed register values for temperature data */ + data_msb = (int32_t)reg_data[3] << 12; + data_lsb = (int32_t)reg_data[4] << 4; + data_xlsb = (int32_t)reg_data[5] >> 4; + uncomp_data->temperature = (int32_t)(data_msb | data_lsb | data_xlsb); + + rslt = st_check_boundaries((int32_t)uncomp_data->temperature, (int32_t)uncomp_data->pressure); + + return rslt; +} + +#ifdef BMP2_DOUBLE_COMPENSATION + +/*! + * @brief This internal API is used to get the compensated temperature from + * uncompensated temperature. This API uses double floating precision. + */ +static int8_t compensate_temperature(double *comp_temperature, + const struct bmp2_uncomp_data *uncomp_data, + struct bmp2_dev *dev) +{ + int8_t rslt = BMP2_OK; + double var1, var2; + double temperature; + + var1 = (((double) uncomp_data->temperature) / 16384.0 - ((double) dev->calib_param.dig_t1) / 1024.0) * + ((double) dev->calib_param.dig_t2); + var2 = + ((((double) uncomp_data->temperature) / 131072.0 - ((double) dev->calib_param.dig_t1) / 8192.0) * + (((double) uncomp_data->temperature) / 131072.0 - ((double) dev->calib_param.dig_t1) / 8192.0)) * + ((double) dev->calib_param.dig_t3); + + dev->calib_param.t_fine = (int32_t) (var1 + var2); + temperature = (var1 + var2) / 5120.0; + + if (temperature < BMP2_MIN_TEMP_DOUBLE) + { + temperature = BMP2_MIN_TEMP_DOUBLE; + rslt = BMP2_W_MIN_TEMP; + } + + if (temperature > BMP2_MAX_TEMP_DOUBLE) + { + temperature = BMP2_MAX_TEMP_DOUBLE; + rslt = BMP2_W_MAX_TEMP; + } + + (*comp_temperature) = temperature; + + return rslt; +} + +/*! + * @brief This internal API is used to get the compensated pressure from + * uncompensated pressure. This API uses double floating precision. + */ +static int8_t compensate_pressure(double *comp_pressure, + const struct bmp2_uncomp_data *uncomp_data, + const struct bmp2_dev *dev) +{ + int8_t rslt = BMP2_OK; + double var1, var2; + double pressure = 0.0; + + var1 = ((double) dev->calib_param.t_fine / 2.0) - 64000.0; + var2 = var1 * var1 * ((double) dev->calib_param.dig_p6) / 32768.0; + var2 = var2 + var1 * ((double) dev->calib_param.dig_p5) * 2.0; + var2 = (var2 / 4.0) + (((double) dev->calib_param.dig_p4) * 65536.0); + var1 = (((double)dev->calib_param.dig_p3) * var1 * var1 / 524288.0 + ((double)dev->calib_param.dig_p2) * var1) / + 524288.0; + var1 = (1.0 + var1 / 32768.0) * ((double) dev->calib_param.dig_p1); + + if (var1 < 0 || var1 > 0) + { + pressure = 1048576.0 - (double)uncomp_data->pressure; + pressure = (pressure - (var2 / 4096.0)) * 6250.0 / var1; + var1 = ((double)dev->calib_param.dig_p9) * pressure * pressure / 2147483648.0; + var2 = pressure * ((double)dev->calib_param.dig_p8) / 32768.0; + + pressure = pressure + (var1 + var2 + ((double)dev->calib_param.dig_p7)) / 16.0; + + if (pressure < BMP2_MIN_PRES_DOUBLE) + { + pressure = BMP2_MIN_PRES_DOUBLE; + rslt = BMP2_W_MIN_PRES; + } + + if (pressure > BMP2_MAX_PRES_DOUBLE) + { + pressure = BMP2_MAX_PRES_DOUBLE; + rslt = BMP2_W_MAX_PRES; + } + + (*comp_pressure) = pressure; + } + + return rslt; +} + +#else + +/*! + * @brief This internal API is used to get the compensated temperature from + * uncompensated temperature. This API uses 32bit integer data type. + */ +static int8_t compensate_temperature(int32_t *comp_temperature, + const struct bmp2_uncomp_data *uncomp_data, + struct bmp2_dev *dev) +{ + int8_t rslt = BMP2_OK; + int32_t var1, var2; + int32_t temperature; + + var1 = + ((((uncomp_data->temperature / 8) - ((int32_t) dev->calib_param.dig_t1 * 2))) * + ((int32_t) dev->calib_param.dig_t2)) / 2048; + var2 = + (((((uncomp_data->temperature / 16) - ((int32_t) dev->calib_param.dig_t1)) * + ((uncomp_data->temperature / 16) - ((int32_t) dev->calib_param.dig_t1))) / 4096) * + ((int32_t) dev->calib_param.dig_t3)) / 16384; + + dev->calib_param.t_fine = var1 + var2; + + temperature = (dev->calib_param.t_fine * 5 + 128) / 256; + + if (temperature < BMP2_MIN_TEMP_INT) + { + temperature = BMP2_MIN_TEMP_INT; + rslt = BMP2_W_MIN_TEMP; + } + + if (temperature > BMP2_MAX_TEMP_INT) + { + temperature = BMP2_MAX_TEMP_INT; + rslt = BMP2_W_MAX_TEMP; + } + + (*comp_temperature) = temperature; + + return rslt; +} + +#ifndef BMP2_32BIT_COMPENSATION + +/*! + * @brief This internal API is used to get the compensated pressure from + * uncompensated pressure. This API uses 64bit integer data type. + */ +static int8_t compensate_pressure(uint32_t *comp_pressure, + const struct bmp2_uncomp_data *uncomp_data, + const struct bmp2_dev *dev) +{ + int8_t rslt = BMP2_OK; + int64_t var1, var2, p; + uint32_t pressure = 0; + + var1 = ((int64_t) dev->calib_param.t_fine) - 128000; + var2 = var1 * var1 * (int64_t) dev->calib_param.dig_p6; + var2 = var2 + ((var1 * (int64_t) dev->calib_param.dig_p5) * 131072); + var2 = var2 + (((int64_t) dev->calib_param.dig_p4) * 34359738368); + var1 = ((var1 * var1 * (int64_t) dev->calib_param.dig_p3) / 256) + + ((var1 * (int64_t) dev->calib_param.dig_p2) * 4096); + var1 = (((((int64_t)1) * 140737488355328) + var1)) * ((int64_t)dev->calib_param.dig_p1) / 8589934592; + + if (var1 != 0) + { + p = 1048576 - uncomp_data->pressure; + p = (((p * 2147483648) - var2) * 3125) / var1; + var1 = (((int64_t) dev->calib_param.dig_p9) * (p / 8192) * (p / 8192)) / 33554432; + var2 = (((int64_t) dev->calib_param.dig_p8) * p) / 524288; + + p = ((p + var1 + var2) / 256) + (((int64_t)dev->calib_param.dig_p7) * 16); + pressure = (uint32_t)p; + + if (pressure < BMP2_MIN_PRES_64INT) + { + pressure = BMP2_MIN_PRES_64INT; + rslt = BMP2_W_MIN_PRES; + } + + if (pressure > BMP2_MAX_PRES_64INT) + { + pressure = BMP2_MAX_PRES_64INT; + rslt = BMP2_W_MAX_PRES; + } + + (*comp_pressure) = pressure; + } + + return rslt; +} + +#else + +/*! + * @brief This internal API is used to get the compensated pressure from + * uncompensated pressure. This API uses 32bit integer data type. + */ +static int8_t compensate_pressure(uint32_t *comp_pressure, + const struct bmp2_uncomp_data *uncomp_data, + const struct bmp2_dev *dev) +{ + int8_t rslt = BMP2_OK; + int32_t var1, var2; + uint32_t pressure = 0; + + var1 = (((int32_t) dev->calib_param.t_fine) / 2) - (int32_t) 64000; + var2 = (((var1 / 4) * (var1 / 4)) / 2048) * ((int32_t) dev->calib_param.dig_p6); + var2 = var2 + ((var1 * ((int32_t) dev->calib_param.dig_p5)) * 2); + var2 = (var2 / 4) + (((int32_t) dev->calib_param.dig_p4) * 65536); + var1 = + (((dev->calib_param.dig_p3 * (((var1 / 4) * (var1 / 4)) / 8192)) / 8) + + ((((int32_t) dev->calib_param.dig_p2) * var1) / 2)) / 262144; + var1 = ((((32768 + var1)) * ((int32_t) dev->calib_param.dig_p1)) / 32768); + + /* Avoid exception caused by division with zero */ + if (var1 != 0) + { + pressure = (((uint32_t)(((int32_t)1048576) - uncomp_data->pressure) - (var2 / 4096))) * 3125; + + /* Check for overflows against UINT32_MAX/2; if pressure is left-shifted by 1 */ + if (pressure < 0x80000000) + { + pressure = (pressure * 2) / ((uint32_t) var1); + } + else + { + pressure = (pressure / (uint32_t) var1) * 2; + } + + var1 = (((int32_t) dev->calib_param.dig_p9) * ((int32_t) (((pressure / 8) * (pressure / 8)) / 8192))) / 4096; + var2 = (((int32_t) (pressure / 4)) * ((int32_t) dev->calib_param.dig_p8)) / 8192; + pressure = (uint32_t) ((int32_t) pressure + ((var1 + var2 + dev->calib_param.dig_p7) / 16)); + + if (pressure < BMP2_MIN_PRES_32INT) + { + pressure = BMP2_MIN_PRES_32INT; + rslt = BMP2_W_MIN_PRES; + } + + if (pressure > BMP2_MAX_PRES_32INT) + { + pressure = BMP2_MAX_PRES_32INT; + rslt = BMP2_W_MAX_PRES; + } + + (*comp_pressure) = pressure; + } + + return rslt; +} + +#endif +#endif + +/*! + * @This internal API checks whether the uncompensated temperature and + * uncompensated pressure are within the range + */ +static int8_t st_check_boundaries(int32_t utemperature, int32_t upressure) +{ + int8_t rslt = 0; + + /* Check Uncompensated pressure in not valid range AND uncompensated temperature in valid range */ + if ((upressure < BMP2_ST_ADC_P_MIN || upressure > BMP2_ST_ADC_P_MAX) && + (utemperature >= BMP2_ST_ADC_T_MIN && utemperature <= BMP2_ST_ADC_T_MAX)) + { + rslt = BMP2_E_UNCOMP_PRESS_RANGE; + } + /* Check Uncompensated temperature in not valid range AND uncompensated pressure in valid range */ + else if ((utemperature < BMP2_ST_ADC_T_MIN || utemperature > BMP2_ST_ADC_T_MAX) && + (upressure >= BMP2_ST_ADC_P_MIN && upressure <= BMP2_ST_ADC_P_MAX)) + { + rslt = BMP2_E_UNCOMP_TEMP_RANGE; + } + /* Check Uncompensated pressure in not valid range AND uncompensated temperature in not valid range */ + else if ((upressure < BMP2_ST_ADC_P_MIN || upressure > BMP2_ST_ADC_P_MAX) && + (utemperature < BMP2_ST_ADC_T_MIN || utemperature > BMP2_ST_ADC_T_MAX)) + { + rslt = BMP2_E_UNCOMP_TEMP_AND_PRESS_RANGE; + } + else + { + rslt = BMP2_OK; + } + + return rslt; +} diff --git a/main/drivers/drv_bmp280_3v3/bmp2/bmp2.h b/main/drivers/drv_bmp280_3v3/bmp2/bmp2.h new file mode 100644 index 0000000..c5ba31a --- /dev/null +++ b/main/drivers/drv_bmp280_3v3/bmp2/bmp2.h @@ -0,0 +1,393 @@ +/** +* Copyright (c) 2021 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 bmp2.h +* @date 2021-05-21 +* @version v1.0.1 +* +*/ + +/*! @file bmp2.h + * @brief Sensor driver for BMP2 sensor + */ + +/*! + * @defgroup bmp2 BMP2 + */ + +#ifndef _BMP2_H +#define _BMP2_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************/ + +/*! Header files + ****************************************************************************/ +#include "bmp2_defs.h" + +/***************************************************************************/ + +/*! BMP2 User Interface function prototypes + ****************************************************************************/ + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiInit Initialization + * @brief Perform initialization of sensor + */ + +/*! + * \ingroup bmp2ApiInit + * \page bmp2_api_bmp2_init bmp2_init + * \code + * int8_t bmp2_init(struct bmp2_dev *dev); + * \endcode + * @details This API is the entry point. + * It reads the chip-id and calibration data from the sensor. + * + * @param[in,out] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_init(struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiRegs Registers + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bmp2ApiRegs + * \page bmp2_api_bmp2_get_regs bmp2_get_regs + * \code + * int8_t bmp2_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, struct bmp2_dev *dev); + * \endcode + * @details This API reads the data from the given register address of the + * sensor. + * + * @param[in] reg_addr : Register address from where the data to be read + * @param[out] reg_data : Pointer to data buffer to store the read data. + * @param[in] len : No of bytes of data to be read. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, struct bmp2_dev *dev); + +/*! + * \ingroup bmp2ApiRegs + * \page bmp2_api_bmp2_set_regs bmp2_set_regs + * \code + * int8_t bmp2_set_regs(uint8_t *reg_addr, const uint8_t *reg_data, uint32_t len, struct bmp2_dev *dev); + * \endcode + * @details This API writes the given data to the register addresses + * of the sensor. + * + * @param[in] reg_addr : Register address from where the data to be written. + * @param[in] reg_data : Pointer to data buffer which is to be written + * in the sensor. + * @param[in] len : No of bytes of data to write.. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_set_regs(uint8_t *reg_addr, const uint8_t *reg_data, uint32_t len, struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiSoftreset Soft reset + * @brief Perform self test + */ + +/*! + * \ingroup bmp2ApiSoftreset + * \page bmp2_api_bmp2_soft_reset bmp2_soft_reset + * \code + * int8_t bmp2_soft_reset(struct bmp2_dev *dev); + * \endcode + * @details This API triggers the soft reset of the sensor. + * + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_soft_reset(struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiPowermode Power mode + * @brief Set / Get power mode of the sensor + */ + +/*! + * \ingroup bmp2ApiPowermode + * \page bmp2_api_bmp2_get_power_mode bmp2_get_power_mode + * \code + * int8_t bmp2_get_power_mode(uint8_t *mode, struct bmp2_dev *dev); + * \endcode + * @details This API reads the power mode. + * + * @param[out] mode : BMP2_POWERMODE_SLEEP, BMP2_POWERMODE_NORMAL, + * BMP2_POWERMODE_FORCED + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_get_power_mode(uint8_t *mode, struct bmp2_dev *dev); + +/*! + * \ingroup bmp2ApiPowermode + * \page bmp2_api_bmp2_set_power_mode bmp2_set_power_mode + * \code + * int8_t bmp2_set_power_mode(uint8_t mode, const struct bmp2_config *conf, struct bmp2_dev *dev); + * \endcode + * @details This API writes the power mode. + * + * @param[in] mode : BMP2_POWERMODE_SLEEP, BMP2_POWERMODE_NORMAL, + * BMP2_POWERMODE_FORCED + * @param[in] conf : Structure instance of bmp2_config + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_set_power_mode(uint8_t mode, const struct bmp2_config *conf, struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiConfig Configuration + * @brief Set / Get configurations of the sensor + */ + +/*! + * \ingroup bmp2ApiConfig + * \page bmp2_api_bmp2_get_config bmp2_get_config + * \code + * int8_t bmp2_get_config(struct bmp2_config *conf, struct bmp2_dev *dev); + * \endcode + * @details This API reads the data from the ctrl_meas register and config + * register. It gives the currently set temperature and pressure over-sampling + * configuration, power mode configuration, sleep duration and + * IIR filter coefficient. + * + * @param[out] conf : Current configuration of the bmp2 + * conf->osrs_t, conf->osrs_p = BMP2_OS_NONE, BMP2_OS_1X, + * BMP2_OS_2X, BMP2_OS_4X, BMP2_OS_8X, BMP2_OS_16X + * + * conf->odr = BMP2_ODR_0_5_MS, BMP2_ODR_62_5_MS, BMP2_ODR_125_MS, + * BMP2_ODR_250_MS, BMP2_ODR_500_MS, BMP2_ODR_1000_MS, + * BMP2_ODR_2000_MS, BMP2_ODR_4000_MS + * + * conf->filter = BMP2_FILTER_OFF, BMP2_FILTER_COEFF_2, + * BMP2_FILTER_COEFF_4, BMP2_FILTER_COEFF_8, BMP2_FILTER_COEFF_16 + * + * conf->spi3w_en = BMP2_SPI3_WIRE_ENABLE, BMP2_SPI3_WIRE_DISABLE + * + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_get_config(struct bmp2_config *conf, struct bmp2_dev *dev); + +/*! + * \ingroup bmp2ApiConfig + * \page bmp2_api_bmp2_set_config bmp2_set_config + * \code + * int8_t bmp2_set_config(const struct bmp2_config *conf, struct bmp2_dev *dev); + * \endcode + * @details This API writes the data to the ctrl_meas register and config register. + * It sets the over-sampling mode, power mode configuration, + * sleep duration and IIR filter coefficient. + * + * @param[in] conf : Desired configuration to the bmp2 + * conf->osrs_t, conf->osrs_p = BMP2_OS_NONE, BMP2_OS_1X, + * BMP2_OS_2X, BMP2_OS_4X, BMP2_OS_8X, BMP2_OS_16X + * + * conf->odr = BMP2_ODR_0_5_MS, BMP2_ODR_62_5_MS, BMP2_ODR_125_MS, + * BMP2_ODR_250_MS, BMP2_ODR_500_MS, BMP2_ODR_1000_MS, + * BMP2_ODR_2000_MS, BMP2_ODR_4000_MS + * + * conf->filter = BMP2_FILTER_OFF, BMP2_FILTER_COEFF_2, + * BMP2_FILTER_COEFF_4, BMP2_FILTER_COEFF_8, BMP2_FILTER_COEFF_16 + * + * conf->spi3w_en = BMP2_SPI3_WIRE_ENABLE, BMP2_SPI3_WIRE_DISABLE + * + * Over-sampling settings | conf->os_pres | conf->os_temp + *--------------------------|-------------------|--------------------------- + * Ultra low power | 1 | 1 + * Low power | 2 | 1 + * Standard resolution | 4 | 1 + * High resolution | 8 | 1 + * Ultra high resolution | 16 | 2 + * + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_set_config(const struct bmp2_config *conf, struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiStatus Status register + * @brief Read status register + */ + +/*! + * \ingroup bmp2ApiStatus + * \page bmp2_api_bmp2_get_status bmp2_get_status + * \code + * int8_t bmp2_get_status(struct bmp2_status *status, struct bmp2_dev *dev); + * \endcode + * @details This API reads the status register + * + * @param[in,out] status : Structure instance of bmp2_status. + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_get_status(struct bmp2_status *status, struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiSensorData Sensor Data + * @brief Data processing of sensor + */ + +/*! + * \ingroup bmp2ApiSensorData + * \page bmp2_api_bmp2_get_sensor_data bmp2_get_sensor_data + * \code + * int8_t bmp2_get_sensor_data(struct bmp2_data *comp_data, struct bmp2_dev *dev); + * \endcode + * @details This API reads the pressure and temperature data from the + * sensor, compensates the data and store it in the bmp2_data structure + * instance passed by the user. + * + * @param[in] comp_data : Structure instance of bmp2_data + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + */ +int8_t bmp2_get_sensor_data(struct bmp2_data *comp_data, struct bmp2_dev *dev); + +/*! + * \ingroup bmp2ApiSensorData + * \page bmp2_api_bmp2_compensate_data bmp2_compensate_data + * \code + * int8_t bmp2_compensate_data(const struct bmp2_uncomp_data *uncomp_data, + * struct bmp2_data *comp_data, + * struct bmp2_dev *dev); + * \endcode + * @details This API is used to compensate the pressure and + * temperature data. + * + * @param[in] uncomp_data : Contains the uncompensated pressure, temperature data. + * @param[out] comp_data : Contains the compensated pressure and/or temperature data. + * @param[in] dev : Structure instance of bmp2_dev. + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval > 0 -> Warning. + * @retval < 0 -> Fail. + * + */ +int8_t bmp2_compensate_data(const struct bmp2_uncomp_data *uncomp_data, + struct bmp2_data *comp_data, + struct bmp2_dev *dev); + +/** + * \ingroup bmp2 + * \defgroup bmp2ApiMeasTime Compute measurement time + * @brief Computes measurement time (in microseconds) + */ + +/*! + * \ingroup bmp2ApiMeasTime + * \page bmp2_api_bmp2_compute_meas_time bmp2_compute_meas_time + * \code + * int8_t bmp2_compute_meas_time(uint32_t *sampling_time, const struct bmp2_config *conf, const struct bmp2_dev *dev); + * \endcode + * @details This API computes the measurement time in microseconds for the + * active configuration based on standbytime(conf->odr) and over-sampling mode(conf->os_mode) + * + * @param[out] sampling_time : Measurement time for the active configuration in microseconds + * @param[in] conf : Structure instance of bmp2_config + * @param[in] dev : Structure instance of bmp2_dev + * + * @return Result of API execution status. + * + * @retval 0 -> Success. + * @retval < 0 -> Fail. + * + */ +int8_t bmp2_compute_meas_time(uint32_t *sampling_time, const struct bmp2_config *conf, const struct bmp2_dev *dev); + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _BMP2_H */ diff --git a/main/drivers/drv_bmp280_3v3/bmp2/bmp2_defs.h b/main/drivers/drv_bmp280_3v3/bmp2/bmp2_defs.h new file mode 100644 index 0000000..8ac811c --- /dev/null +++ b/main/drivers/drv_bmp280_3v3/bmp2/bmp2_defs.h @@ -0,0 +1,602 @@ +/** +* Copyright (c) 2021 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 bmp2_defs.h +* @date 2021-05-21 +* @version v1.0.1 +* +*/ + +/*! @file bmp2_defs.h + * @brief Sensor driver for BMP2 sensor + */ + +#ifndef _BMP2_DEFS_H +#define _BMP2_DEFS_H + +/*! CPP guard */ +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************/ +/*! @name Header includes */ +/****************************************************************/ +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +/****************************************************************/ +/*! @name 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 + +/*! @name C standard macros */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +/******************************************************************************/ +/*! @name Compiler switch macros Definitions */ +/******************************************************************************/ +#ifndef BMP2_64BIT_COMPENSATION /*< Check if 64bit (using BMP2_64BIT_COMPENSATION) is enabled */ +#ifndef BMP2_32BIT_COMPENSATION /*< Check if 32bit (using BMP2_32BIT_COMPENSATION) is enabled */ +#ifndef BMP2_DOUBLE_COMPENSATION /*< If any of the integer data types not enabled then enable + * BMP2_DOUBLE_COMPENSATION */ +#define BMP2_DOUBLE_COMPENSATION +#endif +#endif +#endif + +/******************************************************************************/ +/*! @name General Macro Definitions */ +/******************************************************************************/ + +/*! @name Maximum write length to registers */ +#define BMP2_MAX_LEN UINT8_C(4) + +/*! @name Return codes */ +/*! @name Success code*/ +#define BMP2_OK INT8_C(0) + +/*! @name Error codes */ +#define BMP2_E_NULL_PTR INT8_C(-1) +#define BMP2_E_COM_FAIL INT8_C(-2) +#define BMP2_E_INVALID_LEN INT8_C(-3) +#define BMP2_E_DEV_NOT_FOUND INT8_C(-4) +#define BMP2_E_UNCOMP_TEMP_RANGE INT8_C(-5) +#define BMP2_E_UNCOMP_PRESS_RANGE INT8_C(-6) +#define BMP2_E_UNCOMP_TEMP_AND_PRESS_RANGE INT8_C(-7) + +/*! @name Warning codes */ +#define BMP2_W_MIN_TEMP INT8_C(1) +#define BMP2_W_MAX_TEMP INT8_C(2) +#define BMP2_W_MIN_PRES INT8_C(3) +#define BMP2_W_MAX_PRES INT8_C(4) + +/*! @name Chip ID */ +#define BMP2_CHIP_ID UINT8_C(0x58) + +/*! @name I2C addresses */ +#define BMP2_I2C_ADDR_PRIM UINT8_C(0x76) +#define BMP2_I2C_ADDR_SEC UINT8_C(0x77) + +/*! @name Register addresses */ +#define BMP2_REG_CHIP_ID UINT8_C(0xD0) +#define BMP2_REG_SOFT_RESET UINT8_C(0xE0) +#define BMP2_REG_STATUS UINT8_C(0xF3) +#define BMP2_REG_CTRL_MEAS UINT8_C(0xF4) +#define BMP2_REG_CONFIG UINT8_C(0xF5) +#define BMP2_REG_PRES_MSB UINT8_C(0xF7) +#define BMP2_REG_PRES_LSB UINT8_C(0xF8) +#define BMP2_REG_PRES_XLSB UINT8_C(0xF9) +#define BMP2_REG_TEMP_MSB UINT8_C(0xFA) +#define BMP2_REG_TEMP_LSB UINT8_C(0xFB) +#define BMP2_REG_TEMP_XLSB UINT8_C(0xFC) + +/* Calibration parameter register addresses */ +#define BMP2_REG_DIG_T1_LSB UINT8_C(0x88) +#define BMP2_REG_DIG_T1_MSB UINT8_C(0x89) +#define BMP2_REG_DIG_T2_LSB UINT8_C(0x8A) +#define BMP2_REG_DIG_T2_MSB UINT8_C(0x8B) +#define BMP2_REG_DIG_T3_LSB UINT8_C(0x8C) +#define BMP2_REG_DIG_T3_MSB UINT8_C(0x8D) +#define BMP2_REG_DIG_P1_LSB UINT8_C(0x8E) +#define BMP2_REG_DIG_P1_MSB UINT8_C(0x8F) +#define BMP2_REG_DIG_P2_LSB UINT8_C(0x90) +#define BMP2_REG_DIG_P2_MSB UINT8_C(0x91) +#define BMP2_REG_DIG_P3_LSB UINT8_C(0x92) +#define BMP2_REG_DIG_P3_MSB UINT8_C(0x93) +#define BMP2_REG_DIG_P4_LSB UINT8_C(0x94) +#define BMP2_REG_DIG_P4_MSB UINT8_C(0x95) +#define BMP2_REG_DIG_P5_LSB UINT8_C(0x96) +#define BMP2_REG_DIG_P5_MSB UINT8_C(0x97) +#define BMP2_REG_DIG_P6_LSB UINT8_C(0x98) +#define BMP2_REG_DIG_P6_MSB UINT8_C(0x99) +#define BMP2_REG_DIG_P7_LSB UINT8_C(0x9A) +#define BMP2_REG_DIG_P7_MSB UINT8_C(0x9B) +#define BMP2_REG_DIG_P8_LSB UINT8_C(0x9C) +#define BMP2_REG_DIG_P8_MSB UINT8_C(0x9D) +#define BMP2_REG_DIG_P9_LSB UINT8_C(0x9E) +#define BMP2_REG_DIG_P9_MSB UINT8_C(0x9F) + +/*! @name Interface settings */ +#define BMP2_SPI_RD_MASK UINT8_C(0x80) +#define BMP2_SPI_WR_MASK UINT8_C(0x7F) + +/*! @name Delay definition */ +#define BMP2_DELAY_US_STARTUP_TIME UINT8_C(2000) + +/*! @name Power modes */ +#define BMP2_POWERMODE_SLEEP UINT8_C(0x00) +#define BMP2_POWERMODE_FORCED UINT8_C(0x01) +#define BMP2_POWERMODE_NORMAL UINT8_C(0x03) + +#define BMP2_POWERMODE_POS UINT8_C(0x00) +#define BMP2_POWERMODE_MSK UINT8_C(0x03) + +/*! @name Soft reset command */ +#define BMP2_SOFT_RESET_CMD UINT8_C(0xB6) + +/*! @name Data length */ +#define BMP2_P_T_LEN UINT8_C(0X06) + +/*! @name Temperature range values in integer(32bit, 64bit) and float */ +#define BMP2_MIN_TEMP_INT INT32_C(-4000) +#define BMP2_MAX_TEMP_INT INT32_C(8500) +#define BMP2_MIN_TEMP_DOUBLE -40.0f +#define BMP2_MAX_TEMP_DOUBLE 85.0f + +/*! @name Pressure range values in integer and float */ +#define BMP2_MIN_PRES_32INT UINT32_C(30000) +#define BMP2_MAX_PRES_32INT UINT32_C(110000) +#define BMP2_MIN_PRES_64INT UINT32_C(30000 * 256) +#define BMP2_MAX_PRES_64INT UINT32_C(110000 * 256) +#define BMP2_MIN_PRES_DOUBLE 30000.0f +#define BMP2_MAX_PRES_DOUBLE 110000.0f + +/*! @name ODR options */ +#define BMP2_ODR_0_5_MS UINT8_C(0x00) +#define BMP2_ODR_62_5_MS UINT8_C(0x01) +#define BMP2_ODR_125_MS UINT8_C(0x02) +#define BMP2_ODR_250_MS UINT8_C(0x03) +#define BMP2_ODR_500_MS UINT8_C(0x04) +#define BMP2_ODR_1000_MS UINT8_C(0x05) +#define BMP2_ODR_2000_MS UINT8_C(0x06) +#define BMP2_ODR_4000_MS UINT8_C(0x07) + +/*! @name Over-sampling macros */ +#define BMP2_OS_NONE UINT8_C(0x00) +#define BMP2_OS_1X UINT8_C(0x01) +#define BMP2_OS_2X UINT8_C(0x02) +#define BMP2_OS_4X UINT8_C(0x03) +#define BMP2_OS_8X UINT8_C(0x04) +#define BMP2_OS_16X UINT8_C(0x05) +#define BMP2_OS_TEMP_POS UINT8_C(0x05) +#define BMP2_OS_TEMP_MSK UINT8_C(0xE0) +#define BMP2_OS_PRES_POS UINT8_C(0x02) +#define BMP2_OS_PRES_MSK UINT8_C(0x1C) + +/*! @name Over-sampling mode */ +#define BMP2_OS_MODE_ULTRA_LOW_POWER UINT8_C(0x00) +#define BMP2_OS_MODE_LOW_POWER UINT8_C(0x01) +#define BMP2_OS_MODE_STANDARD_RESOLUTION UINT8_C(0x02) +#define BMP2_OS_MODE_HIGH_RESOLUTION UINT8_C(0x03) +#define BMP2_OS_MODE_ULTRA_HIGH_RESOLUTION UINT8_C(0x04) + +/*! @name Filter coefficient macros */ +#define BMP2_FILTER_OFF UINT8_C(0x00) +#define BMP2_FILTER_COEFF_2 UINT8_C(0x01) +#define BMP2_FILTER_COEFF_4 UINT8_C(0x02) +#define BMP2_FILTER_COEFF_8 UINT8_C(0x03) +#define BMP2_FILTER_COEFF_16 UINT8_C(0x04) + +#define BMP2_FILTER_POS UINT8_C(0x02) +#define BMP2_FILTER_MSK UINT8_C(0x1C) + +/*! @name SPI 3-Wire macros */ +#define BMP2_SPI3_WIRE_ENABLE UINT8_C(0x01) +#define BMP2_SPI3_WIRE_DISABLE UINT8_C(0x00) + +#define BMP2_SPI3_ENABLE_POS UINT8_C(0x00) +#define BMP2_SPI3_ENABLE_MSK UINT8_C(0x01) + +/*! @name Measurement status macros */ +#define BMP2_MEAS_DONE UINT8_C(0x00) +#define BMP2_MEAS_ONGOING UINT8_C(0x01) + +#define BMP2_STATUS_MEAS_POS UINT8_C(0x03) +#define BMP2_STATUS_MEAS_MSK UINT8_C(0x08) + +/*! @name Image update status macros */ +#define BMP2_IM_UPDATE_DONE UINT8_C(0x00) +#define BMP2_IM_UPDATE_ONGOING UINT8_C(0x01) + +#define BMP2_STATUS_IM_UPDATE_POS UINT8_C(0x00) +#define BMP2_STATUS_IM_UPDATE_MSK UINT8_C(0x01) + +/*! @name Standby duration macros */ +#define BMP2_STANDBY_DURN_POS UINT8_C(0x05) +#define BMP2_STANDBY_DURN_MSK UINT8_C(0xE0) + +/*! @name Calibration parameters' relative position */ +#define BMP2_DIG_T1_LSB_POS UINT8_C(0) +#define BMP2_DIG_T1_MSB_POS UINT8_C(1) +#define BMP2_DIG_T2_LSB_POS UINT8_C(2) +#define BMP2_DIG_T2_MSB_POS UINT8_C(3) +#define BMP2_DIG_T3_LSB_POS UINT8_C(4) +#define BMP2_DIG_T3_MSB_POS UINT8_C(5) +#define BMP2_DIG_P1_LSB_POS UINT8_C(6) +#define BMP2_DIG_P1_MSB_POS UINT8_C(7) +#define BMP2_DIG_P2_LSB_POS UINT8_C(8) +#define BMP2_DIG_P2_MSB_POS UINT8_C(9) +#define BMP2_DIG_P3_LSB_POS UINT8_C(10) +#define BMP2_DIG_P3_MSB_POS UINT8_C(11) +#define BMP2_DIG_P4_LSB_POS UINT8_C(12) +#define BMP2_DIG_P4_MSB_POS UINT8_C(13) +#define BMP2_DIG_P5_LSB_POS UINT8_C(14) +#define BMP2_DIG_P5_MSB_POS UINT8_C(15) +#define BMP2_DIG_P6_LSB_POS UINT8_C(16) +#define BMP2_DIG_P6_MSB_POS UINT8_C(17) +#define BMP2_DIG_P7_LSB_POS UINT8_C(18) +#define BMP2_DIG_P7_MSB_POS UINT8_C(19) +#define BMP2_DIG_P8_LSB_POS UINT8_C(20) +#define BMP2_DIG_P8_MSB_POS UINT8_C(21) +#define BMP2_DIG_P9_LSB_POS UINT8_C(22) +#define BMP2_DIG_P9_MSB_POS UINT8_C(23) +#define BMP2_DIG_P10_POS UINT8_C(24) +#define BMP2_CALIB_DATA_SIZE UINT8_C(25) + +/*! @brief Macros holding the minimum and maximum for trimming values */ +#define BMP2_ST_DIG_T1_MIN UINT16_C(19000) +#define BMP2_ST_DIG_T1_MAX UINT16_C(35000) +#define BMP2_ST_DIG_T2_MIN UINT16_C(22000) +#define BMP2_ST_DIG_T2_MAX UINT16_C(30000) +#define BMP2_ST_DIG_T3_MIN INT16_C(-3000) +#define BMP2_ST_DIG_T3_MAX INT16_C(-1000) +#define BMP2_ST_DIG_P1_MIN UINT16_C(30000) +#define BMP2_ST_DIG_P1_MAX UINT16_C(42000) +#define BMP2_ST_DIG_P2_MIN INT16_C(-12970) +#define BMP2_ST_DIG_P2_MAX INT16_C(-8000) +#define BMP2_ST_DIG_P3_MIN INT16_C(-5000) +#define BMP2_ST_DIG_P3_MAX UINT16_C(8000) +#define BMP2_ST_DIG_P4_MIN INT16_C(-10000) +#define BMP2_ST_DIG_P4_MAX UINT16_C(18000) +#define BMP2_ST_DIG_P5_MIN INT16_C(-500) +#define BMP2_ST_DIG_P5_MAX UINT16_C(1100) +#define BMP2_ST_DIG_P6_MIN INT16_C(-1000) +#define BMP2_ST_DIG_P6_MAX UINT16_C(1000) +#define BMP2_ST_DIG_P7_MIN INT16_C(-32768) +#define BMP2_ST_DIG_P7_MAX UINT16_C(32767) +#define BMP2_ST_DIG_P8_MIN INT16_C(-30000) +#define BMP2_ST_DIG_P8_MAX UINT16_C(10000) +#define BMP2_ST_DIG_P9_MIN INT16_C(-10000) +#define BMP2_ST_DIG_P9_MAX UINT16_C(30000) + +/*! @brief Macros holding the minimum and maximum for trimming values */ +/* 0x00000 is minimum output value */ +#define BMP2_ST_ADC_T_MIN INT32_C(0x00000) + +/* 0xFFFF0 is maximum 20-bit output value without over sampling */ +#define BMP2_ST_ADC_T_MAX INT32_C(0xFFFF0) + +/* 0x00000 is minimum output value */ +#define BMP2_ST_ADC_P_MIN INT32_C(0x00000) + +/* 0xFFFF0 is maximum 20-bit output value without over sampling */ +#define BMP2_ST_ADC_P_MAX INT32_C(0xFFFF0) + +/*! @brief Macros to read out API revision number */ +/* Register holding custom trimming values */ +#define BMP2_ST_TRIMCUSTOM_REG UINT8_C(0x87) +#define BMP2_ST_TRIMCUSTOM_REG_APIREV_POS UINT8_C(1) +#define BMP2_ST_TRIMCUSTOM_REG_APIREV_MSK UINT8_C(0x06) +#define BMP2_ST_TRIMCUSTOM_REG_APIREV_LEN UINT8_C(2) +#define BMP2_ST_TRIMCUSTOM_REG_APIREV_REG BMP2_ST_TRIMCUSTOM_REG + +/* Highest API revision supported is revision 0. */ +#define BMP2_ST_MAX_APIREVISION UINT8_C(0x00) + +#define BMP2_MSBLSB_TO_U16(msb, lsb) (((uint16_t)msb << 8) | ((uint16_t)lsb)) + +/*! @name Bit-slicing macros */ +#define BMP2_GET_BITS(reg_data, bitname) ((reg_data & bitname##_MSK) \ + >> bitname##_POS) +#define BMP2_SET_BITS(reg_data, bitname, val) ((reg_data & \ + ~bitname##_MSK) | ((val << bitname##_POS) & bitname##_MSK)) +#define BMP2_SET_BITS_POS_0(reg_data, bitname, data) ((reg_data & \ + ~(bitname##_MSK)) | (data & bitname##_MSK)) +#define BMP2_GET_BITS_POS_0(reg_data, bitname) (reg_data & \ + (bitname##_MSK)) + +/******************************************************************************/ +/*! @name Function Pointers */ +/******************************************************************************/ +#ifndef BMP2_INTF_RET_TYPE +#define BMP2_INTF_RET_TYPE int8_t +#endif + +#ifndef BMP2_INTF_RET_SUCCESS +#define BMP2_INTF_RET_SUCCESS INT8_C(0) +#endif + +/*! + * @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 BMP2_INTF_RET_TYPE (*bmp2_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 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 BMP2_INTF_RET_TYPE (*bmp2_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 (*bmp2_delay_us_fptr_t)(uint32_t period, void *intf_ptr); + +/******************************************************************************/ +/*! @name Enum Declarations */ +/******************************************************************************/ + +/*! + * @brief Enum to define BMP2 sensor interfaces + */ +enum bmp2_intf { + /*! SPI interface */ + BMP2_SPI_INTF, + /*! I2C interface */ + BMP2_I2C_INTF +}; + +/******************************************************************************/ +/*! @name Structure Declarations */ +/******************************************************************************/ + +/*! + * @brief Calibration parameters' structure + */ +struct bmp2_calib_param +{ + /*! Calibration parameter of temperature data */ + + /*! Calibration t1 data */ + uint16_t dig_t1; + + /*! Calibration t2 data */ + int16_t dig_t2; + + /*! Calibration t3 data */ + int16_t dig_t3; + + /*! Calibration parameter of pressure data */ + + /*! Calibration p1 data */ + uint16_t dig_p1; + + /*! Calibration p2 data */ + int16_t dig_p2; + + /*! Calibration p3 data */ + int16_t dig_p3; + + /*! Calibration p4 data */ + int16_t dig_p4; + + /*! Calibration p5 data */ + int16_t dig_p5; + + /*! Calibration p6 data */ + int16_t dig_p6; + + /*! Calibration p7 data */ + int16_t dig_p7; + + /*! Calibration p8 data */ + int16_t dig_p8; + + /*! Calibration p9 data */ + int16_t dig_p9; + + /*! Calibration p10 data */ + int8_t dig_p10; + + /*! Fine resolution temperature value */ + int32_t t_fine; +}; + +/*! + * @brief Sensor configuration structure + */ +struct bmp2_config +{ + /*! Over-sampling of temperature data */ + uint8_t os_temp; + + /*! Over-sampling of pressure data */ + uint8_t os_pres; + + /*! Odr set by setting standby duration */ + uint8_t odr; + + /*! Over-sampling mode */ + uint8_t os_mode; + + /*! Time constant of IIR filter */ + uint8_t filter; + + /*! Enable 3-wire SPI interface */ + uint8_t spi3w_en; +}; + +/*! + * @brief Sensor status structure + */ +struct bmp2_status +{ + /*! Data registers' status */ + uint8_t measuring; + + /*! Image register status */ + uint8_t im_update; +}; + +/*! + * @brief Uncompensated data structure + */ +struct bmp2_uncomp_data +{ + /*! Uncompensated temperature data */ + int32_t temperature; + + /*! Uncompensated pressure data */ + uint32_t pressure; +}; + +/*! + * @brief bmp2 sensor structure which comprises of temperature and pressure + */ +#ifdef BMP2_DOUBLE_COMPENSATION +struct bmp2_data +{ + /*! Compensated pressure */ + double pressure; + + /*! Compensated temperature */ + double temperature; +}; +#else +struct bmp2_data +{ + /*! Compensated pressure */ + uint32_t pressure; + + /*! Compensated temperature */ + int32_t temperature; +}; +#endif + +/*! + * @brief API device structure + */ +struct bmp2_dev +{ + /*! Chip Id */ + uint8_t chip_id; + + /*! SPI/I2C Interface selection */ + enum bmp2_intf intf; + + /*! + * 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; + + /*! Variable that holds result of read/write function */ + BMP2_INTF_RET_TYPE intf_rslt; + + /*! Bus read function pointer */ + bmp2_read_fptr_t read; + + /*! Bus write function pointer */ + bmp2_write_fptr_t write; + + /*! Delay(in us) function pointer */ + bmp2_delay_us_fptr_t delay_us; + + /*! Powermode of the sensor */ + uint8_t power_mode; + + /*! Structure of calibration parameters' */ + struct bmp2_calib_param calib_param; +}; + +#ifdef __cplusplus +} +#endif /* End of CPP guard */ + +#endif /* _BMP2_DEFS_H */ diff --git a/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.c b/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.c index c780bf7..5aa4cec 100644 --- a/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.c +++ b/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.c @@ -1,34 +1,146 @@ #include "drv_bmp280_3v3.h" #include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" -#define DRV_BMP280_3V3_CHIP_ADDR 0x76 +static struct bmp2_status status = {0}; +static struct bmp2_data comp_data = {0}; +static struct bmp2_dev dev = {0}; +static struct bmp2_config conf = {0}; +static uint8_t dev_addr = BMP2_I2C_ADDR_PRIM; + +static void bmp2_error_codes_print_result(const char api_name[], int8_t rslt) +{ + if (rslt != BMP2_OK) + { + printf("%s\t", api_name); + + switch (rslt) + { + case BMP2_E_NULL_PTR: + printf("Error [%d] : Null pointer error.", rslt); + printf( + "It occurs when the user tries to assign value (not address) to a pointer, which has been initialized to NULL.\r\n"); + break; + case BMP2_E_COM_FAIL: + printf("Error [%d] : Communication failure error.", rslt); + printf( + "It occurs due to read/write operation failure and also due to power failure during communication\r\n"); + break; + case BMP2_E_INVALID_LEN: + printf("Error [%d] : Invalid length error.", rslt); + printf("Occurs when length of data to be written is zero\n"); + break; + case BMP2_E_DEV_NOT_FOUND: + printf("Error [%d] : Device not found error. It occurs when the device chip id is incorrectly read\r\n", + rslt); + break; + case BMP2_E_UNCOMP_TEMP_RANGE: + printf("Error [%d] : Uncompensated temperature data not in valid range error.", rslt); + break; + case BMP2_E_UNCOMP_PRESS_RANGE: + printf("Error [%d] : Uncompensated pressure data not in valid range error.", rslt); + break; + case BMP2_E_UNCOMP_TEMP_AND_PRESS_RANGE: + printf( + "Error [%d] : Uncompensated pressure data and uncompensated temperature data are not in valid range error.", + rslt); + break; + default: + printf("Error [%d] : Unknown error code\r\n", rslt); + break; + } + } +} uint8_t drv_bmp280_3v3_init(drv_bmp280_3v3_t *handle) { if (!handle || !handle->drv_i2c_read || !handle->drv_i2c_write) { return 1; } - handle->chip_addr = DRV_BMP280_3V3_CHIP_ADDR; + + int8_t rslt; + uint32_t meas_time; + + dev.read = handle->drv_i2c_read; + dev.write = handle->drv_i2c_write; + dev.delay_us = handle->delay_10ms; + dev.intf = BMP2_I2C_INTF; + dev.intf_ptr = &dev_addr; + + handle->chip_addr = BMP2_I2C_ADDR_PRIM; handle->is_drv_init = 1; handle->drv_state = 1; + printf("1 addr of handle dev = %08x\r\n", (unsigned int)handle->dev); + + handle->dev = &dev; + + printf("2 addr of handle dev = %08x\r\n", (unsigned int)handle->dev); + + rslt = bmp2_init(handle->dev); + bmp2_error_codes_print_result("bmp2_init", rslt); + + rslt = bmp2_get_config(&conf, handle->dev); + bmp2_error_codes_print_result("bmp2_get_config", rslt); + + conf.filter = BMP2_FILTER_OFF; + conf.os_mode = BMP2_OS_MODE_HIGH_RESOLUTION; + conf.odr = BMP2_ODR_250_MS; + + rslt = bmp2_set_config(&conf, handle->dev); + bmp2_error_codes_print_result("bmp2_set_config", rslt); + + rslt = bmp2_set_power_mode(BMP2_POWERMODE_NORMAL, &conf, handle->dev); + bmp2_error_codes_print_result("bmp2_set_power_mode", rslt); + rslt = bmp2_compute_meas_time(&meas_time, &conf, handle->dev); + bmp2_error_codes_print_result("bmp2_compute_meas_time", rslt); + + drv_bmp280_3v3_refresh_data(handle); + return 0; } -uint8_t drv_bmp280_3v3_get_pressure(drv_bmp280_3v3_t *handle, uint32_t *presure) +uint8_t drv_bmp280_3v3_refresh_data(drv_bmp280_3v3_t *handle) { if (!handle) { return 1; } - uint8_t data = 0; - handle->drv_i2c_read(handle->chip_addr, 0x88, &data, 1); - printf("%d\r\n", data); + int8_t rslt = BMP2_E_NULL_PTR; + + rslt = bmp2_get_status(&status, handle->dev); + bmp2_error_codes_print_result("bmp2_get_status", rslt); + + if (status.measuring == BMP2_MEAS_DONE) + { + rslt = bmp2_get_sensor_data(&comp_data, handle->dev); + bmp2_error_codes_print_result("bmp2_get_sensor_data", rslt); + + }else { + return 1; + } return 0; } -uint8_t drv_bmp280_3v3_get_tempreture(drv_bmp280_3v3_t *handle, uint32_t *temperature) +uint8_t drv_bmp280_3v3_get_pressure(drv_bmp280_3v3_t *handle, double *presure) { + if (!handle) { + return 1; + } + + *presure = comp_data.pressure; + + return 0; +} + +uint8_t drv_bmp280_3v3_get_tempreture(drv_bmp280_3v3_t *handle, double *temperature) +{ + if (!handle) { + return 1; + } + + *temperature = comp_data.temperature; return 0; } diff --git a/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.h b/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.h index 47451a7..ccf7a5c 100644 --- a/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.h +++ b/main/drivers/drv_bmp280_3v3/drv_bmp280_3v3.h @@ -2,23 +2,28 @@ #define __DRV_BMP280_3V3_H__ #include +#include "bmp2.h" #ifdef __cplusplus extern "C" { #endif + typedef struct _drv_bmp280_3v3_t_ { uint8_t is_drv_init; uint8_t drv_state; uint8_t chip_addr; - uint8_t (*drv_i2c_read)(uint8_t chip_addr, uint8_t reg_addr, uint8_t *data, uint16_t data_len); - uint8_t (*drv_i2c_write)(uint8_t chip_addr, uint8_t reg_addr, uint8_t data); + int8_t (*drv_i2c_read)(uint8_t reg_addr, uint8_t *data, uint32_t data_len, void *chip_addr); + int8_t (*drv_i2c_write)(uint8_t reg_addr, const uint8_t *data, uint32_t data_len, void *chip_addr); + uint8_t (*delay_10ms)(uint32_t period, void *intf_ptr); + struct bmp2_dev *dev; } drv_bmp280_3v3_t; uint8_t drv_bmp280_3v3_init(drv_bmp280_3v3_t *handle); -uint8_t drv_bmp280_3v3_get_pressure(drv_bmp280_3v3_t *handle, uint32_t *presure); -uint8_t drv_bmp280_3v3_get_tempreture(drv_bmp280_3v3_t *handle, uint32_t *temperature); +uint8_t drv_bmp280_3v3_refresh_data(drv_bmp280_3v3_t *handle); +uint8_t drv_bmp280_3v3_get_pressure(drv_bmp280_3v3_t *handle, double *presure); +uint8_t drv_bmp280_3v3_get_tempreture(drv_bmp280_3v3_t *handle, double *temperature); uint8_t drv_bmp280_3v3_deinit(drv_bmp280_3v3_t *handle); #ifdef __cplusplus diff --git a/sdkconfig b/sdkconfig index 047d7b8..12c29c6 100644 --- a/sdkconfig +++ b/sdkconfig @@ -487,7 +487,7 @@ CONFIG_ESP_CONSOLE_MULTIPLE_UART=y CONFIG_ESP_CONSOLE_UART_NUM=0 CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_TIMEOUT_MS=9000 CONFIG_ESP_TASK_WDT=y # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 @@ -1285,7 +1285,7 @@ CONFIG_CONSOLE_UART=y CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=115200 CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_TIMEOUT_MS=9000 CONFIG_TASK_WDT=y # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 diff --git a/sdkconfig.old b/sdkconfig.old index 047d7b8..b276688 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -487,7 +487,7 @@ CONFIG_ESP_CONSOLE_MULTIPLE_UART=y CONFIG_ESP_CONSOLE_UART_NUM=0 CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_TIMEOUT_MS=1000 CONFIG_ESP_TASK_WDT=y # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 @@ -1285,7 +1285,7 @@ CONFIG_CONSOLE_UART=y CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=115200 CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_TIMEOUT_MS=1000 CONFIG_TASK_WDT=y # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5