Skip to content

Commit 8001bad

Browse files
committed
Adding OneWire library retrieved from http://homepage.mac.com/wtpollard/Software/FileSharing7.html - untested and has no modifications
1 parent 3bc88f5 commit 8001bad

File tree

5 files changed

+607
-0
lines changed

5 files changed

+607
-0
lines changed

OneWire/OneWire.cpp

+375
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
/*
2+
Copyright (c) 2007, Jim Studt
3+
4+
Updated to work with arduino-0008 and to include skip() as of
5+
2007/07/06. --RJL20
6+
7+
Modified to calculate the 8-bit CRC directly, avoiding the need for
8+
the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
9+
-- Tom Pollard, Jan 23, 2008
10+
11+
Permission is hereby granted, free of charge, to any person obtaining
12+
a copy of this software and associated documentation files (the
13+
"Software"), to deal in the Software without restriction, including
14+
without limitation the rights to use, copy, modify, merge, publish,
15+
distribute, sublicense, and/or sell copies of the Software, and to
16+
permit persons to whom the Software is furnished to do so, subject to
17+
the following conditions:
18+
19+
The above copyright notice and this permission notice shall be
20+
included in all copies or substantial portions of the Software.
21+
22+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29+
30+
Much of the code was inspired by Derek Yerger's code, though I don't
31+
think much of that remains. In any event that was..
32+
(copyleft) 2006 by Derek Yerger - Free to distribute freely.
33+
34+
The CRC code was excerpted and inspired by the Dallas Semiconductor
35+
sample code bearing this copyright.
36+
//---------------------------------------------------------------------------
37+
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
38+
//
39+
// Permission is hereby granted, free of charge, to any person obtaining a
40+
// copy of this software and associated documentation files (the "Software"),
41+
// to deal in the Software without restriction, including without limitation
42+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
43+
// and/or sell copies of the Software, and to permit persons to whom the
44+
// Software is furnished to do so, subject to the following conditions:
45+
//
46+
// The above copyright notice and this permission notice shall be included
47+
// in all copies or substantial portions of the Software.
48+
//
49+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
50+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52+
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
53+
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
54+
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
55+
// OTHER DEALINGS IN THE SOFTWARE.
56+
//
57+
// Except as contained in this notice, the name of Dallas Semiconductor
58+
// shall not be used except as stated in the Dallas Semiconductor
59+
// Branding Policy.
60+
//--------------------------------------------------------------------------
61+
*/
62+
63+
#include "OneWire.h"
64+
65+
extern "C" {
66+
#include "WConstants.h"
67+
#include <avr/io.h>
68+
#include "pins_arduino.h"
69+
}
70+
71+
72+
OneWire::OneWire( uint8_t pinArg)
73+
{
74+
pin = pinArg;
75+
port = digitalPinToPort(pin);
76+
bitmask = digitalPinToBitMask(pin);
77+
outputReg = portOutputRegister(port);
78+
inputReg = portInputRegister(port);
79+
modeReg = portModeRegister(port);
80+
#if ONEWIRE_SEARCH
81+
reset_search();
82+
#endif
83+
}
84+
85+
//
86+
// Perform the onewire reset function. We will wait up to 250uS for
87+
// the bus to come high, if it doesn't then it is broken or shorted
88+
// and we return a 0;
89+
//
90+
// Returns 1 if a device asserted a presence pulse, 0 otherwise.
91+
//
92+
uint8_t OneWire::reset() {
93+
uint8_t r;
94+
uint8_t retries = 125;
95+
96+
// wait until the wire is high... just in case
97+
pinMode(pin,INPUT);
98+
do {
99+
if ( retries-- == 0) return 0;
100+
delayMicroseconds(2);
101+
} while( !digitalRead( pin));
102+
103+
digitalWrite(pin,0); // pull low for 500uS
104+
pinMode(pin,OUTPUT);
105+
delayMicroseconds(500);
106+
pinMode(pin,INPUT);
107+
delayMicroseconds(65);
108+
r = !digitalRead(pin);
109+
delayMicroseconds(490);
110+
return r;
111+
}
112+
113+
//
114+
// Write a bit. Port and bit is used to cut lookup time and provide
115+
// more certain timing.
116+
//
117+
void OneWire::write_bit(uint8_t v) {
118+
static uint8_t lowTime[] = { 55, 5 };
119+
static uint8_t highTime[] = { 5, 55};
120+
121+
v = (v&1);
122+
*modeReg |= bitmask; // make pin an output, do first since we
123+
// expect to be at 1
124+
*outputReg &= ~bitmask; // zero
125+
delayMicroseconds(lowTime[v]);
126+
*outputReg |= bitmask; // one, push pin up - important for
127+
// parasites, they might start in here
128+
delayMicroseconds(highTime[v]);
129+
}
130+
131+
//
132+
// Read a bit. Port and bit is used to cut lookup time and provide
133+
// more certain timing.
134+
//
135+
uint8_t OneWire::read_bit() {
136+
uint8_t r;
137+
138+
*modeReg |= bitmask; // make pin an output, do first since we expect to be at 1
139+
*outputReg &= ~bitmask; // zero
140+
delayMicroseconds(1);
141+
*modeReg &= ~bitmask; // let pin float, pull up will raise
142+
delayMicroseconds(5); // A "read slot" is when 1mcs > t > 2mcs
143+
r = ( *inputReg & bitmask) ? 1 : 0; // check the bit
144+
delayMicroseconds(50); // whole bit slot is 60-120uS, need to give some time
145+
146+
return r;
147+
}
148+
149+
//
150+
// Write a byte. The writing code uses the active drivers to raise the
151+
// pin high, if you need power after the write (e.g. DS18S20 in
152+
// parasite power mode) then set 'power' to 1, otherwise the pin will
153+
// go tri-state at the end of the write to avoid heating in a short or
154+
// other mishap.
155+
//
156+
void OneWire::write(uint8_t v, uint8_t power) {
157+
uint8_t bitMask;
158+
159+
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
160+
OneWire::write_bit( (bitMask & v)?1:0);
161+
}
162+
if ( !power) {
163+
pinMode(pin,INPUT);
164+
digitalWrite(pin,0);
165+
}
166+
}
167+
168+
//
169+
// Read a byte
170+
//
171+
uint8_t OneWire::read() {
172+
uint8_t bitMask;
173+
uint8_t r = 0;
174+
175+
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
176+
if ( OneWire::read_bit()) r |= bitMask;
177+
}
178+
return r;
179+
}
180+
181+
//
182+
// Do a ROM select
183+
//
184+
void OneWire::select( uint8_t rom[8])
185+
{
186+
int i;
187+
188+
write(0x55,0); // Choose ROM
189+
190+
for( i = 0; i < 8; i++) write(rom[i],0);
191+
}
192+
193+
//
194+
// Do a ROM skip
195+
//
196+
void OneWire::skip()
197+
{
198+
write(0xCC,0); // Skip ROM
199+
}
200+
201+
void OneWire::depower()
202+
{
203+
pinMode(pin,INPUT);
204+
}
205+
206+
#if ONEWIRE_SEARCH
207+
208+
//
209+
// You need to use this function to start a search again from the beginning.
210+
// You do not need to do it for the first search, though you could.
211+
//
212+
void OneWire::reset_search()
213+
{
214+
uint8_t i;
215+
216+
searchJunction = -1;
217+
searchExhausted = 0;
218+
for( i = 7; ; i--) {
219+
address[i] = 0;
220+
if ( i == 0) break;
221+
}
222+
}
223+
224+
//
225+
// Perform a search. If this function returns a '1' then it has
226+
// enumerated the next device and you may retrieve the ROM from the
227+
// OneWire::address variable. If there are no devices, no further
228+
// devices, or something horrible happens in the middle of the
229+
// enumeration then a 0 is returned. If a new device is found then
230+
// its address is copied to newAddr. Use OneWire::reset_search() to
231+
// start over.
232+
//
233+
uint8_t OneWire::search(uint8_t *newAddr)
234+
{
235+
uint8_t i;
236+
char lastJunction = -1;
237+
uint8_t done = 1;
238+
239+
if ( searchExhausted) return 0;
240+
241+
if ( !reset()) return 0;
242+
write( 0xf0, 0);
243+
244+
for( i = 0; i < 64; i++) {
245+
uint8_t a = read_bit( );
246+
uint8_t nota = read_bit( );
247+
uint8_t ibyte = i/8;
248+
uint8_t ibit = 1<<(i&7);
249+
250+
if ( a && nota) return 0; // I don't think this should happen, this means nothing responded, but maybe if
251+
// something vanishes during the search it will come up.
252+
if ( !a && !nota) {
253+
if ( i == searchJunction) { // this is our time to decide differently, we went zero last time, go one.
254+
a = 1;
255+
searchJunction = lastJunction;
256+
} else if ( i < searchJunction) { // take whatever we took last time, look in address
257+
if ( address[ ibyte]&ibit) a = 1;
258+
else { // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s
259+
a = 0;
260+
done = 0;
261+
lastJunction = i;
262+
}
263+
} else { // we are blazing new tree, take the 0
264+
a = 0;
265+
searchJunction = i;
266+
done = 0;
267+
}
268+
lastJunction = i;
269+
}
270+
if ( a) address[ ibyte] |= ibit;
271+
else address[ ibyte] &= ~ibit;
272+
273+
write_bit( a);
274+
}
275+
if ( done) searchExhausted = 1;
276+
for ( i = 0; i < 8; i++) newAddr[i] = address[i];
277+
return 1;
278+
}
279+
#endif
280+
281+
#if ONEWIRE_CRC
282+
// The 1-Wire CRC scheme is described in Maxim Application Note 27:
283+
// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
284+
//
285+
286+
#if ONEWIRE_CRC8_TABLE
287+
// This table comes from Dallas sample code where it is freely reusable,
288+
// though Copyright (C) 2000 Dallas Semiconductor Corporation
289+
static uint8_t dscrc_table[] = {
290+
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
291+
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
292+
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
293+
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
294+
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
295+
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
296+
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
297+
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
298+
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
299+
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
300+
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
301+
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
302+
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
303+
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
304+
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
305+
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
306+
307+
//
308+
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
309+
// and the registers. (note: this might better be done without to
310+
// table, it would probably be smaller and certainly fast enough
311+
// compared to all those delayMicrosecond() calls. But I got
312+
// confused, so I use this table from the examples.)
313+
//
314+
uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
315+
{
316+
uint8_t i;
317+
uint8_t crc = 0;
318+
319+
for ( i = 0; i < len; i++) {
320+
crc = dscrc_table[ crc ^ addr[i] ];
321+
}
322+
return crc;
323+
}
324+
#else
325+
//
326+
// Compute a Dallas Semiconductor 8 bit CRC directly.
327+
//
328+
uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
329+
{
330+
uint8_t i, j;
331+
uint8_t crc = 0;
332+
333+
for (i = 0; i < len; i++) {
334+
uint8_t inbyte = addr[i];
335+
for (j = 0; j < 8; j++) {
336+
uint8_t mix = (crc ^ inbyte) & 0x01;
337+
crc >>= 1;
338+
if (mix) crc ^= 0x8C;
339+
inbyte >>= 1;
340+
}
341+
}
342+
return crc;
343+
}
344+
#endif
345+
346+
#if ONEWIRE_CRC16
347+
static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
348+
349+
//
350+
// Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of
351+
// these, but here it is.
352+
//
353+
unsigned short OneWire::crc16(unsigned short *data, unsigned short len)
354+
{
355+
unsigned short i;
356+
unsigned short crc = 0;
357+
358+
for ( i = 0; i < len; i++) {
359+
unsigned short cdata = data[len];
360+
361+
cdata = (cdata ^ (crc & 0xff)) & 0xff;
362+
crc >>= 8;
363+
364+
if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001;
365+
366+
cdata <<= 6;
367+
crc ^= cdata;
368+
cdata <<= 1;
369+
crc ^= cdata;
370+
}
371+
return crc;
372+
}
373+
#endif
374+
375+
#endif

0 commit comments

Comments
 (0)