From 0be5e77c8b5f0ab9ac2fddc8a2f2352db690b56f Mon Sep 17 00:00:00 2001
From: Pim van Pelt <pim@ipng.nl>
Date: Wed, 2 Jan 2019 00:13:23 +0100
Subject: [PATCH] Remove MCP9808, CCS811, MPU9250, SHT31, SI7021; they were
 sent upstream. Test INA{219,226,3221}.

---
 src/main.c                  | 236 +++++++-----------------
 src/mgos_ccs811.c           | 238 ------------------------
 src/mgos_ccs811_internal.h  |  74 --------
 src/mgos_htu21df.c          | 167 -----------------
 src/mgos_htu21df_internal.h |  47 -----
 src/mgos_mcp9808.c          | 121 ------------
 src/mgos_mcp9808_internal.h |  59 ------
 src/mgos_mpu9250.c          | 356 ------------------------------------
 src/mgos_mpu9250_internal.h |  71 -------
 src/mgos_sht31.c            | 180 ------------------
 src/mgos_sht31_internal.h   |  53 ------
 src/mgos_si7021.c           | 165 -----------------
 src/mgos_si7021_internal.h  |  55 ------
 13 files changed, 66 insertions(+), 1756 deletions(-)
 delete mode 100644 src/mgos_ccs811.c
 delete mode 100644 src/mgos_ccs811_internal.h
 delete mode 100644 src/mgos_htu21df.c
 delete mode 100644 src/mgos_htu21df_internal.h
 delete mode 100644 src/mgos_mcp9808.c
 delete mode 100644 src/mgos_mcp9808_internal.h
 delete mode 100644 src/mgos_mpu9250.c
 delete mode 100644 src/mgos_mpu9250_internal.h
 delete mode 100644 src/mgos_sht31.c
 delete mode 100644 src/mgos_sht31_internal.h
 delete mode 100644 src/mgos_si7021.c
 delete mode 100644 src/mgos_si7021_internal.h

diff --git a/src/main.c b/src/main.c
index 619d7fa..5d039f8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,38 +1,18 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 #include "mgos.h"
 #include "mgos_i2c.h"
-#include "mgos_sht31.h"
-#include "mgos_si7021.h"
-#include "mgos_htu21df.h"
-#include "mgos_mcp9808.h"
-#include "mgos_ccs811.h"
-#include "mgos_mpu9250.h"
-#include "mgos_imu.h"
-#include "mgos_barometer.h"
+#include "mgos_ina3221.h"
+#include "mgos_ina219.h"
+#include "mgos_ina226.h"
 #include <fcntl.h>
 #include <math.h>
 #include <sys/ioctl.h>
 
-#define I2CBUSNR    7
+#define I2CBUSNR    6
 
 bool i2c_dumpregs(struct mgos_i2c *i2c, uint8_t i2caddr);
+void i2c_scanner(struct mgos_i2c *i2c, bool dumpregs);
 
