Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, 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 * @(#)$Id: sht11.c,v 1.3 2008/11/10 21:10:36 adamdunkels Exp $ 00030 */ 00031 00032 /* 00033 * Device driver for the Sensirion SHT1x/SHT7x family of humidity and 00034 * temperature sensors. 00035 */ 00036 00037 #include "contiki.h" 00038 #include <stdio.h> 00039 #include <dev/sht11.h> 00040 #include "sht11-arch.h" 00041 00042 #define DEBUG 0 00043 00044 #if DEBUG 00045 #include <stdio.h> 00046 #define PRINTF(...) printf(__VA_ARGS__) 00047 #else 00048 #define PRINTF(...) 00049 #endif 00050 00051 #ifndef SDA_0 00052 #define SDA_0() (SHT11_PxDIR |= BV(SHT11_ARCH_SDA)) /* SDA Output=0 */ 00053 #define SDA_1() (SHT11_PxDIR &= ~BV(SHT11_ARCH_SDA)) /* SDA Input */ 00054 #define SDA_IS_1 (SHT11_PxIN & BV(SHT11_ARCH_SDA)) 00055 00056 #define SCL_0() (SHT11_PxOUT &= ~BV(SHT11_ARCH_SCL)) /* SCL Output=0 */ 00057 #define SCL_1() (SHT11_PxOUT |= BV(SHT11_ARCH_SCL)) /* SCL Output=1 */ 00058 #endif 00059 /* adr command r/w */ 00060 #define STATUS_REG_W 0x06 /* 000 0011 0 */ 00061 #define STATUS_REG_R 0x07 /* 000 0011 1 */ 00062 #define MEASURE_TEMP 0x03 /* 000 0001 1 */ 00063 #define MEASURE_HUMI 0x05 /* 000 0010 1 */ 00064 #define RESET 0x1e /* 000 1111 0 */ 00065 00066 /* This can probably be reduced to 250ns according to data sheet. */ 00067 #ifndef delay_400ns 00068 #define delay_400ns() _NOP() 00069 #endif 00070 /*---------------------------------------------------------------------------*/ 00071 static void 00072 sstart(void) 00073 { 00074 SDA_1(); SCL_0(); 00075 delay_400ns(); 00076 SCL_1(); 00077 delay_400ns(); 00078 SDA_0(); 00079 delay_400ns(); 00080 SCL_0(); 00081 delay_400ns(); 00082 SCL_1(); 00083 delay_400ns(); 00084 SDA_1(); 00085 delay_400ns(); 00086 SCL_0(); 00087 } 00088 /*---------------------------------------------------------------------------*/ 00089 static void 00090 sreset(void) 00091 { 00092 int i; 00093 SDA_1(); 00094 SCL_0(); 00095 for(i = 0; i < 9 ; i++) { 00096 SCL_1(); 00097 delay_400ns(); 00098 SCL_0(); 00099 delay_400ns(); 00100 } 00101 sstart(); /* Start transmission, why??? */ 00102 } 00103 /*---------------------------------------------------------------------------*/ 00104 /* 00105 * Return true if we received an ACK. 00106 */ 00107 static int 00108 swrite(unsigned _c) 00109 { 00110 unsigned char c = _c; 00111 int i; 00112 int ret; 00113 00114 for(i = 0; i < 8; i++, c <<= 1) { 00115 if(c & 0x80) { 00116 SDA_1(); 00117 } else { 00118 SDA_0(); 00119 } 00120 SCL_1(); 00121 delay_400ns(); 00122 SCL_0(); 00123 delay_400ns(); 00124 } 00125 00126 SDA_1(); 00127 SCL_1(); 00128 delay_400ns(); 00129 ret = !SDA_IS_1; 00130 00131 SCL_0(); 00132 00133 return ret; 00134 } 00135 /*---------------------------------------------------------------------------*/ 00136 static unsigned 00137 sread(int send_ack) 00138 { 00139 int i; 00140 unsigned char c = 0x00; 00141 00142 SDA_1(); 00143 for(i = 0; i < 8; i++) { 00144 c <<= 1; 00145 SCL_1(); 00146 delay_400ns(); 00147 if(SDA_IS_1) { 00148 c |= 0x1; 00149 } 00150 SCL_0(); 00151 delay_400ns(); 00152 } 00153 00154 if(send_ack) { 00155 SDA_0(); 00156 } 00157 SCL_1(); 00158 delay_400ns(); 00159 SCL_0(); 00160 00161 SDA_1(); /* Release SDA */ 00162 00163 return c; 00164 } 00165 /*---------------------------------------------------------------------------*/ 00166 #define CRC_CHECK 00167 #ifdef CRC_CHECK 00168 static unsigned char 00169 rev8bits(unsigned char v) 00170 { 00171 unsigned char r = v; 00172 int s = 7; 00173 00174 for (v >>= 1; v; v >>= 1) { 00175 r <<= 1; 00176 r |= v & 1; 00177 s--; 00178 } 00179 r <<= s; /* Shift when v's highest bits are zero */ 00180 return r; 00181 } 00182 /*---------------------------------------------------------------------------*/ 00183 /* BEWARE: Bit reversed CRC8 using polynomial ^8 + ^5 + ^4 + 1 */ 00184 static unsigned 00185 crc8_add(unsigned acc, unsigned byte) 00186 { 00187 int i; 00188 acc ^= byte; 00189 for(i = 0; i < 8; i++) { 00190 if(acc & 0x80) { 00191 acc = (acc << 1) ^ 0x31; 00192 } else { 00193 acc <<= 1; 00194 } 00195 } 00196 return acc & 0xff; 00197 } 00198 #endif /* CRC_CHECK */ 00199 /*---------------------------------------------------------------------------*/ 00200 /* 00201 * Power up the device. The device can be used after an additional 00202 * 11ms waiting time. 00203 */ 00204 void 00205 sht11_init(void) 00206 { 00207 /* 00208 * SCL Output={0,1} 00209 * SDA 0: Output=0 00210 * 1: Input and pull-up (Output=0) 00211 */ 00212 #ifdef SHT11_INIT 00213 SHT11_INIT(); 00214 #else 00215 SHT11_PxOUT |= BV(SHT11_ARCH_PWR); 00216 SHT11_PxOUT &= ~(BV(SHT11_ARCH_SDA) | BV(SHT11_ARCH_SCL)); 00217 SHT11_PxDIR |= BV(SHT11_ARCH_PWR) | BV(SHT11_ARCH_SCL); 00218 #endif 00219 } 00220 /*---------------------------------------------------------------------------*/ 00221 /* 00222 * Power of device. 00223 */ 00224 void 00225 sht11_off(void) 00226 { 00227 #ifdef SHT11_OFF 00228 SHT11_OFF(); 00229 #else 00230 SHT11_PxOUT &= ~BV(SHT11_ARCH_PWR); 00231 SHT11_PxOUT &= ~(BV(SHT11_ARCH_SDA) | BV(SHT11_ARCH_SCL)); 00232 SHT11_PxDIR |= BV(SHT11_ARCH_PWR) | BV(SHT11_ARCH_SCL); 00233 #endif 00234 } 00235 /*---------------------------------------------------------------------------*/ 00236 /* 00237 * Only commands MEASURE_HUMI or MEASURE_TEMP! 00238 */ 00239 static unsigned int 00240 scmd(unsigned cmd) 00241 { 00242 unsigned long n; 00243 00244 if(cmd != MEASURE_HUMI && cmd != MEASURE_TEMP) { 00245 PRINTF("Illegal command: %d\n", cmd); 00246 return -1; 00247 } 00248 00249 sstart(); /* Start transmission */ 00250 if(!swrite(cmd)) { 00251 PRINTF("SHT11: scmd - swrite failed\n"); 00252 goto fail; 00253 } 00254 00255 for(n = 0; n < 250000; n++) { 00256 if(!SDA_IS_1) { 00257 unsigned t0, t1, rcrc; 00258 t0 = sread(1); 00259 t1 = sread(1); 00260 rcrc = sread(0); 00261 PRINTF("SHT11: scmd - read %d, %d\n", t0, t1); 00262 #ifdef CRC_CHECK 00263 { 00264 unsigned crc; 00265 crc = crc8_add(0x0, cmd); 00266 crc = crc8_add(crc, t0); 00267 crc = crc8_add(crc, t1); 00268 if(crc != rev8bits(rcrc)) { 00269 PRINTF("SHT11: scmd - crc check failed %d vs %d\n", 00270 crc, rev8bits(rcrc)); 00271 goto fail; 00272 } 00273 } 00274 #endif 00275 return (t0 << 8) | t1; 00276 } 00277 } 00278 00279 fail: 00280 sreset(); 00281 return -1; 00282 } 00283 /*---------------------------------------------------------------------------*/ 00284 /* 00285 * Call may take up to 210ms. 00286 */ 00287 unsigned int 00288 sht11_temp(void) 00289 { 00290 return scmd(MEASURE_TEMP); 00291 } 00292 /*---------------------------------------------------------------------------*/ 00293 /* 00294 * Call may take up to 210ms. 00295 */ 00296 unsigned int 00297 sht11_humidity(void) 00298 { 00299 return scmd(MEASURE_HUMI); 00300 } 00301 /*---------------------------------------------------------------------------*/ 00302 #if 1 /* But ok! */ 00303 unsigned 00304 sht11_sreg(void) 00305 { 00306 unsigned sreg, rcrc; 00307 00308 sstart(); /* Start transmission */ 00309 if(!swrite(STATUS_REG_R)) { 00310 goto fail; 00311 } 00312 00313 sreg = sread(1); 00314 rcrc = sread(0); 00315 00316 #ifdef CRC_CHECK 00317 { 00318 unsigned crc; 00319 crc = crc8_add(0x0, STATUS_REG_R); 00320 crc = crc8_add(crc, sreg); 00321 if (crc != rev8bits(rcrc)) 00322 goto fail; 00323 } 00324 #endif 00325 00326 return sreg; 00327 00328 fail: 00329 sreset(); 00330 return -1; 00331 } 00332 #endif 00333 /*---------------------------------------------------------------------------*/ 00334 #if 0 00335 int 00336 sht11_set_sreg(unsigned sreg) 00337 { 00338 sstart(); /* Start transmission */ 00339 if(!swrite(STATUS_REG_W)) { 00340 goto fail; 00341 } 00342 if(!swrite(sreg)) { 00343 goto fail; 00344 } 00345 00346 return 0; 00347 00348 fail: 00349 sreset(); 00350 return -1; 00351 } 00352 #endif 00353 /*---------------------------------------------------------------------------*/ 00354 #if 0 00355 int 00356 sht11_reset(void) 00357 { 00358 sstart(); /* Start transmission */ 00359 if(!swrite(RESET)) { 00360 goto fail; 00361 } 00362 00363 return 0; 00364 00365 fail: 00366 sreset(); 00367 return -1; 00368 } 00369 #endif 00370 /*---------------------------------------------------------------------------*/