Skip to content

Commit

Permalink
baro: update error codes
Browse files Browse the repository at this point in the history
  • Loading branch information
PonomarevDA committed Mar 14, 2024
1 parent fb8f03c commit 4729c5e
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 56 deletions.
1 change: 1 addition & 0 deletions sensors/barometer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void application_init() {
// 1. The sensor doesn't respond on i2c bus
// 2. DevID register returns wrong value
// 3. Calibration registers cannot be read successfully
return;
}
}

Expand Down
59 changes: 32 additions & 27 deletions sensors/barometer/bmp280.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,46 +87,51 @@ static BarometerBmp280Instance bmp280;


int8_t bmp280Init() {
bmp280.stale_counter = 0;
bmp280.dev_id_confirmed = false;

if (_checkDeviceId() < 0) {
return LIBPERIPH_BPM280_INIT_CHECK_DEV_ID_ERROR;
return -LIBPERIPH_BPM280_INIT_CHECK_DEV_ID_ERROR;
}

if (_setCtrlMeas() < 0) {
return LIBPERIPH_BPM280_INIT_SET_CTRL_MEAS_ERROR;
return -LIBPERIPH_BPM280_INIT_SET_CTRL_MEAS_ERROR;
}

if (_calibrate() < 0) {
return LIBPERIPH_BPM280_INIT_CALIBRATION_ERROR;
return -LIBPERIPH_BPM280_INIT_CALIBRATION_ERROR;
}

return (bmp280IsInitialized()) ? LIBPERIPH_BPM280_OK : LIBPERIPH_BPM280_INIT_WRONG_DEV_ID;
return (bmp280IsInitialized()) ? LIBPERIPH_BPM280_OK : -LIBPERIPH_BPM280_INIT_WRONG_DEV_ID;
}

bool bmp280IsInitialized() {
return bmp280.dev_id_confirmed;
}