-static void i2c_scanner(struct mgos_i2c *i2c, bool dumpregs) {
+void i2c_scanner(struct mgos_i2c *i2c, bool dumpregs) {
   int i;
 
   if (!i2c) {
@@ -69,122 +49,58 @@ bool i2c_dumpregs(struct mgos_i2c *i2c, uint8_t i2caddr) {
   return true;
 }
 
-static bool do_ccs811(struct mgos_ccs811 *sensor) {
-  float eco2, tvoc;
-
-  if (!sensor) {
-    return false;
-  }
-
-  eco2 = mgos_ccs811_get_eco2(sensor);
-  tvoc = mgos_ccs811_get_tvoc(sensor);
-  LOG(LL_INFO, ("eCO2=%.0fppm TVOC=%.0fppb", eco2, tvoc));
-
-  return true;
-}
-
-static bool do_sht31(struct mgos_sht31 *sensor) {
-  float temp, humid;
-
-  if (!sensor) {
-    return false;
-  }
-
-  temp  = mgos_sht31_getTemperature(sensor);
-  humid = mgos_sht31_getHumidity(sensor);
-  LOG(LL_INFO, ("temperature=%.2fC humidity=%.1f%%", temp, humid));
-
-  return true;
-}
-
-static bool do_si7021(struct mgos_si7021 *sensor) {
-  float temp, humid;
-
-  if (!sensor) {
-    return false;
-  }
-
-  temp  = mgos_si7021_getTemperature(sensor);
-  humid = mgos_si7021_getHumidity(sensor);
-  LOG(LL_INFO, ("temperature=%.2fC humidity=%.1f%%", temp, humid));
-
-  return true;
-}
-
-static bool do_htu21df(struct mgos_htu21df *sensor) {
-  float temp, humid;
-
-  if (!sensor) {
-    return false;
-  }
-
-  temp  = mgos_htu21df_getTemperature(sensor);
-  humid = mgos_htu21df_getHumidity(sensor);
-  LOG(LL_INFO, ("temperature=%.2fC humidity=%.1f%%", temp, humid));
-
-  return true;
-}
-
-static bool do_mcp9808(struct mgos_mcp9808 *sensor) {
-  float temp;
-
-  if (!sensor) {
-    return false;
-  }
-
-  temp = mgos_mcp9808_getTemperature(sensor);
-  LOG(LL_INFO, ("temperature=%.2fC", temp));
-
-  return true;
-}
-
-static bool do_mpu9250(struct mgos_mpu9250 *sensor) {
-  float ax, ay, az;
-  float gx, gy, gz;
-  float mx, my, mz;
-
-  if (!sensor) {
-    return false;
-  }
-
-  if (mgos_mpu9250_get_accelerometer(sensor, &ax, &ay, &az)) {
-    LOG(LL_INFO, ("Accel X=%.2f Y=%.2f Z=%.2f", ax, ay, az));
-  }
-  if (mgos_mpu9250_get_gyroscope(sensor, &gx, &gy, &gz)) {
-    LOG(LL_INFO, ("Gyro  X=%.2f Y=%.2f Z=%.2f", gx, gy, gz));
-  }
-  if (mgos_mpu9250_get_magnetometer(sensor, &mx, &my, &mz)) {
-    LOG(LL_INFO, ("Mag   X=%.2f Y=%.2f Z=%.2f", mx, my, mz));
-  }
-  return true;
-}
-
-static bool do_baro(struct mgos_barometer *sensor) {
-  float pressure, temperature;
+static bool do_ina3221(struct mgos_ina3221 *sensor) {
 
   if (!sensor)
     return false;
 
-  if (!mgos_barometer_get_pressure(sensor, &pressure))
-    pressure=NAN;
+  for (uint8_t i=1; i<4; i++) {
+    float bus, shunt, current, res;
+    mgos_ina3221_get_bus_voltage(sensor, i, &bus);
+    mgos_ina3221_get_shunt_resistance(sensor, i, &res);
+    mgos_ina3221_get_shunt_voltage(sensor, i, &shunt);
+    mgos_ina3221_get_current(sensor, i, &current);
+    LOG(LL_INFO, ("Chan[%u]: Vbus=%.3f V Vshunt=%.0f uV Rshunt=%.3f Ohm Ishunt=%.1f mA", i, bus, shunt*10e6, res, current*10e3));
+  }
 
-  if (!mgos_barometer_get_temperature(sensor, &temperature)) 
-    temperature=NAN;
+  return true;
+}
 
-  LOG(LL_INFO, ("type=%s temperature=%.2fC pressure=%.0fPa", mgos_barometer_get_device_name(sensor), temperature, pressure));
+static bool do_ina219(struct mgos_ina219 *sensor) {
+  float bus, shunt, current, res;
+
+  if (!sensor)
+    return false;
+
+  mgos_ina219_get_bus_voltage(sensor, &bus);
+  mgos_ina219_get_shunt_resistance(sensor, &res);
+  mgos_ina219_get_shunt_voltage(sensor, &shunt);
+  mgos_ina219_get_current(sensor, &current);
+  LOG(LL_INFO, ("Vbus=%.3f V Vshunt=%.0f uV Rshunt=%.3f Ohm Ishunt=%.1f mA", bus, shunt*10e6, res, current*10e3));
+
+  return true;
+}
+
+static bool do_ina226(struct mgos_ina226 *sensor) {
+  float bus, shunt, current, res;
+
+  if (!sensor)
+    return false;
+
+  mgos_ina226_get_bus_voltage(sensor, &bus);
+  mgos_ina226_get_shunt_resistance(sensor, &res);
+  mgos_ina226_get_shunt_voltage(sensor, &shunt);
+  mgos_ina226_get_current(sensor, &current);
+  LOG(LL_INFO, ("Vbus=%.3f V Vshunt=%.0f uV Rshunt=%.3f Ohm Ishunt=%.1f mA", bus, shunt*10e6, res, current*10e3));
 
   return true;
 }
 
 int main(int argc, char **argv, char **environ) {
   struct mgos_i2c *    i2c = NULL;
-  struct mgos_si7021 * si7021 = NULL;
-  struct mgos_sht31 *  sht31 = NULL;
-  struct mgos_htu21df *htu21df = NULL;
-  struct mgos_mcp9808 *mcp9808 = NULL;
-  struct mgos_ccs811 * ccs811 = NULL;
-  struct mgos_mpu9250 *mpu9250 = NULL;
-  struct mgos_barometer *baro = NULL;
+  struct mgos_ina3221 *ina3221 = NULL;
+  struct mgos_ina219 *ina219 = NULL;
+  struct mgos_ina226 *ina226 = NULL;
 
   if (!mgos_i2c_open(I2CBUSNR)) {
     LOG(LL_ERROR, ("Cannot open I2C bus %u", I2CBUSNR));
@@ -195,55 +111,35 @@ int main(int argc, char **argv, char **environ) {
     return -2;
   }
 
-  i2c_scanner(i2c, true);
+  // i2c_scanner(i2c, true);
 
   /*
-   * if (!(sht31 = mgos_sht31_create(i2c, 0x44)))
-   * LOG(LL_ERROR, ("Cannot create SHT31 device"));
-   * if (!(si7021 = mgos_si7021_create(i2c, 0x40)))
-   * LOG(LL_ERROR, ("Cannot create SI7021 device"));
-   * if (!(htu21df = mgos_htu21df_create(i2c, 0x40)))
-   * LOG(LL_ERROR, ("Cannot create HTU21DF device"));
-   * if (!(mcp9808 = mgos_mcp9808_create(i2c, 0x18)))
-   * LOG(LL_ERROR, ("Cannot create MCP9808 device"));
-   * if (!(ccs811 = mgos_ccs811_create(i2c, 0x5A)))
-   * LOG(LL_ERROR, ("Cannot create CCS811 device"));
-   */
-
-
-  if (!(mpu9250 = mgos_mpu9250_create(i2c, 0x68))) {
-    LOG(LL_ERROR, ("Cannot create MPU9250 device"));
-  } else {
-    mgos_mpu9250_set_accelerometer_range(mpu9250, RANGE_2G);
-    mgos_mpu9250_set_gyroscope_range(mpu9250, RANGE_GYRO_250);
-    mgos_mpu9250_set_magnetometer_scale(mpu9250, SCALE_14_BITS);
-    mgos_mpu9250_set_magnetometer_speed(mpu9250, MAG_100_HZ);
+  if (!(ina3221 = mgos_ina3221_create(i2c, 0x40))) {
+    LOG(LL_ERROR, ("Cannot create INA3221 device"));
+    return -3;
   }
-
-  if (!(baro=mgos_barometer_create_i2c(i2c, 0x76, BARO_BME280))) {
-    LOG(LL_ERROR, ("Cannot create barometer"));
-  } else {
-    mgos_barometer_set_cache_ttl(baro, 1000);
+  */
+  if (!(ina219 = mgos_ina219_create(i2c, 0x40))) {
+    LOG(LL_ERROR, ("Cannot create INA219 device"));
+    return -3;
   }
+  /*
+  if (!(ina226 = mgos_ina226_create(i2c, 0x40))) {
+    LOG(LL_ERROR, ("Cannot create INA226 device"));
+    return -3;
+  }
+  */
 
   for (;;) {
-    do_sht31(sht31);
-    do_si7021(si7021);
-    do_htu21df(htu21df);
-    do_mcp9808(mcp9808);
-    do_ccs811(ccs811);
-    do_mpu9250(mpu9250);
-    do_baro(baro);
+    do_ina3221(ina3221);
+    do_ina219(ina219);
+    do_ina226(ina226);
     sleep(1);
   }
 
-  mgos_sht31_destroy(&sht31);
-  mgos_si7021_destroy(&si7021);
-  mgos_htu21df_destroy(&htu21df);
-  mgos_mcp9808_destroy(&mcp9808);
-  mgos_ccs811_destroy(&ccs811);
-  mgos_mpu9250_destroy(&mpu9250);
-  mgos_barometer_destroy(&baro);
+  mgos_ina3221_destroy(&ina3221);
+  mgos_ina219_destroy(&ina219);
+  mgos_ina226_destroy(&ina226);
 
   return 0;
   (void)argc;
diff --git a/src/mgos_ccs811.c b/src/mgos_ccs811.c
deleted file mode 100644
index fa2fcfa..0000000
--- a/src/mgos_ccs811.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mgos.h"
-#include "mgos_ccs811_internal.h"
-#include "mgos_i2c.h"
-
-// Datasheet:
-// https://cdn-shop.adafruit.com/product-files/2857/Sensirion_Humidity_SHT3x_Datasheet_digital-767294.pdf
-
-// Private functions follow
-static bool mgos_ccs811_getStatus(struct mgos_ccs811 *sensor, uint8_t *status) {
-  int ret;
-
-  if (!sensor) {
-    return false;
-  }
-  ret = mgos_i2c_read_reg_b(sensor->i2c, sensor->i2caddr, MGOS_CCS811_REG_STATUS);
-  if (ret < 0) {
-    return false;
-  }
-  *status = (uint8_t)ret;
-  return true;
-}
-
-static bool mgos_ccs811_getMeasMode(struct mgos_ccs811 *sensor, uint8_t *meas_mode) {
-  int ret;
-
-  if (!sensor) {
-    return false;
-  }
-  ret = mgos_i2c_read_reg_b(sensor->i2c, sensor->i2caddr, MGOS_CCS811_REG_MEAS_MODE);
-  if (ret < 0) {
-    return false;
-  }
-  *meas_mode = (uint8_t)ret;
-  return true;
-}
-
-// Return true if sensor status register has error-bit set (or upon read failure)
-
-/*
- * static bool mgos_ccs811_error(struct mgos_ccs811 *sensor) {
- * uint8_t status;
- *
- * if (!mgos_ccs811_getStatus(sensor, &status))
- *  return true;
- * // bits -- 7:FW_MODE 6:APP_ERASE 5:APP_VERIFY 4:APP_VALID 3:DATA_READY 0:ERROR
- * return (status & MGOS_CCS811_STATUS_ERR);
- * }
- */
-
-// Return true if sensor status register has data-ready set (false upon read failure)
-static bool mgos_ccs811_dataready(struct mgos_ccs811 *sensor) {
-  uint8_t status;
-
-  if (!mgos_ccs811_getStatus(sensor, &status)) {
-    return false;
-  }
-  return status & MGOS_CCS811_STATUS_DATA_READY;
-}
-
-static bool mgos_ccs811_reset(struct mgos_ccs811 *sensor) {
-  uint8_t data[5] = { MGOS_CCS811_REG_SW_RESET, 0x11, 0xE5, 0x72, 0x8A };
-
-  if (!sensor) {
-    return false;
-  }
-  return mgos_i2c_write(sensor->i2c, sensor->i2caddr, data, 5, true);
-}
-
-// Private functions end
-
-// Public functions follow
-struct mgos_ccs811 *mgos_ccs811_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  struct mgos_ccs811 *sensor;
-  int success = 0;
-  int ret;
-
-  if (!i2c) {
-    return NULL;
-  }
-
-  ret = mgos_i2c_read_reg_b(i2c, i2caddr, MGOS_CCS811_REG_HW_ID);
-  if (ret != MGOS_CCS811_HW_ID_CODE) {
-    LOG(LL_ERROR, ("Failed to detect CCS811 at I2C 0x%02x", i2caddr));
-    return NULL;
-  }
-
-  sensor = calloc(1, sizeof(struct mgos_ccs811));
-  if (!sensor) {
-    return NULL;
-  }
-
-  memset(sensor, 0, sizeof(struct mgos_ccs811));
-  sensor->i2caddr = i2caddr;
-  sensor->i2c     = i2c;
-  sensor->eco2    = 400;
-
-  // Boot the application on CCS811.
-  mgos_ccs811_reset(sensor);
-  mgos_usleep(2000);
-
-  uint8_t cmd        = MGOS_CCS811_BOOTLOADER_REG_APP_START;
-  uint8_t status     = MGOS_CCS811_STATUS_ERR;
-  uint8_t drive_mode = CCS811_DRIVE_MODE_IDLE;
-  mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, true);
-  mgos_usleep(2000);
-
-  // Read status (expecting FW_MODE to be set and ERR to be clear)
-  mgos_ccs811_getStatus(sensor, &status);
-  if (!(status & MGOS_CCS811_STATUS_FW_MODE) || (status & MGOS_CCS811_STATUS_ERR)) {
-    LOG(LL_ERROR, ("CCS811 invalid firmware mode, and/or status error"));
-    goto exit;
-  }
-
-  mgos_ccs811_setDriveMode(sensor, CCS811_DRIVE_MODE_1SEC);
-  mgos_ccs811_getDriveMode(sensor, &drive_mode);
-  if (drive_mode != CCS811_DRIVE_MODE_1SEC) {
-    LOG(LL_ERROR, ("CCS811 failed to set drive mode"));
-    goto exit;
-  }
-
-  success = 1;
-  LOG(LL_INFO, ("CCS811 created at I2C 0x%02x", i2caddr));
-exit:
-  if (!success) {
-    free(sensor);
-    sensor = NULL;
-  }
-  return sensor;
-}
-
-bool mgos_ccs811_getDriveMode(struct mgos_ccs811 *sensor, uint8_t *mode) {
-  uint8_t meas_mode;
-
-  if (!mgos_ccs811_getMeasMode(sensor, &meas_mode)) {
-    return false;
-  }
-  // bits -- 6:4 DRIVE_MOCE 3: Interrupt enable 2: Int on Threshhold
-  meas_mode >>= 4;
-  meas_mode  &= 0x07;
-  *mode       = meas_mode;
-
-  return true;
-}
-
-bool mgos_ccs811_setDriveMode(struct mgos_ccs811 *sensor, enum mgos_ccs811_drive_mode_t mode) {
-  uint8_t meas_mode;
-
-  // bits -- 6:4 DRIVE_MOCE 3: Interrupt enable 2: Int on Threshhold
-  meas_mode = (mode << 4);
-  return mgos_i2c_write_reg_b(sensor->i2c, sensor->i2caddr, MGOS_CCS811_REG_MEAS_MODE, meas_mode);
-}
-
-void mgos_ccs811_destroy(struct mgos_ccs811 **sensor) {
-  if (!*sensor) {
-    return;
-  }
-  free(*sensor);
-  *sensor = NULL;
-  return;
-}
-
-bool mgos_ccs811_read(struct mgos_ccs811 *sensor) {
-  double start = mg_time();
-
-  if (!sensor || !sensor->i2c) {
-    return false;
-  }
-
-  sensor->stats.read++;
-
-  if (start - sensor->stats.last_read_time < MGOS_CCS811_READ_DELAY) {
-    sensor->stats.read_success_cached++;
-    return true;
-  }
-  // Read out sensor data here
-  //
-  if (!mgos_ccs811_dataready(sensor)) {
-    sensor->stats.read_success_cached++;
-    return true;
-  }
-
-  uint8_t data[8];
-  uint8_t cmd = MGOS_CCS811_REG_ALG_RESULT_DATA;
-
-  data[4] = MGOS_CCS811_STATUS_ERR;
-  mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, false);
-  mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 8, true);
-
-  // bytes 0-1:eco2 2-3:tvoc 4:status 5:error 6-7: raw_data
-  if (data[4] & MGOS_CCS811_STATUS_ERR) {
-    LOG(LL_ERROR, ("Read error 0x%02x", data[5]));
-    return false;
-  }
-  sensor->eco2 = ((uint16_t)data[0] << 8) | ((uint16_t)data[1]);
-  sensor->tvoc = ((uint16_t)data[2] << 8) | ((uint16_t)data[3]);
-  LOG(LL_DEBUG, ("eCO2=%u TVOC=%u", sensor->eco2, sensor->tvoc));
-
-  sensor->stats.read_success++;
-  sensor->stats.read_success_usecs += 1000000 * (mg_time() - start);
-  sensor->stats.last_read_time      = start;
-  return true;
-}
-
-float mgos_ccs811_get_eco2(struct mgos_ccs811 *sensor) {
-  if (!mgos_ccs811_read(sensor)) {
-    return NAN;
-  }
-  return (float)sensor->eco2;
-}
-
-float mgos_ccs811_get_tvoc(struct mgos_ccs811 *sensor) {
-  if (!mgos_ccs811_read(sensor)) {
-    return NAN;
-  }
-  return (float)sensor->tvoc;
-}
-
-bool mgos_ccs811_i2c_init(void) {
-  return true;
-}
-
-// Public functions end
diff --git a/src/mgos_ccs811_internal.h b/src/mgos_ccs811_internal.h
deleted file mode 100644
index 27ee1fa..0000000
--- a/src/mgos_ccs811_internal.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mgos.h"
-#include "mgos_i2c.h"
-#include "mgos_ccs811.h"
-#include <math.h>
-
-#define MGOS_SHT31_DEFAULT_I2CADDR               (0x5A)
-
-// Registers
-#define MGOS_CCS811_REG_STATUS                   (0x00)
-#define MGOS_CCS811_REG_MEAS_MODE                (0x01)
-#define MGOS_CCS811_REG_ALG_RESULT_DATA          (0x02)
-#define MGOS_CCS811_REG_RAW_DATA                 (0x03)
-#define MGOS_CCS811_REG_ENV_DATA                 (0x05)
-#define MGOS_CCS811_REG_NTC                      (0x06)
-#define MGOS_CCS811_REG_THRESHOLDS               (0x10)
-#define MGOS_CCS811_REG_BASELINE                 (0x11)
-#define MGOS_CCS811_REG_HW_ID                    (0x20)
-#define MGOS_CCS811_REG_HW_VERSION               (0x21)
-#define MGOS_CCS811_REG_FW_BOOT_VERSION          (0x23)
-#define MGOS_CCS811_REG_FW_APP_VERSION           (0x24)
-#define MGOS_CCS811_REG_ERROR_ID                 (0xE0)
-#define MGOS_CCS811_REG_SW_RESET                 (0xFF)
-
-// Bootloader registers
-#define MGOS_CCS811_BOOTLOADER_REG_APP_ERASE     (0xF1)
-#define MGOS_CCS811_BOOTLOADER_REG_APP_DATA      (0xF2)
-#define MGOS_CCS811_BOOTLOADER_REG_APP_VERIFY    (0xF3)
-#define MGOS_CCS811_BOOTLOADER_REG_APP_START     (0xF4)
-
-// Status register bits
-#define MGOS_CCS811_STATUS_ERR                   (0x01)
-#define MGOS_CCS811_STATUS_DATA_READY            (0x08)
-#define MGOS_CCS811_STATUS_APP_VALID             (0x10)
-#define MGOS_CCS811_STATUS_FW_MODE               (0x80)
-
-// Other defines
-#define MGOS_CCS811_HW_ID_CODE                   (0x81)
-#define MGOS_CCS811_REF_RESISTOR                 (100000)
-
-#ifdef __cplusplus
-extern "C" {
-  #endif
-
-struct mgos_ccs811 {
-  struct mgos_i2c *        i2c;
-  uint8_t                  i2caddr;
-  struct mgos_ccs811_stats stats;
-
-  float                    temperature_offset;
-  uint16_t                 tvoc;
-  uint16_t                 eco2;
-};
-
-  #ifdef __cplusplus
-}
-#endif
diff --git a/src/mgos_htu21df.c b/src/mgos_htu21df.c
deleted file mode 100644
index d2849cf..0000000
--- a/src/mgos_htu21df.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mgos.h"
-#include "mgos_htu21df_internal.h"
-#include "mgos_i2c.h"
-
-// Datasheet:
-// https://cdn-shop.adafruit.com/datasheets/1899_HTU21D.pdf
-
-// Private functions follow
-static bool mgos_htu21df_cmd(struct mgos_htu21df *sensor, uint8_t cmd) {
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  if (!mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, true)) {
-    LOG(LL_ERROR, ("I2C=0x%02x cmd=%u (0x%02x) write error", sensor->i2caddr, cmd, cmd));
-    return false;
-  }
-  LOG(LL_DEBUG, ("I2C=0x%02x cmd=%u (0x%02x) write success", sensor->i2caddr, cmd, cmd));
-  return true;
-}
-
-
-static uint8_t crc8(const uint8_t *data, int len) {
-  const uint8_t poly=0x31;
-  uint8_t crc=0x00;
-
-  for (int j=len; j; --j) {
-    crc^=*data++;
-    for (int i=8; i; --i)
-      crc=(crc & 0x80) ? (crc << 1) ^ poly : (crc << 1);
-  }
-  return crc;
-}
-
-
-// Private functions end
-
-// Public functions follow
-struct mgos_htu21df *mgos_htu21df_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  struct mgos_htu21df *sensor;
-  uint8_t version;
-
-  if (!i2c) return NULL;
-
-  sensor=calloc(1, sizeof(struct mgos_htu21df));
-  if (!sensor) return NULL;
-  sensor->i2caddr=i2caddr;
-  sensor->i2c=i2c;
-  sensor->last_read_time=0;
-
-  mgos_htu21df_cmd(sensor, MGOS_HTU21DF_RESET);
-  mgos_usleep(25000);
-
-  mgos_htu21df_cmd(sensor, MGOS_HTU21DF_READREG);
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, &version, 1, false)) {
-    LOG(LL_ERROR, ("Could not read command"));
-    free(sensor);
-    return NULL;
-  }
-  if (version == 0x02) {
-    LOG(LL_INFO, ("HTU21DF created at I2C 0x%02x", i2caddr));
-    return sensor;
-  }
-
-  LOG(LL_ERROR, ("Failed to create HTU21DF at I2C 0x%02x", i2caddr));
-  free(sensor);
-  return NULL;
-}
-
-
-void mgos_htu21df_destroy(struct mgos_htu21df **sensor) {
-  if (!*sensor) return;
-  free (*sensor);
-  *sensor=NULL;
-  return;
-}
-
-
-bool mgos_htu21df_read(struct mgos_htu21df *sensor) {
-  double now = mg_time();
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  if (now - sensor->last_read_time < MGOS_HTU21DF_READ_DELAY) {
-    return true;
-  }
-  // Read out sensor data here
-  //
-  uint8_t data[3];
-
-  mgos_htu21df_cmd(sensor, MGOS_HTU21DF_READTEMP);
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, false)) {
-    LOG(LL_ERROR, ("Could not read command"));
-    return false;
-  }
-  if (data[2] != crc8(data, 2)) {
-    LOG(LL_ERROR, ("CRC error on temperature data"));
-    return false;
-  }
-
-  uint16_t temp = (data[0]<<8)+data[1];
-  float temperature = temp;
-  temperature *= 175.72;
-  temperature /= 65536;
-  temperature -= 46.85;
-  sensor->temperature=temperature;
-
-  mgos_htu21df_cmd(sensor, MGOS_HTU21DF_READHUM);
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, false)) {
-    LOG(LL_ERROR, ("Could not read command"));
-    return false;
-  }
-  if (data[2] != crc8(data, 2)) {
-    LOG(LL_ERROR, ("CRC error on temperature data"));
-    return false;
-  }
-
-  uint16_t hum = (data[0]<<8)+data[1];
-  float humidity = hum;
-  humidity *= 125;
-  humidity /= 65536;
-  humidity -= 6;
-  sensor->humidity=humidity;
-
-  LOG(LL_DEBUG, ("temperature=%.2fC humidity=%.1f%%", sensor->temperature, sensor->humidity));
-  sensor->last_read_time=now;
-  return true;
-}
-
-
-float mgos_htu21df_getTemperature(struct mgos_htu21df *sensor) {
-  if (!mgos_htu21df_read(sensor)) return NAN;
-
-  return sensor->temperature;
-}
-
-
-float mgos_htu21df_getHumidity(struct mgos_htu21df *sensor) {
-  if (!mgos_htu21df_read(sensor)) return NAN;
-
-  return sensor->humidity;
-}
-
-
-bool mgos_htu21df_i2c_init(void) {
-  return true;
-}
-
-
-// Public functions end
diff --git a/src/mgos_htu21df_internal.h b/src/mgos_htu21df_internal.h
deleted file mode 100644
index f5f08d2..0000000
--- a/src/mgos_htu21df_internal.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mgos.h"
-#include "mgos_i2c.h"
-#include "mgos_htu21df.h"
-#include <math.h>
-
-#define MGOS_HTU21DF_DEFAULT_I2CADDR       (0x40)
-
-#define MGOS_HTU21DF_READTEMP              (0xE3)
-#define MGOS_HTU21DF_READHUM               (0xE5)
-#define MGOS_HTU21DF_WRITEREG              (0xE6)
-#define MGOS_HTU21DF_READREG               (0xE7)
-#define MGOS_HTU21DF_RESET                 (0xFE)
-
-#ifdef __cplusplus
-extern "C" {
-  #endif
-
-  struct mgos_htu21df
-  {
-    struct mgos_i2c *i2c;
-    uint8_t i2caddr;
-    double last_read_time;
-
-    float humidity, temperature;
-  };
-
-  #ifdef __cplusplus
-}
-#endif
diff --git a/src/mgos_mcp9808.c b/src/mgos_mcp9808.c
deleted file mode 100644
index 3f1963a..0000000
--- a/src/mgos_mcp9808.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mgos.h"
-#include "mgos_mcp9808_internal.h"
-#include "mgos_i2c.h"
-
-// Datasheet:
-// https://cdn-shop.adafruit.com/datasheets/MCP9808.pdf
-
-// Private functions follow
-static bool is_mcp9808(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  uint16_t manufacturer_id, device_id;
-
-  manufacturer_id=mgos_i2c_read_reg_w(i2c, i2caddr, MGOS_MCP9808_REG_MANUF_ID);
-  device_id=mgos_i2c_read_reg_w(i2c, i2caddr, MGOS_MCP9808_REG_DEVICE_ID);
-
-  return ((manufacturer_id == 0x0054) && (device_id == 0x0400));
-}
-
-
-static void mgos_mcp9808_reset(struct mgos_mcp9808 *sensor) {
-  if (!sensor) return;
-  mgos_i2c_write_reg_w(sensor->i2c, sensor->i2caddr, MGOS_MCP9808_REG_CONFIG, 0x0);
-}
-
-
-// Private functions end
-
-// Public functions follow
-struct mgos_mcp9808 *mgos_mcp9808_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  struct mgos_mcp9808 *sensor;
-
-  if (!i2c) return NULL;
-
-  if (!is_mcp9808(i2c, i2caddr)) {
-    LOG(LL_ERROR, ("Failed to create MCP9808 at I2C 0x%02x", i2caddr));
-    return NULL;
-  }
-
-  sensor=calloc(1, sizeof(struct mgos_mcp9808));
-  if (!sensor) return NULL;
-  sensor->i2caddr=i2caddr;
-  sensor->i2c=i2c;
-  sensor->last_read_time=0;
-
-  mgos_mcp9808_reset(sensor);
-
-  LOG(LL_INFO, ("MCP9808 created at I2C 0x%02x", i2caddr));
-  return sensor;
-}
-
-
-void mgos_mcp9808_destroy(struct mgos_mcp9808 **sensor) {
-  if (!*sensor) return;
-  free (*sensor);
-  *sensor=NULL;
-  return;
-}
-
-
-bool mgos_mcp9808_read(struct mgos_mcp9808 *sensor) {
-  double now = mg_time();
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  if (now - sensor->last_read_time < MGOS_MCP9808_READ_DELAY) {
-    return true;
-  }
-  // Read out sensor data here
-  //
-  uint16_t temp_reg = mgos_i2c_read_reg_w(sensor->i2c, sensor->i2caddr, MGOS_MCP9808_REG_AMBIENT_TEMP);
-
-  float temperature = temp_reg & 0x0FFF;
-  temperature /= 16.0;
-  if (temp_reg & 0x1000) temperature -= 256;
-  sensor->temperature=temperature;
-
-  LOG(LL_DEBUG, ("temperature=%.2fC", sensor->temperature));
-  sensor->last_read_time=now;
-  return true;
-}
-
-
-float mgos_mcp9808_getTemperature(struct mgos_mcp9808 *sensor) {
-  if (!mgos_mcp9808_read(sensor)) return NAN;
-
-  return sensor->temperature;
-}
-
-
-void mgos_mcp9808_enable(struct mgos_mcp9808 *sensor, bool enable) {
-  uint16_t conf_reg = mgos_i2c_read_reg_w(sensor->i2c, sensor->i2caddr, MGOS_MCP9808_REG_CONFIG);
-  if (enable)
-    conf_reg &= ~MGOS_MCP9808_REG_CONFIG_SHUTDOWN;
-  else
-    conf_reg |= MGOS_MCP9808_REG_CONFIG_SHUTDOWN;
-  mgos_i2c_write_reg_w(sensor->i2c, sensor->i2caddr, MGOS_MCP9808_REG_CONFIG, conf_reg);
-}
-
-
-bool mgos_mcp9808_i2c_init(void) {
-  return true;
-}
-
-
-// Public functions end
diff --git a/src/mgos_mcp9808_internal.h b/src/mgos_mcp9808_internal.h
deleted file mode 100644
index 4a7b67d..0000000
--- a/src/mgos_mcp9808_internal.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mgos.h"
-#include "mgos_i2c.h"
-#include "mgos_mcp9808.h"
-#include <math.h>
-
-#define MGOS_MCP9808_DEFAULT_I2CADDR       (0x18)
-
-#define MGOS_MCP9808_REG_CONFIG            (0x01)
-#define MGOS_MCP9808_REG_CONFIG_SHUTDOWN   (0x0100)
-#define MGOS_MCP9808_REG_CONFIG_CRITLOCKED (0x0080)
-#define MGOS_MCP9808_REG_CONFIG_WINLOCKED  (0x0040)
-#define MGOS_MCP9808_REG_CONFIG_INTCLR     (0x0020)
-#define MGOS_MCP9808_REG_CONFIG_ALERTSTAT  (0x0010)
-#define MGOS_MCP9808_REG_CONFIG_ALERTCTRL  (0x0008)
-#define MGOS_MCP9808_REG_CONFIG_ALERTSEL   (0x0004)
-#define MGOS_MCP9808_REG_CONFIG_ALERTPOL   (0x0002)
-#define MGOS_MCP9808_REG_CONFIG_ALERTMODE  (0x0001)
-
-#define MGOS_MCP9808_REG_UPPER_TEMP        (0x02)
-#define MGOS_MCP9808_REG_LOWER_TEMP        (0x03)
-#define MGOS_MCP9808_REG_CRIT_TEMP         (0x04)
-#define MGOS_MCP9808_REG_AMBIENT_TEMP      (0x05)
-#define MGOS_MCP9808_REG_MANUF_ID          (0x06)
-#define MGOS_MCP9808_REG_DEVICE_ID         (0x07)
-
-#ifdef __cplusplus
-extern "C" {
-  #endif
-
-  struct mgos_mcp9808
-  {
-    struct mgos_i2c *i2c;
-    uint8_t i2caddr;
-    double last_read_time;
-
-    float temperature;
-  };
-
-  #ifdef __cplusplus
-}
-#endif
diff --git a/src/mgos_mpu9250.c b/src/mgos_mpu9250.c
deleted file mode 100644
index 571c065..0000000
--- a/src/mgos_mpu9250.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mgos.h"
-#include "mgos_mpu9250_internal.h"
-#include "mgos_i2c.h"
-
-// Datasheet:
-//
-
-// Private functions follow
-static bool mgos_mpu9250_ak8963_init(struct mgos_mpu9250 *imu, uint8_t i2caddr) {
-  int device_id;
-
-  if (!imu) {
-    return false;
-  }
-
-  imu->i2caddr_ak8963 = i2caddr;
-
-  device_id = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_WHO_AM_I);
-  if (device_id != MGOS_MPU9250_DEVID_AK8963) {
-    return false;
-  }
-  LOG(LL_INFO, ("Detected AK8963 at I2C 0x%02x", i2caddr));
-
-  mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL, 0x00);
-  mgos_usleep(10000);
-
-  mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL, 0x0F);
-  mgos_usleep(10000);
-
-  uint8_t data[3];
-  if (!mgos_i2c_read_reg_n(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_ASAX, 3, data)) {
-    LOG(LL_ERROR, ("Could not read magnetometer adjustment registers"));
-    return false;
-  }
-  imu->mag_adj[0] = (float)(data[0] - 128) / 256. + 1.;
-  imu->mag_adj[1] = (float)(data[1] - 128) / 256. + 1.;
-  imu->mag_adj[2] = (float)(data[2] - 128) / 256. + 1.;
-  LOG(LL_DEBUG, ("magnetometer adjustment %.2f %.2f %.2f", imu->mag_adj[0], imu->mag_adj[1], imu->mag_adj[2]));
-
-  mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL, 0x00);
-  mgos_usleep(10000);
-
-  // Set magnetometer data resolution and sample ODR
-  mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL, 0x16);
-  mgos_usleep(10000);
-
-  return true;
-}
-
-// Private functions end
-
-// Public functions follow
-struct mgos_mpu9250 *mgos_mpu9250_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  struct mgos_mpu9250 *imu;
-  int device_id;
-
-  if (!i2c) {
-    return NULL;
-  }
-
-  imu = calloc(1, sizeof(struct mgos_mpu9250));
-  if (!imu) {
-    return NULL;
-  }
-  imu->i2caddr = i2caddr;
-  imu->i2c     = i2c;
-
-  device_id = mgos_i2c_read_reg_b(i2c, i2caddr, MGOS_MPU9250_REG_WHO_AM_I);
-  switch (device_id) {
-  case MGOS_MPU9250_DEVID_9250:
-    LOG(LL_INFO, ("Detected MPU9250 at I2C 0x%02x", i2caddr));
-    break;
-
-  case MGOS_MPU9250_DEVID_9255:
-    LOG(LL_INFO, ("Detected MPU9255 at I2C 0x%02x", i2caddr));
-    break;
-
-  default:
-    LOG(LL_ERROR, ("Failed to detect MPU9250 at I2C 0x%02x (device_id=0x%02x)", i2caddr, device_id));
-    free(imu);
-    return NULL;
-  }
-
-  // Reset
-  mgos_i2c_write_reg_b(i2c, i2caddr, MGOS_MPU9250_REG_PWR_MGMT_1, 0x80);
-  mgos_usleep(100000);
-
-  // Enable imus
-  mgos_i2c_write_reg_b(i2c, i2caddr, MGOS_MPU9250_REG_PWR_MGMT_2, 0x00);
-
-  // Magnetometer enable
-  mgos_i2c_write_reg_b(i2c, i2caddr, MGOS_MPU9250_REG_INT_PIN_CFG, 0x02);
-
-  // TODO(pim): is the mag always on 0x0C ?
-  if (false == (imu->mag_enabled = mgos_mpu9250_ak8963_init(imu, MGOS_AK8963_DEFAULT_I2CADDR))) {
-    LOG(LL_ERROR, ("Could not detect/initialize AK8963 magnetometer, disabling"));
-  }
-
-  return imu;
-}
-
-void mgos_mpu9250_destroy(struct mgos_mpu9250 **imu) {
-  if (!*imu) {
-    return;
-  }
-  free(*imu);
-  *imu = NULL;
-  return;
-}
-
-bool mgos_mpu9250_set_accelerometer_range(struct mgos_mpu9250 *imu, enum mgos_mpu9250_accelerometer_range range) {
-  int val;
-
-  if (!imu) {
-    return false;
-  }
-
-  if ((val = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_ACCEL_CONFIG)) < 0) {
-    return false;
-  }
-  val &= 0xE7; // 11100111
-  val |= range << 3;
-
-  return mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_ACCEL_CONFIG, val);
-}
-
-bool mgos_mpu9250_get_accelerometer_range(struct mgos_mpu9250 *imu, enum mgos_mpu9250_accelerometer_range *range) {
-  int val;
-
-  if (!imu) {
-    return false;
-  }
-
-  if ((val = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_ACCEL_CONFIG)) < 0) {
-    return false;
-  }
-  val   &= 0x18; // 00011000
-  val  >>= 3;
-  *range = val;
-  return true;
-}
-
-bool mgos_mpu9250_get_accelerometer(struct mgos_mpu9250 *imu, float *x, float *y, float *z) {
-  uint8_t data[6];
-  int16_t ax, ay, az;
-  enum mgos_mpu9250_accelerometer_range acc_range;
-  uint16_t divider;
-
-  if (!imu) {
-    return false;
-  }
-  if (!mgos_mpu9250_get_accelerometer_range(imu, &acc_range)) {
-    return false;
-  }
-  if (!mgos_i2c_read_reg_n(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_ACCEL_XOUT_H, 6, data)) {
-    return false;
-  }
-  ax = (data[0] << 8) | (data[1]);
-  ay = (data[2] << 8) | (data[3]);
-  az = (data[4] << 8) | (data[5]);
-//  LOG(LL_DEBUG, ("ax=%d ay=%d az=%d", ax, ay, az));
-
-  switch (acc_range) {
-  case RANGE_16G: divider = 2048; break;
-
-  case RANGE_8G: divider = 4096; break;
-
-  case RANGE_4G: divider = 8192; break;
-
-  case RANGE_2G: divider = 16384; break;
-
-  default: return false;
-  }
-  *x = (float)ax / divider;
-  *y = (float)ay / divider;
-  *z = (float)az / divider;
-
-  return true;
-}
-
-bool mgos_mpu9250_set_gyroscope_range(struct mgos_mpu9250 *imu, enum mgos_mpu9250_gyroscope_range range) {
-  int val;
-
-  if (!imu) {
-    return false;
-  }
-
-  if ((val = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_GYRO_CONFIG)) < 0) {
-    return false;
-  }
-  val &= 0xE7; // 11100111
-  val |= range << 3;
-
-  return mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_GYRO_CONFIG, val);
-}
-
-bool mgos_mpu9250_get_gyroscope_range(struct mgos_mpu9250 *imu, enum mgos_mpu9250_gyroscope_range *range) {
-  int val;
-
-  if (!imu) {
-    return false;
-  }
-
-  if ((val = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_GYRO_CONFIG)) < 0) {
-    return false;
-  }
-  val   &= 0x18; // 00011000
-  val  >>= 3;
-  *range = val;
-  return true;
-}
-
-bool mgos_mpu9250_get_gyroscope(struct mgos_mpu9250 *imu, float *x, float *y, float *z) {
-  uint8_t data[6];
-  int16_t gx, gy, gz;
-  enum mgos_mpu9250_gyroscope_range gyr_range;
-  float divider;
-
-  if (!imu) {
-    return false;
-  }
-  if (!mgos_mpu9250_get_gyroscope_range(imu, &gyr_range)) {
-    return false;
-  }
-  if (!mgos_i2c_read_reg_n(imu->i2c, imu->i2caddr, MGOS_MPU9250_REG_GYRO_XOUT_H, 6, data)) {
-    return false;
-  }
-  gx = (data[0] << 8) | (data[1]);
-  gy = (data[2] << 8) | (data[3]);
-  gz = (data[4] << 8) | (data[5]);
-//  LOG(LL_DEBUG, ("gx=%d gy=%d gz=%d", gx, gy, gz));
-
-  switch (gyr_range) {
-  case RANGE_GYRO_2000: divider = 16.4; break;
-
-  case RANGE_GYRO_1000: divider = 32.8; break;
-
-  case RANGE_GYRO_500: divider = 65.5; break;
-
-  case RANGE_GYRO_250: divider = 131.0; break;
-
-  default: return false;
-  }
-  *x = (float)gx / divider;
-  *y = (float)gy / divider;
-  *z = (float)gz / divider;
-  return true;
-}
-
-bool mgos_mpu9250_set_magnetometer_scale(struct mgos_mpu9250 *imu, enum mgos_mpu9250_magnetometer_scale scale) {
-  int val;
-
-  if (!imu || !imu->mag_enabled) {
-    return false;
-  }
-
-  if ((val = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL)) < 0) {
-    return false;
-  }
-  val &= 0x06;
-  mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL, 0x00);
-  mgos_usleep(10000);
-
-  mgos_i2c_write_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL, (scale << 4) | val);
-  mgos_usleep(10000);
-
-  return true;
-}
-
-bool mgos_mpu9250_get_magnetometer_scale(struct mgos_mpu9250 *imu, enum mgos_mpu9250_magnetometer_scale *scale) {
-  int val;
-
-  if (!imu || !imu->mag_enabled) {
-    return false;
-  }
-  if ((val = mgos_i2c_read_reg_b(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_CNTL)) < 0) {
-    return false;
-  }
-  *scale = (val >> 4) & 0x01;
-  return true;
-}
-
-bool mgos_mpu9250_set_magnetometer_speed(struct mgos_mpu9250 *imu, enum mgos_mpu9250_magnetometer_speed speed) {
-  if (!imu || !imu->mag_enabled) {
-    return false;
-  }
-  return false;
-  (void) speed;
-}
-
-bool mgos_mpu9250_get_magnetometer_speed(struct mgos_mpu9250 *imu, enum mgos_mpu9250_magnetometer_speed *speed) {
-  if (!imu || !imu->mag_enabled) {
-    return false;
-  }
-  return false;
-  (void) speed;
-}
-
-bool mgos_mpu9250_get_magnetometer(struct mgos_mpu9250 *imu, float *x, float *y, float *z) {
-  uint8_t data[7];
-  int16_t mx, my, mz;
-  enum mgos_mpu9250_magnetometer_scale mag_scale;
-  float divider;
-
-  if (!imu || !imu->mag_enabled) {
-    return false;
-  }
-  if (!mgos_mpu9250_get_magnetometer_scale(imu, &mag_scale)) {
-    return false;
-  }
-  if (!mgos_i2c_read_reg_n(imu->i2c, imu->i2caddr_ak8963, MGOS_MPU9250_REG_AK8963_XOUT_L, 7, data)) {
-    return false;
-  }
-  if (data[6] & 0x08) {
-    return false;
-  }
-
-  mx = (data[1] << 8) | (data[0]);
-  my = (data[3] << 8) | (data[2]);
-  mz = (data[5] << 8) | (data[4]);
-//  LOG(LL_DEBUG, ("mx=%d my=%d mz=%d", mx, my, mz));
-
-  switch (mag_scale) {
-  case SCALE_14_BITS: divider = 8190.0; break;
-
-  case SCALE_16_BITS: divider = 32760.0; break;
-
-  default: return false;
-  }
-  *x = (float)mx * 4912.0 * imu->mag_adj[0] / divider;
-  *y = (float)my * 4912.0 * imu->mag_adj[1] / divider;
-  *z = (float)mz * 4912.0 * imu->mag_adj[2] / divider;
-  return true;
-}
-
-bool mgos_mpu9250_i2c_init(void) {
-  return true;
-}
-
-// Public functions end
diff --git a/src/mgos_mpu9250_internal.h b/src/mgos_mpu9250_internal.h
deleted file mode 100644
index c53c64d..0000000
--- a/src/mgos_mpu9250_internal.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mgos.h"
-#include "mgos_i2c.h"
-#include "mgos_mpu9250.h"
-#include <math.h>
-
-#define MGOS_MPU9250_DEFAULT_I2CADDR        (0x68)
-#define MGOS_AK8963_DEFAULT_I2CADDR         (0x0C)
-
-#define MGOS_MPU9250_DEVID_9250             (0x71)
-#define MGOS_MPU9250_DEVID_9255             (0x73)
-#define MGOS_MPU9250_DEVID_AK8963           (0x48)
-
-// MPU9250 -- Accelerometer and Gyro registers
-#define MGOS_MPU9250_REG_SMPLRT_DIV         (0x19)
-#define MGOS_MPU9250_REG_CONFIG             (0x1A)
-#define MGOS_MPU9250_REG_GYRO_CONFIG        (0x1B)
-#define MGOS_MPU9250_REG_ACCEL_CONFIG       (0x1C)
-#define MGOS_MPU9250_REG_ACCEL_CONFIG2      (0x1D)
-#define MGOS_MPU9250_REG_INT_PIN_CFG        (0x37)
-#define MGOS_MPU9250_REG_INT_ENABLE         (0x38)
-#define MGOS_MPU9250_REG_INT_STATUS         (0x3A)
-#define MGOS_MPU9250_REG_ACCEL_XOUT_H       (0x3B)
-#define MGOS_MPU9250_REG_TEMP_OUT_H         (0x41)
-#define MGOS_MPU9250_REG_GYRO_XOUT_H        (0x43)
-#define MGOS_MPU9250_REG_PWR_MGMT_1         (0x6B)
-#define MGOS_MPU9250_REG_PWR_MGMT_2         (0x6C)
-#define MGOS_MPU9250_REG_WHO_AM_I           (0x75)
-
-// AK8963 Companion -- Magnetometer Registers
-#define MGOS_MPU9250_REG_AK8963_WHO_AM_I    (0x00)
-#define MGOS_MPU9250_REG_AK8963_ST1         (0x02)
-#define MGOS_MPU9250_REG_AK8963_XOUT_L      (0x03)
-#define MGOS_MPU9250_REG_AK8963_CNTL        (0x0A)
-#define MGOS_MPU9250_REG_AK8963_ASAX        (0x10)
-#define MGOS_MPU9250_REG_AK8963_ASAY        (0x11)
-#define MGOS_MPU9250_REG_AK8963_ASAZ        (0x12)
-
-#ifdef __cplusplus
-extern "C" {
-  #endif
-
-struct mgos_mpu9250 {
-  struct mgos_i2c *i2c;
-  uint8_t          i2caddr;
-  uint8_t          i2caddr_ak8963;
-
-  bool             mag_enabled;
-  float            mag_adj[3];
-};
-
-  #ifdef __cplusplus
-}
-#endif
diff --git a/src/mgos_sht31.c b/src/mgos_sht31.c
deleted file mode 100644
index abdb39e..0000000
--- a/src/mgos_sht31.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mgos.h"
-#include "mgos_sht31_internal.h"
-#include "mgos_i2c.h"
-
-// Datasheet:
-// https://cdn-shop.adafruit.com/product-files/2857/Sensirion_Humidity_SHT3x_Datasheet_digital-767294.pdf
-
-// Private functions follow
-static bool mgos_sht31_cmd(struct mgos_sht31 *sensor, uint16_t cmd) {
-  uint8_t data[2];
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  data[0]=cmd>>8;
-  data[1]=cmd&0xFF;
-  if (!mgos_i2c_write(sensor->i2c, sensor->i2caddr, data, 2, true)) {
-    LOG(LL_ERROR, ("I2C=0x%02x cmd=%u (0x%04x) write error", sensor->i2caddr, cmd, cmd));
-    return false;
-  }
-  LOG(LL_DEBUG, ("I2C=0x%02x cmd=%u (0x%04x) write success", sensor->i2caddr, cmd, cmd));
-
-  return true;
-}
-
-
-static uint8_t crc8(const uint8_t *data, int len) {
-  const uint8_t poly=0x31;
-  uint8_t crc=0xFF;
-
-  for (int j=len; j; --j) {
-    crc^=*data++;
-    for (int i=8; i; --i)
-      crc=(crc & 0x80) ? (crc << 1) ^ poly : (crc << 1);
-  }
-  return crc;
-}
-
-
-static uint16_t mgos_sht31_status(struct mgos_sht31 *sensor) {
-  uint8_t data[3];
-  uint16_t value;
-
-  mgos_sht31_cmd(sensor, MGOS_SHT31_READSTATUS);
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, true))
-    return 0;
-
-  // Check CRC8 checksums
-  if ((data[2]!=crc8(data, 2)))
-    return 0;
-  value=(data[0]<<8) + data[1];
-
-  return value;
-}
-
-
-// Private functions end
-
-// Public functions follow
-struct mgos_sht31 *mgos_sht31_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  struct mgos_sht31 *sensor;
-  uint16_t status0, status1, status2;
-
-  if (!i2c) return NULL;
-
-  sensor=calloc(1, sizeof(struct mgos_sht31));
-  if (!sensor) return NULL;
-  sensor->i2caddr=i2caddr;
-  sensor->i2c=i2c;
-  sensor->last_read_time=0;
-
-  mgos_sht31_cmd(sensor, MGOS_SHT31_SOFTRESET);
-
-  // Toggle heater on and off, which shows up in status register bit 13 (0=Off, 1=On)
-                                 // heater is off, bit13 is 0
-  status0=mgos_sht31_status(sensor);
-  mgos_sht31_cmd(sensor, MGOS_SHT31_HEATEREN);
-                                 // heater is on, bit13 is 1
-  status1=mgos_sht31_status(sensor);
-  mgos_sht31_cmd(sensor, MGOS_SHT31_HEATERDIS);
-                                 // heater is off, bit13 is 0
-  status2=mgos_sht31_status(sensor);
-
-  if (((status0 & 0x2000) == 0) && ((status1 & 0x2000) != 0) && ((status2 & 0x2000) == 0)) {
-    LOG(LL_INFO, ("SHT31 created at I2C 0x%02x", i2caddr));
-    return sensor;
-  }
-
-  LOG(LL_ERROR, ("Failed to create SHT31 at I2C 0x%02x", i2caddr));
-  free(sensor);
-  return NULL;
-}
-
-
-void mgos_sht31_destroy(struct mgos_sht31 **sensor) {
-  if (!*sensor) return;
-  free (*sensor);
-  *sensor=NULL;
-  return;
-}
-
-
-bool mgos_sht31_read(struct mgos_sht31 *sensor) {
-  double now = mg_time();
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  if (now - sensor->last_read_time < MGOS_SHT31_READ_DELAY) {
-    return true;
-  }
-  // Read out sensor data here
-  //
-  uint8_t data[6];
-  float humidity, temperature;
-
-  mgos_sht31_cmd(sensor, MGOS_SHT31_MEAS_HIGHREP);
-
-  mgos_usleep(500);
-
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 6, true))
-    return false;
-
-  // Check CRC8 checksums
-  if ((data[2]!=crc8(data, 2)) || (data[5]!=crc8(data+3, 2)))
-    return false;
-
-  temperature = data[0]*256 + data[1];
-  temperature *= 175;
-  temperature /= 0xffff;
-  temperature -= 45;
-  sensor->temperature = temperature;
-
-  humidity = data[3] * 256 + data[4];
-  humidity *= 100;
-  humidity /= 0xFFFF;
-  sensor->humidity = humidity;
-
-  LOG(LL_DEBUG, ("temperature=%.2fC humidity=%.1f%%", sensor->temperature, sensor->humidity));
-  sensor->last_read_time=now;
-  return true;
-}
-
-
-float mgos_sht31_getTemperature(struct mgos_sht31 *sensor) {
-  if (!mgos_sht31_read(sensor)) return NAN;
-
-  return sensor->temperature;
-}
-
-
-float mgos_sht31_getHumidity(struct mgos_sht31 *sensor) {
-  if (!mgos_sht31_read(sensor)) return NAN;
-
-  return sensor->humidity;
-}
-
-
-bool mgos_sht31_i2c_init(void) {
-  return true;
-}
-
-
-// Public functions end
diff --git a/src/mgos_sht31_internal.h b/src/mgos_sht31_internal.h
deleted file mode 100644
index 46f7570..0000000
--- a/src/mgos_sht31_internal.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mgos.h"
-#include "mgos_i2c.h"
-#include "mgos_sht31.h"
-#include <math.h>
-
-#define MGOS_SHT31_DEFAULT_I2CADDR       (0x44)
-
-#define MGOS_SHT31_MEAS_HIGHREP_STRETCH  (0x2C06)
-#define MGOS_SHT31_MEAS_MEDREP_STRETCH   (0x2C0D)
-#define MGOS_SHT31_MEAS_LOWREP_STRETCH   (0x2C10)
-#define MGOS_SHT31_MEAS_HIGHREP          (0x2400)
-#define MGOS_SHT31_MEAS_MEDREP           (0x240B)
-#define MGOS_SHT31_MEAS_LOWREP           (0x2416)
-#define MGOS_SHT31_READSTATUS            (0xF32D)
-#define MGOS_SHT31_CLEARSTATUS           (0x3041)
-#define MGOS_SHT31_SOFTRESET             (0x30A2)
-#define MGOS_SHT31_HEATEREN              (0x306D)
-#define MGOS_SHT31_HEATERDIS             (0x3066)
-
-#ifdef __cplusplus
-extern "C" {
-  #endif
-
-  struct mgos_sht31
-  {
-    struct mgos_i2c *i2c;
-    uint8_t i2caddr;
-    double last_read_time;
-
-    float humidity, temperature;
-  };
-
-  #ifdef __cplusplus
-}
-#endif
diff --git a/src/mgos_si7021.c b/src/mgos_si7021.c
deleted file mode 100644
index 78d07f3..0000000
--- a/src/mgos_si7021.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mgos.h"
-#include "mgos_si7021_internal.h"
-#include "mgos_i2c.h"
-
-// Datasheet:
-// https://cdn-learn.adafruit.com/assets/assets/000/035/931/original/Support_Documents_TechnicalDocs_Si7021-A20.pdf
-
-// Private functions follow
-static bool mgos_si7021_cmd(struct mgos_si7021 *sensor, uint8_t cmd) {
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  if (!mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, true)) {
-    LOG(LL_ERROR, ("I2C=0x%02x cmd=%u (0x%02x) write error", sensor->i2caddr, cmd, cmd));
-    return false;
-  }
-  LOG(LL_DEBUG, ("I2C=0x%02x cmd=%u (0x%02x) write success", sensor->i2caddr, cmd, cmd));
-  return true;
-}
-
-
-static uint8_t crc8(const uint8_t *data, int len) {
-  const uint8_t poly=0x31;
-  uint8_t crc=0x00;
-
-  for (int j=len; j; --j) {
-    crc^=*data++;
-    for (int i=8; i; --i)
-      crc=(crc & 0x80) ? (crc << 1) ^ poly : (crc << 1);
-  }
-  return crc;
-}
-
-
-// Private functions end
-
-// Public functions follow
-struct mgos_si7021 *mgos_si7021_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
-  struct mgos_si7021 *sensor;
-  int ret;
-
-  if (!i2c) return NULL;
-
-  // Reset and query register
-  ret=mgos_i2c_read_reg_b(i2c, i2caddr, MGOS_SI7021_READRHT_REG_CMD);
-  if (ret!=0x3A) {
-    LOG(LL_ERROR, ("Chip ID register invalid, expected 0x3A got 0x%02x (%d)", ret, ret));
-    return NULL;
-  }
-
-  sensor=calloc(1, sizeof(struct mgos_si7021));
-  if (!sensor) return NULL;
-  sensor->i2caddr=i2caddr;
-  sensor->i2c=i2c;
-  sensor->last_read_time=0;
-
-  LOG(LL_INFO, ("SI7021 created at I2C 0x%02x", i2caddr));
-  return sensor;
-}
-
-
-void mgos_si7021_destroy(struct mgos_si7021 **sensor) {
-  if (!*sensor) return;
-  free (*sensor);
-  *sensor=NULL;
-  return;
-}
-
-
-bool mgos_si7021_read(struct mgos_si7021 *sensor) {
-  double now = mg_time();
-
-  if (!sensor || !sensor->i2c)
-    return false;
-
-  if (now - sensor->last_read_time < MGOS_SI7021_READ_DELAY) {
-    return true;
-  }
-  // Read out sensor data here
-  //
-  uint8_t data[3];
-
-  if (!mgos_si7021_cmd(sensor, MGOS_SI7021_MEASRH_NOHOLD_CMD)) {
-    LOG(LL_ERROR, ("Could not write command"));
-    return false;
-  }
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, false)) {
-    LOG(LL_ERROR, ("Could not read command"));
-    return false;
-  }
-  if (data[2] != crc8(&data[0], 2)) {
-    LOG(LL_ERROR, ("CRC error on humidity data"));
-    return false;
-  }
-
-  uint16_t hum = (data[0]<<8)+data[1];
-  float humidity = hum;
-  humidity *= 125;
-  humidity /= 65536;
-  humidity -= 6;
-  sensor->humidity = humidity;
-
-  if (!mgos_si7021_cmd(sensor, MGOS_SI7021_MEASTEMP_NOHOLD_CMD)) {
-    LOG(LL_ERROR, ("Could not write command"));
-    return false;
-  }
-  if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, false)) {
-    LOG(LL_ERROR, ("Could not read command"));
-    return false;
-  }
-  if (data[2] != crc8(&data[0], 2)) {
-    LOG(LL_ERROR, ("CRC error on temperature data"));
-    return false;
-  }
-
-  uint16_t temp = (data[0]<<8)+data[1];
-  float temperature = temp;
-  temperature *= 175.72;
-  temperature /= 65536;
-  temperature -= 46.85;
-  sensor->temperature = temperature;
-
-  LOG(LL_DEBUG, ("temperature=%.2fC humidity=%.1f%%", sensor->temperature, sensor->humidity));
-  sensor->last_read_time=now;
-  return true;
-}
-
-
-float mgos_si7021_getTemperature(struct mgos_si7021 *sensor) {
-  if (!mgos_si7021_read(sensor)) return NAN;
-
-  return sensor->temperature;
-}
-
-
-float mgos_si7021_getHumidity(struct mgos_si7021 *sensor) {
-  if (!mgos_si7021_read(sensor)) return NAN;
-
-  return sensor->humidity;
-}
-
-
-bool mgos_si7021_i2c_init(void) {
-  return true;
-}
-
-
-// Public functions end
diff --git a/src/mgos_si7021_internal.h b/src/mgos_si7021_internal.h
deleted file mode 100644
index 3237928..0000000
--- a/src/mgos_si7021_internal.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mgos.h"
-#include "mgos_i2c.h"
-#include "mgos_si7021.h"
-#include <math.h>
-
-#define MGOS_SI7021_DEFAULT_I2CADDR       (0x40)
-
-#define MGOS_SI7021_MEASRH_HOLD_CMD       (0xE5)
-#define MGOS_SI7021_MEASRH_NOHOLD_CMD     (0xF5)
-#define MGOS_SI7021_MEASTEMP_HOLD_CMD     (0xE3)
-#define MGOS_SI7021_MEASTEMP_NOHOLD_CMD   (0xF3)
-#define MGOS_SI7021_READPREVTEMP_CMD      (0xE0)
-#define MGOS_SI7021_RESET_CMD             (0xFE)
-#define MGOS_SI7021_WRITERHT_REG_CMD      (0xE6)
-#define MGOS_SI7021_READRHT_REG_CMD       (0xE7)
-#define MGOS_SI7021_WRITEHEATER_REG_CMD   (0x51)
-#define MGOS_SI7021_READHEATER_REG_CMD    (0x11)
-#define MGOS_SI7021_ID1_CMD               (0xFA0F)
-#define MGOS_SI7021_ID2_CMD               (0xFCC9)
-#define MGOS_SI7021_FIRMVERS_CMD          (0x84B8)
-
-#ifdef __cplusplus
-extern "C" {
-  #endif
-
-  struct mgos_si7021
-  {
-    struct mgos_i2c *i2c;
-    uint8_t i2caddr;
-    double last_read_time;
-
-    float humidity, temperature;
-  };
-
-  #ifdef __cplusplus
-}
-#endif