31 #define ADDR_CMD_CONVERT_D1_OSR256 0x40 32 #define ADDR_CMD_CONVERT_D1_OSR512 0x42 33 #define ADDR_CMD_CONVERT_D1_OSR1024 0x44 34 #define ADDR_CMD_CONVERT_D1_OSR2048 0x46 35 #define ADDR_CMD_CONVERT_D1_OSR4096 0x48 38 #define ADDR_CMD_CONVERT_D2_OSR256 0x50 39 #define ADDR_CMD_CONVERT_D2_OSR512 0x52 40 #define ADDR_CMD_CONVERT_D2_OSR1024 0x54 41 #define ADDR_CMD_CONVERT_D2_OSR2048 0x56 42 #define ADDR_CMD_CONVERT_D2_OSR4096 0x58 58 , _dev(
std::move(dev))
59 , _ms56xx_type(ms56xx_type)
71 if (!sensor || !sensor->
_init()) {
85 AP_HAL::panic(
"PANIC: AP_Baro_MS56XX: failed to take serial semaphore for init");
92 bool prom_read_ok =
false;
97 const char *
name =
"MS5611";
156 static uint16_t
crc4(uint16_t *data)
161 for (uint8_t cnt = 0; cnt < 16; cnt++) {
164 n_rem ^= (uint8_t)((data[cnt >> 1]) & 0x00FF);
166 n_rem ^= (uint8_t)(data[cnt >> 1] >> 8);
169 for (n_bit = 8; n_bit > 0; n_bit--) {
170 if (n_rem & 0x8000) {
171 n_rem = (n_rem << 1) ^ 0x3000;
173 n_rem = (n_rem << 1);
178 return (n_rem >> 12) & 0xF;
188 return (val[0] << 8) | val[1];
197 return (val[0] << 16) | (val[1] << 8) | val[2];
209 bool all_zero =
true;
210 for (uint8_t i = 0; i < 8; i++) {
222 const uint16_t crc_read = prom[7] & 0xf;
227 return crc_read ==
crc4(prom);
240 bool all_zero =
true;
241 for (uint8_t i = 0; i < 7; i++) {
255 const uint16_t crc_read = (prom[0] & 0xf000) >> 12;
260 return crc_read ==
crc4(prom);
284 next_state = (
_state + 1) % 5;
323 uint8_t *
count, uint8_t max_count)
327 if (*count == max_count) {
328 *count = max_count / 2;
336 uint8_t d1count, d2count;
342 if (
_accum.d1_count == 0) {
349 d1count =
_accum.d1_count;
350 d2count =
_accum.d2_count;
356 _D1 = ((float)sD1) / d1count;
359 _D2 = ((float)sD2) / d2count;
398 float T2 = (dT*dT) / 0x80000000;
399 float Aux = TEMP*TEMP;
400 float OFF2 = 2.5f*Aux;
401 float SENS2 = 1.25f*Aux;
407 float pressure = (
_D1*SENS/2097152 - OFF)/32768;
433 float T2 = (dT*dT) / 0x80000000;
434 float Aux = TEMP*TEMP;
435 float OFF2 = 61.0f*Aux/16.0f;
436 float SENS2 = 2.0f*Aux;
442 float pressure = (
_D1*SENS/2097152 - OFF)/32768;
452 int32_t raw_pressure =
_D1;
453 int32_t raw_temperature =
_D2;
458 dT = raw_temperature - (((uint32_t)
_cal_reg.c5) << 8);
459 TEMP = 2000 + ((int64_t)dT * (int64_t)
_cal_reg.c6) / 8388608;
460 OFF = (int64_t)
_cal_reg.c2 * (int64_t)131072 + ((int64_t)
_cal_reg.c4 * (int64_t)dT) / (int64_t)64;
461 SENS = (int64_t)
_cal_reg.c1 * (int64_t)65536 + ((int64_t)
_cal_reg.c3 * (int64_t)dT) / (int64_t)128;
465 int32_t T2 = ((int64_t)3 * ((int64_t)dT * (int64_t)dT) / (int64_t)8589934592);
466 int64_t aux = (TEMP - 2000) * (TEMP - 2000);
467 int64_t OFF2 = 61 * aux / 16;
468 int64_t SENS2 = 29 * aux / 16;
475 int32_t pressure = ((int64_t)raw_pressure * SENS / (int64_t)2097152 - OFF) / (int64_t)32768;
485 int32_t raw_pressure =
_D1;
486 int32_t raw_temperature =
_D2;
491 dT = raw_temperature - (((uint32_t)
_cal_reg.c5) << 8);
492 TEMP = 2000 + ((int64_t)dT * (int64_t)
_cal_reg.c6) / 8388608;
493 OFF = (int64_t)
_cal_reg.c2 * (int64_t)65536 + ((int64_t)
_cal_reg.c4 * (int64_t)dT) / (int64_t)128;
494 SENS = (int64_t)
_cal_reg.c1 * (int64_t)32768 + ((int64_t)
_cal_reg.c3 * (int64_t)dT) / (int64_t)256;
498 int32_t T2 = ((int64_t)3 * ((int64_t)dT * (int64_t)dT) / (int64_t)8589934592);
499 int64_t aux = (TEMP - 2000) * (TEMP - 2000);
500 int64_t OFF2 = 3 * aux / 2;
501 int64_t SENS2 = 5 * aux / 8;
508 int32_t pressure = ((int64_t)raw_pressure * SENS / (int64_t)2097152 - OFF) / (int64_t)8192;
509 pressure = pressure * 10;
int printf(const char *fmt,...)
static void _update_and_wrap_accumulator(uint32_t *accum, uint32_t val, uint8_t *count, uint8_t max_count)
static const uint8_t ADDR_CMD_CONVERT_PRESSURE
virtual PeriodicHandle register_periodic_callback(uint32_t period_usec, PeriodicCb)=0
void _copy_to_frontend(uint8_t instance, float pressure, float temperature)
uint8_t register_sensor(void)
static uint16_t crc4(uint16_t *data)
virtual AP_HAL::Semaphore * get_semaphore()=0
virtual void set_retries(uint8_t retries)
static AP_Baro_Backend * probe(AP_Baro &baro, AP_HAL::OwnPtr< AP_HAL::Device > dev, enum MS56XX_TYPE ms56xx_type=BARO_MS5611)
uint8_t get_bus_address(void) const
#define HAL_SEMAPHORE_BLOCK_FOREVER
virtual bool take(uint32_t timeout_ms) WARN_IF_UNUSED=0
uint8_t bus_num(void) const
struct AP_Baro_MS56XX::@11 _cal_reg
static const uint8_t ADDR_CMD_CONVERT_TEMPERATURE
virtual void delay(uint16_t ms)=0
uint16_t _read_prom_word(uint8_t word)
static const uint8_t CMD_MS56XX_PROM
struct AP_Baro_MS56XX::@10 _accum
static AP_HAL::OwnPtr< AP_HAL::Device > dev
bool pressure_ok(float press)
static const uint8_t CMD_MS56XX_RESET
AP_Baro_MS56XX(AP_Baro &baro, AP_HAL::OwnPtr< AP_HAL::Device > dev, enum MS56XX_TYPE ms56xx_type)
static const uint8_t CMD_MS56XX_READ_ADC
bool _read_prom_5611(uint16_t prom[8])
virtual bool transfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len)=0
void set_type(uint8_t instance, baro_type_t type)
AP_HAL::OwnPtr< AP_HAL::Device > _dev
#define ADDR_CMD_CONVERT_D1_OSR1024
enum MS56XX_TYPE _ms56xx_type
#define FUNCTOR_BIND_MEMBER(func, rettype,...)
bool _read_prom_5637(uint16_t prom[8])
#define ADDR_CMD_CONVERT_D2_OSR1024
void panic(const char *errormsg,...) FMT_PRINTF(1
AP_HAL::Scheduler * scheduler