Contiki-NG
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  */
32 /*
33  * Device driver for the Dallas Semiconductor DS2411 chip. Heavily
34  * based on the application note 126 "1-Wire Communications Through
35  * Software".
36  *
37  * http://www.maxim-ic.com/appnotes.cfm/appnote_number/126
38  */
39 
40 /*
41  * For now we stuff in Moteiv Corporation's unique OUI.
42  * From http://www.ethereal.com/distribution/manuf.txt:
43  * 00:12:75 Moteiv # Moteiv Corporation
44  *
45  * The EUI-64 is a concatenation of the 24-bit OUI value assigned by
46  * the IEEE Registration Authority and a 40-bit extension identifier
47  * assigned by the organization with that OUI assignment.
48  */
49 
50 #include <string.h>
51 
52 #include "contiki.h"
53 #include "dev/ds2411/ds2411.h"
54 
55 unsigned char ds2411_id[8];
56 
57 #ifdef CONTIKI_TARGET_SKY
58 /* 1-wire is at p2.4 */
59 #define PIN BV(4)
60 
61 #define PIN_INIT() {\
62  P2DIR &= ~PIN; /* p2.4 in, resistor pull high */\
63  P2OUT &= ~PIN; /* p2.4 == 0 but still input */\
64 }
65 
66 /* Set 1-Wire low or high. */
67 #define OUTP_0() (P2DIR |= PIN) /* output and p2.4 == 0 from above */
68 #define OUTP_1() (P2DIR &= ~PIN) /* p2.4 in, external resistor pull high */
69 
70 /* Read one bit. */
71 #define INP() (P2IN & PIN)
72 
73 /*
74  * Delay for u microseconds on a MSP430 at 2.4756MHz.
75  *
76  * The loop in clock_delay consists of one add and one jnz, i.e 3
77  * cycles.
78  *
79  * 3 cycles at 2.4756MHz ==> 1.2us = 6/5us.
80  *
81  * Call overhead is roughly 7 cycles and the loop 3 cycles, to
82  * compensate for call overheads we make 7/3=14/6 fewer laps in the
83  * loop.
84  *
85  * This macro will loose badly if not passed a constant argument, it
86  * relies on the compiler doing the arithmetic during compile time!!
87  * TODO: Fix above comment to be correct - below code is modified for 4Mhz
88  */
89 #define udelay(u) clock_delay((u*8 - 14)/6)
90 
91 /*
92  * Where call overhead dominates, use a macro!
93  * Note: modified for 4 Mhz
94  */
95 #define udelay_6() { _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); }
96 
97 #endif /* CONTIKI_TARGET_SKY */
98 
99 /*
100  * Recommended delay times in us.
101  */
102 #define udelay_tA() udelay_6()
103 /* tA 6 max 15 */
104 #define tB 64
105 #define tC 60 /* max 120 */
106 #define tD 10
107 #define tE 9 /* max 12 */
108 #define tF 55
109 #define tG 0
110 #define tH 480
111 #define tI 70
112 #define tJ 410
113 /*---------------------------------------------------------------------------*/
114 static int
115 owreset(void)
116 {
117  int result;
118  OUTP_0();
119  udelay(tH);
120  OUTP_1(); /* Releases the bus */
121  udelay(tI);
122  result = INP();
123  udelay(tJ);
124  return result;
125 }
126 /*---------------------------------------------------------------------------*/
127 static void
128 owwriteb(unsigned byte)
129 {
130  int i = 7;
131  do {
132  if(byte & 0x01) {
133  OUTP_0();
134  udelay_tA();
135  OUTP_1(); /* Releases the bus */
136  udelay(tB);
137  } else {
138  OUTP_0();
139  udelay(tC);
140  OUTP_1(); /* Releases the bus */
141  udelay(tD);
142  }
143  if(i == 0) {
144  return;
145  }
146  i--;
147  byte >>= 1;
148  } while(1);
149 }
150 /*---------------------------------------------------------------------------*/
151 static unsigned
152 owreadb(void)
153 {
154  unsigned result = 0;
155  int i = 7;
156  do {
157  OUTP_0();
158  udelay_tA();
159  OUTP_1(); /* Releases the bus */
160  udelay(tE);
161  if(INP()) {
162  result |= 0x80; /* LSbit first */
163  }
164  udelay(tF);
165  if(i == 0) {
166  return result;
167  }
168  i--;
169  result >>= 1;
170  } while(1);
171 }
172 /*---------------------------------------------------------------------------*/
173 /* Polynomial ^8 + ^5 + ^4 + 1 */
174 static unsigned
175 crc8_add(unsigned acc, unsigned byte)
176 {
177  int i;
178  acc ^= byte;
179  for(i = 0; i < 8; i++) {
180  if(acc & 1) {
181  acc = (acc >> 1) ^ 0x8c;
182  } else {
183  acc >>= 1;
184  }
185  }
186  return acc;
187 }
188 /*---------------------------------------------------------------------------*/
189 int
190 ds2411_init()
191 {
192  int i;
193  unsigned family, crc, acc;
194 
195  PIN_INIT();
196 
197  if(owreset() == 0) { /* Something pulled down 1-wire. */
198  /*
199  * Read MAC id with interrupts disabled.
200  */
201  int s = splhigh();
202  owwriteb(0x33); /* Read ROM command. */
203  family = owreadb();
204  /* We receive 6 bytes in the reverse order, LSbyte first. */
205  for(i = 7; i >= 2; i--) {
206  ds2411_id[i] = owreadb();
207  }
208  crc = owreadb();
209  splx(s);
210 
211  /* Verify family and that CRC match. */
212  if(family != 0x01) {
213  goto fail;
214  }
215  acc = crc8_add(0x0, family);
216  for(i = 7; i >= 2; i--) {
217  acc = crc8_add(acc, ds2411_id[i]);
218  }
219  if(acc == crc) {
220 #ifdef CONTIKI_TARGET_SKY
221  /* 00:12:75 Moteiv # Moteiv Corporation */
222  ds2411_id[0] = 0x00;
223  ds2411_id[1] = 0x12;
224  ds2411_id[2] = 0x75;
225 #endif /* CONTIKI_TARGET_SKY */
226  return 1; /* Success! */
227  }
228  }
229 
230  fail:
231  memset(ds2411_id, 0x0, sizeof(ds2411_id));
232  return 0; /* Fail! */
233 }
234 /*---------------------------------------------------------------------------*/