From 1db8c1a0bf94d2ea045ef8e50ae1341efe8df8c6 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Thu, 3 Jan 2019 20:12:04 +0100 Subject: [PATCH] Refactor framework -- point to a tests/* directory for the user supplied tests --- Makefile | 4 +- README.md | 24 +++ include/mgos_gpio.h | 162 ++++++++++++++++ include/mgos_mock.h | 2 + src/main.c | 190 +------------------ 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_mock.c | 30 +++ 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 ------ 18 files changed, 222 insertions(+), 1776 deletions(-) create mode 100644 README.md create mode 100644 include/mgos_gpio.h 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/Makefile b/Makefile index 0836053..a4a1f8b 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,8 @@ OBJDIR = build LIBDIR = libs BINDIR = . -SRCS := $(shell find -L $(SRCDIR) $(LIBDIR) -type f -name '*.c') -INCS := $(shell find -L $(SRCDIR) $(LIBDIR) $(INCDIR) -type d -name 'include') +SRCS := $(shell find -L $(SRCDIR) $(LIBDIR) -type f -name '*.c' | egrep -v 'deps/|build/' ) +INCS := $(shell find -L $(SRCDIR) $(LIBDIR) $(INCDIR) -type d -name 'include'| egrep -v 'deps/|build/' ) INCFLAGS := $(patsubst %,-I %, $(INCS)) OBJS := $(patsubst %.c, build/%.o, $(SRCS)) RM = rm -f diff --git a/README.md b/README.md new file mode 100644 index 0000000..1aaf124 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# A Mongoose OS I2C Mock + +Files in this repository are a Linux I2C implementation of the Mongoose OS +I2C interface. + +## Howto + +Register tests in `tests/*.[ch]` and they will be compiled in. Each test must +have functions uniquely named: +``` +bool test_*_create(); +bool test_*_run(); +bool test_*_destroy(); +``` + +And static variables named: +``` +uint32_t test_*_period_ms; +``` + +Running `make` will then generate the test skeleton, recursively compile +all sources found in `src/`, `tests/`, and `libs/`, and for each, call the +`create()` function, then the `run()` function each `period_ms` milliseconds, +and upon exiting, call each `destroy()` function and clean up. diff --git a/include/mgos_gpio.h b/include/mgos_gpio.h new file mode 100644 index 0000000..8939d5b --- /dev/null +++ b/include/mgos_gpio.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014-2018 Cesanta Software Limited + * All rights reserved + * + * 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. + */ + +#ifndef CS_FW_INCLUDE_MGOS_GPIO_H_ +#define CS_FW_INCLUDE_MGOS_GPIO_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +enum mgos_gpio_mode { + MGOS_GPIO_MODE_INPUT = 0, + MGOS_GPIO_MODE_OUTPUT = 1, + MGOS_GPIO_MODE_OUTPUT_OD = 2, /* open-drain output */ +}; + +enum mgos_gpio_pull_type { + MGOS_GPIO_PULL_NONE = 0, /* floating */ + MGOS_GPIO_PULL_UP = 1, + MGOS_GPIO_PULL_DOWN = 2, +}; + +enum mgos_gpio_int_mode { + MGOS_GPIO_INT_NONE = 0, + MGOS_GPIO_INT_EDGE_POS = 1, /* positive edge */ + MGOS_GPIO_INT_EDGE_NEG = 2, /* negative edge */ + MGOS_GPIO_INT_EDGE_ANY = 3, /* any edge - positive or negative */ + MGOS_GPIO_INT_LEVEL_HI = 4, /* high voltage level */ + MGOS_GPIO_INT_LEVEL_LO = 5 /* low voltage level */ +}; + +/* GPIO interrupt handler signature. */ +typedef void (*mgos_gpio_int_handler_f)(int pin, void *arg); + +/* Set mode - input or output. */ +bool mgos_gpio_set_mode(int pin, enum mgos_gpio_mode mode); + +/* Set pull-up or pull-down type. */ +bool mgos_gpio_set_pull(int pin, enum mgos_gpio_pull_type pull); + +/* Sets up a pin as an input and confiures pull-up or pull-down. */ +bool mgos_gpio_setup_input(int pin, enum mgos_gpio_pull_type pull); + +/* + * Sets up pin output while avoiding spurious transitions: + * desired output level is configured first, then mode. + */ +bool mgos_gpio_setup_output(int pin, bool level); + +/* Read pin input level. */ +bool mgos_gpio_read(int pin); + +/* Set pin's output level. */ +void mgos_gpio_write(int pin, bool level); + +/* Flip output pin value. Returns value that was written. */ +bool mgos_gpio_toggle(int pin); + +/* Read the value of the output register. */ +bool mgos_gpio_read_out(int pin); + +/* + * Install a GPIO interrupt handler. + * + * This will invoke handler on the main task, which makes it possible to use + * any functions but may delay servicing of the interrupt. If lower latency + * is required, use `mgos_gpio_set_int_handler_isr`, but you'll need to + * understand the implications, which are platform-specific. + * + * Interrupt is automatically cleared once upon triggering. + * Then it is disabled until the handler gets a chance to run, at which point + * it is re-enabled. At this point it may re-trigger immediately if the + * interrupt condition arose again while the handler was pending or running. + * Handler may use `mgos_gpio_clear_int` to explicitly clear the condition. + * + * Note that this will not enable the interrupt, this must be done explicitly + * with `mgos_gpio_enable_int()`. + */ +bool mgos_gpio_set_int_handler(int pin, enum mgos_gpio_int_mode mode, + mgos_gpio_int_handler_f cb, void *arg); + +/* + * Same as mgos_gpio_set_int_handler but invokes handler in ISR context, + * without the overhead of a context switch. GPIO interrupts are disabled while + * the handler is running. + */ +bool mgos_gpio_set_int_handler_isr(int pin, enum mgos_gpio_int_mode mode, + mgos_gpio_int_handler_f cb, void *arg); + +/* Enable interrupt on the specified pin. */ +bool mgos_gpio_enable_int(int pin); + +/* Disables interrupt (without removing the handler). */ +bool mgos_gpio_disable_int(int pin); + +/* Clears a GPIO interrupt flag. */ +void mgos_gpio_clear_int(int pin); + +/* + * Removes a previosuly set interrupt handler. + * + * If `cb` and `arg` are not NULL, they will contain previous handler and arg. + */ +void mgos_gpio_remove_int_handler(int pin, mgos_gpio_int_handler_f *old_cb, + void **old_arg); + +/* + * Handle a button on the specified pin. + * + * Configures the pin for input with specified pull-up and performs debouncing: + * upon first triggering user's callback is invoked immediately but further + * interrupts are inhibited for the following debounce_ms millseconds. + * + * Typically 50 ms of debouncing time is sufficient. + * int_mode is one of the `MGOS_GPIO_INT_EDGE_*` values and will specify whether + * the handler triggers when button is pressed, released or both. + * Which is which depends on how the button is wired: if the normal state is + * pull-up (typical), then `MGOS_GPIO_INT_EDGE_NEG` is press and + * `_POS` is release. + * + * Calling with `cb` = NULL will remove a previously installed handler. + * + * Note: implicitly enables the interrupt. + */ +bool mgos_gpio_set_button_handler(int pin, enum mgos_gpio_pull_type pull_type, + enum mgos_gpio_int_mode int_mode, + int debounce_ms, mgos_gpio_int_handler_f cb, + void *arg); + +/* + * A utility function that takes care of blinking an LED. + * The pin must be configured as output first. + * On (output "1") and off ("0") times are specified in milliseconds. + * Set to (0, 0) to disable. + */ +bool mgos_gpio_blink(int pin, int on_ms, int off_ms); + +/* String representation of pin number. + * Will return "PA5" or "PK3" for platforms that have port banks. */ +const char *mgos_gpio_str(int pin_def, char buf[8]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CS_FW_INCLUDE_MGOS_GPIO_H_ */ diff --git a/include/mgos_mock.h b/include/mgos_mock.h index 982dd0e..12ba111 100644 --- a/include/mgos_mock.h +++ b/include/mgos_mock.h @@ -22,6 +22,8 @@ #include "mgos.h" #include #include +#include "mgos_gpio.h" +#include "mgos_i2c.h" // mgos_log enum cs_log_level diff --git a/src/main.c b/src/main.c index 619d7fa..e72a679 100644 --- a/src/main.c +++ b/src/main.c @@ -1,29 +1,4 @@ -/* - * 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 #include #include @@ -31,8 +6,9 @@ #define I2CBUSNR 7 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 +45,8 @@ 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; - - if (!sensor) - return false; - - if (!mgos_barometer_get_pressure(sensor, &pressure)) - pressure=NAN; - - if (!mgos_barometer_get_temperature(sensor, &temperature)) - temperature=NAN; - - LOG(LL_INFO, ("type=%s temperature=%.2fC pressure=%.0fPa", mgos_barometer_get_device_name(sensor), temperature, pressure)); - - 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; if (!mgos_i2c_open(I2CBUSNR)) { LOG(LL_ERROR, ("Cannot open I2C bus %u", I2CBUSNR)); @@ -197,54 +59,6 @@ int main(int argc, char **argv, char **environ) { 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 (!(baro=mgos_barometer_create_i2c(i2c, 0x76, BARO_BME280))) { - LOG(LL_ERROR, ("Cannot create barometer")); - } else { - mgos_barometer_set_cache_ttl(baro, 1000); - } - - for (;;) { - do_sht31(sht31); - do_si7021(si7021); - do_htu21df(htu21df); - do_mcp9808(mcp9808); - do_ccs811(ccs811); - do_mpu9250(mpu9250); - do_baro(baro); - 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); - return 0; (void)argc; (void)argv; 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 - -#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 - -#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 - -#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_mock.c b/src/mgos_mock.c index 3bf07a6..f0bac31 100644 --- a/src/mgos_mock.c +++ b/src/mgos_mock.c @@ -81,3 +81,33 @@ double mg_time(void) { void mgos_usleep(uint32_t usecs) { usleep(usecs); } + + +bool mgos_gpio_set_int_handler(int pin, enum mgos_gpio_int_mode mode, mgos_gpio_int_handler_f cb, void *arg) { + LOG(LL_INFO, ("Not implemented.")); + return true; + (void)pin; + (void)mode; + (void)cb; + (void)arg; +} + + + +bool mgos_gpio_enable_int(int pin) { + LOG(LL_INFO, ("Not implemented.")); + return true; + (void)pin; +} + +bool mgos_gpio_disable_int(int pin) { + LOG(LL_INFO, ("Not implemented.")); + return true; + (void)pin; +} + +void mgos_gpio_clear_int(int pin) { + LOG(LL_INFO, ("Not implemented.")); + return; + (void)pin; +} 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 - -#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 - -#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 - -#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