Contiki-NG
Loading...
Searching...
No Matches
tmp-007-sensor.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/*---------------------------------------------------------------------------*/
31/**
32 * \addtogroup sensortag-cc26xx-tmp-sensor
33 * @{
34 *
35 * \file
36 * Driver for the Sensortag TI TMP007 infrared thermophile sensor
37 */
38/*---------------------------------------------------------------------------*/
39#include "contiki.h"
40#include "lib/sensors.h"
41#include "tmp-007-sensor.h"
42#include "sys/ctimer.h"
43#include "board-i2c.h"
44#include "sensor-common.h"
45#include "ti-lib.h"
46
47#include <stdint.h>
48#include <string.h>
49#include <stdio.h>
50#include <math.h>
51/*---------------------------------------------------------------------------*/
52#define DEBUG 0
53#if DEBUG
54#define PRINTF(...) printf(__VA_ARGS__)
55#else
56#define PRINTF(...)
57#endif
58/*---------------------------------------------------------------------------*/
59/* Slave address */
60#define SENSOR_I2C_ADDRESS 0x44
61/*---------------------------------------------------------------------------*/
62/* TMP007 register addresses */
63#define TMP007_REG_ADDR_VOLTAGE 0x00
64#define TMP007_REG_ADDR_LOCAL_TEMP 0x01
65#define TMP007_REG_ADDR_CONFIG 0x02
66#define TMP007_REG_ADDR_OBJ_TEMP 0x03
67#define TMP007_REG_ADDR_STATUS 0x04
68#define TMP007_REG_PROD_ID 0x1F
69/*---------------------------------------------------------------------------*/
70/* TMP007 register values */
71#define TMP007_VAL_CONFIG_ON 0x1000 /* Sensor on state */
72#define TMP007_VAL_CONFIG_OFF 0x0000 /* Sensor off state */
73#define TMP007_VAL_CONFIG_RESET 0x8000
74#define TMP007_VAL_PROD_ID 0x0078 /* Product ID */
75/*---------------------------------------------------------------------------*/
76/* Conversion ready (status register) bit values */
77#define CONV_RDY_BIT 0x4000
78/*---------------------------------------------------------------------------*/
79/* Register length */
80#define REGISTER_LENGTH 2
81/*---------------------------------------------------------------------------*/
82/* Sensor data size */
83#define DATA_SIZE 4
84/*---------------------------------------------------------------------------*/
85/* Byte swap of 16-bit register value */
86#define HI_UINT16(a) (((a) >> 8) & 0xFF)
87#define LO_UINT16(a) ((a) & 0xFF)
88
89#define SWAP(v) ((LO_UINT16(v) << 8) | HI_UINT16(v))
90/*---------------------------------------------------------------------------*/
91#define SELECT() board_i2c_select(BOARD_I2C_INTERFACE_0, SENSOR_I2C_ADDRESS)
92/*---------------------------------------------------------------------------*/
93static uint8_t buf[DATA_SIZE];
94static uint16_t val;
95/*---------------------------------------------------------------------------*/
96#define SENSOR_STATUS_DISABLED 0
97#define SENSOR_STATUS_INITIALISED 1
98#define SENSOR_STATUS_NOT_READY 2
99#define SENSOR_STATUS_READY 3
100
101static int enabled = SENSOR_STATUS_DISABLED;
102/*---------------------------------------------------------------------------*/
103/* Wait SENSOR_STARTUP_DELAY clock ticks for the sensor to be ready - 275ms */
104#define SENSOR_STARTUP_DELAY 36
105
106static struct ctimer startup_timer;
107/*---------------------------------------------------------------------------*/
108/* Latched values */
109static int obj_temp_latched;
110static int amb_temp_latched;
111/*---------------------------------------------------------------------------*/
112static void
113notify_ready(void *not_used)
114{
115 enabled = SENSOR_STATUS_READY;
116 sensors_changed(&tmp_007_sensor);
117}
118/*---------------------------------------------------------------------------*/
119/**
120 * \brief Turn the sensor on/off
121 */
122static bool
123enable_sensor(bool enable)
124{
125 bool success;
126
127 SELECT();
128
129 if(enable) {
130 val = TMP007_VAL_CONFIG_ON;
131 } else {
132 val = TMP007_VAL_CONFIG_OFF;
133 }
134 val = SWAP(val);
135
136 success = sensor_common_write_reg(TMP007_REG_ADDR_CONFIG, (uint8_t *)&val,
137 REGISTER_LENGTH);
138
139 return success;
140}
141/*---------------------------------------------------------------------------*/
142/**
143 * \brief Read the sensor value registers
144 * \param raw_temp Temperature in 16 bit format
145 * \param raw_obj_temp object temperature in 16 bit format
146 * \return TRUE if valid data could be retrieved
147 */
148static bool
150{
151 bool success;
152
153 SELECT();
154
155 success = sensor_common_read_reg(TMP007_REG_ADDR_STATUS, (uint8_t *)&val,
156 REGISTER_LENGTH);
157
158 if(success) {
159 val = SWAP(val);
160 success = val & CONV_RDY_BIT;
161 }
162
163 if(success) {
164 success = sensor_common_read_reg(TMP007_REG_ADDR_LOCAL_TEMP, &buf[0],
165 REGISTER_LENGTH);
166 if(success) {
167 success = sensor_common_read_reg(TMP007_REG_ADDR_OBJ_TEMP, &buf[2],
168 REGISTER_LENGTH);
169 }
170 }
171
172 if(!success) {
174 }
175
176 /* Swap byte order */
177 *raw_temp = buf[0] << 8 | buf[1];
178 *raw_obj_temp = buf[2] << 8 | buf[3];
179
180 return success;
181}
182/*---------------------------------------------------------------------------*/
183/**
184 * \brief Convert raw data to values in degrees C
185 * \param raw_temp raw ambient temperature from sensor
186 * \param raw_obj_temp raw object temperature from sensor
187 * \param obj converted object temperature
188 * \param amb converted ambient temperature
189 */
190static void
191convert(uint16_t raw_temp, uint16_t raw_obj_temp, float *obj, float *amb)
192{
193 const float SCALE_LSB = 0.03125;
194 float t;
195 int it;
196
197 it = (int)((raw_obj_temp) >> 2);
198 t = ((float)(it)) * SCALE_LSB;
199 *obj = t;
200
201 it = (int)((raw_temp) >> 2);
202 t = (float)it;
203 *amb = t * SCALE_LSB;
204}
205/*---------------------------------------------------------------------------*/
206/**
207 * \brief Returns a reading from the sensor
208 * \param type TMP_007_SENSOR_TYPE_OBJECT or TMP_007_SENSOR_TYPE_AMBIENT
209 * \return Object or Ambient temperature in milli degrees C
210 */
211static int
212value(int type)
213{
214 int rv;
215 uint16_t raw_temp;
217 float obj_temp;
218 float amb_temp;
219
220 if(enabled != SENSOR_STATUS_READY) {
221 PRINTF("Sensor disabled or starting up (%d)\n", enabled);
222 return CC26XX_SENSOR_READING_ERROR;
223 }
224
225 if((type & TMP_007_SENSOR_TYPE_ALL) == 0) {
226 PRINTF("Invalid type\n");
227 return CC26XX_SENSOR_READING_ERROR;
228 }
229
230 rv = CC26XX_SENSOR_READING_ERROR;
231
232 if(type == TMP_007_SENSOR_TYPE_ALL) {
233 rv = read_data(&raw_temp, &raw_obj_temp);
234
235 if(rv == 0) {
236 return CC26XX_SENSOR_READING_ERROR;
237 }
238
239 convert(raw_temp, raw_obj_temp, &obj_temp, &amb_temp);
240 PRINTF("TMP: %04X %04X o=%d a=%d\n", raw_temp, raw_obj_temp,
241 (int)(obj_temp * 1000), (int)(amb_temp * 1000));
242
243 obj_temp_latched = (int)(obj_temp * 1000);
244 amb_temp_latched = (int)(amb_temp * 1000);
245 rv = 1;
246 } else if(type == TMP_007_SENSOR_TYPE_OBJECT) {
247 rv = obj_temp_latched;
248 } else if(type == TMP_007_SENSOR_TYPE_AMBIENT) {
249 rv = amb_temp_latched;
250 }
251
252 return rv;
253}
254/*---------------------------------------------------------------------------*/
255/**
256 * \brief Configuration function for the TMP007 sensor.
257 *
258 * \param type Activate, enable or disable the sensor. See below
259 * \param enable
260 *
261 * When type == SENSORS_HW_INIT we turn on the hardware
262 * When type == SENSORS_ACTIVE and enable==1 we enable the sensor
263 * When type == SENSORS_ACTIVE and enable==0 we disable the sensor
264 */
265static int
266configure(int type, int enable)
267{
268 switch(type) {
269 case SENSORS_HW_INIT:
270 ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_TMP_RDY);
271 ti_lib_ioc_io_port_pull_set(BOARD_IOID_TMP_RDY, IOC_IOPULL_UP);
272 ti_lib_ioc_io_hyst_set(BOARD_IOID_TMP_RDY, IOC_HYST_ENABLE);
273
274 enable_sensor(false);
275 enabled = SENSOR_STATUS_INITIALISED;
276 break;
277 case SENSORS_ACTIVE:
278 /* Must be initialised first */
279 if(enabled == SENSOR_STATUS_DISABLED) {
280 return SENSOR_STATUS_DISABLED;
281 }
282 if(enable) {
283 enable_sensor(true);
284 ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL);
285 enabled = SENSOR_STATUS_NOT_READY;
286 } else {
287 ctimer_stop(&startup_timer);
288 enable_sensor(false);
289 enabled = SENSOR_STATUS_INITIALISED;
290 }
291 break;
292 default:
293 break;
294 }
295 return enabled;
296}
297/*---------------------------------------------------------------------------*/
298/**
299 * \brief Returns the status of the sensor
300 * \param type SENSORS_ACTIVE or SENSORS_READY
301 * \return 1 if the sensor is enabled
302 */
303static int
304status(int type)
305{
306 switch(type) {
307 case SENSORS_ACTIVE:
308 case SENSORS_READY:
309 return enabled;
310 break;
311 default:
312 break;
313 }
314 return SENSOR_STATUS_DISABLED;
315}
316/*---------------------------------------------------------------------------*/
317SENSORS_SENSOR(tmp_007_sensor, "TMP007", value, configure, status);
318/*---------------------------------------------------------------------------*/
319/** @} */
Header file for the Sensortag I2C Driver.
Header file for the Sensortag TI TMP007 infrared thermophile sensor.
Header file for the callback timer.
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition ctimer.c:138
static void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition ctimer.h:137
#define BOARD_IOID_TMP_RDY
TMP Sensor.
Definition board.h:200
static bool read_data()
Take readings from the sensor.
void sensor_common_set_error_data(uint8_t *buf, uint8_t len)
Fill a result buffer with dummy error data.
bool sensor_common_read_reg(uint8_t addr, uint8_t *buf, uint8_t len)
Reads a sensor's register over I2C.
bool sensor_common_write_reg(uint8_t addr, uint8_t *buf, uint8_t len)
Write to a sensor's register over I2C.
static int value(int type)
Returns a reading from the sensor.
static int status(int type)
Returns the status of the sensor.
static bool enable_sensor(bool enable)
Turn the sensor on/off.
static void convert(uint16_t raw_temp, uint16_t raw_obj_temp, float *obj, float *amb)
Convert raw data to values in degrees C.
static int configure(int type, int enable)
Configuration function for the TMP007 sensor.
Header file for the Sensortag Common sensor utilities.
Header file with macros which rename TI CC26xxware functions.