Contiki 2.6
|
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 "contiki.h" 00044 #include "i2cmaster.h" 00045 #include "tmp102.h" 00046 00047 00048 00049 /* Bitmasks and bit flag variable for keeping track of tmp102 status. */ 00050 enum TMP102_STATUSTYPES 00051 { 00052 /* must be a bit and not more, not using 0x00. */ 00053 INITED = 0x01, 00054 RUNNING = 0x02, 00055 STOPPED = 0x04, 00056 LOW_POWER = 0x08, 00057 AAA = 0x10, // available to extend this... 00058 BBB = 0x20, // available to extend this... 00059 CCC = 0x40, // available to extend this... 00060 DDD = 0x80 // available to extend this... 00061 }; 00062 static enum TMP102_STATUSTYPES _TMP102_STATUS = 0x00; 00063 00064 00065 /*---------------------------------------------------------------------------*/ 00066 //PROCESS(tmp102_process, "Temperature Sensor process"); 00067 00068 /*---------------------------------------------------------------------------*/ 00069 /* Init the temperature sensor: ports, pins, registers, interrupts (none enabled), I2C, 00070 default threshold values etc. */ 00071 00072 void 00073 tmp102_init (void) 00074 { 00075 if (!(_TMP102_STATUS & INITED)) 00076 { 00077 PRINTFDEBUG ("TMP102 init\n"); 00078 _TMP102_STATUS |= INITED; 00079 /* Power Up TMP102 via pin */ 00080 TMP102_PWR_DIR |= TMP102_PWR_PIN; 00081 TMP102_PWR_SEL &= ~TMP102_PWR_SEL; 00082 TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; 00083 TMP102_PWR_REN &= ~TMP102_PWR_SEL; 00084 TMP102_PWR_OUT |= TMP102_PWR_PIN; 00085 00086 /* Set up ports and pins for I2C communication */ 00087 i2c_enable (); 00088 00089 } 00090 } 00091 00092 /*---------------------------------------------------------------------------*/ 00093 /* Write to a 16-bit register. 00094 args: 00095 reg register to write to 00096 val value to write 00097 */ 00098 00099 void 00100 tmp102_write_reg (uint8_t reg, uint16_t val) 00101 { 00102 uint8_t tx_buf[] = { reg, 0x00, 0x00 }; 00103 00104 tx_buf[1] = (uint8_t) (val >> 8); 00105 tx_buf[2] = (uint8_t) (val & 0x00FF); 00106 00107 i2c_transmitinit (TMP102_ADDR); 00108 while (i2c_busy ()); 00109 PRINTFDEBUG ("I2C Ready to TX\n"); 00110 00111 i2c_transmit_n (3, tx_buf); 00112 while (i2c_busy ()); 00113 PRINTFDEBUG ("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); 00114 } 00115 00116 /*---------------------------------------------------------------------------*/ 00117 /* Read register. 00118 args: 00119 reg what register to read 00120 returns the value of the read register type uint16_t 00121 */ 00122 00123 uint16_t 00124 tmp102_read_reg (uint8_t reg) 00125 { 00126 uint8_t buf[] = { 0x00, 0x00 }; 00127 uint16_t retVal = 0; 00128 uint8_t rtx = reg; 00129 PRINTFDEBUG ("READ_REG 0x%02X\n", reg); 00130 00131 // transmit the register to read 00132 i2c_transmitinit (TMP102_ADDR); 00133 while (i2c_busy ()); 00134 i2c_transmit_n (1, &rtx); 00135 while (i2c_busy ()); 00136 00137 // receive the data 00138 i2c_receiveinit (TMP102_ADDR); 00139 while (i2c_busy ()); 00140 i2c_receive_n (2, &buf[0]); 00141 while (i2c_busy ()); 00142 00143 retVal = (uint16_t) (buf[0] << 8 | (buf[1])); 00144 00145 return retVal; 00146 } 00147 00148 /*---------------------------------------------------------------------------*/ 00149 /* Read temperature in a raw format. Further processing will be needed 00150 to make an interpretation of these 12 or 13-bit data, depending on configuration 00151 */ 00152 00153 uint16_t 00154 tmp102_read_temp_raw (void) 00155 { 00156 uint16_t rd = 0; 00157 00158 rd = tmp102_read_reg (TMP102_TEMP); 00159 00160 return rd; 00161 } 00162 00163 int16_t 00164 tmp102_read_temp_x100(void) 00165 { 00166 int16_t raw = 0; 00167 int8_t rd = 0; 00168 int16_t sign = 1; 00169 int16_t abstemp, temp_int; 00170 00171 raw = (int16_t) tmp102_read_reg (TMP102_TEMP); 00172 if(raw < 0) { 00173 abstemp = (raw ^ 0xFFFF) + 1; 00174 sign = -1; 00175 } else { 00176 abstemp = raw; 00177 } 00178 00179 /* Integer part of the temperature value and percents*/ 00180 temp_int = (abstemp >> 8) * sign * 100; 00181 temp_int += ((abstemp & 0xff) * 100) / 0x100; 00182 00183 /* See test-tmp102.c on how to print values of temperature with decimals 00184 fractional part in 1/10000 of degree 00185 temp_frac = ((abstemp >>4) % 16) * 625; 00186 Data could be multiplied by 63 to have less bit-growth and 1/1000 precision 00187 Data could be multiplied by 64 (<< 6) to trade-off precision for speed 00188 */ 00189 00190 return temp_int; 00191 } 00192 00193 /*---------------------------------------------------------------------------*/ 00194 /* Simple Read temperature. Return is an integer with temperature in 1deg. precision 00195 Return value is a signed 8 bit integer. 00196 */ 00197 00198 int8_t 00199 tmp102_read_temp_simple (void) 00200 { 00201 return (int8_t) tmp102_read_temp_x100() / 100; 00202 }