Contiki 2.6

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