ds2411.c

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 /*---------------------------------------------------------------------------*/

Generated on Mon Apr 11 14:23:28 2011 for Contiki 2.5 by  doxygen 1.6.1