sensor: add driver for HDC1008 temperature and humidity sensor

Add driver for the HDC1008 temperature and relative humidity
sensor.

Datasheet:
	http://www.ti.com/lit/ds/symlink/hdc1008.pdf

Origin: Original
Change-Id: I63cb4cdd94120b80d0d6f3205da073f0817c4f17
Signed-off-by: Bogdan Davidoaia <bogdan.m.davidoaia@intel.com>
This commit is contained in:
Bogdan Davidoaia 2016-02-26 14:40:25 +02:00 committed by Anas Nashif
commit ef65f155c2
5 changed files with 291 additions and 0 deletions

View file

@ -46,6 +46,8 @@ config SENSOR_DEBUG
source "drivers/sensor/Kconfig.bma280"
source "drivers/sensor/Kconfig.hdc1008"
source "drivers/sensor/Kconfig.isl29035"
source "drivers/sensor/Kconfig.mcp9808"

View file

@ -0,0 +1,101 @@
# Kconfig.hdc1008 - HDC1008 temperature and humidity sensor configuration options
#
# Copyright (c) 2016 Intel Corporation
#
# 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.
#
menuconfig HDC1008
bool
prompt "HDC1008 Temperature and Humidity Sensor"
depends on SENSOR && I2C && GPIO
default n
help
Enable driver for HDC1008 temperature and humidity sensors.
config HDC1008_NAME
string
prompt "Driver name"
default "HDC1008"
depends on HDC1008
help
Device name with which the HDC1008 sensor is identified.
config HDC1008_INIT_PRIORITY
int
prompt "Init priority"
depends on HDC1008
default 70
help
Device driver initialization priority.
choice
prompt "I2C address"
depends on HDC1008
default HDC1008_I2C_ADDR_0
help
I2C address of the HDC1008 sensor.
config HDC1008_I2C_ADDR_0
bool
prompt "0x40"
help
A0 connected GND and A1 connected to GND.
config HDC1008_I2C_ADDR_1
bool
prompt "0x41"
help
A0 connected VDD and A1 connected to GND.
config HDC1008_I2C_ADDR_2
bool
prompt "0x42"
help
A0 connected GND and A1 connected to VDD.
config HDC1008_I2C_ADDR_3
bool
prompt "0x43"
help
A0 connected VDD and A1 connected to VDD.
endchoice
config HDC1008_I2C_MASTER_DEV_NAME
string
prompt "I2C master where HDC1008 is connected"
depends on HDC1008
default "I2C0"
help
Specify the device name of the I2C master device to which the
HDC1008 chip is connected.
config HDC1008_GPIO_DEV_NAME
string
prompt "GPIO device"
default "GPIO_0"
depends on HDC1008
help
The device name of the GPIO device to which the HDC1008 data-ready
pin is connected.
config HDC1008_GPIO_PIN_NUM
int
prompt "Interrupt GPIO pin number"
default 0
depends on HDC1008
help
The number of the GPIO on which the data-ready signal from the HDC1008
chip will be received.

View file

