User | Revision | Line number | New contents of line |
gbeardall |
0:2f78e3dca55d
|
1
|
/*
|
gbeardall |
0:2f78e3dca55d
|
2
|
* OneWireCRC. This is a port to mbed of Jim Studt's Adruino One Wire
|
gbeardall |
0:2f78e3dca55d
|
3
|
* library. Please see additional copyrights below this one, including
|
gbeardall |
0:2f78e3dca55d
|
4
|
* references to other copyrights.
|
gbeardall |
0:2f78e3dca55d
|
5
|
*
|
gbeardall |
0:2f78e3dca55d
|
6
|
* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
|
gbeardall |
0:2f78e3dca55d
|
7
|
*
|
gbeardall |
0:2f78e3dca55d
|
8
|
* This file is part of OneWireCRC.
|
gbeardall |
0:2f78e3dca55d
|
9
|
*
|
gbeardall |
0:2f78e3dca55d
|
10
|
* OneWireCRC is free software: you can redistribute it and/or modify
|
gbeardall |
0:2f78e3dca55d
|
11
|
* it under the terms of the GNU General Public License as published by
|
gbeardall |
0:2f78e3dca55d
|
12
|
* the Free Software Foundation, either version 3 of the License, or
|
gbeardall |
0:2f78e3dca55d
|
13
|
* (at your option) any later version.
|
gbeardall |
0:2f78e3dca55d
|
14
|
*
|
gbeardall |
0:2f78e3dca55d
|
15
|
* OneWireCRC is distributed in the hope that it will be useful,
|
gbeardall |
0:2f78e3dca55d
|
16
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
gbeardall |
0:2f78e3dca55d
|
17
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
gbeardall |
0:2f78e3dca55d
|
18
|
* GNU General Public License for more details.
|
gbeardall |
0:2f78e3dca55d
|
19
|
*
|
gbeardall |
0:2f78e3dca55d
|
20
|
* You should have received a copy of the GNU General Public License
|
gbeardall |
0:2f78e3dca55d
|
21
|
* along with OneWireCRC. If not, see <http://www.gnu.org/licenses/>.
|
gbeardall |
0:2f78e3dca55d
|
22
|
*/
|
gbeardall |
0:2f78e3dca55d
|
23
|
/*
|
gbeardall |
0:2f78e3dca55d
|
24
|
Copyright (c) 2007, Jim Studt
|
gbeardall |
0:2f78e3dca55d
|
25
|
|
gbeardall |
0:2f78e3dca55d
|
26
|
Updated to work with arduino-0008 and to include skip() as of
|
gbeardall |
0:2f78e3dca55d
|
27
|
2007/07/06. --RJL20
|
gbeardall |
0:2f78e3dca55d
|
28
|
|
gbeardall |
0:2f78e3dca55d
|
29
|
Modified to calculate the 8-bit CRC directly, avoiding the need for
|
gbeardall |
0:2f78e3dca55d
|
30
|
the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
|
gbeardall |
0:2f78e3dca55d
|
31
|
-- Tom Pollard, Jan 23, 2008
|
gbeardall |
0:2f78e3dca55d
|
32
|
|
gbeardall |
0:2f78e3dca55d
|
33
|
Permission is hereby granted, free of charge, to any person obtaining
|
gbeardall |
0:2f78e3dca55d
|
34
|
a copy of this software and associated documentation files (the
|
gbeardall |
0:2f78e3dca55d
|
35
|
"Software"), to deal in the Software without restriction, including
|
gbeardall |
0:2f78e3dca55d
|
36
|
without limitation the rights to use, copy, modify, merge, publish,
|
gbeardall |
0:2f78e3dca55d
|
37
|
distribute, sublicense, and/or sell copies of the Software, and to
|
gbeardall |
0:2f78e3dca55d
|
38
|
permit persons to whom the Software is furnished to do so, subject to
|
gbeardall |
0:2f78e3dca55d
|
39
|
the following conditions:
|
gbeardall |
0:2f78e3dca55d
|
40
|
|
gbeardall |
0:2f78e3dca55d
|
41
|
The above copyright notice and this permission notice shall be
|
gbeardall |
0:2f78e3dca55d
|
42
|
included in all copies or substantial portions of the Software.
|
gbeardall |
0:2f78e3dca55d
|
43
|
|
gbeardall |
0:2f78e3dca55d
|
44
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
gbeardall |
0:2f78e3dca55d
|
45
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
gbeardall |
0:2f78e3dca55d
|
46
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
gbeardall |
0:2f78e3dca55d
|
47
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
gbeardall |
0:2f78e3dca55d
|
48
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
gbeardall |
0:2f78e3dca55d
|
49
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
gbeardall |
0:2f78e3dca55d
|
50
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
gbeardall |
0:2f78e3dca55d
|
51
|
|
gbeardall |
0:2f78e3dca55d
|
52
|
Much of the code was inspired by Derek Yerger's code, though I don't
|
gbeardall |
0:2f78e3dca55d
|
53
|
think much of that remains. In any event that was..
|
gbeardall |
0:2f78e3dca55d
|
54
|
(copyleft) 2006 by Derek Yerger - Free to distribute freely.
|
gbeardall |
0:2f78e3dca55d
|
55
|
|
gbeardall |
0:2f78e3dca55d
|
56
|
The CRC code was excerpted and inspired by the Dallas Semiconductor
|
gbeardall |
0:2f78e3dca55d
|
57
|
sample code bearing this copyright.
|
gbeardall |
0:2f78e3dca55d
|
58
|
//---------------------------------------------------------------------------
|
gbeardall |
0:2f78e3dca55d
|
59
|
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
|
gbeardall |
0:2f78e3dca55d
|
60
|
//
|
gbeardall |
0:2f78e3dca55d
|
61
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
gbeardall |
0:2f78e3dca55d
|
62
|
// copy of this software and associated documentation files (the "Software"),
|
gbeardall |
0:2f78e3dca55d
|
63
|
// to deal in the Software without restriction, including without limitation
|
gbeardall |
0:2f78e3dca55d
|
64
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
gbeardall |
0:2f78e3dca55d
|
65
|
// and/or sell copies of the Software, and to permit persons to whom the
|
gbeardall |
0:2f78e3dca55d
|
66
|
// Software is furnished to do so, subject to the following conditions:
|
gbeardall |
0:2f78e3dca55d
|
67
|
//
|
gbeardall |
0:2f78e3dca55d
|
68
|
// The above copyright notice and this permission notice shall be included
|
gbeardall |
0:2f78e3dca55d
|
69
|
// in all copies or substantial portions of the Software.
|
gbeardall |
0:2f78e3dca55d
|
70
|
//
|
gbeardall |
0:2f78e3dca55d
|
71
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
gbeardall |
0:2f78e3dca55d
|
72
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
gbeardall |
0:2f78e3dca55d
|
73
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
gbeardall |
0:2f78e3dca55d
|
74
|
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
|
gbeardall |
0:2f78e3dca55d
|
75
|
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
gbeardall |
0:2f78e3dca55d
|
76
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
gbeardall |
0:2f78e3dca55d
|
77
|
// OTHER DEALINGS IN THE SOFTWARE.
|
gbeardall |
0:2f78e3dca55d
|
78
|
//
|
gbeardall |
0:2f78e3dca55d
|
79
|
// Except as contained in this notice, the name of Dallas Semiconductor
|
gbeardall |
0:2f78e3dca55d
|
80
|
// shall not be used except as stated in the Dallas Semiconductor
|
gbeardall |
0:2f78e3dca55d
|
81
|
// Branding Policy.
|
gbeardall |
0:2f78e3dca55d
|
82
|
//--------------------------------------------------------------------------
|
gbeardall |
0:2f78e3dca55d
|
83
|
*/
|
gbeardall |
0:2f78e3dca55d
|
84
|
|
gbeardall |
0:2f78e3dca55d
|
85
|
#include "OneWireCRC.h"
|
gbeardall |
0:2f78e3dca55d
|
86
|
#include "OneWireDefs.h"
|
gbeardall |
0:2f78e3dca55d
|
87
|
|
gbeardall |
0:2f78e3dca55d
|
88
|
// recommended data sheet timings in micro seconds
|
gbeardall |
0:2f78e3dca55d
|
89
|
const int standardT[] = {6, 64, 60, 10, 9, 55, 0, 480, 70, 410};
|
gbeardall |
0:2f78e3dca55d
|
90
|
const int overdriveT[] = {1.5, 7.5, 7.5, 2.5, 0.75, 7, 2.5, 70, 8.5, 40};
|
gbeardall |
0:2f78e3dca55d
|
91
|
|
gbeardall |
0:2f78e3dca55d
|
92
|
OneWireCRC::OneWireCRC(PinName oneWire, eSpeed speed) : oneWirePort(oneWire)
|
gbeardall |
0:2f78e3dca55d
|
93
|
{
|
gbeardall |
0:2f78e3dca55d
|
94
|
if (STANDARD == speed) timing = standardT;
|
gbeardall |
0:2f78e3dca55d
|
95
|
else timing = overdriveT; // overdrive
|
gbeardall |
0:2f78e3dca55d
|
96
|
|
gbeardall |
0:2f78e3dca55d
|
97
|
resetSearch(); // reset address search state
|
gbeardall |
0:2f78e3dca55d
|
98
|
}
|
gbeardall |
0:2f78e3dca55d
|
99
|
|
gbeardall |
0:2f78e3dca55d
|
100
|
// Generate a 1-wire reset, return 1 if no presence detect was found,
|
gbeardall |
0:2f78e3dca55d
|
101
|
// return 0 otherwise.
|
gbeardall |
0:2f78e3dca55d
|
102
|
// (NOTE: does not handle alarm presence from DS2404/DS1994)
|
gbeardall |
0:2f78e3dca55d
|
103
|
int OneWireCRC::reset()
|
gbeardall |
0:2f78e3dca55d
|
104
|
{
|
gbeardall |
0:2f78e3dca55d
|
105
|
|
gbeardall |
0:2f78e3dca55d
|
106
|
BYTE result = 0; // sample presence pulse result
|
gbeardall |
0:2f78e3dca55d
|
107
|
|
gbeardall |
0:2f78e3dca55d
|
108
|
wait_us(timing[6]);
|
gbeardall |
0:2f78e3dca55d
|
109
|
oneWirePort.output();
|
gbeardall |
0:2f78e3dca55d
|
110
|
oneWirePort = 0;
|
gbeardall |
0:2f78e3dca55d
|
111
|
wait_us(timing[7]);
|
gbeardall |
0:2f78e3dca55d
|
112
|
oneWirePort.input();
|
gbeardall |
0:2f78e3dca55d
|
113
|
wait_us(timing[8]);
|
gbeardall |
0:2f78e3dca55d
|
114
|
result = !(oneWirePort & 0x01);
|
gbeardall |
0:2f78e3dca55d
|
115
|
wait_us(timing[9]);
|
gbeardall |
0:2f78e3dca55d
|
116
|
|
gbeardall |
0:2f78e3dca55d
|
117
|
return result;
|
gbeardall |
0:2f78e3dca55d
|
118
|
}
|
gbeardall |
0:2f78e3dca55d
|
119
|
|
gbeardall |
0:2f78e3dca55d
|
120
|
//
|
gbeardall |
0:2f78e3dca55d
|
121
|
// Write a bit. Port and bit is used to cut lookup time and provide
|
gbeardall |
0:2f78e3dca55d
|
122
|
// more certain timing.
|
gbeardall |
0:2f78e3dca55d
|
123
|
//
|
gbeardall |
0:2f78e3dca55d
|
124
|
void OneWireCRC::writeBit(int bit)
|
gbeardall |
0:2f78e3dca55d
|
125
|
{
|
gbeardall |
0:2f78e3dca55d
|
126
|
bit = bit & 0x01;
|
gbeardall |
0:2f78e3dca55d
|
127
|
|
gbeardall |
0:2f78e3dca55d
|
128
|
if (bit)
|
gbeardall |
0:2f78e3dca55d
|
129
|
{
|
gbeardall |
0:2f78e3dca55d
|
130
|
// Write '1' bit
|
gbeardall |
0:2f78e3dca55d
|
131
|
oneWirePort.output();
|
gbeardall |
0:2f78e3dca55d
|
132
|
oneWirePort = 0;
|
gbeardall |
0:2f78e3dca55d
|
133
|
wait_us(timing[0]);
|
gbeardall |
0:2f78e3dca55d
|
134
|
oneWirePort.input();
|
gbeardall |
0:2f78e3dca55d
|
135
|
wait_us(timing[1]);
|
gbeardall |
0:2f78e3dca55d
|
136
|
}
|
gbeardall |
0:2f78e3dca55d
|
137
|
else
|
gbeardall |
0:2f78e3dca55d
|
138
|
{
|
gbeardall |
0:2f78e3dca55d
|
139
|
// Write '0' bit
|
gbeardall |
0:2f78e3dca55d
|
140
|
oneWirePort.output();
|
gbeardall |
0:2f78e3dca55d
|
141
|
oneWirePort = 0;
|
gbeardall |
0:2f78e3dca55d
|
142
|
wait_us(timing[2]);
|
gbeardall |
0:2f78e3dca55d
|
143
|
oneWirePort.input();
|
gbeardall |
0:2f78e3dca55d
|
144
|
wait_us(timing[3]);
|
gbeardall |
0:2f78e3dca55d
|
145
|
}
|
gbeardall |
0:2f78e3dca55d
|
146
|
}
|
gbeardall |
0:2f78e3dca55d
|
147
|
|
gbeardall |
0:2f78e3dca55d
|
148
|
//
|
gbeardall |
0:2f78e3dca55d
|
149
|
// Read a bit. Port and bit is used to cut lookup time and provide
|
gbeardall |
0:2f78e3dca55d
|
150
|
// more certain timing.
|
gbeardall |
0:2f78e3dca55d
|
151
|
//
|
gbeardall |
0:2f78e3dca55d
|
152
|
int OneWireCRC::readBit()
|
gbeardall |
0:2f78e3dca55d
|
153
|
{
|
gbeardall |
0:2f78e3dca55d
|
154
|
BYTE result;
|
gbeardall |
0:2f78e3dca55d
|
155
|
|
gbeardall |
0:2f78e3dca55d
|
156
|
oneWirePort.output();
|
gbeardall |
0:2f78e3dca55d
|
157
|
oneWirePort = 0;
|
gbeardall |
0:2f78e3dca55d
|
158
|
wait_us(timing[0]);
|
gbeardall |
0:2f78e3dca55d
|
159
|
oneWirePort.input();
|
gbeardall |
0:2f78e3dca55d
|
160
|
wait_us(timing[4]);
|
gbeardall |
0:2f78e3dca55d
|
161
|
result = oneWirePort & 0x01;
|
gbeardall |
0:2f78e3dca55d
|
162
|
wait_us(timing[5]);
|
gbeardall |
0:2f78e3dca55d
|
163
|
|
gbeardall |
0:2f78e3dca55d
|
164
|
return result;
|
gbeardall |
0:2f78e3dca55d
|
165
|
}
|
gbeardall |
0:2f78e3dca55d
|
166
|
|
gbeardall |
0:2f78e3dca55d
|
167
|
//
|
gbeardall |
0:2f78e3dca55d
|
168
|
// Write a byte. The writing code uses the active drivers to raise the
|
gbeardall |
0:2f78e3dca55d
|
169
|
// pin high, if you need power after the write (e.g. DS18S20 in
|
gbeardall |
0:2f78e3dca55d
|
170
|
// parasite power mode) then set 'power' to 1, otherwise the pin will
|
gbeardall |
0:2f78e3dca55d
|
171
|
// go tri-state at the end of the write to avoid heating in a short or
|
gbeardall |
0:2f78e3dca55d
|
172
|
// other mishap.
|
gbeardall |
0:2f78e3dca55d
|
173
|
//
|
gbeardall |
0:2f78e3dca55d
|
174
|
void OneWireCRC::writeByte(int data)
|
gbeardall |
0:2f78e3dca55d
|
175
|
{
|
gbeardall |
0:2f78e3dca55d
|
176
|
// Loop to write each bit in the byte, LS-bit first
|
gbeardall |
0:2f78e3dca55d
|
177
|
for (int loop = 0; loop < 8; loop++)
|
gbeardall |
0:2f78e3dca55d
|
178
|
{
|
gbeardall |
0:2f78e3dca55d
|
179
|
writeBit(data & 0x01);
|
gbeardall |
0:2f78e3dca55d
|
180
|
|
gbeardall |
0:2f78e3dca55d
|
181
|
// shift the data byte for the next bit
|
gbeardall |
0:2f78e3dca55d
|
182
|
data >>= 1;
|
gbeardall |
0:2f78e3dca55d
|
183
|
}
|
gbeardall |
0:2f78e3dca55d
|
184
|
}
|
gbeardall |
0:2f78e3dca55d
|
185
|
|
gbeardall |
0:2f78e3dca55d
|
186
|
//
|
gbeardall |
0:2f78e3dca55d
|
187
|
// Read a byte
|
gbeardall |
0:2f78e3dca55d
|
188
|
//
|
gbeardall |
0:2f78e3dca55d
|
189
|
int OneWireCRC::readByte()
|
gbeardall |
0:2f78e3dca55d
|
190
|
{
|
gbeardall |
0:2f78e3dca55d
|
191
|
int result = 0;
|
gbeardall |
0:2f78e3dca55d
|
192
|
|
gbeardall |
0:2f78e3dca55d
|
193
|
for (int loop = 0; loop < 8; loop++)
|
gbeardall |
0:2f78e3dca55d
|
194
|
{
|
gbeardall |
0:2f78e3dca55d
|
195
|
// shift the result to get it ready for the next bit
|
gbeardall |
0:2f78e3dca55d
|
196
|
result >>= 1;
|
gbeardall |
0:2f78e3dca55d
|
197
|
|
gbeardall |
0:2f78e3dca55d
|
198
|
// if result is one, then set MS bit
|
gbeardall |
0:2f78e3dca55d
|
199
|
if (readBit()) result |= 0x80;
|
gbeardall |
0:2f78e3dca55d
|
200
|
}
|
gbeardall |
0:2f78e3dca55d
|
201
|
|
gbeardall |
0:2f78e3dca55d
|
202
|
return result;
|
gbeardall |
0:2f78e3dca55d
|
203
|
}
|
gbeardall |
0:2f78e3dca55d
|
204
|
|
gbeardall |
0:2f78e3dca55d
|
205
|
int OneWireCRC::touchByte(int data)
|
gbeardall |
0:2f78e3dca55d
|
206
|
{
|
gbeardall |
0:2f78e3dca55d
|
207
|
int result = 0;
|
gbeardall |
0:2f78e3dca55d
|
208
|
|
gbeardall |
0:2f78e3dca55d
|
209
|
for (int loop = 0; loop < 8; loop++)
|
gbeardall |
0:2f78e3dca55d
|
210
|
{
|
gbeardall |
0:2f78e3dca55d
|
211
|
// shift the result to get it ready for the next bit
|
gbeardall |
0:2f78e3dca55d
|
212
|
result >>= 1;
|
gbeardall |
0:2f78e3dca55d
|
213
|
|
gbeardall |
0:2f78e3dca55d
|
214
|
// If sending a '1' then read a bit else write a '0'
|
gbeardall |
0:2f78e3dca55d
|
215
|
if (data & 0x01)
|
gbeardall |
0:2f78e3dca55d
|
216
|
{
|
gbeardall |
0:2f78e3dca55d
|
217
|
if (readBit()) result |= 0x80;
|
gbeardall |
0:2f78e3dca55d
|
218
|
}
|
gbeardall |
0:2f78e3dca55d
|
219
|
else writeBit(0);
|
gbeardall |
0:2f78e3dca55d
|
220
|
|
gbeardall |
0:2f78e3dca55d
|
221
|
// shift the data byte for the next bit
|
gbeardall |
0:2f78e3dca55d
|
222
|
data >>= 1;
|
gbeardall |
0:2f78e3dca55d
|
223
|
}
|
gbeardall |
0:2f78e3dca55d
|
224
|
|
gbeardall |
0:2f78e3dca55d
|
225
|
return result;
|
gbeardall |
0:2f78e3dca55d
|
226
|
}
|
gbeardall |
0:2f78e3dca55d
|
227
|
|
gbeardall |
0:2f78e3dca55d
|
228
|
void OneWireCRC::block(BYTE* data, int data_len)
|
gbeardall |
0:2f78e3dca55d
|
229
|
{
|
gbeardall |
0:2f78e3dca55d
|
230
|
for (int loop = 0; loop < data_len; loop++)
|
gbeardall |
0:2f78e3dca55d
|
231
|
{
|
gbeardall |
0:2f78e3dca55d
|
232
|
data[loop] = touchByte(data[loop]);
|
gbeardall |
0:2f78e3dca55d
|
233
|
}
|
gbeardall |
0:2f78e3dca55d
|
234
|
}
|
gbeardall |
0:2f78e3dca55d
|
235
|
|
gbeardall |
0:2f78e3dca55d
|
236
|
int OneWireCRC::overdriveSkip(BYTE* data, int data_len)
|
gbeardall |
0:2f78e3dca55d
|
237
|
{
|
gbeardall |
0:2f78e3dca55d
|
238
|
// set the speed to 'standard'
|
gbeardall |
0:2f78e3dca55d
|
239
|
timing = standardT;
|
gbeardall |
0:2f78e3dca55d
|
240
|
|
gbeardall |
0:2f78e3dca55d
|
241
|
// reset all devices
|
gbeardall |
0:2f78e3dca55d
|
242
|
if (reset()) return 0; // if no devices found
|
gbeardall |
0:2f78e3dca55d
|
243
|
|
gbeardall |
0:2f78e3dca55d
|
244
|
// overdrive skip command
|
gbeardall |
0:2f78e3dca55d
|
245
|
writeByte(OVERDRIVE_SKIP);
|
gbeardall |
0:2f78e3dca55d
|
246
|
|
gbeardall |
0:2f78e3dca55d
|
247
|
// set the speed to 'overdrive'
|
gbeardall |
0:2f78e3dca55d
|
248
|
timing = overdriveT;
|
gbeardall |
0:2f78e3dca55d
|
249
|
|
gbeardall |
0:2f78e3dca55d
|
250
|
// do a 1-Wire reset in 'overdrive' and return presence result
|
gbeardall |
0:2f78e3dca55d
|
251
|
return reset();
|
gbeardall |
0:2f78e3dca55d
|
252
|
}
|
gbeardall |
0:2f78e3dca55d
|
253
|
|
gbeardall |
0:2f78e3dca55d
|
254
|
//
|
gbeardall |
0:2f78e3dca55d
|
255
|
// Do a ROM select
|
gbeardall |
0:2f78e3dca55d
|
256
|
//
|
gbeardall |
0:2f78e3dca55d
|
257
|
void OneWireCRC::matchROM(BYTE rom[8])
|
gbeardall |
0:2f78e3dca55d
|
258
|
{
|
gbeardall |
0:2f78e3dca55d
|
259
|
writeByte(MATCH_ROM); // Choose ROM
|
gbeardall |
0:2f78e3dca55d
|
260
|
|
gbeardall |
0:2f78e3dca55d
|
261
|
for(int i = 0; i < 8; i++) writeByte(rom[i]);
|
gbeardall |
0:2f78e3dca55d
|
262
|
}
|
gbeardall |
0:2f78e3dca55d
|
263
|
|
gbeardall |
0:2f78e3dca55d
|
264
|
//
|
gbeardall |
0:2f78e3dca55d
|
265
|
// Do a ROM skip
|
gbeardall |
0:2f78e3dca55d
|
266
|
//
|
gbeardall |
0:2f78e3dca55d
|
267
|
void OneWireCRC::skipROM()
|
gbeardall |
0:2f78e3dca55d
|
268
|
{
|
gbeardall |
0:2f78e3dca55d
|
269
|
writeByte(SKIP_ROM); // Skip ROM
|
gbeardall |
0:2f78e3dca55d
|
270
|
}
|
gbeardall |
0:2f78e3dca55d
|
271
|
|
gbeardall |
0:2f78e3dca55d
|
272
|
//
|
gbeardall |
0:2f78e3dca55d
|
273
|
// You need to use this function to start a search again from the beginning.
|
gbeardall |
0:2f78e3dca55d
|
274
|
// You do not need to do it for the first search, though you could.
|
gbeardall |
0:2f78e3dca55d
|
275
|
//
|
gbeardall |
0:2f78e3dca55d
|
276
|
void OneWireCRC::resetSearch()
|
gbeardall |
0:2f78e3dca55d
|
277
|
{
|
gbeardall |
0:2f78e3dca55d
|
278
|
searchJunction = -1;
|
gbeardall |
0:2f78e3dca55d
|
279
|
searchExhausted = false;
|
gbeardall |
0:2f78e3dca55d
|
280
|
for (int i = 0; i < 8; i++)
|
gbeardall |
0:2f78e3dca55d
|
281
|
{
|
gbeardall |
0:2f78e3dca55d
|
282
|
address[i] = 0;
|
gbeardall |
0:2f78e3dca55d
|
283
|
}
|
gbeardall |
0:2f78e3dca55d
|
284
|
}
|
gbeardall |
0:2f78e3dca55d
|
285
|
|
gbeardall |
0:2f78e3dca55d
|
286
|
//
|
gbeardall |
0:2f78e3dca55d
|
287
|
// Perform a search. If this function returns a '1' then it has
|
gbeardall |
0:2f78e3dca55d
|
288
|
// enumerated the next device and you may retrieve the ROM from the
|
gbeardall |
0:2f78e3dca55d
|
289
|
// OneWire::address variable. If there are no devices, no further
|
gbeardall |
0:2f78e3dca55d
|
290
|
// devices, or something horrible happens in the middle of the
|
gbeardall |
0:2f78e3dca55d
|
291
|
// enumeration then a 0 is returned. If a new device is found then
|
gbeardall |
0:2f78e3dca55d
|
292
|
// its address is copied to newAddr. Use OneWire::reset_search() to
|
gbeardall |
0:2f78e3dca55d
|
293
|
// start over.
|
gbeardall |
0:2f78e3dca55d
|
294
|
//
|
gbeardall |
0:2f78e3dca55d
|
295
|
BYTE OneWireCRC::search(BYTE* newAddr)
|
gbeardall |
0:2f78e3dca55d
|
296
|
{
|
gbeardall |
0:2f78e3dca55d
|
297
|
BYTE i;
|
gbeardall |
0:2f78e3dca55d
|
298
|
int lastJunction = -1;
|
gbeardall |
0:2f78e3dca55d
|
299
|
BYTE done = 1;
|
gbeardall |
0:2f78e3dca55d
|
300
|
|
gbeardall |
0:2f78e3dca55d
|
301
|
if (searchExhausted) return 0;
|
gbeardall |
0:2f78e3dca55d
|
302
|
|
gbeardall |
0:2f78e3dca55d
|
303
|
if (!reset()) return 0;
|
gbeardall |
0:2f78e3dca55d
|
304
|
|
gbeardall |
0:2f78e3dca55d
|
305
|
writeByte(SEARCH_ROM);
|
gbeardall |
0:2f78e3dca55d
|
306
|
|
gbeardall |
0:2f78e3dca55d
|
307
|
for(i = 0; i < 64; i++)
|
gbeardall |
0:2f78e3dca55d
|
308
|
{
|
gbeardall |
0:2f78e3dca55d
|
309
|
BYTE a = readBit( );
|
gbeardall |
0:2f78e3dca55d
|
310
|
BYTE nota = readBit( );
|
gbeardall |
0:2f78e3dca55d
|
311
|
BYTE ibyte = i/8;
|
gbeardall |
0:2f78e3dca55d
|
312
|
BYTE ibit = 1 << (i & 7);
|
gbeardall |
0:2f78e3dca55d
|
313
|
|
gbeardall |
0:2f78e3dca55d
|
314
|
// I don't think this should happen, this means nothing responded, but maybe if
|
gbeardall |
0:2f78e3dca55d
|
315
|
// something vanishes during the search it will come up.
|
gbeardall |
0:2f78e3dca55d
|
316
|
if (a && nota) return 0;
|
gbeardall |
0:2f78e3dca55d
|
317
|
|
gbeardall |
0:2f78e3dca55d
|
318
|
if (!a && !nota)
|
gbeardall |
0:2f78e3dca55d
|
319
|
{
|
gbeardall |
0:2f78e3dca55d
|
320
|
if (i == searchJunction)
|
gbeardall |
0:2f78e3dca55d
|
321
|
{
|
gbeardall |
0:2f78e3dca55d
|
322
|
// this is our time to decide differently, we went zero last time, go one.
|
gbeardall |
0:2f78e3dca55d
|
323
|
a = 1;
|
gbeardall |
0:2f78e3dca55d
|
324
|
searchJunction = lastJunction;
|
gbeardall |
0:2f78e3dca55d
|
325
|
}
|
gbeardall |
0:2f78e3dca55d
|
326
|
else if (i < searchJunction)
|
gbeardall |
0:2f78e3dca55d
|
327
|
{
|
gbeardall |
0:2f78e3dca55d
|
328
|
// take whatever we took last time, look in address
|
gbeardall |
0:2f78e3dca55d
|
329
|
if (address[ibyte] & ibit) a = 1;
|
gbeardall |
0:2f78e3dca55d
|
330
|
else
|
gbeardall |
0:2f78e3dca55d
|
331
|
{
|
gbeardall |
0:2f78e3dca55d
|
332
|
// Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s
|
gbeardall |
0:2f78e3dca55d
|
333
|
a = 0;
|
gbeardall |
0:2f78e3dca55d
|
334
|
done = 0;
|
gbeardall |
0:2f78e3dca55d
|
335
|
lastJunction = i;
|
gbeardall |
0:2f78e3dca55d
|
336
|
}
|
gbeardall |
0:2f78e3dca55d
|
337
|
}
|
gbeardall |
0:2f78e3dca55d
|
338
|
else
|
gbeardall |
0:2f78e3dca55d
|
339
|
{
|
gbeardall |
0:2f78e3dca55d
|
340
|
// we are blazing new tree, take the 0
|
gbeardall |
0:2f78e3dca55d
|
341
|
a = 0;
|
gbeardall |
0:2f78e3dca55d
|
342
|
searchJunction = i;
|
gbeardall |
0:2f78e3dca55d
|
343
|
done = 0;
|
gbeardall |
0:2f78e3dca55d
|
344
|
}
|
gbeardall |
0:2f78e3dca55d
|
345
|
lastJunction = i;
|
gbeardall |
0:2f78e3dca55d
|
346
|
}
|
gbeardall |
0:2f78e3dca55d
|
347
|
|
gbeardall |
0:2f78e3dca55d
|
348
|
if (a) address[ibyte] |= ibit;
|
gbeardall |
0:2f78e3dca55d
|
349
|
else address[ibyte] &= ~ibit;
|
gbeardall |
0:2f78e3dca55d
|
350
|
|
gbeardall |
0:2f78e3dca55d
|
351
|
writeBit(a);
|
gbeardall |
0:2f78e3dca55d
|
352
|
}
|
gbeardall |
0:2f78e3dca55d
|
353
|
|
gbeardall |
0:2f78e3dca55d
|
354
|
if (done) searchExhausted = true;
|
gbeardall |
0:2f78e3dca55d
|
355
|
|
gbeardall |
0:2f78e3dca55d
|
356
|
for (i = 0; i < 8; i++) newAddr[i] = address[i];
|
gbeardall |
0:2f78e3dca55d
|
357
|
|
gbeardall |
0:2f78e3dca55d
|
358
|
return 1;
|
gbeardall |
0:2f78e3dca55d
|
359
|
}
|
gbeardall |
0:2f78e3dca55d
|
360
|
|
gbeardall |
0:2f78e3dca55d
|
361
|
// The 1-Wire CRC scheme is described in Maxim Application Note 27:
|
gbeardall |
0:2f78e3dca55d
|
362
|
// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
|
gbeardall |
0:2f78e3dca55d
|
363
|
//
|
gbeardall |
0:2f78e3dca55d
|
364
|
|
gbeardall |
0:2f78e3dca55d
|
365
|
#if ONEWIRE_CRC8_TABLE
|
gbeardall |
0:2f78e3dca55d
|
366
|
// This table comes from Dallas sample code where it is freely reusable,
|
gbeardall |
0:2f78e3dca55d
|
367
|
// though Copyright (C) 2000 Dallas Semiconductor Corporation
|
gbeardall |
0:2f78e3dca55d
|
368
|
static BYTE dscrc_table[] =
|
gbeardall |
0:2f78e3dca55d
|
369
|
{
|
gbeardall |
0:2f78e3dca55d
|
370
|
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
|
gbeardall |
0:2f78e3dca55d
|
371
|
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
|
gbeardall |
0:2f78e3dca55d
|
372
|
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
|
gbeardall |
0:2f78e3dca55d
|
373
|
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
|
gbeardall |
0:2f78e3dca55d
|
374
|
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
|
gbeardall |
0:2f78e3dca55d
|
375
|
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
|
gbeardall |
0:2f78e3dca55d
|
376
|
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
|
gbeardall |
0:2f78e3dca55d
|
377
|
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
|
gbeardall |
0:2f78e3dca55d
|
378
|
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
|
gbeardall |
0:2f78e3dca55d
|
379
|
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
|
gbeardall |
0:2f78e3dca55d
|
380
|
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
|
gbeardall |
0:2f78e3dca55d
|
381
|
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
|
gbeardall |
0:2f78e3dca55d
|
382
|
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
|
gbeardall |
0:2f78e3dca55d
|
383
|
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
|
gbeardall |
0:2f78e3dca55d
|
384
|
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
|
gbeardall |
0:2f78e3dca55d
|
385
|
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
|
gbeardall |
0:2f78e3dca55d
|
386
|
|
gbeardall |
0:2f78e3dca55d
|
387
|
//
|
gbeardall |
0:2f78e3dca55d
|
388
|
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
|
gbeardall |
0:2f78e3dca55d
|
389
|
// and the registers. (note: this might better be done without the
|
gbeardall |
0:2f78e3dca55d
|
390
|
// table, it would probably be smaller and certainly fast enough
|
gbeardall |
0:2f78e3dca55d
|
391
|
// compared to all those delayMicrosecond() calls. But I got
|
gbeardall |
0:2f78e3dca55d
|
392
|
// confused, so I use this table from the examples.)
|
gbeardall |
0:2f78e3dca55d
|
393
|
//
|
gbeardall |
0:2f78e3dca55d
|
394
|
BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
|
gbeardall |
0:2f78e3dca55d
|
395
|
{
|
gbeardall |
0:2f78e3dca55d
|
396
|
BYTE i;
|
gbeardall |
0:2f78e3dca55d
|
397
|
BYTE crc = 0;
|
gbeardall |
0:2f78e3dca55d
|
398
|
|
gbeardall |
0:2f78e3dca55d
|
399
|
for (i = 0; i < len; i++)
|
gbeardall |
0:2f78e3dca55d
|
400
|
{
|
gbeardall |
0:2f78e3dca55d
|
401
|
crc = dscrc_table[crc ^ addr[i] ];
|
gbeardall |
0:2f78e3dca55d
|
402
|
}
|
gbeardall |
0:2f78e3dca55d
|
403
|
|
gbeardall |
0:2f78e3dca55d
|
404
|
return crc;
|
gbeardall |
0:2f78e3dca55d
|
405
|
}
|
gbeardall |
0:2f78e3dca55d
|
406
|
#else
|
gbeardall |
0:2f78e3dca55d
|
407
|
//
|
gbeardall |
0:2f78e3dca55d
|
408
|
// Compute a Dallas Semiconductor 8 bit CRC directly.
|
gbeardall |
0:2f78e3dca55d
|
409
|
//
|
gbeardall |
0:2f78e3dca55d
|
410
|
BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
|
gbeardall |
0:2f78e3dca55d
|
411
|
{
|
gbeardall |
0:2f78e3dca55d
|
412
|
BYTE i, j;
|
gbeardall |
0:2f78e3dca55d
|
413
|
BYTE crc = 0;
|
gbeardall |
0:2f78e3dca55d
|
414
|
|
gbeardall |
0:2f78e3dca55d
|
415
|
for (i = 0; i < len; i++)
|
gbeardall |
0:2f78e3dca55d
|
416
|
{
|
gbeardall |
0:2f78e3dca55d
|
417
|
BYTE inbyte = addr[i];
|
gbeardall |
0:2f78e3dca55d
|
418
|
for (j = 0; j < 8; j++)
|
gbeardall |
0:2f78e3dca55d
|
419
|
{
|
gbeardall |
0:2f78e3dca55d
|
420
|
BYTE mix = (crc ^ inbyte) & 0x01;
|
gbeardall |
0:2f78e3dca55d
|
421
|
crc >>= 1;
|
gbeardall |
0:2f78e3dca55d
|
422
|
if (mix) crc ^= 0x8C;
|
gbeardall |
0:2f78e3dca55d
|
423
|
inbyte >>= 1;
|
gbeardall |
0:2f78e3dca55d
|
424
|
}
|
gbeardall |
0:2f78e3dca55d
|
425
|
}
|
gbeardall |
0:2f78e3dca55d
|
426
|
|
gbeardall |
0:2f78e3dca55d
|
427
|
return crc;
|
gbeardall |
0:2f78e3dca55d
|
428
|
}
|
gbeardall |
0:2f78e3dca55d
|
429
|
#endif
|
gbeardall |
0:2f78e3dca55d
|
430
|
|
gbeardall |
0:2f78e3dca55d
|
431
|
static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
|
gbeardall |
0:2f78e3dca55d
|
432
|
|
gbeardall |
0:2f78e3dca55d
|
433
|
//
|
gbeardall |
0:2f78e3dca55d
|
434
|
// Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of
|
gbeardall |
0:2f78e3dca55d
|
435
|
// these, but here it is.
|
gbeardall |
0:2f78e3dca55d
|
436
|
//
|
gbeardall |
0:2f78e3dca55d
|
437
|
unsigned short OneWireCRC::crc16(unsigned short* data, unsigned short len)
|
gbeardall |
0:2f78e3dca55d
|
438
|
{
|
gbeardall |
0:2f78e3dca55d
|
439
|
unsigned short i;
|
gbeardall |
0:2f78e3dca55d
|
440
|
unsigned short crc = 0;
|
gbeardall |
0:2f78e3dca55d
|
441
|
|
gbeardall |
0:2f78e3dca55d
|
442
|
for ( i = 0; i < len; i++)
|
gbeardall |
0:2f78e3dca55d
|
443
|
{
|
gbeardall |
0:2f78e3dca55d
|
444
|
unsigned short cdata = data[len];
|
gbeardall |
0:2f78e3dca55d
|
445
|
|
gbeardall |
0:2f78e3dca55d
|
446
|
cdata = (cdata ^ (crc & 0xff)) & 0xff;
|
gbeardall |
0:2f78e3dca55d
|
447
|
crc >>= 8;
|
gbeardall |
0:2f78e3dca55d
|
448
|
|
gbeardall |
0:2f78e3dca55d
|
449
|
if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001;
|
gbeardall |
0:2f78e3dca55d
|
450
|
|
gbeardall |
0:2f78e3dca55d
|
451
|
cdata <<= 6;
|
gbeardall |
0:2f78e3dca55d
|
452
|
crc ^= cdata;
|
gbeardall |
0:2f78e3dca55d
|
453
|
cdata <<= 1;
|
gbeardall |
0:2f78e3dca55d
|
454
|
crc ^= cdata;
|
gbeardall |
0:2f78e3dca55d
|
455
|
}
|
gbeardall |
0:2f78e3dca55d
|
456
|
|
gbeardall |
0:2f78e3dca55d
|
457
|
return crc;
|
gbeardall |
0:2f78e3dca55d
|
458
|
}
|
gbeardall |
0:2f78e3dca55d
|
459
|
|