00001 /* 00002 * Copyright (c) 2005, 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 * @(#)$Id: ds2411.c,v 1.5 2010/08/25 18:35:52 nifi Exp $ 00032 */ 00033 /* 00034 * Device driver for the Dallas Semiconductor DS2411 chip. Heavily 00035 * based on the application note 126 "1-Wire Communications Through 00036 * Software". 00037 * 00038 * http://www.maxim-ic.com/appnotes.cfm/appnote_number/126 00039 */ 00040 00041 /* 00042 * For now we stuff in Moteiv Corporation's unique OUI. 00043 * From http://www.ethereal.com/distribution/manuf.txt: 00044 * 00:12:75 Moteiv # Moteiv Corporation 00045 * 00046 * The EUI-64 is a concatenation of the 24-bit OUI value assigned by 00047 * the IEEE Registration Authority and a 40-bit extension identifier 00048 * assigned by the organization with that OUI assignment. 00049 */ 00050 00051 #include <string.h> 00052 00053 #include <io.h> 00054 00055 #include "contiki.h" 00056 00057 #include "dev/ds2411.h" 00058 00059 unsigned char ds2411_id[8]; 00060 00061 #ifdef CONTIKI_TARGET_SKY 00062 /* 1-wire is at p2.4 */ 00063 #define PIN BV(4) 00064 00065 #define PIN_INIT() {\ 00066 P2DIR &= ~PIN; /* p2.4 in, resistor pull high */\ 00067 P2OUT &= ~PIN; /* p2.4 == 0 but still input */\ 00068 } 00069 00070 /* Set 1-Wire low or high. */ 00071 #define OUTP_0() (P2DIR |= PIN) /* output and p2.4 == 0 from above */ 00072 #define OUTP_1() (P2DIR &= ~PIN) /* p2.4 in, external resistor pull high */ 00073 00074 /* Read one bit. */ 00075 #define INP() (P2IN & PIN) 00076 00077 /* 00078 * Delay for u microseconds on a MSP430 at 2.4756MHz. 00079 * 00080 * The loop in clock_delay consists of one add and one jnz, i.e 3 00081 * cycles. 00082 * 00083 * 3 cycles at 2.4756MHz ==> 1.2us = 6/5us. 00084 * 00085 * Call overhead is roughly 7 cycles and the loop 3 cycles, to 00086 * compensate for call overheads we make 7/3=14/6 fewer laps in the 00087 * loop. 00088 * 00089 * This macro will loose badly if not passed a constant argument, it 00090 * relies on the compiler doing the arithmetic during compile time!! 00091 * TODO: Fix above comment to be correct - below code is modified for 4Mhz 00092 */ 00093 #define udelay(u) clock_delay((u*8 - 14)/6) 00094 00095 /* 00096 * Where call overhead dominates, use a macro! 00097 * Note: modified for 4 Mhz 00098 */ 00099 #define udelay_6() { _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); } 00100 00101 #endif /* CONTIKI_TARGET_SKY */ 00102 00103 /* 00104 * Recommended delay times in us. 00105 */ 00106 #define udelay_tA() udelay_6() 00107 /* tA 6 max 15 */ 00108 #define tB 64 00109 #define tC 60 /* max 120 */ 00110 #define tD 10 00111 #define tE 9 /* max 12 */ 00112 #define tF 55 00113 #define tG 0 00114 #define tH 480 00115 #define tI 70 00116 #define tJ 410 00117 /*---------------------------------------------------------------------------*/ 00118 static int 00119 owreset(void) 00120 { 00121 int result; 00122 OUTP_0(); 00123 udelay(tH); 00124 OUTP_1(); /* Releases the bus */ 00125 udelay(tI); 00126 result = INP(); 00127 udelay(tJ); 00128 return result; 00129 } 00130 /*---------------------------------------------------------------------------*/ 00131 static void 00132 owwriteb(unsigned byte) 00133 { 00134 int i = 7; 00135 do { 00136 if(byte & 0x01) { 00137 OUTP_0(); 00138 udelay_tA(); 00139 OUTP_1(); /* Releases the bus */ 00140 udelay(tB); 00141 } else { 00142 OUTP_0(); 00143 udelay(tC); 00144 OUTP_1(); /* Releases the bus */ 00145 udelay(tD); 00146 } 00147 if(i == 0) { 00148 return; 00149 } 00150 i--; 00151 byte >>= 1; 00152 } while(1); 00153 } 00154 /*---------------------------------------------------------------------------*/ 00155 static unsigned 00156 owreadb(void) 00157 { 00158 unsigned result = 0; 00159 int i = 7; 00160 do { 00161 OUTP_0(); 00162 udelay_tA(); 00163 OUTP_1(); /* Releases the bus */ 00164 udelay(tE); 00165 if(INP()) { 00166 result |= 0x80; /* LSbit first */ 00167 } 00168 udelay(tF); 00169 if(i == 0) { 00170 return result; 00171 } 00172 i--; 00173 result >>= 1; 00174 } while(1); 00175 } 00176 /*---------------------------------------------------------------------------*/ 00177 /* Polynomial ^8 + ^5 + ^4 + 1 */ 00178 static unsigned 00179 crc8_add(unsigned acc, unsigned byte) 00180 { 00181 int i; 00182 acc ^= byte; 00183 for(i = 0; i < 8; i++) { 00184 if(acc & 1) { 00185 acc = (acc >> 1) ^ 0x8c; 00186 } else { 00187 acc >>= 1; 00188 } 00189 } 00190 return acc; 00191 } 00192 /*---------------------------------------------------------------------------*/ 00193 int 00194 ds2411_init() 00195 { 00196 int i; 00197 unsigned family, crc, acc; 00198 00199 PIN_INIT(); 00200 00201 if(owreset() == 0) { /* Something pulled down 1-wire. */ 00202 /* 00203 * Read MAC id with interrupts disabled. 00204 */ 00205 int s = splhigh(); 00206 owwriteb(0x33); /* Read ROM command. */ 00207 family = owreadb(); 00208 /* We receive 6 bytes in the reverse order, LSbyte first. */ 00209 for(i = 7; i >= 2; i--) { 00210 ds2411_id[i] = owreadb(); 00211 } 00212 crc = owreadb(); 00213 splx(s); 00214 00215 /* Verify family and that CRC match. */ 00216 if(family != 0x01) { 00217 goto fail; 00218 } 00219 acc = crc8_add(0x0, family); 00220 for(i = 7; i >= 2; i--) { 00221 acc = crc8_add(acc, ds2411_id[i]); 00222 } 00223 if(acc == crc) { 00224 #ifdef CONTIKI_TARGET_SKY 00225 /* 00:12:75 Moteiv # Moteiv Corporation */ 00226 ds2411_id[0] = 0x00; 00227 ds2411_id[1] = 0x12; 00228 ds2411_id[2] = 0x75; 00229 #endif /* CONTIKI_TARGET_SKY */ 00230 return 1; /* Success! */ 00231 } 00232 } 00233 00234 fail: 00235 memset(ds2411_id, 0x0, sizeof(ds2411_id)); 00236 return 0; /* Fail! */ 00237 } 00238 /*---------------------------------------------------------------------------*/