diff --git a/sw/airborne/boards/baro_board_ms5611_i2c.c b/sw/airborne/boards/baro_board_ms5611_i2c.c index fb5b10eaec..8e55b850a2 100644 --- a/sw/airborne/boards/baro_board_ms5611_i2c.c +++ b/sw/airborne/boards/baro_board_ms5611_i2c.c @@ -46,7 +46,7 @@ #endif -/* default i2c address +/** default i2c address * when CSB is set to GND addr is 0xEE * when CSB is set to VCC addr is 0xEC * @@ -56,13 +56,18 @@ #define BB_MS5611_SLAVE_ADDR 0xEE #endif +/// set to TRUE if baro is actually a MS5607 +#ifndef BB_MS5611_TYPE_MS5607 +#define BB_MS5611_TYPE_MS5607 FALSE +#endif +PRINT_CONFIG_VAR(BB_MS5611_TYPE_MS5607) struct Ms5611_I2c bb_ms5611; void baro_init(void) { - ms5611_i2c_init(&bb_ms5611, &BB_MS5611_I2C_DEV, BB_MS5611_SLAVE_ADDR); + ms5611_i2c_init(&bb_ms5611, &BB_MS5611_I2C_DEV, BB_MS5611_SLAVE_ADDR, BB_MS5611_TYPE_MS5607); #ifdef BARO_LED LED_OFF(BARO_LED); diff --git a/sw/airborne/boards/baro_board_ms5611_spi.c b/sw/airborne/boards/baro_board_ms5611_spi.c index 5b5d78880b..0185d0d600 100644 --- a/sw/airborne/boards/baro_board_ms5611_spi.c +++ b/sw/airborne/boards/baro_board_ms5611_spi.c @@ -45,13 +45,17 @@ #endif #endif +/// set to TRUE if baro is actually a MS5607 +#ifndef BB_MS5611_TYPE_MS5607 +#define BB_MS5611_TYPE_MS5607 FALSE +#endif struct Ms5611_Spi bb_ms5611; void baro_init(void) { - ms5611_spi_init(&bb_ms5611, &BB_MS5611_SPI_DEV, BB_MS5611_SLAVE_IDX); + ms5611_spi_init(&bb_ms5611, &BB_MS5611_SPI_DEV, BB_MS5611_SLAVE_IDX, BB_MS5611_TYPE_MS5607); #ifdef BARO_LED LED_OFF(BARO_LED); diff --git a/sw/airborne/boards/bebop/baro_board.h b/sw/airborne/boards/bebop/baro_board.h index 2a91d3ebe9..c0b4b019c9 100644 --- a/sw/airborne/boards/bebop/baro_board.h +++ b/sw/airborne/boards/bebop/baro_board.h @@ -21,12 +21,15 @@ /** * @file boards/bebop/baro_board.h - * Paparazzi Bebop Baro Sensor implementation using the ms5611. + * Paparazzi Bebop Baro Sensor implementation for the MS5607. + * Actually uses the MS5611 driver, but sets BB_MS5611_TYPE_MS5607 to TRUE. */ #ifndef BOARDS_BEBOP_BARO_H #define BOARDS_BEBOP_BARO_H +#define BB_MS5611_TYPE_MS5607 TRUE + // only for printing the baro type during compilation #ifndef BARO_BOARD #define BARO_BOARD BARO_MS5611_I2C diff --git a/sw/airborne/modules/sensors/baro_ms5611_i2c.c b/sw/airborne/modules/sensors/baro_ms5611_i2c.c index 8e4e9689ac..bc830a9000 100644 --- a/sw/airborne/modules/sensors/baro_ms5611_i2c.c +++ b/sw/airborne/modules/sensors/baro_ms5611_i2c.c @@ -59,7 +59,7 @@ float baro_ms5611_sigma2; void baro_ms5611_init(void) { - ms5611_i2c_init(&baro_ms5611, &MS5611_I2C_DEV, MS5611_SLAVE_ADDR); + ms5611_i2c_init(&baro_ms5611, &MS5611_I2C_DEV, MS5611_SLAVE_ADDR, FALSE); baro_ms5611_enabled = TRUE; baro_ms5611_alt_valid = FALSE; diff --git a/sw/airborne/modules/sensors/baro_ms5611_spi.c b/sw/airborne/modules/sensors/baro_ms5611_spi.c index 619a527bf0..b043f4d8fb 100644 --- a/sw/airborne/modules/sensors/baro_ms5611_spi.c +++ b/sw/airborne/modules/sensors/baro_ms5611_spi.c @@ -58,7 +58,7 @@ float baro_ms5611_sigma2; void baro_ms5611_init(void) { - ms5611_spi_init(&baro_ms5611, &MS5611_SPI_DEV, MS5611_SLAVE_IDX); + ms5611_spi_init(&baro_ms5611, &MS5611_SPI_DEV, MS5611_SLAVE_IDX, FALSE); baro_ms5611_enabled = TRUE; baro_ms5611_alt_valid = FALSE; diff --git a/sw/airborne/peripherals/ms5611.c b/sw/airborne/peripherals/ms5611.c index bfc8e68b99..99ed156f10 100644 --- a/sw/airborne/peripherals/ms5611.c +++ b/sw/airborne/peripherals/ms5611.c @@ -23,7 +23,7 @@ /** * @file peripherals/ms5611.c * - * MS5611 barometer driver common functions (I2C and SPI). + * MS5611 and MS5607 barometer driver common functions (I2C and SPI). */ #include "peripherals/ms5611.h" @@ -61,7 +61,7 @@ bool_t ms5611_prom_crc_ok(uint16_t *prom) } /** - * Calculate temperature and compensated pressure. + * Calculate temperature and compensated pressure for MS5611. * @return TRUE if measurement was valid, FALSE otherwise */ bool_t ms5611_calc(struct Ms5611Data *ms) @@ -101,3 +101,46 @@ bool_t ms5611_calc(struct Ms5611Data *ms) } return FALSE; } + +/** + * Calculate temperature and compensated pressure for MS5607. + * MS5607 basically has half the resolution of the MS5611. + * @return TRUE if measurement was valid, FALSE otherwise + */ +bool_t ms5607_calc(struct Ms5611Data *ms) +{ + int64_t dt, tempms, off, sens, t2, off2, sens2; + + /* difference between actual and ref temperature */ + dt = ms->d2 - (int64_t)ms->c[5] * (1 << 8); + /* actual temperature */ + tempms = 2000 + ((int64_t)dt * ms->c[6]) / (1 << 23); + /* offset at actual temperature */ + off = ((int64_t)ms->c[2] * (1 << 17)) + ((int64_t)ms->c[4] * dt) / (1 << 6); + /* sensitivity at actual temperature */ + sens = ((int64_t)ms->c[1] * (1 << 16)) + ((int64_t)ms->c[3] * dt) / (1 << 7); + /* second order temperature compensation */ + if (tempms < 2000) { + t2 = (dt * dt) / (1 << 31); + off2 = 61 * ((int64_t)(tempms - 2000) * (tempms - 2000)) / (1 << 4); + sens2 = 2 * ((int64_t)(tempms - 2000) * (tempms - 2000)); + if (tempms < -1500) { + off2 = off2 + 15 * (int64_t)(tempms + 1500) * (tempms + 1500); + sens2 = sens2 + 8 * ((int64_t)(tempms + 1500) * (tempms + 1500)); + } + tempms = tempms - t2; + off = off - off2; + sens = sens - sens2; + } + + /* temperature compensated pressure in Pascal (0.01mbar) */ + uint32_t p = (((int64_t)ms->d1 * sens) / (1 << 21) - off) / (1 << 15); + /* if temp and pressare are in valid bounds, copy and return TRUE (valid) */ + if ((tempms > -4000) && (tempms < 8500) && (p > 1000) && (p < 120000)) { + /* temperature in deg Celsius with 0.01 degC resolultion */ + ms->temperature = (int32_t)tempms; + ms->pressure = p; + return TRUE; + } + return FALSE; +} diff --git a/sw/airborne/peripherals/ms5611.h b/sw/airborne/peripherals/ms5611.h index 7ab7c65eb0..dd51cff1e8 100644 --- a/sw/airborne/peripherals/ms5611.h +++ b/sw/airborne/peripherals/ms5611.h @@ -58,5 +58,6 @@ struct Ms5611Data { extern bool_t ms5611_prom_crc_ok(uint16_t *prom); extern bool_t ms5611_calc(struct Ms5611Data *ms); +extern bool_t ms5607_calc(struct Ms5611Data *ms); #endif /* MS5611_H */ diff --git a/sw/airborne/peripherals/ms5611_i2c.c b/sw/airborne/peripherals/ms5611_i2c.c index dbd1b2cce9..ccc2c9017e 100644 --- a/sw/airborne/peripherals/ms5611_i2c.c +++ b/sw/airborne/peripherals/ms5611_i2c.c @@ -22,7 +22,7 @@ /** * @file peripherals/ms5611_i2c.c - * Measurement Specialties (Intersema) MS5611-01BA pressure/temperature sensor interface for I2C. + * Measurement Specialties (Intersema) MS5611-01BA and MS5607-02BA03 pressure/temperature sensor interface for I2C. * */ @@ -30,7 +30,8 @@ #include "peripherals/ms5611_i2c.h" -void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t addr) +void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t addr, + bool_t is_ms5607) { /* set i2c_peripheral */ ms->i2c_p = i2c_p; @@ -44,6 +45,7 @@ void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t ad ms->initialized = FALSE; ms->status = MS5611_STATUS_UNINIT; ms->prom_cnt = 0; + ms->is_ms5607 = is_ms5607; } void ms5611_i2c_start_configure(struct Ms5611_I2c *ms) @@ -152,8 +154,11 @@ void ms5611_i2c_event(struct Ms5611_I2c *ms) ms->status = MS5611_STATUS_IDLE; } else { /* calculate temp and pressure from measurements and set available if valid */ - if (ms5611_calc(&(ms->data))) { - ms->data_available = TRUE; + if (ms->is_ms5607) { + ms->data_available = ms5607_calc(&(ms->data)); + } + else { + ms->data_available = ms5611_calc(&(ms->data)); } ms->status = MS5611_STATUS_IDLE; } diff --git a/sw/airborne/peripherals/ms5611_i2c.h b/sw/airborne/peripherals/ms5611_i2c.h index 3cb5b5d562..8954e66a8c 100644 --- a/sw/airborne/peripherals/ms5611_i2c.h +++ b/sw/airborne/peripherals/ms5611_i2c.h @@ -22,7 +22,7 @@ /** * @file peripherals/ms5611_i2c.h * - * Measurement Specialties (Intersema) MS5611-01BA pressure/temperature sensor interface for I2C. + * Measurement Specialties (Intersema) MS5611-01BA and MS5607-02BA03 pressure/temperature sensor interface for I2C. */ #ifndef MS5611_I2C_H @@ -37,6 +37,7 @@ struct Ms5611_I2c { struct i2c_periph *i2c_p; struct i2c_transaction i2c_trans; enum Ms5611Status status; + bool_t is_ms5607; ///< TRUE if MS5607, FALSE if MS5611 bool_t initialized; ///< config done flag volatile bool_t data_available; ///< data ready flag struct Ms5611Data data; @@ -44,7 +45,8 @@ struct Ms5611_I2c { }; // Functions -extern void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t addr); +extern void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t addr, + bool_t is_ms5607); extern void ms5611_i2c_start_configure(struct Ms5611_I2c *ms); extern void ms5611_i2c_start_conversion(struct Ms5611_I2c *ms); extern void ms5611_i2c_periodic_check(struct Ms5611_I2c *ms); diff --git a/sw/airborne/peripherals/ms5611_spi.c b/sw/airborne/peripherals/ms5611_spi.c index 7640cbb068..a3b8d0e988 100644 --- a/sw/airborne/peripherals/ms5611_spi.c +++ b/sw/airborne/peripherals/ms5611_spi.c @@ -22,7 +22,7 @@ /** * @file peripherals/ms5611_spi.c - * Measurement Specialties (Intersema) MS5611-01BA pressure/temperature sensor interface for SPI. + * Measurement Specialties (Intersema) MS5611-01BA and MS5607-02BA03 pressure/temperature sensor interface for SPI. * */ @@ -30,7 +30,8 @@ #include "peripherals/ms5611_spi.h" -void ms5611_spi_init(struct Ms5611_Spi *ms, struct spi_periph *spi_p, uint8_t slave_idx) +void ms5611_spi_init(struct Ms5611_Spi *ms, struct spi_periph *spi_p, uint8_t slave_idx, + bool_t is_ms5607) { /* set spi_peripheral */ ms->spi_p = spi_p; @@ -58,6 +59,7 @@ void ms5611_spi_init(struct Ms5611_Spi *ms, struct spi_periph *spi_p, uint8_t sl ms->initialized = FALSE; ms->status = MS5611_STATUS_UNINIT; ms->prom_cnt = 0; + ms->is_ms5607 = is_ms5607; } void ms5611_spi_start_configure(struct Ms5611_Spi *ms) @@ -164,8 +166,11 @@ void ms5611_spi_event(struct Ms5611_Spi *ms) ms->status = MS5611_STATUS_IDLE; } else { /* calculate temp and pressure from measurements and set available if valid */ - if (ms5611_calc(&(ms->data))) { - ms->data_available = TRUE; + if (ms->is_ms5607) { + ms->data_available = ms5607_calc(&(ms->data)); + } + else { + ms->data_available = ms5611_calc(&(ms->data)); } ms->status = MS5611_STATUS_IDLE; } diff --git a/sw/airborne/peripherals/ms5611_spi.h b/sw/airborne/peripherals/ms5611_spi.h index b885faa79f..5e8b809d29 100644 --- a/sw/airborne/peripherals/ms5611_spi.h +++ b/sw/airborne/peripherals/ms5611_spi.h @@ -22,7 +22,7 @@ /** * @file peripherals/ms5611_spi.h * - * Measurement Specialties (Intersema) MS5611-01BA pressure/temperature sensor interface for SPI. + * Measurement Specialties (Intersema) MS5611-01BA and MS5607-02BA03 pressure/temperature sensor interface for SPI. */ #ifndef MS5611_SPI_H @@ -39,6 +39,7 @@ struct Ms5611_Spi { volatile uint8_t tx_buf[1]; volatile uint8_t rx_buf[4]; enum Ms5611Status status; + bool_t is_ms5607; ///< TRUE if MS5607, FALSE if MS5611 bool_t initialized; ///< config done flag volatile bool_t data_available; ///< data ready flag struct Ms5611Data data; @@ -46,7 +47,8 @@ struct Ms5611_Spi { }; // Functions -extern void ms5611_spi_init(struct Ms5611_Spi *ms, struct spi_periph *spi_p, uint8_t addr); +extern void ms5611_spi_init(struct Ms5611_Spi *ms, struct spi_periph *spi_p, uint8_t addr, + bool_t is_ms5607); extern void ms5611_spi_start_configure(struct Ms5611_Spi *ms); extern void ms5611_spi_start_conversion(struct Ms5611_Spi *ms); extern void ms5611_spi_periodic_check(struct Ms5611_Spi *ms);