Contiki 2.5
tmp102.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Swedish Institute of Computer Science.
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 Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Device drivers for tmp102 temperature sensor in Zolertia Z1.
36  * \author
37  * Enric M. Calvo, Zolertia <ecalvo@zolertia.com>
38  * Marcus Lundén, SICS <mlunden@sics.se>
39  */
40 
41 
42 #include <stdio.h>
43 #include "contiki.h"
44 #include "i2cmaster.h"
45 #include "tmp102.h"
46 
47 
48 
49 /* Bitmasks and bit flag variable for keeping track of tmp102 status. */
50 enum TMP102_STATUSTYPES
51 {
52  /* must be a bit and not more, not using 0x00. */
53  INITED = 0x01,
54  RUNNING = 0x02,
55  STOPPED = 0x04,
56  LOW_POWER = 0x08,
57  AAA = 0x10, // available to extend this...
58  BBB = 0x20, // available to extend this...
59  CCC = 0x40, // available to extend this...
60  DDD = 0x80 // available to extend this...
61 };
62 static enum TMP102_STATUSTYPES _TMP102_STATUS = 0x00;
63 
64 
65 /*---------------------------------------------------------------------------*/
66 //PROCESS(tmp102_process, "Temperature Sensor process");
67 
68 /*---------------------------------------------------------------------------*/
69 /* Init the temperature sensor: ports, pins, registers, interrupts (none enabled), I2C,
70  default threshold values etc. */
71 
72 void
73 tmp102_init (void)
74 {
75  if (!(_TMP102_STATUS & INITED))
76  {
77  PRINTFDEBUG ("TMP102 init\n");
78  _TMP102_STATUS |= INITED;
79  /* Power Up TMP102 via pin */
80  TMP102_PWR_DIR |= TMP102_PWR_PIN;
81  TMP102_PWR_SEL &= ~TMP102_PWR_SEL;
82  TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL;
83  TMP102_PWR_REN &= ~TMP102_PWR_SEL;
84  TMP102_PWR_OUT |= TMP102_PWR_PIN;
85 
86  /* Set up ports and pins for I2C communication */
87  i2c_enable ();
88 
89  }
90 }
91 
92 /*---------------------------------------------------------------------------*/
93 /* Write to a 16-bit register.
94  args:
95  reg register to write to
96  val value to write
97 */
98 
99 void
100 tmp102_write_reg (u8_t reg, u16_t val)
101 {
102  u8_t tx_buf[] = { reg, 0x00, 0x00 };
103 
104  tx_buf[1] = (u8_t) (val >> 8);
105  tx_buf[2] = (u8_t) (val & 0x00FF);
106 
107  i2c_transmitinit (TMP102_ADDR);
108  while (i2c_busy ());
109  PRINTFDEBUG ("I2C Ready to TX\n");
110 
111  i2c_transmit_n (3, tx_buf);
112  while (i2c_busy ());
113  PRINTFDEBUG ("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg);
114 }
115 
116 /*---------------------------------------------------------------------------*/
117 /* Read register.
118  args:
119  reg what register to read
120  returns the value of the read register type u16_t
121 */
122 
123 u16_t
124 tmp102_read_reg (u8_t reg)
125 {
126  u8_t buf[] = { 0x00, 0x00 };
127  u16_t retVal = 0;
128  u8_t rtx = reg;
129  PRINTFDEBUG ("READ_REG 0x%02X\n", reg);
130 
131  // transmit the register to read
132  i2c_transmitinit (TMP102_ADDR);
133  while (i2c_busy ());
134  i2c_transmit_n (1, &rtx);
135  while (i2c_busy ());
136 
137  // receive the data
138  i2c_receiveinit (TMP102_ADDR);
139  while (i2c_busy ());
140  i2c_receive_n (2, &buf[0]);
141  while (i2c_busy ());
142 
143  retVal = (u16_t) (buf[0] << 8 | (buf[1]));
144 
145  return retVal;
146 }
147 
148 /*---------------------------------------------------------------------------*/
149 /* Read temperature in a raw format. Further processing will be needed
150  to make an interpretation of these 12 or 13-bit data, depending on configuration
151 */
152 
153 u16_t
154 tmp102_read_temp_raw (void)
155 {
156  u16_t rd = 0;
157 
158  rd = tmp102_read_reg (TMP102_TEMP);
159 
160  return rd;
161 }
162 
163 /*---------------------------------------------------------------------------*/
164 /* Simple Read temperature. Return is an integer with temperature in 1deg. precision
165  Return value is a signed 8 bit integer.
166 */
167 
168 int8_t
169 tmp102_read_temp_simple (void)
170 {
171  int16_t raw = 0;
172  int8_t rd = 0;
173  int16_t sign = 1;
174  int16_t abstemp, temp_int;
175 
176  raw = (int16_t) tmp102_read_reg (TMP102_TEMP);
177  if(raw < 0) {
178  abstemp = (raw ^ 0xFFFF) + 1;
179  sign = -1;
180  } else {
181  abstemp = raw;
182  }
183 
184  /* Integer part of the temperature value */
185  temp_int = (abstemp >> 8) * sign;
186 
187  /* See test-tmp102.c on how to print values of temperature with decimals
188  fractional part in 1/10000 of degree
189  temp_frac = ((abstemp >>4) % 16) * 625;
190  Data could be multiplied by 63 to have less bit-growth and 1/1000 precision
191  Data could be multiplied by 64 (<< 6) to trade-off precision for speed
192  */
193 
194  rd = (int8_t) (temp_int);
195  return rd;
196 }