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/etc/ds2411/ds2411.h"
54
55unsigned 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/*---------------------------------------------------------------------------*/
114static int
115owreset(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/*---------------------------------------------------------------------------*/
127static void
128owwriteb(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/*---------------------------------------------------------------------------*/
151static unsigned
152owreadb(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 */
174static unsigned
175crc8_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/*---------------------------------------------------------------------------*/
189int
190ds2411_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/*---------------------------------------------------------------------------*/