diff --git a/include/mgos_mcp9808.h b/include/mgos_mcp9808.h index 5fb7d05..af0cd4c 100644 --- a/include/mgos_mcp9808.h +++ b/include/mgos_mcp9808.h @@ -44,6 +44,12 @@ bool mgos_mcp9808_read(struct mgos_mcp9808 *sensor); */ float mgos_mcp9808_getTemperature(struct mgos_mcp9808 *sensor); +/* + * The sensor will be enabled (true) or disabled and put into deep sleep (false) + * based on the `enable` argument. + */ +void mgos_mcp9808_enable(struct mgos_mcp9808 *sensor, bool enable); + /* * Initialization function for MGOS -- currently a noop. */ diff --git a/src/main.c b/src/main.c index c9dce46..719c2ec 100644 --- a/src/main.c +++ b/src/main.c @@ -122,6 +122,7 @@ int main() { do_sht31(sht31); do_si7021(si7021); do_htu21df(htu21df); + do_mcp9808(mcp9808); sleep(5); } diff --git a/src/mgos_mcp9808.c b/src/mgos_mcp9808.c index ff54497..95af064 100644 --- a/src/mgos_mcp9808.c +++ b/src/mgos_mcp9808.c @@ -22,6 +22,19 @@ // 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 @@ -30,21 +43,21 @@ struct mgos_mcp9808 *mgos_mcp9808_create(struct mgos_i2c *i2c, uint8_t i2caddr) 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; - // Check for the right chip. - if (false) { - LOG(LL_INFO, ("MCP9808 created at I2C 0x%02x", i2caddr)); - return sensor; - } + mgos_mcp9808_reset(sensor); - LOG(LL_ERROR, ("Failed to create MCP9808 at I2C 0x%02x", i2caddr)); - free(sensor); - return NULL; + LOG(LL_INFO, ("MCP9808 created at I2C 0x%02x", i2caddr)); + return sensor; } void mgos_mcp9808_destroy(struct mgos_mcp9808 **sensor) { @@ -65,6 +78,13 @@ bool mgos_mcp9808_read(struct mgos_mcp9808 *sensor) { } // 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; @@ -76,6 +96,15 @@ float mgos_mcp9808_getTemperature(struct mgos_mcp9808 *sensor) { 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; } diff --git a/src/mgos_mcp9808_internal.h b/src/mgos_mcp9808_internal.h index 2a20fec..ffc2057 100644 --- a/src/mgos_mcp9808_internal.h +++ b/src/mgos_mcp9808_internal.h @@ -7,17 +7,23 @@ #define MGOS_MCP9808_DEFAULT_I2CADDR (0x18) -#define MGOS_MCP9808_MEAS_HIGHREP_STRETCH (0x2C06) -#define MGOS_MCP9808_MEAS_MEDREP_STRETCH (0x2C0D) -#define MGOS_MCP9808_MEAS_LOWREP_STRETCH (0x2C10) -#define MGOS_MCP9808_MEAS_HIGHREP (0x2400) -#define MGOS_MCP9808_MEAS_MEDREP (0x240B) -#define MGOS_MCP9808_MEAS_LOWREP (0x2416) -#define MGOS_MCP9808_READSTATUS (0xF32D) -#define MGOS_MCP9808_CLEARSTATUS (0x3041) -#define MGOS_MCP9808_SOFTRESET (0x30A2) -#define MGOS_MCP9808_HEATEREN (0x306D) -#define MGOS_MCP9808_HEATERDIS (0x3066) +#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" {