int8_t bmp280GetData(BarometerMeasurements* out_data) {
if (bmp280CollectData() < 0) {
return -1;
int8_t res = bmp280CollectData();
if (res < 0) {
return res;
}

if (bmp280ParseCollectedData(out_data) < 0) {
return -1;
res = bmp280ParseCollectedData(out_data);
if (res < 0) {
return res;
}

return 0;
return bmp280VerifyData(out_data);
}

int8_t bmp280CollectData() {
uint8_t tx[1] = {PRESS_REG};
if (i2cTransmit(I2C_ID, tx, 1) < 0) {
return LIBPERIPH_BPM280_NO_RESPONSE;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

BMP280_measurement_registers_t data = {};
if (i2cReceive(I2C_ID + 1, (uint8_t*)&data, 6) < 0) {
return LIBPERIPH_BPM280_NO_RESPONSE;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

BarometerMeasurements temp = {
Expand All @@ -148,7 +153,7 @@ int8_t bmp280CollectData() {

int8_t bmp280ParseCollectedData(BarometerMeasurements* out_data) {
if (out_data == NULL) {
return -1;
return -LIBPERIPH_BPM280_INTERNAL_ERROR;
}

float ofs = bmp280.raw.temperature - bmp280.calib.t[0];
Expand All @@ -159,29 +164,29 @@ int8_t bmp280ParseCollectedData(BarometerMeasurements* out_data) {
float x1 = (tf * bmp280.calib.p[5] + bmp280.calib.p[4]) * tf + bmp280.calib.p[3];
float x2 = (tf * bmp280.calib.p[2] + bmp280.calib.p[1]) * tf + bmp280.calib.p[0];
if (x2 == 0) {
return -1;
return -LIBPERIPH_BPM280_INTERNAL_ERROR;
}
float pf = (bmp280.raw.pressure + x1) / x2;
out_data->pressure = (pf * bmp280.calib.p[8] + bmp280.calib.p[7]) * pf + bmp280.calib.p[6];

return 0;
return LIBPERIPH_BPM280_OK;
}


int8_t bmp280VerifyData(const BarometerMeasurements* data) {
if (data->pressure < 30000 || data->pressure > 110000) {
return -1; // out of bound
return -LIBPERIPH_BPM280_VERIFICATION_PRESSURE_OUT_OF_BOUND;
}

if (data->temperature < 233 || data->temperature > 368) {
return -1; // out of bound
return -LIBPERIPH_BPM280_VERIFICATION_TEMPERATURE_OUT_OF_BOUND;
}

if (bmp280.stale_counter >= 10) {
return -1; // stale
return -LIBPERIPH_BPM280_VERIFICATION_STALE;
}

return 0;
return LIBPERIPH_BPM280_OK;
}


Expand All @@ -192,17 +197,17 @@ int8_t bmp280VerifyData(const BarometerMeasurements* data) {
static int8_t _checkDeviceId() {
uint8_t tx[1] = {ID_REG};
if (i2cTransmit(I2C_ID, tx, 1) < 0) {
return -1;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

uint8_t rx[1] = {0};
if (i2cReceive(I2C_ID, rx, 1) < 0) {
return -1;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

bmp280.dev_id_confirmed = (rx[0] == DEVICE_ID) ? true : false;

return 0;
return LIBPERIPH_BPM280_OK;
}

/**
Expand All @@ -211,15 +216,15 @@ static int8_t _checkDeviceId() {
static int8_t _setCtrlMeas() {
uint8_t tx[2] = {CTRL_MEAS_REG, CTRL_MEAS_SETTINGS};
if (i2cTransmit(I2C_ID, tx, 2) < 0) {
return -1;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

uint8_t rx[1] = {0};
if (i2cReceive(I2C_ID, rx, 1) < 0) {
return -1;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

return 0;
return LIBPERIPH_BPM280_OK;
}

/**
Expand All @@ -228,12 +233,12 @@ static int8_t _setCtrlMeas() {
static int8_t _calibrate() {
uint8_t tx[1] = {0x88};
if (i2cTransmit(I2C_ID, tx, 1) < 0) {
return -1;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

TrimmingParameters_t params;
if (i2cReceive(I2C_ID, (uint8_t*)(&params), 24) < 0) {
return -1;
return -LIBPERIPH_BPM280_I2C_NO_RESPONSE;
}

bmp280.calib.t[0] = params.dig_T1 * powf(2, 4);
Expand All @@ -252,5 +257,5 @@ static int8_t _calibrate() {
bmp280.calib.p[7] = params.dig_P8 * powf(2, -19) + 1.0f;
bmp280.calib.p[8] = params.dig_P9 * powf(2, -35);

return 0;
return LIBPERIPH_BPM280_OK;
}
48 changes: 25 additions & 23 deletions sensors/barometer/bmp280.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,31 @@ extern "C" {

#define BMP280_MAX_MEASUREMENT_FREQUENCY 50

#define LIBPERIPH_BPM280_OK 0
#define LIBPERIPH_BPM280_NO_RESPONSE -1
#define LIBPERIPH_BPM280_BAD_RESPONSE -2
#define LIBPERIPH_BPM280_INIT_CHECK_DEV_ID_ERROR -10
#define LIBPERIPH_BPM280_INIT_SET_CTRL_MEAS_ERROR -11
#define LIBPERIPH_BPM280_INIT_CALIBRATION_ERROR -12
#define LIBPERIPH_BPM280_INIT_WRONG_DEV_ID -13
typedef enum {
LIBPERIPH_BPM280_OK = 0,
LIBPERIPH_BPM280_UNKNOWN_ERRROR = 1,

LIBPERIPH_BPM280_I2C_NO_RESPONSE = 2,

LIBPERIPH_BPM280_INIT_CHECK_DEV_ID_ERROR = 10,
LIBPERIPH_BPM280_INIT_SET_CTRL_MEAS_ERROR = 11,
LIBPERIPH_BPM280_INIT_CALIBRATION_ERROR = 12,
LIBPERIPH_BPM280_INIT_WRONG_DEV_ID = 13,

LIBPERIPH_BPM280_VERIFICATION_PRESSURE_OUT_OF_BOUND = 20,
LIBPERIPH_BPM280_VERIFICATION_TEMPERATURE_OUT_OF_BOUND = 21,
LIBPERIPH_BPM280_VERIFICATION_STALE = 22,

LIBPERIPH_BPM280_INTERNAL_ERROR = 127,
} Bpm280ErrorCode;


typedef struct {
float pressure;
float temperature;
} BarometerMeasurements;


/**
* @brief Initialize the device including:
* 1. Check device ID
Expand All @@ -44,31 +56,19 @@ bool bmp280IsInitialized();


/**
* @brief Collect data from i2c and parse it
* @brief Collect data from i2c, parse it and verify
* @param[out] out_data - pressure in Pascal and temperature in Kelvin
* @return LIBPERIPH_BPM280_OK on success, otherwise error code < 0
* @note Sequentially call bmp280CollectData, bmp280ParseCollectedData and bmp280VerifyData.
*/
int8_t bmp280GetData(BarometerMeasurements* out_data);


/**
* @brief Collect data
* @return LIBPERIPH_BPM280_OK on success, otherwise error code < 0
*/
int8_t bmp280CollectData();


/**
* @param[out] out_data - Barometer parsed measurements
* @return LIBPERIPH_BPM280_OK on success, otherwise error code < 0
*/
int8_t bmp280ParseCollectedData(BarometerMeasurements* out_data);


/**
* @brief Alternatively, you can collect, parse and verify the measurements separately
* @param[in] data - barometer measurements
* @return LIBPERIPH_BPM280_OK on success, otherwise error code < 0
* @note A few checks:
* @note The verification consist of:
* 1. Verify that the Pressure in range within [30.000, 110.000] Pascal
* (equiv. to +9000 .. -500 m above/below sea level)
*
Expand All @@ -77,6 +77,8 @@ int8_t bmp280ParseCollectedData(BarometerMeasurements* out_data);
*
* 3. Verify that the measurements are not stale
*/
int8_t bmp280CollectData();
int8_t bmp280ParseCollectedData(BarometerMeasurements* out_data);
int8_t bmp280VerifyData(const BarometerMeasurements* data);

#ifdef __cplusplus
Expand Down
53 changes: 47 additions & 6 deletions tests/sensors/test_bmp280.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Dmitry Ponomarev <[email protected]>
* Copyright (C) 2021-2024 Dmitry Ponomarev <[email protected]>
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
Expand All @@ -13,27 +13,51 @@
struct Bmp280 : public SitlI2CSensor {
Bmp280() : SitlI2CSensor(0xC4) {}
int8_t callback_on_i2c_transmit(uint8_t id, const uint8_t tx[], uint8_t len) override {
if (len > 0) {
latest_reg = tx[0];
}
return i2c_tx_status;
}
int8_t callback_on_i2c_receive(uint8_t id, uint8_t* rx, uint8_t len) override {
if (latest_reg == 0xF7 && len == 6) {
// we can fill pressure and temperature here
}
return i2c_rx_status;
}

uint8_t latest_reg = 0;
int8_t i2c_tx_status = 0;
int8_t i2c_rx_status = 0;
};

static Bmp280 bmp280;

TEST(BMP280, test_bmp280ParseCollectedData_normal) {
TEST(BMP280, test_bmp280IsInitialized) {
ASSERT_FALSE(bmp280IsInitialized());
}

TEST(BMP280, test_bmp280GetData) {
bmp280.i2c_tx_status = 0;
bmp280.i2c_rx_status = 0;

bmp280Init();

ASSERT_TRUE(bmp280CollectData() >= 0);
BarometerMeasurements data;
bmp280ParseCollectedData(&data);
ASSERT_EQ(bmp280GetData(&data), -LIBPERIPH_BPM280_VERIFICATION_PRESSURE_OUT_OF_BOUND);
}

TEST(BMP280, test_bmp280ParseCollectedData) {
bmp280.i2c_tx_status = 0;
bmp280.i2c_rx_status = 0;
bmp280Init();
ASSERT_EQ(bmp280CollectData(), LIBPERIPH_BPM280_OK);
BarometerMeasurements data;

// Normal
ASSERT_EQ(bmp280ParseCollectedData(&data), LIBPERIPH_BPM280_OK);

// Bad argument
ASSERT_EQ(bmp280ParseCollectedData(NULL), -LIBPERIPH_BPM280_INTERNAL_ERROR);
}

TEST(BMP280, test_bmp280CollectData_no_rx_response) {
Expand All @@ -54,8 +78,25 @@ TEST(BMP280, test_bmp280CollectData_no_tx_response) {
ASSERT_FALSE(bmp280CollectData() >= 0);
}

TEST(BMP280, test_bmp280IsInitialized) {
ASSERT_FALSE(bmp280IsInitialized());
TEST(BMP280, test_bmp280VerifyData) {
bmp280Init(); // reset internal state
BarometerMeasurements data;

// Normal
data = BarometerMeasurements{100000, 273};
ASSERT_EQ(bmp280VerifyData(&data), LIBPERIPH_BPM280_OK);

// Pressure out of bound
data = BarometerMeasurements{29999, 273};
ASSERT_EQ(bmp280VerifyData(&data), -LIBPERIPH_BPM280_VERIFICATION_PRESSURE_OUT_OF_BOUND);
data = BarometerMeasurements{110001, 273};
ASSERT_EQ(bmp280VerifyData(&data), -LIBPERIPH_BPM280_VERIFICATION_PRESSURE_OUT_OF_BOUND);

// Temperature out of bound
data = BarometerMeasurements{100000, 232};
ASSERT_EQ(bmp280VerifyData(&data), -LIBPERIPH_BPM280_VERIFICATION_TEMPERATURE_OUT_OF_BOUND);
data = BarometerMeasurements{100000, 369};
ASSERT_EQ(bmp280VerifyData(&data), -LIBPERIPH_BPM280_VERIFICATION_TEMPERATURE_OUT_OF_BOUND);
}


Expand Down

0 comments on commit 4729c5e

Please sign in to comment.