00001 /* 00002 * Copyright (c) 2010, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 00033 /** 00034 * \file 00035 * Device drivers for tmp102 temperature sensor in Zolertia Z1. 00036 * \author 00037 * Enric M. Calvo, Zolertia <ecalvo@zolertia.com> 00038 * Marcus Lundén, SICS <mlunden@sics.se> 00039 */ 00040 00041 00042 #include <stdio.h> 00043 #include <signal.h> 00044 #include "contiki.h" 00045 #include "i2cmaster.h" 00046 #include "tmp102.h" 00047 00048 00049 00050 /* Bitmasks and bit flag variable for keeping track of tmp102 status. */ 00051 enum TMP102_STATUSTYPES 00052 { 00053 /* must be a bit and not more, not using 0x00. */ 00054 INITED = 0x01, 00055 RUNNING = 0x02, 00056 STOPPED = 0x04, 00057 LOW_POWER = 0x08, 00058 AAA = 0x10, // available to extend this... 00059 BBB = 0x20, // available to extend this... 00060 CCC = 0x40, // available to extend this... 00061 DDD = 0x80 // available to extend this... 00062 }; 00063 static enum TMP102_STATUSTYPES _TMP102_STATUS = 0x00; 00064 00065 00066 /*---------------------------------------------------------------------------*/ 00067 //PROCESS(tmp102_process, "Temperature Sensor process"); 00068 00069 /*---------------------------------------------------------------------------*/ 00070 /* Init the temperature sensor: ports, pins, registers, interrupts (none enabled), I2C, 00071 default threshold values etc. */ 00072 00073 void 00074 tmp102_init (void) 00075 { 00076 if (!(_TMP102_STATUS & INITED)) 00077 { 00078 PRINTFDEBUG ("TMP102 init\n"); 00079 _TMP102_STATUS |= INITED; 00080 /* Power Up TMP102 via pin */ 00081 TMP102_PWR_DIR |= TMP102_PWR_PIN; 00082 TMP102_PWR_SEL &= ~TMP102_PWR_SEL; 00083 TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; 00084 TMP102_PWR_REN &= ~TMP102_PWR_SEL; 00085 TMP102_PWR_OUT |= TMP102_PWR_PIN; 00086 00087 /* Set up ports and pins for I2C communication */ 00088 i2c_enable (); 00089 00090 } 00091 } 00092 00093 /*---------------------------------------------------------------------------*/ 00094 /* Write to a 16-bit register. 00095 args: 00096 reg register to write to 00097 val value to write 00098 */ 00099 00100 void 00101 tmp102_write_reg (u8_t reg, u16_t val) 00102 { 00103 u8_t tx_buf[] = { reg, 0x00, 0x00 }; 00104 00105 tx_buf[1] = (u8_t) (val >> 8); 00106 tx_buf[2] = (u8_t) (val & 0x00FF); 00107 00108 i2c_transmitinit (TMP102_ADDR); 00109 while (i2c_busy ()); 00110 PRINTFDEBUG ("I2C Ready to TX\n"); 00111 00112 i2c_transmit_n (3, tx_buf); 00113 while (i2c_busy ()); 00114 PRINTFDEBUG ("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); 00115 } 00116 00117 /*---------------------------------------------------------------------------*/ 00118 /* Read register. 00119 args: 00120 reg what register to read 00121 returns the value of the read register type u16_t 00122 */ 00123 00124 u16_t 00125 tmp102_read_reg (u8_t reg) 00126 { 00127 u8_t buf[] = { 0x00, 0x00 }; 00128 u16_t retVal = 0; 00129 u8_t rtx = reg; 00130 PRINTFDEBUG ("READ_REG 0x%02X\n", reg); 00131 00132 // transmit the register to read 00133 i2c_transmitinit (TMP102_ADDR); 00134 while (i2c_busy ()); 00135 i2c_transmit_n (1, &rtx); 00136 while (i2c_busy ()); 00137 00138 // receive the data 00139 i2c_receiveinit (TMP102_ADDR); 00140 while (i2c_busy ()); 00141 i2c_receive_n (2, &buf[0]); 00142 while (i2c_busy ()); 00143 00144 retVal = (u16_t) (buf[0] << 8 | (buf[1])); 00145 00146 return retVal; 00147 } 00148 00149 /*---------------------------------------------------------------------------*/ 00150 /* Read temperature in a raw format. Further processing will be needed 00151 to make an interpretation of these 12 or 13-bit data, depending on configuration 00152 */ 00153 00154 u16_t 00155 tmp102_read_temp_raw (void) 00156 { 00157 u16_t rd = 0; 00158 00159 rd = tmp102_read_reg (TMP102_TEMP); 00160 00161 return rd; 00162 } 00163 00164 /*---------------------------------------------------------------------------*/ 00165 /* Simple Read temperature. Return is an integer with temperature in 1deg. precision 00166 Return value is a signed 8 bit integer. 00167 */ 00168 00169 int8_t 00170 tmp102_read_temp_simple (void) 00171 { 00172 int16_t raw = 0; 00173 int8_t rd = 0; 00174 int16_t sign = 1; 00175 int16_t abstemp, temp_int; 00176 00177 raw = (int16_t) tmp102_read_reg (TMP102_TEMP); 00178 if (raw < 0) 00179 { 00180 abstemp = (raw ^ 0xFFFF) + 1; 00181 sign = -1; 00182 } 00183 00184 /* Integer part of the temperature value */ 00185 temp_int = (abstemp >> 8) * sign; 00186 00187 /* See test-tmp102.c on how to print values of temperature with decimals 00188 fractional part in 1/10000 of degree 00189 temp_frac = ((abstemp >>4) % 16) * 625; 00190 Data could be multiplied by 63 to have less bit-growth and 1/1000 precision 00191 Data could be multiplied by 64 (<< 6) to trade-off precision for speed 00192 */ 00193 00194 rd = (int8_t) (temp_int); 00195 return rd; 00196 } 00197 00198 00199