122 lines
3.1 KiB
C
122 lines
3.1 KiB
C
/*
|
|
* 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
|