Contiki 2.5
ds2411.c
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * @(#)$Id: ds2411.c,v 1.5 2010/08/25 18:35:52 nifi Exp $
32  */
33 /*
34  * Device driver for the Dallas Semiconductor DS2411 chip. Heavily
35  * based on the application note 126 "1-Wire Communications Through
36  * Software".
37  *
38  * http://www.maxim-ic.com/appnotes.cfm/appnote_number/126
39  */
40 
41 /*
42  * For now we stuff in Moteiv Corporation's unique OUI.
43  * From http://www.ethereal.com/distribution/manuf.txt:
44  * 00:12:75 Moteiv # Moteiv Corporation
45  *
46  * The EUI-64 is a concatenation of the 24-bit OUI value assigned by
47  * the IEEE Registration Authority and a 40-bit extension identifier
48  * assigned by the organization with that OUI assignment.
49  */
50 
51 #include <string.h>
52 
53 #include "contiki.h"
54 #include "dev/ds2411.h"
55 
56 unsigned char ds2411_id[8];
57 
58 #ifdef CONTIKI_TARGET_SKY
59 /* 1-wire is at p2.4 */
60 #define PIN BV(4)
61 
62 #define PIN_INIT() {\
63  P2DIR &= ~PIN; /* p2.4 in, resistor pull high */\
64  P2OUT &= ~PIN; /* p2.4 == 0 but still input */\
65 }
66 
67 /* Set 1-Wire low or high. */
68 #define OUTP_0() (P2DIR |= PIN) /* output and p2.4 == 0 from above */
69 #define OUTP_1() (P2DIR &= ~PIN) /* p2.4 in, external resistor pull high */
70 
71 /* Read one bit. */
72 #define INP() (P2IN & PIN)
73 
74 /*
75  * Delay for u microseconds on a MSP430 at 2.4756MHz.
76  *
77  * The loop in clock_delay consists of one add and one jnz, i.e 3
78  * cycles.
79  *
80  * 3 cycles at 2.4756MHz ==> 1.2us = 6/5us.
81  *
82  * Call overhead is roughly 7 cycles and the loop 3 cycles, to
83  * compensate for call overheads we make 7/3=14/6 fewer laps in the
84  * loop.
85  *
86  * This macro will loose badly if not passed a constant argument, it
87  * relies on the compiler doing the arithmetic during compile time!!
88  * TODO: Fix above comment to be correct - below code is modified for 4Mhz
89  */
90 #define udelay(u) clock_delay((u*8 - 14)/6)
91 
92 /*
93  * Where call overhead dominates, use a macro!
94  * Note: modified for 4 Mhz
95  */
96 #define udelay_6() { _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); }
97 
98 #endif /* CONTIKI_TARGET_SKY */
99 
100 /*
101  * Recommended delay times in us.
102  */
103 #define udelay_tA() udelay_6()
104 /* tA 6 max 15 */
105 #define tB 64
106 #define tC 60 /* max 120 */
107 #define tD 10
108 #define tE 9 /* max 12 */
109 #define tF 55
110 #define tG 0
111 #define tH 480
112 #define tI 70
113 #define tJ 410
114 /*---------------------------------------------------------------------------*/
115 static int
116 owreset(void)
117 {
118  int result;
119  OUTP_0();
120  udelay(tH);
121  OUTP_1(); /* Releases the bus */
122  udelay(tI);
123  result = INP();
124  udelay(tJ);
125  return result;
126 }
127 /*---------------------------------------------------------------------------*/
128 static void
129 owwriteb(unsigned byte)
130 {
131  int i = 7;
132  do {
133  if(byte & 0x01) {
134  OUTP_0();
135  udelay_tA();
136  OUTP_1(); /* Releases the bus */
137  udelay(tB);
138  } else {
139  OUTP_0();
140  udelay(tC);
141  OUTP_1(); /* Releases the bus */
142  udelay(tD);
143  }
144  if(i == 0) {
145  return;
146  }
147  i--;
148  byte >>= 1;
149  } while(1);
150 }
151 /*---------------------------------------------------------------------------*/
152 static unsigned
153 owreadb(void)
154 {
155  unsigned result = 0;
156  int i = 7;
157  do {
158  OUTP_0();
159  udelay_tA();
160  OUTP_1(); /* Releases the bus */
161  udelay(tE);
162  if(INP()) {
163  result |= 0x80; /* LSbit first */
164  }
165  udelay(tF);
166  if(i == 0) {
167  return result;
168  }
169  i--;
170  result >>= 1;
171  } while(1);
172 }
173 /*---------------------------------------------------------------------------*/
174 /* Polynomial ^8 + ^5 + ^4 + 1 */
175 static unsigned
176 crc8_add(unsigned acc, unsigned byte)
177 {
178  int i;
179  acc ^= byte;
180  for(i = 0; i < 8; i++) {
181  if(acc & 1) {
182  acc = (acc >> 1) ^ 0x8c;
183  } else {
184  acc >>= 1;
185  }
186  }
187  return acc;
188 }
189 /*---------------------------------------------------------------------------*/
190 int
191 ds2411_init()
192 {
193  int i;
194  unsigned family, crc, acc;
195 
196  PIN_INIT();
197 
198  if(owreset() == 0) { /* Something pulled down 1-wire. */
199  /*
200  * Read MAC id with interrupts disabled.
201  */
202  int s = splhigh();
203  owwriteb(0x33); /* Read ROM command. */
204  family = owreadb();
205  /* We receive 6 bytes in the reverse order, LSbyte first. */
206  for(i = 7; i >= 2; i--) {
207  ds2411_id[i] = owreadb();
208  }
209  crc = owreadb();
210  splx(s);
211 
212  /* Verify family and that CRC match. */
213  if(family != 0x01) {
214  goto fail;
215  }
216  acc = crc8_add(0x0, family);
217  for(i = 7; i >= 2; i--) {
218  acc = crc8_add(acc, ds2411_id[i]);
219  }
220  if(acc == crc) {
221 #ifdef CONTIKI_TARGET_SKY
222  /* 00:12:75 Moteiv # Moteiv Corporation */
223  ds2411_id[0] = 0x00;
224  ds2411_id[1] = 0x12;
225  ds2411_id[2] = 0x75;
226 #endif /* CONTIKI_TARGET_SKY */
227  return 1; /* Success! */
228  }
229  }
230 
231  fail:
232  memset(ds2411_id, 0x0, sizeof(ds2411_id));
233  return 0; /* Fail! */
234 }
235 /*---------------------------------------------------------------------------*/