sensor: mcp9808: Adding temperature resolution to MCP9808 sensor driver

During the driver init, the function will set the sensor resolution
based on the driver's dts variable "resolution"

The driver's device tree has been updated to include the value
"resolution".

The default is set to the highest resolution of 0.0625C.

Moved mcp9808_reg_write from mcp9808_trigger.c to mcp9808.c

This allows resue of the same function in both the trigger and
resolution functions.

Function name changed to xxx_16bit to distinquish it from the 8
bit write function that will added.

Signed-off-by: Steven Daglish <s.c.daglish@gmail.com>
This commit is contained in:
Steven Daglish 2021-01-29 17:42:29 +00:00 committed by Anas Nashif
commit 5427d6bbc7
4 changed files with 66 additions and 21 deletions

View file

@ -22,7 +22,7 @@ LOG_MODULE_REGISTER(MCP9808, CONFIG_SENSOR_LOG_LEVEL);
int mcp9808_reg_read(const struct device *dev, uint8_t reg, uint16_t *val) int mcp9808_reg_read(const struct device *dev, uint8_t reg, uint16_t *val)
{ {
const struct mcp9808_data *data = dev->data; struct mcp9808_data *data = dev->data;
const struct mcp9808_config *cfg = dev->config; const struct mcp9808_config *cfg = dev->config;
int rc = i2c_write_read(data->i2c_master, cfg->i2c_addr, int rc = i2c_write_read(data->i2c_master, cfg->i2c_addr,
&reg, sizeof(reg), &reg, sizeof(reg),
@ -35,6 +35,39 @@ int mcp9808_reg_read(const struct device *dev, uint8_t reg, uint16_t *val)
return rc; return rc;
} }
int mcp9808_reg_write_16bit(const struct device *dev, uint8_t reg,
uint16_t val)
{
struct mcp9808_data *data = dev->data;
const struct mcp9808_config *cfg = dev->config;
uint8_t buf[3];
buf[0] = reg;
sys_put_be16(val, &buf[1]);
return i2c_write(data->i2c_master, buf, sizeof(buf), cfg->i2c_addr);
}
int mcp9808_reg_write_8bit(const struct device *dev, uint8_t reg,
uint8_t val)
{
struct mcp9808_data *data = dev->data;
const struct mcp9808_config *cfg = dev->config;
uint8_t buf[2] = {
reg,
val,
};
return i2c_write(data->i2c_master, buf, sizeof(buf), cfg->i2c_addr);
}
static int mcp9808_set_temperature_resolution(const struct device *dev,
uint8_t resolution)
{
return mcp9808_reg_write_8bit(dev, MCP9808_REG_RESOLUTION, resolution);
}
static int mcp9808_sample_fetch(const struct device *dev, static int mcp9808_sample_fetch(const struct device *dev,
enum sensor_channel chan) enum sensor_channel chan)
{ {
@ -78,10 +111,16 @@ int mcp9808_init(const struct device *dev)
data->i2c_master = device_get_binding(cfg->i2c_bus); data->i2c_master = device_get_binding(cfg->i2c_bus);
if (!data->i2c_master) { if (!data->i2c_master) {
LOG_DBG("mcp9808: i2c master not found: %s", cfg->i2c_bus); LOG_ERR("mcp9808: i2c master not found: %s", cfg->i2c_bus);
return -EINVAL; return -EINVAL;
} }
rc = mcp9808_set_temperature_resolution(dev, cfg->resolution);
if (rc) {
LOG_ERR("Could not set the resolution of mcp9808 module");
return rc;
}
#ifdef CONFIG_MCP9808_TRIGGER #ifdef CONFIG_MCP9808_TRIGGER
rc = mcp9808_setup_interrupt(dev); rc = mcp9808_setup_interrupt(dev);
#endif /* CONFIG_MCP9808_TRIGGER */ #endif /* CONFIG_MCP9808_TRIGGER */
@ -97,9 +136,10 @@ static const struct mcp9808_config mcp9808_cfg = {
.alert_pin = DT_INST_GPIO_PIN(0, int_gpios), .alert_pin = DT_INST_GPIO_PIN(0, int_gpios),
.alert_flags = DT_INST_GPIO_FLAGS(0, int_gpios), .alert_flags = DT_INST_GPIO_FLAGS(0, int_gpios),
.alert_controller = DT_INST_GPIO_LABEL(0, int_gpios), .alert_controller = DT_INST_GPIO_LABEL(0, int_gpios),
.resolution = DT_INST_PROP(0, resolution),
#endif /* CONFIG_MCP9808_TRIGGER */ #endif /* CONFIG_MCP9808_TRIGGER */
}; };
DEVICE_DT_INST_DEFINE(0, mcp9808_init, device_pm_control_nop, DEVICE_DT_INST_DEFINE(0, mcp9808_init, device_pm_control_nop,
&mcp9808_data, &mcp9808_cfg, POST_KERNEL, &mcp9808_data, &mcp9808_cfg, POST_KERNEL,
CONFIG_SENSOR_INIT_PRIORITY, &mcp9808_api_funcs); CONFIG_SENSOR_INIT_PRIORITY, &mcp9808_api_funcs);

View file

@ -55,6 +55,8 @@
#define MCP9808_TEMP_UPR_BIT BIT(14) #define MCP9808_TEMP_UPR_BIT BIT(14)
#define MCP9808_TEMP_CRT_BIT BIT(15) #define MCP9808_TEMP_CRT_BIT BIT(15)
#define MCP9808_REG_RESOLUTION 0x08
struct mcp9808_data { struct mcp9808_data {
const struct device *i2c_master; const struct device *i2c_master;
@ -82,6 +84,7 @@ struct mcp9808_data {
struct mcp9808_config { struct mcp9808_config {
const char *i2c_bus; const char *i2c_bus;
uint16_t i2c_addr; uint16_t i2c_addr;
uint8_t resolution;
#ifdef CONFIG_MCP9808_TRIGGER #ifdef CONFIG_MCP9808_TRIGGER
uint8_t alert_pin; uint8_t alert_pin;
uint8_t alert_flags; uint8_t alert_flags;
@ -90,6 +93,10 @@ struct mcp9808_config {
}; };
int mcp9808_reg_read(const struct device *dev, uint8_t reg, uint16_t *val); int mcp9808_reg_read(const struct device *dev, uint8_t reg, uint16_t *val);
int mcp9808_reg_write_16bit(const struct device *dev, uint8_t reg,
uint16_t val);
int mcp9808_reg_write_8bit(const struct device *dev, uint8_t reg,
uint8_t val);
#ifdef CONFIG_MCP9808_TRIGGER #ifdef CONFIG_MCP9808_TRIGGER
int mcp9808_attr_set(const struct device *dev, enum sensor_channel chan, int mcp9808_attr_set(const struct device *dev, enum sensor_channel chan,

View file

@ -14,20 +14,6 @@
LOG_MODULE_DECLARE(MCP9808, CONFIG_SENSOR_LOG_LEVEL); LOG_MODULE_DECLARE(MCP9808, CONFIG_SENSOR_LOG_LEVEL);
static int mcp9808_reg_write(const struct device *dev, uint8_t reg,
uint16_t val)
{
const struct mcp9808_data *data = dev->data;
const struct mcp9808_config *cfg = dev->config;
uint8_t buf[3] = {
reg,
val >> 8, /* big-endian register storage */
val & 0xFF,
};
return i2c_write(data->i2c_master, buf, sizeof(buf), cfg->i2c_addr);
}
int mcp9808_attr_set(const struct device *dev, enum sensor_channel chan, int mcp9808_attr_set(const struct device *dev, enum sensor_channel chan,
enum sensor_attribute attr, enum sensor_attribute attr,
const struct sensor_value *val) const struct sensor_value *val)
@ -54,7 +40,7 @@ int mcp9808_attr_set(const struct device *dev, enum sensor_channel chan,
temp = val->val1 * MCP9808_TEMP_SCALE_CEL; temp = val->val1 * MCP9808_TEMP_SCALE_CEL;
temp += (MCP9808_TEMP_SCALE_CEL * val->val2) / 1000000; temp += (MCP9808_TEMP_SCALE_CEL * val->val2) / 1000000;
return mcp9808_reg_write(dev, reg_addr, return mcp9808_reg_write_16bit(dev, reg_addr,
mcp9808_temp_reg_from_signed(temp)); mcp9808_temp_reg_from_signed(temp));
} }
@ -162,10 +148,10 @@ int mcp9808_setup_interrupt(const struct device *dev)
struct mcp9808_data *data = dev->data; struct mcp9808_data *data = dev->data;
const struct mcp9808_config *cfg = dev->config; const struct mcp9808_config *cfg = dev->config;
const struct device *gpio; const struct device *gpio;
int rc = mcp9808_reg_write(dev, MCP9808_REG_CRITICAL, int rc = mcp9808_reg_write_16bit(dev, MCP9808_REG_CRITICAL,
MCP9808_TEMP_ABS_MASK); MCP9808_TEMP_ABS_MASK);
if (rc == 0) { if (rc == 0) {
rc = mcp9808_reg_write(dev, MCP9808_REG_CONFIG, rc = mcp9808_reg_write_16bit(dev, MCP9808_REG_CONFIG,
MCP9808_CFG_ALERT_ENA); MCP9808_CFG_ALERT_ENA);
} }

View file

@ -18,3 +18,15 @@ properties:
sensor, and is open-drain. A pull-up may be appropriate. The sensor, and is open-drain. A pull-up may be appropriate. The
property value should ensure the flags properly describe the property value should ensure the flags properly describe the
signal that is presented to the driver. signal that is presented to the driver.
resolution:
type: int
required: false
default: 3
description: Sensor resolution. Default is 0.0625C (0b11),
which is the power-up default.
enum:
- 0 # 0.5C
- 1 # 0.25C
- 2 # 0.125C
- 3 # 0.0625C