@ -4,6 +4,7 @@ obj-$(CONFIG_SENSOR_DELAYED_WORK) += sensor.o
obj-$(CONFIG_BMA280) += sensor_bma280.o
obj-$(CONFIG_BMA280_TRIGGER) += sensor_bma280_trigger.o
obj-$(CONFIG_HDC1008) += sensor_hdc1008.o
obj-$(CONFIG_ISL29035) += sensor_isl29035.o
obj-$(CONFIG_ISL29035_TRIGGER) += sensor_isl29035_trigger.o
obj-$(CONFIG_MCP9808) += sensor_mcp9808.o

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* 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 <device.h>
#include <i2c.h>
#include <gpio.h>
#include <nanokernel.h>
#include <sensor.h>
#include "sensor_hdc1008.h"
#ifndef CONFIG_SENSOR_DEBUG
#define DBG(...) { ; }
#else
#include <misc/printk.h>
#define DBG printk
#endif /* CONFIG_SENSOR_DEBUG */
static struct hdc1008_data hdc1008_driver;
static void hdc1008_gpio_callback(struct device *dev, uint32_t pin)
{
gpio_pin_disable_callback(dev, pin);
nano_sem_give(&hdc1008_driver.data_sem);
}
static int hdc1008_sample_fetch(struct device *dev)
{
struct hdc1008_data *drv_data = dev->driver_data;
uint8_t buf[4];
int rc;
gpio_pin_enable_callback(drv_data->gpio, CONFIG_HDC1008_GPIO_PIN_NUM);
buf[0] = HDC1008_REG_TEMP;
rc = i2c_write(drv_data->i2c, buf, 1, HDC1008_I2C_ADDRESS);
if (rc != DEV_OK) {
DBG("Failed to write address pointer\n");
return DEV_FAIL;
}
nano_sem_take(&drv_data->data_sem, TICKS_UNLIMITED);
rc = i2c_read(drv_data->i2c, buf, 4, HDC1008_I2C_ADDRESS);
if (rc != DEV_OK) {
DBG("Failed to read sample data\n");
return DEV_FAIL;
}
drv_data->t_sample = (buf[0] << 8) + buf[1];
drv_data->rh_sample = (buf[2] << 8) + buf[3];
return DEV_OK;
}
static int hdc1008_channel_get(struct device *dev,
enum sensor_channel chan,
struct sensor_value *val)
{
struct hdc1008_data *drv_data = dev->driver_data;
uint64_t tmp;
/*
* See datasheet "Temperature Register" and "Humidity
* Register" sections for more details on processing
* sample data.
*/
if (chan == SENSOR_CHAN_TEMP) {
/* val = -40 + 165 * sample / 2^16 */
tmp = 165 * (uint64_t)drv_data->t_sample;
val->type = SENSOR_TYPE_INT_PLUS_MICRO;
val->val1 = (int32_t)(tmp >> 16) - 40;
val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16;
} else if (chan == SENSOR_CHAN_HUMIDITY) {
/* val = 100000 * sample / 2^16 */
tmp = 100000 * (uint64_t)drv_data->rh_sample;
val->type = SENSOR_TYPE_INT_PLUS_MICRO;
val->val1 = tmp >> 16;
val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16;
} else {
return DEV_INVALID_OP;
}
return DEV_OK;
}
static struct sensor_driver_api hdc1008_driver_api = {
.sample_fetch = hdc1008_sample_fetch,
.channel_get = hdc1008_channel_get,
};
int hdc1008_init(struct device *dev)
{
struct hdc1008_data *drv_data = dev->driver_data;
int rc;
dev->driver_api = &hdc1008_driver_api;
drv_data->i2c = device_get_binding(CONFIG_HDC1008_I2C_MASTER_DEV_NAME);
if (drv_data->i2c == NULL) {
DBG("Failed to get pointer to %s device!\n",
CONFIG_HDC1008_I2C_MASTER_DEV_NAME);
return DEV_INVALID_CONF;
}
nano_sem_init(&drv_data->data_sem);
/* setup data ready gpio interrupt */
drv_data->gpio = device_get_binding(CONFIG_HDC1008_GPIO_DEV_NAME);
if (drv_data->gpio == NULL) {
DBG("Failed to get pointer to %s device\n",
CONFIG_HDC1008_GPIO_DEV_NAME);
return DEV_INVALID_CONF;
}
gpio_pin_configure(drv_data->gpio, CONFIG_HDC1008_GPIO_PIN_NUM,
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE);
rc = gpio_set_callback(drv_data->gpio, hdc1008_gpio_callback);
if (rc != DEV_OK) {
DBG("Failed to set GPIO callback\n");
return DEV_FAIL;
}
return DEV_OK;
}
DEVICE_INIT(hdc1008, CONFIG_HDC1008_NAME, hdc1008_init, &hdc1008_driver,
NULL, SECONDARY, CONFIG_HDC1008_INIT_PRIORITY);

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* 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 _SENSOR_HDC1008
#define _SENSOR_HDC1008
#include <nanokernel.h>
#if CONFIG_HDC1008_I2C_ADDR_0
#define HDC1008_I2C_ADDRESS 0x40
#elif CONFIG_HDC1008_I2C_ADDR_1
#define HDC1008_I2C_ADDRESS 0x41
#elif CONFIG_HDC1008_I2C_ADDR_2
#define HDC1008_I2C_ADDRESS 0x42
#elif CONFIG_HDC1008_I2C_ADDR_3
#define HDC1008_I2C_ADDRESS 0x43
#endif
#define HDC1008_REG_TEMP 0x0
#define HDC1008_REG_HUMIDITY 0x1
struct hdc1008_data {
struct device *i2c;
struct device *gpio;
uint16_t t_sample;
uint16_t rh_sample;
struct nano_sem data_sem;
};
#endif