diff --git a/src/main.c b/src/main.c index 5405819..290d3a4 100644 --- a/src/main.c +++ b/src/main.c @@ -215,8 +215,8 @@ int main() { mgos_mpu9250_set_magnetometer_speed(mpu9250, MAG_100_HZ); } */ - if (!(baro=mgos_barometer_create_i2c(i2c, 0x60, BARO_MPL115))) { - LOG(LL_ERROR, ("Cannot create MPL115 barometer")); + if (!(baro=mgos_barometer_create_i2c(i2c, 0x60, BARO_MPL3115))) { + LOG(LL_ERROR, ("Cannot create barometer")); } else { mgos_barometer_set_cache_ttl(baro, 0); } diff --git a/src/mgos_barometer.c b/src/mgos_barometer.c index 4eab53b..2443e2f 100644 --- a/src/mgos_barometer.c +++ b/src/mgos_barometer.c @@ -47,22 +47,31 @@ struct mgos_barometer *mgos_barometer_create_i2c(struct mgos_i2c *i2c, uint8_t i sensor->detect = mgos_barometer_mpl3115_detect; sensor->create = mgos_barometer_mpl3115_create; sensor->read = mgos_barometer_mpl3115_read; - sensor->destroy = mgos_barometer_mpl3115_destroy; + break; default: LOG(LL_ERROR, ("Unknown mgos_barometer_type %d", type)); free(sensor); return NULL; } - if ((sensor->detect) && !sensor->detect(sensor)) { - LOG(LL_ERROR, ("Could not detect mgos_barometer_type %d at I2C 0x%02x", type, i2caddr)); - free(sensor); - return NULL; + sensor->type=type; + if (sensor->detect) { + if (!sensor->detect(sensor)) { + LOG(LL_ERROR, ("Could not detect mgos_barometer_type %d at I2C 0x%02x", type, i2caddr)); + free(sensor); + return NULL; + } else { + LOG(LL_DEBUG, ("Successfully detected mgos_barometer_type %d at I2C 0x%02x", type, i2caddr)); + } } - if ((sensor->create) && !sensor->create(sensor)) { - LOG(LL_ERROR, ("Could not create mgos_barometer_type %d at I2C 0x%02x", type, i2caddr)); - free(sensor); - return NULL; + if (sensor->create) { + if (!sensor->create(sensor)) { + LOG(LL_ERROR, ("Could not create mgos_barometer_type %d at I2C 0x%02x", type, i2caddr)); + free(sensor); + return NULL; + } else { + LOG(LL_DEBUG, ("Successfully created mgos_barometer_type %d at I2C 0x%02x", type, i2caddr)); + } } return sensor; diff --git a/src/mgos_barometer_mpl3115.c b/src/mgos_barometer_mpl3115.c index d0377c8..69a8a5c 100644 --- a/src/mgos_barometer_mpl3115.c +++ b/src/mgos_barometer_mpl3115.c @@ -1,21 +1,97 @@ -#include "mgos_barometer_mpl115.h" +#include "mgos_barometer_mpl3115.h" #include "mgos_i2c.h" // Datasheet: // https://cdn-shop.adafruit.com/datasheets/1893_datasheet.pdf bool mgos_barometer_mpl3115_detect(struct mgos_barometer *dev) { - return false; + int val; + + if (!dev) { + return false; + } + + if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_WHOAMI)) < 0) { + return false; + } + + if (val != 0xC4) { + return false; + } + + return true; } bool mgos_barometer_mpl3115_create(struct mgos_barometer *dev) { - return false; -} + if (!dev) { + return false; + } -bool mgos_barometer_mpl3115_destroy(struct mgos_barometer *dev){ - return false; + + // Reset + if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_CTRL1, 0x04)) { + return false; + } + mgos_usleep(20000); + + // Set sample period to 1sec ST[3:0], period 2^ST seconds + if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_CTRL2, 0x00)) { + return false; + } + + // Set Barometer Mode, OS[2:0], oversampling 2^OS times, continuous sampling + if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_CTRL1, 0x39)) { + return false; + } + + // Set event flags for temp+pressure + if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_PT_DATA, 0x07)) { + return false; + } + + dev->has_barometer = true; + dev->has_thermometer = true; + + return true; } bool mgos_barometer_mpl3115_read(struct mgos_barometer *dev) { - return false; + if (!dev) { + return false; + } + + uint8_t val = 0; + while (!(val & 0x80)) { // Data Ready + if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_STATUS)) < 0) { + return false; + } + mgos_usleep(10000); + } + + uint32_t pressure; + int16_t temperature; + uint8_t data[5]; + + if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, MPL3115_REG_PRESSURE_MSB, 5, data)) { + return false; + } + + pressure = data[0]; + pressure <<= 8; + pressure |= data[1]; + pressure <<= 8; + pressure |= data[2]; + pressure >>= 4; + + temperature = data[3]; + temperature <<= 8; + temperature |= data[4]; + temperature >>= 4; + if (temperature & 0x800) { + temperature |= 0xF000; + } + + dev->pressure = pressure / 4.0; + dev->temperature = temperature / 16.0; + return true; } diff --git a/src/mgos_barometer_mpl3115.h b/src/mgos_barometer_mpl3115.h index 61a28b0..6a3796d 100644 --- a/src/mgos_barometer_mpl3115.h +++ b/src/mgos_barometer_mpl3115.h @@ -3,11 +3,18 @@ #include "mgos.h" #include "mgos_barometer_internal.h" -struct mgos_barometer_mpl3115_data { - float a0, b1, b2, c12; -}; +#define MPL3115_REG_STATUS (0x00) +#define MPL3115_REG_PRESSURE_MSB (0x01) +#define MPL3115_REG_PRESSURE_CSB (0x02) +#define MPL3115_REG_PRESSURE_LSB (0x03) +#define MPL3115_REG_TEMP_MSB (0x04) +#define MPL3115_REG_TEMP_LSB (0x05) +#define MPL3115_REG_DR_STATUS (0x06) +#define MPL3115_REG_WHOAMI (0x0C) +#define MPL3115_REG_PT_DATA (0x13) +#define MPL3115_REG_CTRL1 (0x26) +#define MPL3115_REG_CTRL2 (0x27) bool mgos_barometer_mpl3115_detect(struct mgos_barometer *dev); bool mgos_barometer_mpl3115_create(struct mgos_barometer *dev); -bool mgos_barometer_mpl3115_destroy(struct mgos_barometer *dev); bool mgos_barometer_mpl3115_read(struct mgos_barometer *dev);