Merge pull request #7168 from smlng/driver/tmp006/rework

driver: tmp006 rework
master
Alexandre Abadie 6 years ago committed by GitHub
commit 92147cf269

@ -4,8 +4,9 @@ endif
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio
USEMODULE += hdc1000
USEMODULE += mag3110
USEMODULE += mma8x5x
USEMODULE += hdc1000
USEMODULE += tmp006
USEMODULE += tcs37727
endif

@ -76,6 +76,9 @@ endif
ifneq (,$(filter bm%280,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/bmx280/include
endif
ifneq (,$(filter tmp006,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/tmp006/include
endif
ifneq (,$(filter tsl2561,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/tsl2561/include
endif

@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
* 2017 HAW Hamburg
*
* 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
@ -7,62 +8,62 @@
*/
/**
* @defgroup drivers_tmp006 TMP006 Infrared Thermopile Sensor
* @defgroup drivers_tmp006 TI TMP006 Infrared Thermopile Sensor
* @ingroup drivers_sensors
* @brief Driver for the Texas Instruments TMP006 sensor.
* The sensor measures the temperature of an object
* without the need of direct contact with the object.
* After initialization and set active the sensor
* will make measurements at periodic times.
* The conversion duration depends on oversample ratio.<br>
* The oversample ratio can be determined
* by sensor initialization.<br>
* The target object temperature can be calculated as follows:<br><br>
* Temperature of sensor's die (2 times right shifting and devide-by 32):
* \f{eqnarray*}{
* T_{\mathrm{DIE}} &=& \frac{T_{\mathrm{RAW}}}{128}
* \f}
* Difference Temperature in Kelvin:
* \f{eqnarray*}{
* T_{\mathrm{DIFF}} &=& T_{\mathrm{DIE}} - T_{\mathrm{REF}}
* \f}
* Sensitivity of the thermopile sensor,
* with \f$S_{\mathrm{0}}\f$ as calibration factor:
* \f{eqnarray*}{
* S &=& S_{\mathrm{0}} \cdot ( 1 + a_1 \cdot T_{\mathrm{DIFF}}
* + a_2 \cdot T_{\mathrm{DIFF}}^2 ) \\
* \f}
* Sensor's voltage (the LSB size is \f$ 156.25\,\mathrm{nV} \f$):
* \f{eqnarray*}{
* V_{\mathrm{OBJ}} &=& V_{\mathrm{RAW}} \cdot 156.25\,\mathrm{nV}
* \f}
* Offset voltage:
* \f{eqnarray*}{
* V_{OS} &=& b_0 + b_1 \cdot T_{\mathrm{DIFF}}
* + b_2 \cdot T_{\mathrm{DIFF}}^2 \\
* \f}
* Seebeck coefficients of the thermopile:
* \f{eqnarray*}{
* f(V_{\mathrm{OBJ}}) &=& (V_{\mathrm{OBJ}} - V_{O\mathrm{S}})
* + c_2 \cdot (V_{\mathrm{OBJ}} - V_{\mathrm{OS}})^2 \\
* \f}
* Temperature of the target object:
* \f{eqnarray*}{
* T_{\mathrm{OBJ}} &=& \sqrt[4]{T_{\mathrm{DIE}}^4
* + \frac{f(V_{\mathrm{OBJ}})}{S}} \\
* \f}
* Constants:<br>
* \f{eqnarray*}{
* a_{\mathrm{1}} &=& 1.75 \cdot 10^{-3} \\
* a_{\mathrm{2}} &=& -1.678 \cdot 10^{-5} \\
* T_{\mathrm{REF}} &=& 298.15\,\mathrm{K} \\
* b_{\mathrm{0}} &=& -2.94 \cdot 10^{-5} \\
* b_{\mathrm{1}} &=& -5.7 \cdot 10^{-7} \\
* b_{\mathrm{2}} &=& 4.63 \cdot 10^{-9} \\
* c_{\mathrm{2}} &=& 13.4
* \f}
*
* The calculation and constants are wrapped from TI TMP006 User's Guide SBOU107.
*
* The TI TMP006 (Infrared Thermopile Contactless Temperature Sensor) measures
* the temperature of an object without need of direct contact with the object.
* After initialization the sensor can be set active for periodic measurements.
* <br> The conversion duration depends on oversample ratio. The oversample
* ratio can be determined by sensor initialization. The target object
* temperature can be calculated as follows:<br><br>
* Temperature of sensor's die (2 times right shifting and devide-by 32):
* \f{eqnarray*}{
* T_{\mathrm{DIE}} &=& \frac{T_{\mathrm{RAW}}}{128}
* \f}
* Difference Temperature in Kelvin:
* \f{eqnarray*}{
* T_{\mathrm{DIFF}} &=& T_{\mathrm{DIE}} - T_{\mathrm{REF}}
* \f}
* Sensitivity of the thermopile sensor, with \f$S_{\mathrm{0}}\f$ as
* calibration factor:
* \f{eqnarray*}{
* S &=& S_{\mathrm{0}} \cdot ( 1 + a_1 \cdot T_{\mathrm{DIFF}}
* + a_2 \cdot T_{\mathrm{DIFF}}^2 ) \\
* \f}
* Sensor's voltage (the LSB size is \f$ 156.25\,\mathrm{nV} \f$):
* \f{eqnarray*}{
* V_{\mathrm{OBJ}} &=& V_{\mathrm{RAW}} \cdot 156.25\,\mathrm{nV}
* \f}
* Offset voltage:
* \f{eqnarray*}{
* V_{OS} &=& b_0 + b_1 \cdot T_{\mathrm{DIFF}}
* + b_2 \cdot T_{\mathrm{DIFF}}^2 \\
* \f}
* Seebeck coefficients of the thermopile:
* \f{eqnarray*}{
* f(V_{\mathrm{OBJ}}) &=& (V_{\mathrm{OBJ}} - V_{O\mathrm{S}})
* + c_2 \cdot (V_{\mathrm{OBJ}}
* - V_{\mathrm{OS}})^2 \\
* \f}
* Temperature of the target object:
* \f{eqnarray*}{
* T_{\mathrm{OBJ}} &=& \sqrt[4]{T_{\mathrm{DIE}}^4
* + \frac{f(V_{\mathrm{OBJ}})}{S}} \\
* \f}
* Constants:<br>
* \f{eqnarray*}{
* a_{\mathrm{1}} &=& 1.75 \cdot 10^{-3} \\
* a_{\mathrm{2}} &=& -1.678 \cdot 10^{-5} \\
* T_{\mathrm{REF}} &=& 298.15\,\mathrm{K} \\
* b_{\mathrm{0}} &=& -2.94 \cdot 10^{-5} \\
* b_{\mathrm{1}} &=& -5.7 \cdot 10^{-7} \\
* b_{\mathrm{2}} &=& 4.63 \cdot 10^{-9} \\
* c_{\mathrm{2}} &=& 13.4
* \f}
*
* The calculation and constants are wrapped from TI TMP006 User's Guide SBOU107.
*
* @{
*
@ -70,6 +71,7 @@
* @brief Interface definition for the TMP006 sensor driver.
*
* @author Johann Fischer <j.fischer@phytec.de>
* @author Sebastian Meiling <s@mlng.net>
*/
#ifndef TMP006_H
@ -84,72 +86,91 @@ extern "C"
{
#endif
/**
* @brief TMP006 Default Address
*/
#ifndef TMP006_I2C_ADDRESS
#define TMP006_I2C_ADDRESS 0x41 /**< TMP006 Sensor Default Address */
#define TMP006_I2C_ADDRESS (0x41)
#endif
/**
* @brief Default Conversion Time in us
*/
#ifndef TMP006_CONVERSION_TIME
#define TMP006_CONVERSION_TIME 1E6 /**< Default Conversion Time in us */
#define TMP006_CONVERSION_TIME (1E6)
#endif
#define TMP006_CONFIG_CR_AS1 0x00 /**< Conversion Time 0.25 s, AVG Samples: 1 */
#define TMP006_CONFIG_CR_AS2 0x01 /**< Conversion Time 0.5 s, AVG Samples: 2 */
#define TMP006_CONFIG_CR_AS4 0x02 /**< Conversion Time 1 s, AVG Samples: 4 */
#define TMP006_CONFIG_CR_AS8 0x03 /**< Conversion Time 2 s, AVG Samples: 8 */
#define TMP006_CONFIG_CR_AS16 0x04 /**< Conversion Time 4 s, AVG Samples: 16 */
/**
* @name Conversion rate and AVG sampling configuration
* @{
*/
#define TMP006_CONFIG_CR_AS1 (0x00) /**< Conversion Time 0.25s, AVG Samples: 1 */
#define TMP006_CONFIG_CR_AS2 (0x01) /**< Conversion Time 0.5s, AVG Samples: 2 */
#define TMP006_CONFIG_CR_AS4 (0x02) /**< Conversion Time 1s, AVG Samples: 4 */
#define TMP006_CONFIG_CR_AS8 (0x03) /**< Conversion Time 2s, AVG Samples: 8 */
#define TMP006_CONFIG_CR_AS16 (0x04) /**< Conversion Time 4s, AVG Samples: 16 */
#define TMP006_CONFIG_CR_DEF TMP006_CONFIG_CR_AS4 /**< Default for Testing */
/** @} */
/**
* @name Constants for TMP006 calibration
* @{
*/
#ifndef TMP006_CCONST_S0
#define TMP006_CCONST_S0 6.4E-14 /**< Calibration Factor */
#define TMP006_CCONST_S0 (6.4E-14) /**< Calibration Factor */
#endif
#define TMP006_CCONST_A1 (1.75E-3) /**< Constant \f$a_{\mathrm{1}}\f$ */
#define TMP006_CCONST_A2 (-1.678E-5) /**< Constant \f$a_{\mathrm{2}}\f$ */
#define TMP006_CCONST_TREF (298.15) /**< Constant \f$T_{\mathrm{REF}}\f$ */
#define TMP006_CCONST_B0 (-2.94E-5) /**< Constant \f$b_{\mathrm{0}}\f$ */
#define TMP006_CCONST_B1 (-5.7E-7) /**< Constant \f$b_{\mathrm{1}}\f$ */
#define TMP006_CCONST_B2 (4.63E-9) /**< Constant \f$b_{\mathrm{2}}\f$ */
#define TMP006_CCONST_C2 (13.4) /**< Constant \f$c_{\mathrm{2}}\f$ */
#define TMP006_CCONST_LSB_SIZE (156.25E-9) /**< Sensor Voltage Register LSB Size */
/** @} */
#define TMP006_CCONST_A1 1.75E-3 /**< Constant \f$a_{\mathrm{1}}\f$ */
#define TMP006_CCONST_A2 -1.678E-5 /**< Constant \f$a_{\mathrm{2}}\f$ */
#define TMP006_CCONST_TREF 298.15 /**< Constant \f$T_{\mathrm{REF}}\f$ */
#define TMP006_CCONST_B0 -2.94E-5 /**< Constant \f$b_{\mathrm{0}}\f$ */
#define TMP006_CCONST_B1 -5.7E-7 /**< Constant \f$b_{\mathrm{1}}\f$ */
#define TMP006_CCONST_B2 4.63E-9 /**< Constant \f$b_{\mathrm{2}}\f$ */
#define TMP006_CCONST_C2 13.4 /**< Constant \f$c_{\mathrm{2}}\f$ */
#define TMP006_CCONST_LSB_SIZE 156.25E-9 /**< Sensor Voltage Register LSB Size */
/**
* @brief Parameters needed for device initialization
*/
typedef struct {
i2c_t i2c; /**< I2C device, the sensor is connected to */
uint8_t addr; /**< the sensor's slave address on the I2C bus */
uint8_t rate; /**< number of averaged samples */
} tmp006_params_t;
/**
* @brief Device descriptor for TMP006 sensors.
* @brief Device descriptor for TMP006 sensors.
*/
typedef struct {
i2c_t i2c; /**< I2C device, the sensor is connected to */
uint8_t addr; /**< the sensor's slave address on the I2C bus */
bool initialized; /**< sensor status, true if sensor is initialized */
tmp006_params_t p; /**< Configuration parameters */
} tmp006_t;
/**
* @brief TMP006 sensor test.
* This function looks for Device ID of the TMP006 sensor.
*
* @param[in] dev device descriptor of sensor
*
* @return 0 on success
* @return -1 on error
* @brief TMP006 specific return values
*/
int tmp006_test(tmp006_t *dev);
enum {
TMP006_OK, /**< Success, no error */
TMP006_ERROR_BUS, /**< I2C bus error */
TMP006_ERROR_DEV, /**< internal device error */
TMP006_ERROR_CONF, /**< invalid device configuration */
TMP006_ERROR, /**< general error */
};
/**
* @brief Initialize the TMP006 sensor driver.
* @brief Initialize the TMP006 sensor driver.
*
* @param[out] dev device descriptor of sensor to initialize
* @param[in] i2c I2C bus the sensor is connected to
* @param[in] address sensor's I2C slave address
* @param[in] conv_rate number of averaged samples
* @param[in] params configuration parameters
*
* @return 0 on success
* @return -1 if conv_rate is wrong
* @return -2 if initialization of I2C bus failed
* @return -3 if sensor test failed
* @return -4 if sensor configuration failed
* @return -TMP006_ERROR_BUS on I2C bus error
* @return -TMP006_ERROR_DEV if sensor test failed
* @return -TMP006_ERROR_CONF if sensor configuration failed
*/
int tmp006_init(tmp006_t *dev, i2c_t i2c, uint8_t address, uint8_t conv_rate);
int tmp006_init(tmp006_t *dev, const tmp006_params_t *params);
/**
* @brief Reset the TMP006 sensor. After that, the sensor should be reinitialized.
* @brief Reset the TMP006 sensor, afterwards it should be reinitialized.
*
* @param[out] dev device descriptor of sensor
*
@ -159,7 +180,7 @@ int tmp006_init(tmp006_t *dev, i2c_t i2c, uint8_t address, uint8_t conv_rate);
int tmp006_reset(tmp006_t *dev);
/**
* @brief Set active mode, this enables periodic measurements.
* @brief Set active mode, this enables periodic measurements.
*
* @param[in] dev device descriptor of sensor
*
@ -169,7 +190,7 @@ int tmp006_reset(tmp006_t *dev);
int tmp006_set_active(tmp006_t *dev);
/**
* @brief Set standby mode.
* @brief Set standby mode.
*
* @param[in] dev device descriptor of sensor
*
@ -179,7 +200,7 @@ int tmp006_set_active(tmp006_t *dev);
int tmp006_set_standby(tmp006_t *dev);
/**
* @brief Read sensor's data.
* @brief Read sensor's data.
*
* @param[in] dev device descriptor of sensor
* @param[out] rawv object voltage value
@ -192,7 +213,7 @@ int tmp006_set_standby(tmp006_t *dev);
int tmp006_read(tmp006_t *dev, int16_t *rawv, int16_t *rawt, uint8_t *drdy);
/**
* @brief Convert raw sensor values to temperature.
* @brief Convert raw sensor values to temperature.
*
* @param[in] rawv object voltage value
* @param[in] rawt raw die temperature value
@ -201,6 +222,17 @@ int tmp006_read(tmp006_t *dev, int16_t *rawv, int16_t *rawt, uint8_t *drdy);
*/
void tmp006_convert(int16_t rawv, int16_t rawt, float *tamb, float *tobj);
/**
* @brief Convenience function to get ambient and object temperatures in [°C]
*
* @note Temperature scaled by x100 for accuracy and avoid floats
*
* @param[in] dev device descriptor of sensor
* @param[out] ta converted ambient temperature
* @param[out] to converted object temperature
*/
int tmp006_read_temperature(tmp006_t *dev, int16_t *ta, int16_t *to);
#ifdef __cplusplus
}
#endif

@ -0,0 +1,74 @@
/*
* Copyright (C) 2017 HAW Hamburg
*
* 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_tmp006
*
* @{
* @file
* @brief Default configuration for TMP006 devices
*
* @author Sebastian Meiling <s@mlng.net>
*/
#ifndef TMP006_PARAMS_H
#define TMP006_PARAMS_H
#include "board.h"
#include "tmp006.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Set default configuration parameters for the TMP006 driver
* @{
*/
#ifndef TMP006_PARAM_I2C
#define TMP006_PARAM_I2C I2C_DEV(0)
#endif
#ifndef TMP006_PARAM_ADDR
#define TMP006_PARAM_ADDR (TMP006_I2C_ADDRESS)
#endif
#ifndef TMP006_PARAM_RATE
#define TMP006_PARAM_RATE TMP006_CONFIG_CR_DEF
#endif
#define TMP006_PARAMS_DEFAULT { .i2c = TMP006_PARAM_I2C, \
.addr = TMP006_PARAM_ADDR, \
.rate = TMP006_PARAM_RATE }
/**@}*/
/**
* @brief HDC1000 configuration
*/
static const tmp006_params_t tmp006_params[] =
{
#ifdef TMP006_PARAMS_BOARD
TMP006_PARAMS_BOARD,
#else
TMP006_PARAMS_DEFAULT,
#endif
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t tmp006_saul_info[] =
{
{ .name = "tmp006" }
};
#ifdef __cplusplus
}
#endif
#endif /* TMP006_PARAMS_H */
/** @} */

@ -0,0 +1,44 @@
/*
* Copyright (C) 2017 HAW Hamburg
*
* 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_tmp006
*
* @{
* @file
* @brief Register definitions for TMP006 devices
*
* @author Sebastian Meiling <s@mlng.net>
*/
#ifndef TMP006_REGS_H
#define TMP006_REGS_H
#include "board.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Register Map
* @{
*/
#define TMP006_REGS_V_OBJECT 0x00 /**< Sensor Voltage Register */
#define TMP006_REGS_T_AMBIENT 0x01 /**< Ambient Temperature Register */
#define TMP006_REGS_CONFIG 0x02 /**< Configuration Register */
#define TMP006_REGS_MANUFACTURER_ID 0xFE /**< Manufacturer ID Register */
#define TMP006_REGS_DEVICE_ID 0xFF /**< Device ID Register */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* TMP006_REGS_H */
/** @} */

@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
* 2017 HAW Hamburg
*
* 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
@ -16,230 +17,185 @@
*
* @author Johann Fischer <j.fischer@phytec.de>
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
* @author Sebastian Meiling <s@mlng.net>
*
* @}
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include "log.h"
#include "periph/i2c.h"
#include "tmp006.h"
#include "tmp006_regs.h"
#define ENABLE_DEBUG (0)
#define ENABLE_DEBUG (0)
#include "debug.h"
#define TMP006_V_OBJECT 0x00 /**< Sensor Voltage Register */
#define TMP006_T_AMBIENT 0x01 /**< Ambient Temperature Register */
#define TMP006_CONFIG 0x02 /**< Configuration Register */
#define TMP006_MANUFACTURER_ID 0xFE /**< Manufacturer ID Register */
#define TMP006_DEVICE_ID 0xFF /**< Device ID Register */
#define TMP006_CONFIG_RST (1 << 15)
#define TMP006_CONFIG_RST (1 << 15)
#define TMP006_CONFIG_MOD_SHIFT 12
#define TMP006_CONFIG_MOD_MASK 0x7000
#define TMP006_CONFIG_MOD(x) (((uint16_t)(((uint16_t)(x))<<TMP006_CONFIG_MOD_SHIFT))\
&TMP006_CONFIG_MOD_MASK)
#define TMP006_CONFIG_MOD_CC 0x07
#define TMP006_CONFIG_MOD_OFF 0x00
#define TMP006_CONFIG_MOD_SHIFT (12U)
#define TMP006_CONFIG_MOD_MASK (0x7000)
#define TMP006_CONFIG_MOD(x) (((uint16_t)(((uint16_t)(x)) << TMP006_CONFIG_MOD_SHIFT))\
& TMP006_CONFIG_MOD_MASK)
#define TMP006_CONFIG_MOD_CC (0x07)
#define TMP006_CONFIG_MOD_OFF (0x00)
#define TMP006_CONFIG_CR_SHIFT 9
#define TMP006_CONFIG_CR_MASK 0x0E00
#define TMP006_CONFIG_CR(x) (((uint16_t)(((uint16_t)(x))<<TMP006_CONFIG_CR_SHIFT))\
&TMP006_CONFIG_CR_MASK)
#define TMP006_CONFIG_CR_SHIFT (9U)
#define TMP006_CONFIG_CR_MASK (0x0E00)
#define TMP006_CONFIG_CR(x) (((uint16_t)(((uint16_t)(x)) << TMP006_CONFIG_CR_SHIFT))\
& TMP006_CONFIG_CR_MASK)
#define TMP006_CONFIG_DRDY_PIN_EN (1 << 8)
#define TMP006_CONFIG_DRDY (1 << 7)
#define TMP006_CONFIG_DRDY_PIN_EN (1 << 8)
#define TMP006_CONFIG_DRDY (1 << 7)
#define TMP006_MID_VALUE 0x5449 /**< Manufacturer ID */
#define TMP006_DID_VALUE 0x0067 /**< Device ID */
#define TMP006_MID_VALUE (0x5449) /**< Manufacturer ID */
#define TMP006_DID_VALUE (0x0067) /**< Device ID */
#define I2C_SPEED I2C_SPEED_FAST
#define I2C_SPEED I2C_SPEED_FAST
#define BUS (dev->p.i2c)
#define ADDR (dev->p.addr)
int tmp006_test(tmp006_t *dev)
int tmp006_init(tmp006_t *dev, const tmp006_params_t *params)
{
int status;
/* check parameters */
assert(dev && params);
uint8_t reg[2];
uint16_t tmp;
/* Acquire exclusive access to the bus. */
i2c_acquire(dev->i2c);
status = i2c_read_regs(dev->i2c, dev->addr, TMP006_DEVICE_ID, reg, 2);
if (status != 2) {
/* Release the bus for other threads. */
i2c_release(dev->i2c);
return -1;
}
i2c_release(dev->i2c);
/* initialize the device descriptor */
memcpy(&dev->p, params, sizeof(tmp006_params_t));
tmp = ((uint16_t)reg[0] << 8) | reg[1];
if (tmp != TMP006_DID_VALUE) {
return -1;
if (dev->p.rate > TMP006_CONFIG_CR_AS16) {
LOG_ERROR("tmp006_init: invalid conversion rate!\n");
return -TMP006_ERROR_CONF;
}
return 0;
}
int tmp006_init(tmp006_t *dev, i2c_t i2c, uint8_t address, uint8_t conv_rate)
{
int status;
uint8_t reg[2];
/* write device descriptor */
dev->i2c = i2c;
dev->addr = address;
dev->initialized = false;
if (conv_rate > TMP006_CONFIG_CR_AS16) {
return -1;
/* setup the I2C bus */
i2c_acquire(BUS);
if (i2c_init_master(BUS, I2C_SPEED) < 0) {
i2c_release(BUS);
LOG_ERROR("tmp006_init: error initializing I2C bus\n");
return -TMP006_ERROR_BUS;
}
i2c_acquire(dev->i2c);
/* initialize the I2C bus */
status = i2c_init_master(i2c, I2C_SPEED);
if (status < 0) {
i2c_release(dev->i2c);
return -2;
/* test device id */
if (i2c_read_regs(BUS, ADDR, TMP006_REGS_DEVICE_ID, reg, 2) != 2) {
i2c_release(BUS);
LOG_ERROR("tmp006_init: error reading device ID!\n");
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
if (tmp006_test(dev)) {
return -3;
tmp = ((uint16_t)reg[0] << 8) | reg[1];
if (tmp != TMP006_DID_VALUE) {
return -TMP006_ERROR_DEV;
}
uint16_t tmp = TMP006_CONFIG_CR(conv_rate);
/* set conversion rate */
tmp = TMP006_CONFIG_CR(dev->p.rate);
reg[0] = (tmp >> 8);
reg[1] = tmp;
/* Acquire exclusive access to the bus. */
i2c_acquire(dev->i2c);
status = i2c_write_regs(dev->i2c, dev->addr, TMP006_CONFIG, reg, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -4;
if (i2c_write_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
LOG_ERROR("tmp006_init: error setting conversion rate!\n");
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
dev->initialized = true;
return 0;
i2c_release(BUS);
return TMP006_OK;
}
int tmp006_reset(tmp006_t *dev)
{
int status;
uint8_t reg[2];
uint16_t tmp = TMP006_CONFIG_RST;
reg[0] = (tmp >> 8);
reg[1] = tmp;
dev->initialized = false;
/* Acquire exclusive access to the bus. */
i2c_acquire(dev->i2c);
status = i2c_write_regs(dev->i2c, dev->addr, TMP006_CONFIG, reg, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
i2c_acquire(BUS);
if (i2c_write_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
return 0;
i2c_release(BUS);
return TMP006_OK;
}
int tmp006_set_active(tmp006_t *dev)
{
int status;
uint8_t reg[2];
if (dev->initialized == false) {
return -1;
}
i2c_acquire(dev->i2c);
status = i2c_read_regs(dev->i2c, dev->addr, TMP006_CONFIG, reg, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
i2c_acquire(BUS);
if (i2c_read_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
reg[0] |= (TMP006_CONFIG_MOD(TMP006_CONFIG_MOD_CC) >> 8);
status = i2c_write_regs(dev->i2c, dev->addr, TMP006_CONFIG, reg, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
if (i2c_write_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
return 0;
i2c_release(BUS);
return TMP006_OK;
}
int tmp006_set_standby(tmp006_t *dev)
{
int status;
uint8_t reg[2];
i2c_acquire(dev->i2c);
status = i2c_read_regs(dev->i2c, dev->addr, TMP006_CONFIG, reg, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
i2c_acquire(BUS);
if (i2c_read_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
reg[0] &= ~(TMP006_CONFIG_MOD(TMP006_CONFIG_MOD_CC) >> 8);
i2c_acquire(dev->i2c);
status = i2c_write_regs(dev->i2c, dev->addr, TMP006_CONFIG, reg, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
if (i2c_write_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
return 0;
i2c_release(BUS);
return TMP006_OK;
}
int tmp006_read(tmp006_t *dev, int16_t *rawv, int16_t *rawt, uint8_t *drdy)
{
int status;
uint8_t buf[2];
if (dev->initialized == false) {
return -1;
}
uint8_t reg[2];
i2c_acquire(dev->i2c);
i2c_acquire(BUS);
/* Register bytes are sent MSB first. */
status = i2c_read_regs(dev->i2c, dev->addr, TMP006_CONFIG, buf, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
if (i2c_read_regs(BUS, ADDR, TMP006_REGS_CONFIG, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
*drdy = buf[1] & (TMP006_CONFIG_DRDY);
i2c_release(BUS);
*drdy = reg[1] & (TMP006_CONFIG_DRDY);
if (!(*drdy)) {
/* conversion in progress */
return -1;
LOG_DEBUG("tmp006_read: conversion in progress!\n");
return -TMP006_ERROR;
}
i2c_acquire(dev->i2c);
status = i2c_read_regs(dev->i2c, dev->addr, TMP006_V_OBJECT, buf, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
i2c_acquire(BUS);
if (i2c_read_regs(BUS, ADDR, TMP006_REGS_V_OBJECT, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
i2c_release(BUS);
*rawv = ((uint16_t)buf[0] << 8) | buf[1];
*rawv = ((uint16_t)reg[0] << 8) | reg[1];
i2c_acquire(dev->i2c);
status = i2c_read_regs(dev->i2c, dev->addr, TMP006_T_AMBIENT, buf, 2);
if (status != 2) {
i2c_release(dev->i2c);
return -1;
i2c_acquire(BUS);
if (i2c_read_regs(BUS, ADDR, TMP006_REGS_T_AMBIENT, reg, 2) != 2) {
i2c_release(BUS);
return -TMP006_ERROR_BUS;
}
i2c_release(dev->i2c);
*rawt = ((uint16_t)buf[0] << 8) | buf[1];
return 0;
i2c_release(BUS);
*rawt = ((uint16_t)reg[0] << 8) | reg[1];
return TMP006_OK;
}
void tmp006_convert(int16_t rawv, int16_t rawt, float *tamb, float *tobj)
@ -267,3 +223,20 @@ void tmp006_convert(int16_t rawv, int16_t rawt, float *tamb, float *tobj)
/* calculate object temperature in Celsius */
*tobj = (t - 273.15);
}
int tmp006_read_temperature(tmp006_t *dev, int16_t *ta, int16_t *to)
{
int16_t rawtemp, rawvolt;
float tamb, tobj;
uint8_t drdy;
tmp006_read(dev, &rawvolt, &rawtemp, &drdy);
if (!drdy) {
return TMP006_ERROR;
}
tmp006_convert(rawvolt, rawtemp, &tamb, &tobj);
*ta = (int16_t)(tamb*100);
*to = (int16_t)(tobj*100);
return TMP006_OK;
}

@ -0,0 +1,42 @@
/*
* Copyright (C) 2017 HAW Hamburg
*
* 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 driver_tmp006
* @{
*
* @file
* @brief TMP006 adaption to the RIOT actuator/sensor interface
*
* @author Sebastian Meiling <s@mlng.net>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "tmp006.h"
static int read_temp(void *dev, phydat_t *res)
{
if (tmp006_read_temperature((tmp006_t *)dev, &res->val[0], &res->val[1]) != TMP006_OK) {
return -ECANCELED;
}
res->val[2] = 0;
res->unit = UNIT_TEMP_C;
res->scale = -2;
return 2;
}
const saul_driver_t tmp006_saul_driver = {
.read = read_temp,
.write = saul_notsup,
.type = SAUL_SENSE_TEMP,
};

@ -315,6 +315,10 @@ void auto_init(void)
extern void auto_init_dht(void);
auto_init_dht();
#endif
#ifdef MODULE_TMP006
extern void auto_init_tmp006(void);
auto_init_tmp006();
#endif
#ifdef MODULE_TCS37727
extern void auto_init_tcs37727(void);
auto_init_tcs37727();

@ -0,0 +1,73 @@
/*
* Copyright (C) 2017 HAW Hamburg
*
* 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 auto_init_saul
* @{
*
* @file
* @brief Auto initialization of TMP006 temperature sensor
*
* @author Sebastian Meiling <s@mlng.net>
*
* @}
*/
#ifdef MODULE_TMP006
#include "log.h"
#include "saul_reg.h"
#include "tmp006.h"
#include "tmp006_params.h"
/**
* @brief Define the number of configured sensors
*/
#define TMP006_NUM (sizeof(tmp006_params) / sizeof(tmp006_params[0]))
/**
* @brief Allocate memory for the device descriptors
*/
static tmp006_t tmp006_devs[TMP006_NUM];
/**
* @brief Memory for the SAUL registry entries
*/
static saul_reg_t saul_entries[TMP006_NUM];
/**
* @brief Reference the driver struct
*/
extern const saul_driver_t tmp006_saul_driver;
void auto_init_tmp006(void)
{
for (unsigned i = 0; i < TMP006_NUM; i++) {
LOG_DEBUG("[auto_init_saul] initializing tmp006 #%u\n", i);
if (tmp006_init(&tmp006_devs[i], &tmp006_params[i]) != TMP006_OK) {
LOG_ERROR("[auto_init_saul] error initializing tmp006 #%u\n", i);
continue;
}
if (tmp006_set_active(&tmp006_devs[i]) != TMP006_OK) {
LOG_ERROR("[auto_init_saul] error set active tmp006 #%u\n", i);
continue;
}
saul_entries[i].dev = &(tmp006_devs[i]);
saul_entries[i].name = tmp006_saul_info[i].name;
saul_entries[i].driver = &tmp006_saul_driver;
saul_reg_add(&(saul_entries[i]));
}
}
#else
typedef int dont_be_pedantic;
#endif /* MODULE_TMP006 */

@ -6,14 +6,4 @@ FEATURES_REQUIRED = periph_i2c
USEMODULE += tmp006
USEMODULE += xtimer
# set default device parameters in case they are undefined
TEST_TMP006_I2C ?= I2C_DEV\(0\)
TEST_TMP006_ADDR ?= 0x41
TEST_TMP006_CONFIG_CR ?= TMP006_CONFIG_CR_DEF
# export parameters
CFLAGS += -DTEST_TMP006_I2C=$(TEST_TMP006_I2C)
CFLAGS += -DTEST_TMP006_ADDR=$(TEST_TMP006_ADDR)
CFLAGS += -DTEST_TMP006_CONFIG_CR=$(TEST_TMP006_CONFIG_CR)
include $(RIOTBASE)/Makefile.include

@ -1,6 +1,7 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
* 2017 HAW Hamburg
*
* 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
@ -16,24 +17,16 @@
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Johann Fischer <j.fischer@phytec.de>
* @author Sebastian Meiling <s@mlng.net>
*
* @}
*/
#ifndef TEST_TMP006_I2C
#error "TEST_TMP006_I2C not defined"
#endif
#ifndef TEST_TMP006_ADDR
#error "TEST_TMP006_ADDR not defined"
#endif
#ifndef TEST_TMP006_CONFIG_CR
#error "TEST_TMP006_ADDR not defined"
#endif
#include <stdio.h>
#include "xtimer.h"
#include "tmp006.h"
#include "tmp006_params.h"
int main(void)
{
@ -43,33 +36,30 @@ int main(void)
uint8_t drdy;
puts("TMP006 infrared thermopile sensor driver test application\n");
printf("Initializing TMP006 sensor at I2C_%i... ", TEST_TMP006_I2C);
if (tmp006_init(&dev, TEST_TMP006_I2C, TEST_TMP006_ADDR, TEST_TMP006_CONFIG_CR) == 0) {
puts("[OK]\n");
}
else {
puts("[Failed]");
printf("Initializing TMP006 sensor at I2C_%i ... ", tmp006_params[0].i2c);
if (tmp006_init(&dev, &tmp006_params[0]) != TMP006_OK) {
puts("init device [ERROR]");
return -1;
}
if (tmp006_set_active(&dev)) {
puts("Measurement start failed.");
puts("start measurement [ERROR]");
return -1;
}
xtimer_usleep(TMP006_CONVERSION_TIME);
puts("[SUCCESS]\n");
while (1) {
tmp006_read(&dev, &rawvolt, &rawtemp, &drdy);
if (drdy) {
printf("Raw data T: %5d V: %5d\n", rawtemp, rawvolt);
tmp006_convert(rawvolt, rawtemp, &tamb, &tobj);
printf("Data Tabm: %d Tobj: %d\n", (int)(tamb*100), (int)(tobj*100));
}
else {
printf("conversion in progress\n");
puts("conversion in progress ... ");
}
tmp006_convert(rawvolt, rawtemp, &tamb, &tobj);
printf("Data Tabm: %d Tobj: %d\n", (int)(tamb*100), (int)(tobj*100));
xtimer_usleep(TMP006_CONVERSION_TIME);
}

Loading…
Cancel
Save