Files
PX4-Autopilot/src/drivers/barometer/bmp388/bmp388.h
T

366 lines
10 KiB
C++

/****************************************************************************
*
* Copyright (C) 2019 PX4 Development Team. All rights reserved.
*
* 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 PX4 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 OWNER 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 bmp388.h
*
* Shared defines for the bmp388 driver.
*/
#pragma once
#include <math.h>
#include <drivers/drv_baro.h>
#include <drivers/drv_hrt.h>
#include <lib/cdev/CDev.hpp>
#include <perf/perf_counter.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
#include <lib/drivers/barometer/PX4Barometer.hpp>
#include "board_config.h"
// From https://github.com/BoschSensortec/BMP3-Sensor-API/blob/master/bmp3_defs.h
#define BMP3_CHIP_ID (0x50)
/* Over sampling macros */
#define BMP3_NO_OVERSAMPLING (0x00)
#define BMP3_OVERSAMPLING_2X (0x01)
#define BMP3_OVERSAMPLING_4X (0x02)
#define BMP3_OVERSAMPLING_8X (0x03)
#define BMP3_OVERSAMPLING_16X (0x04)
#define BMP3_OVERSAMPLING_32X (0x05)
/* Filter setting macros */
#define BMP3_IIR_FILTER_DISABLE (0x00)
#define BMP3_IIR_FILTER_COEFF_1 (0x01)
#define BMP3_IIR_FILTER_COEFF_3 (0x02)
#define BMP3_IIR_FILTER_COEFF_7 (0x03)
#define BMP3_IIR_FILTER_COEFF_15 (0x04)
#define BMP3_IIR_FILTER_COEFF_31 (0x05)
#define BMP3_IIR_FILTER_COEFF_63 (0x06)
#define BMP3_IIR_FILTER_COEFF_127 (0x07)
/* Odr setting macros */
#define BMP3_ODR_200_HZ (0x00)
#define BMP3_ODR_100_HZ (0x01)
#define BMP3_ODR_50_HZ (0x02)
#define BMP3_ODR_25_HZ (0x03)
/* Register Address */
#define BMP3_CHIP_ID_ADDR (0x00)
#define BMP3_ERR_REG_ADDR (0x02)
#define BMP3_SENS_STATUS_REG_ADDR (0x03)
#define BMP3_DATA_ADDR (0x04)
#define BMP3_PWR_CTRL_ADDR (0x1B)
#define BMP3_OSR_ADDR (0X1C)
#define BMP3_CALIB_DATA_ADDR (0x31)
#define BMP3_CMD_ADDR (0x7E)
/* Error status macros */
#define BMP3_FATAL_ERR (0x01)
#define BMP3_CMD_ERR (0x02)
#define BMP3_CONF_ERR (0x04)
/* Status macros */
#define BMP3_CMD_RDY (0x10)
#define BMP3_DRDY_PRESS (0x20)
#define BMP3_DRDY_TEMP (0x40)
/* Power mode macros */
#define BMP3_SLEEP_MODE (0x00)
#define BMP3_FORCED_MODE (0x01)
#define BMP3_NORMAL_MODE (0x03)
#define BMP3_ENABLE (0x01)
#define BMP3_DISABLE (0x00)
/* Sensor component selection macros. These values are internal for API implementation.
* Don't relate this t0 data sheet.
*/
#define BMP3_PRESS (1)
#define BMP3_TEMP (1 << 1)
#define BMP3_ALL (0x03)
/* Macros related to size */
#define BMP3_CALIB_DATA_LEN (21)
#define BMP3_P_T_DATA_LEN (6)
/* Macros to select the which sensor settings are to be set by the user.
* These values are internal for API implementation. Don't relate this to
* data sheet. */
#define BMP3_PRESS_EN_SEL (1 << 1)
#define BMP3_TEMP_EN_SEL (1 << 2)
#define BMP3_PRESS_OS_SEL (1 << 4)
/* Macros for bit masking */
#define BMP3_OP_MODE_MSK (0x30)
#define BMP3_OP_MODE_POS (0x04)
#define BMP3_PRESS_EN_MSK (0x01)
#define BMP3_TEMP_EN_MSK (0x02)
#define BMP3_TEMP_EN_POS (0x01)
#define BMP3_IIR_FILTER_MSK (0x0E)
#define BMP3_IIR_FILTER_POS (0x01)
#define BMP3_ODR_MSK (0x1F)
#define BMP3_PRESS_OS_MSK (0x07)
#define BMP3_TEMP_OS_MSK (0x38)
#define BMP3_TEMP_OS_POS (0x03)
#define BMP3_SET_BITS(reg_data, bitname, data) \
((reg_data & ~(bitname##_MSK)) | \
((data << bitname##_POS) & bitname##_MSK))
/* Macro variant to handle the bitname position if it is zero */
#define BMP3_SET_BITS_POS_0(reg_data, bitname, data) \
((reg_data & ~(bitname##_MSK)) | \
(data & bitname##_MSK))
#define BMP3_GET_BITS(reg_data, bitname) ((reg_data & (bitname##_MSK)) >> \
(bitname##_POS))
/* Macro variant to handle the bitname position if it is zero */
#define BMP3_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK))
// From https://github.com/BoschSensortec/BMP3-Sensor-API/blob/master/self-test/bmp3_selftest.c
#define BMP3_POST_SLEEP_WAIT_TIME 5000
#define BMP3_POST_RESET_WAIT_TIME 2000
#define BMP3_POST_INIT_WAIT_TIME 40000
#define BMP3_TRIM_CRC_DATA_ADDR 0x30
#define BPM3_CMD_SOFT_RESET 0xB6
#define BMP3_ODR_ADDR 0x1D
#define BMP3_IIR_ADDR 0x1F
// https://github.com/BoschSensortec/BMP3-Sensor-API/blob/master/bmp3.c
/* Power control settings */
#define POWER_CNTL (0x0006)
/* Odr and filter settings */
#define ODR_FILTER (0x00F0)
/* Interrupt control settings */
#define INT_CTRL (0x0708)
/* Advance settings */
#define ADV_SETT (0x1800)
#pragma pack(push,1)
struct calibration_s {
uint16_t par_t1;
uint16_t par_t2;
int8_t par_t3;
int16_t par_p1;
int16_t par_p2;
int8_t par_p3;
int8_t par_p4;
uint16_t par_p5;
uint16_t par_p6;
int8_t par_p7;
int8_t par_p8;
int16_t par_p9;
int8_t par_p10;
int8_t par_p11;
}; //calibration data
struct data_s {
uint8_t p_msb;
uint8_t p_lsb;
uint8_t p_xlsb;
uint8_t t_msb;
uint8_t t_lsb;
uint8_t t_xlsb;
}; // data
struct bmp3_reg_calib_data {
/**
* @ Trim Variables
*/
/**@{*/
uint16_t par_t1;
uint16_t par_t2;
int8_t par_t3;
int16_t par_p1;
int16_t par_p2;
int8_t par_p3;
int8_t par_p4;
uint16_t par_p5;
uint16_t par_p6;
int8_t par_p7;
int8_t par_p8;
int16_t par_p9;
int8_t par_p10;
int8_t par_p11;
int64_t t_lin;
/**@}*/
};
#pragma pack(pop)
/*!
* bmp3 sensor structure which comprises of temperature and pressure data.
*/
struct bmp3_data {
/* Compensated temperature */
int64_t temperature;
/* Compensated pressure */
uint64_t pressure;
};
/*!
* Calibration data
*/
struct bmp3_calib_data {
/*! Register data */
struct bmp3_reg_calib_data reg_calib_data;
};
/*!
* bmp3 sensor structure which comprises of un-compensated temperature
* and pressure data.
*/
struct bmp3_uncomp_data {
/*! un-compensated pressure */
uint32_t pressure;
/*! un-compensated temperature */
uint32_t temperature;
};
struct fcalibration_s {
float t1;
float t2;
float t3;
float p1;
float p2;
float p3;
float p4;
float p5;
float p6;
float p7;
float p8;
float p9;
};
/*
* BMP388 internal constants and data structures.
*/
class IBMP388
{
public:
virtual ~IBMP388() = default;
virtual bool is_external() = 0;
virtual int init() = 0;
// read reg value
virtual uint8_t get_reg(uint8_t addr) = 0;
// bulk read reg value
virtual int get_reg_buf(uint8_t addr, uint8_t *buf, uint8_t len) = 0;
// write reg value
virtual int set_reg(uint8_t value, uint8_t addr) = 0;
// bulk read of data into buffer, return same pointer
virtual data_s *get_data(uint8_t addr) = 0;
// bulk read of calibration data into buffer, return same pointer
virtual calibration_s *get_calibration(uint8_t addr) = 0;
virtual uint32_t get_device_id() const = 0;
};
class BMP388 : public cdev::CDev, public px4::ScheduledWorkItem
{
public:
BMP388(IBMP388 *interface, const char *path);
virtual ~BMP388();
virtual int init();
/**
* Diagnostics - print some basic information about the driver.
*/
void print_info();
private:
PX4Barometer _px4_baro;
IBMP388 *_interface;
unsigned _measure_interval{0}; // interval in microseconds needed to measure
uint8_t _osr_t; // oversampling rate, temperature
uint8_t _osr_p; // oversampling rate, pressure
uint8_t _odr; // output data rate
uint8_t _iir_coef; // IIR coefficient
perf_counter_t _sample_perf;
perf_counter_t _measure_perf;
perf_counter_t _comms_errors;
struct calibration_s *_cal; // stored calibration constants
bool _collect_phase;
void Run() override;
void start();
void stop();
int measure();
int collect(); //get results and publish
uint32_t get_measurement_time(uint8_t osr_t, uint8_t osr_p);
bool soft_reset();
bool get_calib_data();
bool validate_trimming_param();
bool set_sensor_settings();
bool set_op_mode(uint8_t op_mode);
bool get_sensor_data(uint8_t sensor_comp, struct bmp3_data *comp_data);
bool compensate_data(uint8_t sensor_comp, const struct bmp3_uncomp_data *uncomp_data, struct bmp3_data *comp_data);
};
/* interface factories */
extern IBMP388 *bmp388_spi_interface(uint8_t busnum, uint32_t device, bool external);
extern IBMP388 *bmp388_i2c_interface(uint8_t busnum, uint32_t device, bool external);
typedef IBMP388 *(*BMP388_constructor)(uint8_t, uint32_t, bool);