2014-11-24 00:16:29 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
|
2016-01-15 17:44:02 +01:00
|
|
|
* 2017 Freie Universität Berlin
|
2014-11-24 00:16:29 +01:00
|
|
|
*
|
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
|
|
* directory for more details.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ingroup drivers_hdc1000
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @brief Driver for the TI HDC1000 Humidity and Temperature Sensor.
|
|
|
|
*
|
|
|
|
* @author Johann Fischer <j.fischer@phytec.de>
|
2016-01-15 17:44:02 +01:00
|
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
2014-11-24 00:16:29 +01:00
|
|
|
*
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "assert.h"
|
|
|
|
#include "xtimer.h"
|
2014-11-24 00:16:29 +01:00
|
|
|
#include "periph/i2c.h"
|
|
|
|
#include "hdc1000.h"
|
|
|
|
|
|
|
|
#define ENABLE_DEBUG (0)
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
#define I2C_SPEED I2C_SPEED_FAST
|
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
int hdc1000_init(hdc1000_t *dev, const hdc1000_params_t *params)
|
2014-11-24 00:16:29 +01:00
|
|
|
{
|
2016-09-30 23:01:46 +02:00
|
|
|
uint8_t reg[2];
|
2014-11-24 00:16:29 +01:00
|
|
|
uint16_t tmp;
|
|
|
|
|
|
|
|
/* write device descriptor */
|
2016-01-15 17:44:02 +01:00
|
|
|
memcpy(&dev->p, params, sizeof(hdc1000_params_t));
|
2014-11-24 00:16:29 +01:00
|
|
|
|
|
|
|
/* initialize the I2C bus */
|
2016-01-15 17:44:02 +01:00
|
|
|
i2c_acquire(dev->p.i2c);
|
|
|
|
if (i2c_init_master(dev->p.i2c, I2C_SPEED) < 0) {
|
|
|
|
i2c_release(dev->p.i2c);
|
|
|
|
return HDC1000_NOBUS;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
/* try if we can interact with the device by reading its manufacturer ID */
|
|
|
|
if (i2c_read_regs(dev->p.i2c, dev->p.addr,
|
|
|
|
HDC1000_MANUFACTURER_ID, reg, 2) != 2) {
|
|
|
|
i2c_release(dev->p.i2c);
|
|
|
|
return HDC1000_NOBUS;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
tmp = ((uint16_t)reg[0] << 8) | reg[1];
|
|
|
|
if (tmp != HDC1000_MID_VALUE) {
|
|
|
|
i2c_release(dev->p.i2c);
|
|
|
|
return HDC1000_NODEV;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
/* set resolution for both sensors and sequence mode */
|
|
|
|
tmp = (HDC1000_SEQ_MOD | dev->p.res);
|
2016-09-30 23:01:46 +02:00
|
|
|
reg[0] = (tmp >> 8);
|
|
|
|
reg[1] = tmp;
|
2014-11-24 00:16:29 +01:00
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
if (i2c_write_regs(dev->p.i2c, dev->p.addr, HDC1000_CONFIG, reg, 2) != 2) {
|
|
|
|
i2c_release(dev->p.i2c);
|
|
|
|
return HDC1000_NOBUS;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
2016-01-15 17:44:02 +01:00
|
|
|
i2c_release(dev->p.i2c);
|
2015-01-26 15:56:24 +01:00
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
/* all set */
|
|
|
|
return HDC1000_OK;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
|
|
|
|
2017-05-12 11:57:43 +02:00
|
|
|
int hdc1000_trigger_conversion(hdc1000_t *dev)
|
2014-11-24 00:16:29 +01:00
|
|
|
{
|
2017-05-12 11:57:43 +02:00
|
|
|
int status = HDC1000_OK;
|
2016-01-15 17:44:02 +01:00
|
|
|
assert(dev);
|
|
|
|
|
|
|
|
i2c_acquire(dev->p.i2c);
|
2015-01-26 15:56:24 +01:00
|
|
|
|
2014-11-24 00:16:29 +01:00
|
|
|
/* Trigger the measurements by executing a write access
|
|
|
|
* to the address 0x00 (HDC1000_TEMPERATURE).
|
2016-01-15 17:44:02 +01:00
|
|
|
* Conversion Time is 6.50ms for each value for 14 bit resolution.
|
2014-11-24 00:16:29 +01:00
|
|
|
*/
|
2017-05-12 11:57:43 +02:00
|
|
|
if (i2c_write_byte(dev->p.i2c, dev->p.addr, HDC1000_TEMPERATURE) != 1) {
|
|
|
|
status = HDC1000_BUSERR;
|
|
|
|
}
|
2015-01-26 15:56:24 +01:00
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
i2c_release(dev->p.i2c);
|
2017-05-12 11:57:43 +02:00
|
|
|
return status;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
|
|
|
|
2017-05-12 11:57:43 +02:00
|
|
|
int hdc1000_get_results(hdc1000_t *dev, int16_t *temp, int16_t *hum)
|
2014-11-24 00:16:29 +01:00
|
|
|
{
|
2017-05-12 11:57:43 +02:00
|
|
|
int status = HDC1000_OK;
|
2016-01-15 17:44:02 +01:00
|
|
|
assert(dev);
|
|
|
|
|
2016-09-30 23:01:46 +02:00
|
|
|
uint8_t buf[4];
|
2014-11-24 00:16:29 +01:00
|
|
|
|
2016-01-15 17:44:02 +01:00
|
|
|
/* first we read the RAW results from the device */
|
|
|
|
i2c_acquire(dev->p.i2c);
|
2017-05-12 11:57:43 +02:00
|
|
|
if (i2c_read_bytes(dev->p.i2c, dev->p.addr, buf, 4) != 4) {
|
|
|
|
status = HDC1000_BUSERR;
|
|
|
|
}
|
2016-01-15 17:44:02 +01:00
|
|
|
i2c_release(dev->p.i2c);
|
2015-01-26 15:56:24 +01:00
|
|
|
|
2017-05-12 11:57:43 +02:00
|
|
|
if (status == HDC1000_OK) {
|
|
|
|
/* if all ok, we convert the values to their physical representation */
|
|
|
|
if (temp) {
|
|
|
|
uint16_t traw = ((uint16_t)buf[0] << 8) | buf[1];
|
|
|
|
*temp = (int16_t)((((int32_t)traw * 16500) >> 16) - 4000);
|
|
|
|
}
|
|
|
|
if (hum) {
|
|
|
|
uint16_t hraw = ((uint16_t)buf[2] << 8) | buf[3];
|
|
|
|
*hum = (int16_t)(((int32_t)hraw * 10000) >> 16);
|
|
|
|
}
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
2017-05-12 11:57:43 +02:00
|
|
|
|
|
|
|
return status;
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|
|
|
|
|
2017-05-12 11:57:43 +02:00
|
|
|
int hdc1000_read(hdc1000_t *dev, int16_t *temp, int16_t *hum)
|
2014-11-24 00:16:29 +01:00
|
|
|
{
|
2017-05-12 11:57:43 +02:00
|
|
|
if (hdc1000_trigger_conversion(dev) != HDC1000_OK) {
|
|
|
|
return HDC1000_BUSERR;
|
|
|
|
}
|
2016-01-15 17:44:02 +01:00
|
|
|
xtimer_usleep(HDC1000_CONVERSION_TIME);
|
2017-05-12 11:57:43 +02:00
|
|
|
return hdc1000_get_results(dev, temp, hum);
|
2014-11-24 00:16:29 +01:00
|
|
|
}
|