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