User | Revision | Line number | New contents of line |
Wimpie |
1:7218c076189b
|
1
|
/*
|
Wimpie |
1:7218c076189b
|
2
|
* OneWireCRC. This is a port to mbed of Jim Studt's Adruino One Wire
|
Wimpie |
1:7218c076189b
|
3
|
* library. Please see additional copyrights below this one, including
|
Wimpie |
1:7218c076189b
|
4
|
* references to other copyrights.
|
Wimpie |
1:7218c076189b
|
5
|
*
|
Wimpie |
1:7218c076189b
|
6
|
* Copyright (C) <2011> Version 1.2 Wim De Roeve
|
Wimpie |
1:7218c076189b
|
7
|
* <2009> Petras Saduikis <petras@petras.co.uk>
|
Wimpie |
1:7218c076189b
|
8
|
*
|
Wimpie |
1:7218c076189b
|
9
|
* This file is part of OneWireCRC.
|
Wimpie |
1:7218c076189b
|
10
|
*
|
Wimpie |
1:7218c076189b
|
11
|
* OneWireCRC is free software: you can redistribute it and/or modify
|
Wimpie |
1:7218c076189b
|
12
|
* it under the terms of the GNU General Public License as published by
|
Wimpie |
1:7218c076189b
|
13
|
* the Free Software Foundation, either version 3 of the License, or
|
Wimpie |
1:7218c076189b
|
14
|
* (at your option) any later version.
|
Wimpie |
1:7218c076189b
|
15
|
*
|
Wimpie |
1:7218c076189b
|
16
|
* OneWireCRC is distributed in the hope that it will be useful,
|
Wimpie |
1:7218c076189b
|
17
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Wimpie |
1:7218c076189b
|
18
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Wimpie |
1:7218c076189b
|
19
|
* GNU General Public License for more details.
|
Wimpie |
1:7218c076189b
|
20
|
*
|
Wimpie |
1:7218c076189b
|
21
|
* You should have received a copy of the GNU General Public License
|
Wimpie |
1:7218c076189b
|
22
|
* along with OneWireCRC. If not, see <http://www.gnu.org/licenses/>.
|
Wimpie |
1:7218c076189b
|
23
|
*/
|
Wimpie |
1:7218c076189b
|
24
|
/*
|
Wimpie |
1:7218c076189b
|
25
|
Copyright (c) 2007, Jim Studt
|
Wimpie |
1:7218c076189b
|
26
|
|
Wimpie |
1:7218c076189b
|
27
|
Version 2.0: Modifications by Paul Stoffregen, January 2010:
|
Wimpie |
1:7218c076189b
|
28
|
http://www.pjrc.com/teensy/td_libs_OneWire.html
|
Wimpie |
1:7218c076189b
|
29
|
Search fix from Robin James
|
Wimpie |
1:7218c076189b
|
30
|
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
|
Wimpie |
1:7218c076189b
|
31
|
Use direct optimized I/O in all cases
|
Wimpie |
1:7218c076189b
|
32
|
Disable interrupts during timing critical sections
|
Wimpie |
1:7218c076189b
|
33
|
(this solves many random communication errors)
|
Wimpie |
1:7218c076189b
|
34
|
Disable interrupts during read-modify-write I/O
|
Wimpie |
1:7218c076189b
|
35
|
Reduce RAM consumption by eliminating unnecessary
|
Wimpie |
1:7218c076189b
|
36
|
variables and trimming many to 8 bits
|
Wimpie |
1:7218c076189b
|
37
|
Optimize both crc8 - table version moved to flash
|
Wimpie |
1:7218c076189b
|
38
|
|
Wimpie |
1:7218c076189b
|
39
|
Modified to work with larger numbers of devices - avoids loop.
|
Wimpie |
1:7218c076189b
|
40
|
Tested in Arduino 11 alpha with 12 sensors.
|
Wimpie |
1:7218c076189b
|
41
|
26 Sept 2008 -- Robin James
|
Wimpie |
1:7218c076189b
|
42
|
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
|
Wimpie |
1:7218c076189b
|
43
|
|
Wimpie |
1:7218c076189b
|
44
|
|
Wimpie |
1:7218c076189b
|
45
|
Updated to work with arduino-0008 and to include skip() as of
|
Wimpie |
1:7218c076189b
|
46
|
2007/07/06. --RJL20
|
Wimpie |
1:7218c076189b
|
47
|
|
Wimpie |
1:7218c076189b
|
48
|
Modified to calculate the 8-bit CRC directly, avoiding the need for
|
Wimpie |
1:7218c076189b
|
49
|
the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
|
Wimpie |
1:7218c076189b
|
50
|
-- Tom Pollard, Jan 23, 2008
|
Wimpie |
1:7218c076189b
|
51
|
|
Wimpie |
1:7218c076189b
|
52
|
Permission is hereby granted, free of charge, to any person obtaining
|
Wimpie |
1:7218c076189b
|
53
|
a copy of this software and associated documentation files (the
|
Wimpie |
1:7218c076189b
|
54
|
"Software"), to deal in the Software without restriction, including
|
Wimpie |
1:7218c076189b
|
55
|
without limitation the rights to use, copy, modify, merge, publish,
|
Wimpie |
1:7218c076189b
|
56
|
distribute, sublicense, and/or sell copies of the Software, and to
|
Wimpie |
1:7218c076189b
|
57
|
permit persons to whom the Software is furnished to do so, subject to
|
Wimpie |
1:7218c076189b
|
58
|
the following conditions:
|
Wimpie |
1:7218c076189b
|
59
|
|
Wimpie |
1:7218c076189b
|
60
|
The above copyright notice and this permission notice shall be
|
Wimpie |
1:7218c076189b
|
61
|
included in all copies or substantial portions of the Software.
|
Wimpie |
1:7218c076189b
|
62
|
|
Wimpie |
1:7218c076189b
|
63
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
Wimpie |
1:7218c076189b
|
64
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Wimpie |
1:7218c076189b
|
65
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
Wimpie |
1:7218c076189b
|
66
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
Wimpie |
1:7218c076189b
|
67
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
Wimpie |
1:7218c076189b
|
68
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
Wimpie |
1:7218c076189b
|
69
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Wimpie |
1:7218c076189b
|
70
|
|
Wimpie |
1:7218c076189b
|
71
|
Much of the code was inspired by Derek Yerger's code, though I don't
|
Wimpie |
1:7218c076189b
|
72
|
think much of that remains. In any event that was..
|
Wimpie |
1:7218c076189b
|
73
|
(copyleft) 2006 by Derek Yerger - Free to distribute freely.
|
Wimpie |
1:7218c076189b
|
74
|
|
Wimpie |
1:7218c076189b
|
75
|
The CRC code was excerpted and inspired by the Dallas Semiconductor
|
Wimpie |
1:7218c076189b
|
76
|
sample code bearing this copyright.
|
Wimpie |
1:7218c076189b
|
77
|
*/
|
Wimpie |
1:7218c076189b
|
78
|
//---------------------------------------------------------------------------
|
Wimpie |
1:7218c076189b
|
79
|
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
|
Wimpie |
1:7218c076189b
|
80
|
//
|
Wimpie |
1:7218c076189b
|
81
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
Wimpie |
1:7218c076189b
|
82
|
// copy of this software and associated documentation files (the "Software"),
|
Wimpie |
1:7218c076189b
|
83
|
// to deal in the Software without restriction, including without limitation
|
Wimpie |
1:7218c076189b
|
84
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
Wimpie |
1:7218c076189b
|
85
|
// and/or sell copies of the Software, and to permit persons to whom the
|
Wimpie |
1:7218c076189b
|
86
|
// Software is furnished to do so, subject to the following conditions:
|
Wimpie |
1:7218c076189b
|
87
|
//
|
Wimpie |
1:7218c076189b
|
88
|
// The above copyright notice and this permission notice shall be included
|
Wimpie |
1:7218c076189b
|
89
|
// in all copies or substantial portions of the Software.
|
Wimpie |
1:7218c076189b
|
90
|
//
|
Wimpie |
1:7218c076189b
|
91
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
Wimpie |
1:7218c076189b
|
92
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Wimpie |
1:7218c076189b
|
93
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
Wimpie |
1:7218c076189b
|
94
|
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
|
Wimpie |
1:7218c076189b
|
95
|
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
Wimpie |
1:7218c076189b
|
96
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
Wimpie |
1:7218c076189b
|
97
|
// OTHER DEALINGS IN THE SOFTWARE.
|
Wimpie |
1:7218c076189b
|
98
|
//
|
Wimpie |
1:7218c076189b
|
99
|
// Except as contained in this notice, the name of Dallas Semiconductor
|
Wimpie |
1:7218c076189b
|
100
|
// shall not be used except as stated in the Dallas Semiconductor
|
Wimpie |
1:7218c076189b
|
101
|
// Branding Policy.
|
Wimpie |
1:7218c076189b
|
102
|
//--------------------------------------------------------------------------
|
Wimpie |
1:7218c076189b
|
103
|
|
Wimpie |
1:7218c076189b
|
104
|
#include "OneWireCRC.h"
|
Wimpie |
2:193926923cb0
|
105
|
|
Wimpie |
2:193926923cb0
|
106
|
// ROM commands
|
Wimpie |
2:193926923cb0
|
107
|
#define OVERDRIVE_SKIP 0x3C
|
Wimpie |
2:193926923cb0
|
108
|
#define MATCH_ROM 0x55
|
Wimpie |
2:193926923cb0
|
109
|
#define SKIP_ROM 0xCC
|
Wimpie |
1:7218c076189b
|
110
|
|
Wimpie |
1:7218c076189b
|
111
|
// recommended data sheet timings in micro seconds
|
Wimpie |
1:7218c076189b
|
112
|
const int standardT[] = {6, 64, 60, 10, 9, 55, 0, 480, 70, 410};
|
Wimpie |
1:7218c076189b
|
113
|
const int overdriveT[] = {1.5, 7.5, 7.5, 2.5, 0.75, 7, 2.5, 70, 8.5, 40};
|
Wimpie |
1:7218c076189b
|
114
|
|
Wimpie |
1:7218c076189b
|
115
|
OneWireCRC::OneWireCRC(PinName oneWire, eSpeed speed) : oneWirePort(oneWire)
|
Wimpie |
1:7218c076189b
|
116
|
{
|
Wimpie |
1:7218c076189b
|
117
|
if (STANDARD == speed) timing = standardT;
|
Wimpie |
1:7218c076189b
|
118
|
else timing = overdriveT; // overdrive
|
Wimpie |
1:7218c076189b
|
119
|
|
Wimpie |
1:7218c076189b
|
120
|
resetSearch(); // reset address search state
|
Wimpie |
1:7218c076189b
|
121
|
}
|
Wimpie |
1:7218c076189b
|
122
|
|
Wimpie |
1:7218c076189b
|
123
|
// Generate a 1-wire reset, return 1 if no presence detect was found,
|
Wimpie |
1:7218c076189b
|
124
|
// return 0 otherwise.
|
Wimpie |
1:7218c076189b
|
125
|
// (NOTE: does not handle alarm presence from DS2404/DS1994)
|
Wimpie |
1:7218c076189b
|
126
|
int OneWireCRC::reset()
|
Wimpie |
1:7218c076189b
|
127
|
{
|
Wimpie |
1:7218c076189b
|
128
|
|
Wimpie |
1:7218c076189b
|
129
|
BYTE result = 0; // sample presence pulse result
|
Wimpie |
1:7218c076189b
|
130
|
|
Wimpie |
1:7218c076189b
|
131
|
wait_us(timing[6]);
|
Wimpie |
1:7218c076189b
|
132
|
oneWirePort.output();
|
Wimpie |
1:7218c076189b
|
133
|
oneWirePort = 0;
|
Wimpie |
1:7218c076189b
|
134
|
wait_us(timing[7]);
|
Wimpie |
1:7218c076189b
|
135
|
oneWirePort.input();
|
Wimpie |
1:7218c076189b
|
136
|
wait_us(timing[8]);
|
Wimpie |
1:7218c076189b
|
137
|
result = !(oneWirePort & 0x01);
|
Wimpie |
1:7218c076189b
|
138
|
wait_us(timing[9]);
|
Wimpie |
1:7218c076189b
|
139
|
|
Wimpie |
1:7218c076189b
|
140
|
return result;
|
Wimpie |
1:7218c076189b
|
141
|
}
|
Wimpie |
1:7218c076189b
|
142
|
|
Wimpie |
1:7218c076189b
|
143
|
//
|
Wimpie |
1:7218c076189b
|
144
|
// Write a bit. Port and bit is used to cut lookup time and provide
|
Wimpie |
1:7218c076189b
|
145
|
// more certain timing.
|
Wimpie |
1:7218c076189b
|
146
|
//
|
Wimpie |
1:7218c076189b
|
147
|
void OneWireCRC::writeBit(int bit)
|
Wimpie |
1:7218c076189b
|
148
|
{
|
Wimpie |
1:7218c076189b
|
149
|
bit = bit & 0x01;
|
Wimpie |
1:7218c076189b
|
150
|
|
Wimpie |
1:7218c076189b
|
151
|
if (bit)
|
Wimpie |
1:7218c076189b
|
152
|
{
|
Wimpie |
1:7218c076189b
|
153
|
// Write '1' bit
|
Wimpie |
1:7218c076189b
|
154
|
oneWirePort.output();
|
Wimpie |
1:7218c076189b
|
155
|
oneWirePort = 0;
|
Wimpie |
1:7218c076189b
|
156
|
wait_us(timing[0]);
|
Wimpie |
1:7218c076189b
|
157
|
oneWirePort.input();
|
Wimpie |
1:7218c076189b
|
158
|
wait_us(timing[1]);
|
Wimpie |
1:7218c076189b
|
159
|
}
|
Wimpie |
1:7218c076189b
|
160
|
else
|
Wimpie |
1:7218c076189b
|
161
|
{
|
Wimpie |
1:7218c076189b
|
162
|
// Write '0' bit
|
Wimpie |
1:7218c076189b
|
163
|
oneWirePort.output();
|
Wimpie |
1:7218c076189b
|
164
|
oneWirePort = 0;
|
Wimpie |
1:7218c076189b
|
165
|
wait_us(timing[2]);
|
Wimpie |
1:7218c076189b
|
166
|
oneWirePort.input();
|
Wimpie |
1:7218c076189b
|
167
|
wait_us(timing[3]);
|
Wimpie |
1:7218c076189b
|
168
|
}
|
Wimpie |
1:7218c076189b
|
169
|
}
|
Wimpie |
1:7218c076189b
|
170
|
|
Wimpie |
1:7218c076189b
|
171
|
//
|
Wimpie |
1:7218c076189b
|
172
|
// Read a bit. Port and bit is used to cut lookup time and provide
|
Wimpie |
1:7218c076189b
|
173
|
// more certain timing.
|
Wimpie |
1:7218c076189b
|
174
|
//
|
Wimpie |
1:7218c076189b
|
175
|
int OneWireCRC::readBit()
|
Wimpie |
1:7218c076189b
|
176
|
{
|
Wimpie |
1:7218c076189b
|
177
|
BYTE result;
|
Wimpie |
1:7218c076189b
|
178
|
|
Wimpie |
1:7218c076189b
|
179
|
oneWirePort.output();
|
Wimpie |
1:7218c076189b
|
180
|
oneWirePort = 0;
|
Wimpie |
1:7218c076189b
|
181
|
wait_us(timing[0]);
|
Wimpie |
1:7218c076189b
|
182
|
oneWirePort.input();
|
Wimpie |
1:7218c076189b
|
183
|
wait_us(timing[4]);
|
Wimpie |
1:7218c076189b
|
184
|
result = oneWirePort & 0x01;
|
Wimpie |
1:7218c076189b
|
185
|
wait_us(timing[5]);
|
Wimpie |
1:7218c076189b
|
186
|
|
Wimpie |
1:7218c076189b
|
187
|
return result;
|
Wimpie |
1:7218c076189b
|
188
|
}
|
Wimpie |
1:7218c076189b
|
189
|
|
Wimpie |
1:7218c076189b
|
190
|
//
|
Wimpie |
1:7218c076189b
|
191
|
// Write a byte. The writing code uses the active drivers to raise the
|
Wimpie |
1:7218c076189b
|
192
|
// pin high, if you need power after the write (e.g. DS18S20 in
|
Wimpie |
1:7218c076189b
|
193
|
// parasite power mode) then set 'power' to 1, otherwise the pin will
|
Wimpie |
1:7218c076189b
|
194
|
// go tri-state at the end of the write to avoid heating in a short or
|
Wimpie |
1:7218c076189b
|
195
|
// other mishap.
|
Wimpie |
1:7218c076189b
|
196
|
//
|
Wimpie |
1:7218c076189b
|
197
|
void OneWireCRC::writeByte(int data)
|
Wimpie |
1:7218c076189b
|
198
|
{
|
Wimpie |
1:7218c076189b
|
199
|
// Loop to write each bit in the byte, LS-bit first
|
Wimpie |
1:7218c076189b
|
200
|
for (int loop = 0; loop < 8; loop++)
|
Wimpie |
1:7218c076189b
|
201
|
{
|
Wimpie |
1:7218c076189b
|
202
|
writeBit(data & 0x01);
|
Wimpie |
1:7218c076189b
|
203
|
|
Wimpie |
1:7218c076189b
|
204
|
// shift the data byte for the next bit
|
Wimpie |
1:7218c076189b
|
205
|
data >>= 1;
|
Wimpie |
1:7218c076189b
|
206
|
}
|
Wimpie |
1:7218c076189b
|
207
|
}
|
Wimpie |
1:7218c076189b
|
208
|
|
Wimpie |
1:7218c076189b
|
209
|
//
|
Wimpie |
1:7218c076189b
|
210
|
// Read a byte
|
Wimpie |
1:7218c076189b
|
211
|
//
|
Wimpie |
1:7218c076189b
|
212
|
int OneWireCRC::readByte()
|
Wimpie |
1:7218c076189b
|
213
|
{
|
Wimpie |
1:7218c076189b
|
214
|
int result = 0;
|
Wimpie |
1:7218c076189b
|
215
|
|
Wimpie |
1:7218c076189b
|
216
|
for (int loop = 0; loop < 8; loop++)
|
Wimpie |
1:7218c076189b
|
217
|
{
|
Wimpie |
1:7218c076189b
|
218
|
// shift the result to get it ready for the next bit
|
Wimpie |
1:7218c076189b
|
219
|
result >>= 1;
|
Wimpie |
1:7218c076189b
|
220
|
|
Wimpie |
1:7218c076189b
|
221
|
// if result is one, then set MS bit
|
Wimpie |
1:7218c076189b
|
222
|
if (readBit()) result |= 0x80;
|
Wimpie |
1:7218c076189b
|
223
|
}
|
Wimpie |
1:7218c076189b
|
224
|
|
Wimpie |
1:7218c076189b
|
225
|
return result;
|
Wimpie |
1:7218c076189b
|
226
|
}
|
Wimpie |
1:7218c076189b
|
227
|
|
Wimpie |
1:7218c076189b
|
228
|
int OneWireCRC::touchByte(int data)
|
Wimpie |
1:7218c076189b
|
229
|
{
|
Wimpie |
1:7218c076189b
|
230
|
int result = 0;
|
Wimpie |
1:7218c076189b
|
231
|
|
Wimpie |
1:7218c076189b
|
232
|
for (int loop = 0; loop < 8; loop++)
|
Wimpie |
1:7218c076189b
|
233
|
{
|
Wimpie |
1:7218c076189b
|
234
|
// shift the result to get it ready for the next bit
|
Wimpie |
1:7218c076189b
|
235
|
result >>= 1;
|
Wimpie |
1:7218c076189b
|
236
|
|
Wimpie |
1:7218c076189b
|
237
|
// If sending a '1' then read a bit else write a '0'
|
Wimpie |
1:7218c076189b
|
238
|
if (data & 0x01)
|
Wimpie |
1:7218c076189b
|
239
|
{
|
Wimpie |
1:7218c076189b
|
240
|
if (readBit()) result |= 0x80;
|
Wimpie |
1:7218c076189b
|
241
|
}
|
Wimpie |
1:7218c076189b
|
242
|
else writeBit(0);
|
Wimpie |
1:7218c076189b
|
243
|
|
Wimpie |
1:7218c076189b
|
244
|
// shift the data byte for the next bit
|
Wimpie |
1:7218c076189b
|
245
|
data >>= 1;
|
Wimpie |
1:7218c076189b
|
246
|
}
|
Wimpie |
1:7218c076189b
|
247
|
|
Wimpie |
1:7218c076189b
|
248
|
return result;
|
Wimpie |
1:7218c076189b
|
249
|
}
|
Wimpie |
1:7218c076189b
|
250
|
|
Wimpie |
1:7218c076189b
|
251
|
void OneWireCRC::block(BYTE* data, int data_len)
|
Wimpie |
1:7218c076189b
|
252
|
{
|
Wimpie |
1:7218c076189b
|
253
|
for (int loop = 0; loop < data_len; loop++)
|
Wimpie |
1:7218c076189b
|
254
|
{
|
Wimpie |
1:7218c076189b
|
255
|
data[loop] = touchByte(data[loop]);
|
Wimpie |
1:7218c076189b
|
256
|
}
|
Wimpie |
1:7218c076189b
|
257
|
}
|
Wimpie |
1:7218c076189b
|
258
|
|
Wimpie |
1:7218c076189b
|
259
|
int OneWireCRC::overdriveSkip(BYTE* data, int data_len)
|
Wimpie |
1:7218c076189b
|
260
|
{
|
Wimpie |
1:7218c076189b
|
261
|
// set the speed to 'standard'
|
Wimpie |
1:7218c076189b
|
262
|
timing = standardT;
|
Wimpie |
1:7218c076189b
|
263
|
|
Wimpie |
1:7218c076189b
|
264
|
// reset all devices
|
Wimpie |
1:7218c076189b
|
265
|
if (reset()) return 0; // if no devices found
|
Wimpie |
1:7218c076189b
|
266
|
|
Wimpie |
1:7218c076189b
|
267
|
// overdrive skip command
|
Wimpie |
1:7218c076189b
|
268
|
writeByte(OVERDRIVE_SKIP);
|
Wimpie |
1:7218c076189b
|
269
|
|
Wimpie |
1:7218c076189b
|
270
|
// set the speed to 'overdrive'
|
Wimpie |
1:7218c076189b
|
271
|
timing = overdriveT;
|
Wimpie |
1:7218c076189b
|
272
|
|
Wimpie |
1:7218c076189b
|
273
|
// do a 1-Wire reset in 'overdrive' and return presence result
|
Wimpie |
1:7218c076189b
|
274
|
return reset();
|
Wimpie |
1:7218c076189b
|
275
|
}
|
Wimpie |
1:7218c076189b
|
276
|
|
Wimpie |
1:7218c076189b
|
277
|
//
|
Wimpie |
1:7218c076189b
|
278
|
// Do a ROM select
|
Wimpie |
1:7218c076189b
|
279
|
//
|
Wimpie |
1:7218c076189b
|
280
|
void OneWireCRC::matchROM(BYTE rom[8])
|
Wimpie |
1:7218c076189b
|
281
|
{
|
Wimpie |
1:7218c076189b
|
282
|
writeByte(MATCH_ROM); // Choose ROM
|
Wimpie |
1:7218c076189b
|
283
|
|
Wimpie |
1:7218c076189b
|
284
|
for(int i = 0; i < 8; i++) writeByte(rom[i]);
|
Wimpie |
1:7218c076189b
|
285
|
}
|
Wimpie |
1:7218c076189b
|
286
|
|
Wimpie |
1:7218c076189b
|
287
|
//
|
Wimpie |
1:7218c076189b
|
288
|
// Do a ROM skip
|
Wimpie |
1:7218c076189b
|
289
|
//
|
Wimpie |
1:7218c076189b
|
290
|
void OneWireCRC::skipROM()
|
Wimpie |
1:7218c076189b
|
291
|
{
|
Wimpie |
1:7218c076189b
|
292
|
writeByte(SKIP_ROM); // Skip ROM
|
Wimpie |
1:7218c076189b
|
293
|
}
|
Wimpie |
1:7218c076189b
|
294
|
|
Wimpie |
1:7218c076189b
|
295
|
//
|
Wimpie |
1:7218c076189b
|
296
|
// You need to use this function to start a search again from the beginning.
|
Wimpie |
1:7218c076189b
|
297
|
// You do not need to do it for the first search, though you could.
|
Wimpie |
1:7218c076189b
|
298
|
//
|
Wimpie |
1:7218c076189b
|
299
|
void OneWireCRC::resetSearch()
|
Wimpie |
1:7218c076189b
|
300
|
{
|
Wimpie |
1:7218c076189b
|
301
|
/* searchJunction = -1;
|
Wimpie |
1:7218c076189b
|
302
|
searchExhausted = false;
|
Wimpie |
1:7218c076189b
|
303
|
for (int i = 0; i < 8; i++)
|
Wimpie |
1:7218c076189b
|
304
|
{
|
Wimpie |
1:7218c076189b
|
305
|
_address[i] = 0;
|
Wimpie |
1:7218c076189b
|
306
|
}*/
|
Wimpie |
1:7218c076189b
|
307
|
|
Wimpie |
1:7218c076189b
|
308
|
// reset the search state
|
Wimpie |
1:7218c076189b
|
309
|
LastDiscrepancy = 0;
|
Wimpie |
1:7218c076189b
|
310
|
LastDeviceFlag = 0;
|
Wimpie |
1:7218c076189b
|
311
|
LastFamilyDiscrepancy = 0;
|
Wimpie |
1:7218c076189b
|
312
|
for(int i = 7; ; i--)
|
Wimpie |
1:7218c076189b
|
313
|
{
|
Wimpie |
1:7218c076189b
|
314
|
ROM_NO[i] = 0;
|
Wimpie |
1:7218c076189b
|
315
|
if ( i == 0) break;
|
Wimpie |
1:7218c076189b
|
316
|
}
|
Wimpie |
1:7218c076189b
|
317
|
}
|
Wimpie |
1:7218c076189b
|
318
|
// Changed in version 1.1
|
Wimpie |
1:7218c076189b
|
319
|
//
|
Wimpie |
1:7218c076189b
|
320
|
// Perform a search. If this function returns a '1' then it has
|
Wimpie |
1:7218c076189b
|
321
|
// enumerated the next device and you may retrieve the ROM from the
|
Wimpie |
1:7218c076189b
|
322
|
// OneWire::address variable. If there are no devices, no further
|
Wimpie |
1:7218c076189b
|
323
|
// devices, or something horrible happens in the middle of the
|
Wimpie |
1:7218c076189b
|
324
|
// enumeration then a 0 is returned. If a new device is found then
|
Wimpie |
1:7218c076189b
|
325
|
// its address is copied to newAddr. Use OneWire::reset_search() to
|
Wimpie |
1:7218c076189b
|
326
|
// start over.
|
Wimpie |
1:7218c076189b
|
327
|
//
|
Wimpie |
1:7218c076189b
|
328
|
// --- Replaced by the one from the Dallas Semiconductor web site ---
|
Wimpie |
1:7218c076189b
|
329
|
//--------------------------------------------------------------------------
|
Wimpie |
1:7218c076189b
|
330
|
// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
|
Wimpie |
1:7218c076189b
|
331
|
// search state.
|
Wimpie |
1:7218c076189b
|
332
|
// Return TRUE : device found, ROM number in ROM_NO buffer
|
Wimpie |
1:7218c076189b
|
333
|
// FALSE : device not found, end of search
|
Wimpie |
1:7218c076189b
|
334
|
//
|
Wimpie |
1:7218c076189b
|
335
|
uint8_t OneWireCRC::search(uint8_t *newAddr)
|
Wimpie |
1:7218c076189b
|
336
|
{
|
Wimpie |
1:7218c076189b
|
337
|
uint8_t id_bit_number;
|
Wimpie |
1:7218c076189b
|
338
|
uint8_t last_zero, rom_byte_number, search_result;
|
Wimpie |
1:7218c076189b
|
339
|
uint8_t id_bit, cmp_id_bit;
|
Wimpie |
1:7218c076189b
|
340
|
|
Wimpie |
1:7218c076189b
|
341
|
unsigned char rom_byte_mask, search_direction;
|
Wimpie |
1:7218c076189b
|
342
|
|
Wimpie |
1:7218c076189b
|
343
|
// initialize for search
|
Wimpie |
1:7218c076189b
|
344
|
id_bit_number = 1;
|
Wimpie |
1:7218c076189b
|
345
|
last_zero = 0;
|
Wimpie |
1:7218c076189b
|
346
|
rom_byte_number = 0;
|
Wimpie |
1:7218c076189b
|
347
|
rom_byte_mask = 1;
|
Wimpie |
1:7218c076189b
|
348
|
search_result = 0;
|
Wimpie |
1:7218c076189b
|
349
|
|
Wimpie |
1:7218c076189b
|
350
|
// if the last call was not the last one
|
Wimpie |
1:7218c076189b
|
351
|
if (!LastDeviceFlag)
|
Wimpie |
1:7218c076189b
|
352
|
{
|
Wimpie |
1:7218c076189b
|
353
|
// 1-Wire reset
|
Wimpie |
1:7218c076189b
|
354
|
if (!reset())
|
Wimpie |
1:7218c076189b
|
355
|
{
|
Wimpie |
1:7218c076189b
|
356
|
// reset the search
|
Wimpie |
1:7218c076189b
|
357
|
LastDiscrepancy = 0;
|
Wimpie |
1:7218c076189b
|
358
|
LastDeviceFlag = 0;
|
Wimpie |
1:7218c076189b
|
359
|
LastFamilyDiscrepancy = 0;
|
Wimpie |
1:7218c076189b
|
360
|
return 0;
|
Wimpie |
1:7218c076189b
|
361
|
}
|
Wimpie |
1:7218c076189b
|
362
|
|
Wimpie |
1:7218c076189b
|
363
|
// issue the search command
|
Wimpie |
1:7218c076189b
|
364
|
writeByte(0xF0);
|
Wimpie |
1:7218c076189b
|
365
|
|
Wimpie |
1:7218c076189b
|
366
|
// loop to do the search
|
Wimpie |
1:7218c076189b
|
367
|
do
|
Wimpie |
1:7218c076189b
|
368
|
{
|
Wimpie |
1:7218c076189b
|
369
|
// read a bit and its complement
|
Wimpie |
1:7218c076189b
|
370
|
id_bit = readBit();
|
Wimpie |
1:7218c076189b
|
371
|
cmp_id_bit = readBit();
|
Wimpie |
1:7218c076189b
|
372
|
|
Wimpie |
1:7218c076189b
|
373
|
// check for no devices on 1-wire
|
Wimpie |
1:7218c076189b
|
374
|
if ((id_bit == 1) && (cmp_id_bit == 1))
|
Wimpie |
1:7218c076189b
|
375
|
break;
|
Wimpie |
1:7218c076189b
|
376
|
else
|
Wimpie |
1:7218c076189b
|
377
|
{
|
Wimpie |
1:7218c076189b
|
378
|
// all devices coupled have 0 or 1
|
Wimpie |
1:7218c076189b
|
379
|
if (id_bit != cmp_id_bit)
|
Wimpie |
1:7218c076189b
|
380
|
search_direction = id_bit; // bit write value for search
|
Wimpie |
1:7218c076189b
|
381
|
else
|
Wimpie |
1:7218c076189b
|
382
|
{
|
Wimpie |
1:7218c076189b
|
383
|
// if this discrepancy if before the Last Discrepancy
|
Wimpie |
1:7218c076189b
|
384
|
// on a previous next then pick the same as last time
|
Wimpie |
1:7218c076189b
|
385
|
if (id_bit_number < LastDiscrepancy)
|
Wimpie |
1:7218c076189b
|
386
|
search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
|
Wimpie |
1:7218c076189b
|
387
|
else
|
Wimpie |
1:7218c076189b
|
388
|
// if equal to last pick 1, if not then pick 0
|
Wimpie |
1:7218c076189b
|
389
|
search_direction = (id_bit_number == LastDiscrepancy);
|
Wimpie |
1:7218c076189b
|
390
|
|
Wimpie |
1:7218c076189b
|
391
|
// if 0 was picked then record its position in LastZero
|
Wimpie |
1:7218c076189b
|
392
|
if (search_direction == 0)
|
Wimpie |
1:7218c076189b
|
393
|
{
|
Wimpie |
1:7218c076189b
|
394
|
last_zero = id_bit_number;
|
Wimpie |
1:7218c076189b
|
395
|
|
Wimpie |
1:7218c076189b
|
396
|
// check for Last discrepancy in family
|
Wimpie |
1:7218c076189b
|
397
|
if (last_zero < 9)
|
Wimpie |
1:7218c076189b
|
398
|
LastFamilyDiscrepancy = last_zero;
|
Wimpie |
1:7218c076189b
|
399
|
}
|
Wimpie |
1:7218c076189b
|
400
|
}
|
Wimpie |
1:7218c076189b
|
401
|
|
Wimpie |
1:7218c076189b
|
402
|
// set or clear the bit in the ROM byte rom_byte_number
|
Wimpie |
1:7218c076189b
|
403
|
// with mask rom_byte_mask
|
Wimpie |
1:7218c076189b
|
404
|
if (search_direction == 1)
|
Wimpie |
1:7218c076189b
|
405
|
ROM_NO[rom_byte_number] |= rom_byte_mask;
|
Wimpie |
1:7218c076189b
|
406
|
else
|
Wimpie |
1:7218c076189b
|
407
|
ROM_NO[rom_byte_number] &= ~rom_byte_mask;
|
Wimpie |
1:7218c076189b
|
408
|
|
Wimpie |
1:7218c076189b
|
409
|
// serial number search direction write bit
|
Wimpie |
1:7218c076189b
|
410
|
writeBit(search_direction);
|
Wimpie |
1:7218c076189b
|
411
|
|
Wimpie |
1:7218c076189b
|
412
|
// increment the byte counter id_bit_number
|
Wimpie |
1:7218c076189b
|
413
|
// and shift the mask rom_byte_mask
|
Wimpie |
1:7218c076189b
|
414
|
id_bit_number++;
|
Wimpie |
1:7218c076189b
|
415
|
rom_byte_mask <<= 1;
|
Wimpie |
1:7218c076189b
|
416
|
|
Wimpie |
1:7218c076189b
|
417
|
// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
|
Wimpie |
1:7218c076189b
|
418
|
if (rom_byte_mask == 0)
|
Wimpie |
1:7218c076189b
|
419
|
{
|
Wimpie |
1:7218c076189b
|
420
|
rom_byte_number++;
|
Wimpie |
1:7218c076189b
|
421
|
rom_byte_mask = 1;
|
Wimpie |
1:7218c076189b
|
422
|
}
|
Wimpie |
1:7218c076189b
|
423
|
}
|
Wimpie |
1:7218c076189b
|
424
|
}
|
Wimpie |
1:7218c076189b
|
425
|
while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
|
Wimpie |
1:7218c076189b
|
426
|
|
Wimpie |
1:7218c076189b
|
427
|
// if the search was successful then
|
Wimpie |
1:7218c076189b
|
428
|
if (!(id_bit_number < 65))
|
Wimpie |
1:7218c076189b
|
429
|
{
|
Wimpie |
1:7218c076189b
|
430
|
// search successful so set LastDiscrepancy,LastDeviceFlag,search_result
|
Wimpie |
1:7218c076189b
|
431
|
LastDiscrepancy = last_zero;
|
Wimpie |
1:7218c076189b
|
432
|
|
Wimpie |
1:7218c076189b
|
433
|
// check for last device
|
Wimpie |
1:7218c076189b
|
434
|
if (LastDiscrepancy == 0)
|
Wimpie |
1:7218c076189b
|
435
|
LastDeviceFlag = 1;
|
Wimpie |
1:7218c076189b
|
436
|
|
Wimpie |
1:7218c076189b
|
437
|
search_result = 1;
|
Wimpie |
1:7218c076189b
|
438
|
}
|
Wimpie |
1:7218c076189b
|
439
|
}
|
Wimpie |
1:7218c076189b
|
440
|
|
Wimpie |
1:7218c076189b
|
441
|
// if no device found then reset counters so next 'search' will be like a first
|
Wimpie |
1:7218c076189b
|
442
|
if (!search_result || !ROM_NO[0])
|
Wimpie |
1:7218c076189b
|
443
|
{
|
Wimpie |
1:7218c076189b
|
444
|
LastDiscrepancy = 0;
|
Wimpie |
1:7218c076189b
|
445
|
LastDeviceFlag = 0;
|
Wimpie |
1:7218c076189b
|
446
|
LastFamilyDiscrepancy = 0;
|
Wimpie |
1:7218c076189b
|
447
|
search_result = 0;
|
Wimpie |
1:7218c076189b
|
448
|
}
|
Wimpie |
1:7218c076189b
|
449
|
else
|
Wimpie |
1:7218c076189b
|
450
|
for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
|
Wimpie |
1:7218c076189b
|
451
|
|
Wimpie |
1:7218c076189b
|
452
|
return search_result;
|
Wimpie |
1:7218c076189b
|
453
|
}
|
Wimpie |
1:7218c076189b
|
454
|
|
Wimpie |
1:7218c076189b
|
455
|
// The 1-Wire CRC scheme is described in Maxim Application Note 27:
|
Wimpie |
1:7218c076189b
|
456
|
// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
|
Wimpie |
1:7218c076189b
|
457
|
//
|
Wimpie |
1:7218c076189b
|
458
|
|
Wimpie |
1:7218c076189b
|
459
|
#if ONEWIRE_CRC8_TABLE
|
Wimpie |
1:7218c076189b
|
460
|
// This table comes from Dallas sample code where it is freely reusable,
|
Wimpie |
1:7218c076189b
|
461
|
// though Copyright (C) 2000 Dallas Semiconductor Corporation
|
Wimpie |
1:7218c076189b
|
462
|
static BYTE dscrc_table[] =
|
Wimpie |
1:7218c076189b
|
463
|
{
|
Wimpie |
1:7218c076189b
|
464
|
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
|
Wimpie |
1:7218c076189b
|
465
|
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
|
Wimpie |
1:7218c076189b
|
466
|
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
|
Wimpie |
1:7218c076189b
|
467
|
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
|
Wimpie |
1:7218c076189b
|
468
|
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
|
Wimpie |
1:7218c076189b
|
469
|
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
|
Wimpie |
1:7218c076189b
|
470
|
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
|
Wimpie |
1:7218c076189b
|
471
|
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
|
Wimpie |
1:7218c076189b
|
472
|
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
|
Wimpie |
1:7218c076189b
|
473
|
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
|
Wimpie |
1:7218c076189b
|
474
|
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
|
Wimpie |
1:7218c076189b
|
475
|
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
|
Wimpie |
1:7218c076189b
|
476
|
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
|
Wimpie |
1:7218c076189b
|
477
|
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
|
Wimpie |
1:7218c076189b
|
478
|
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
|
Wimpie |
1:7218c076189b
|
479
|
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
|
Wimpie |
1:7218c076189b
|
480
|
|
Wimpie |
1:7218c076189b
|
481
|
//
|
Wimpie |
1:7218c076189b
|
482
|
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
|
Wimpie |
1:7218c076189b
|
483
|
// and the registers. (note: this might better be done without the
|
Wimpie |
1:7218c076189b
|
484
|
// table, it would probably be smaller and certainly fast enough
|
Wimpie |
1:7218c076189b
|
485
|
// compared to all those delayMicrosecond() calls. But I got
|
Wimpie |
1:7218c076189b
|
486
|
// confused, so I use this table from the examples.)
|
Wimpie |
1:7218c076189b
|
487
|
//
|
Wimpie |
1:7218c076189b
|
488
|
BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
|
Wimpie |
1:7218c076189b
|
489
|
{
|
Wimpie |
1:7218c076189b
|
490
|
BYTE i;
|
Wimpie |
1:7218c076189b
|
491
|
BYTE crc = 0;
|
Wimpie |
1:7218c076189b
|
492
|
|
Wimpie |
1:7218c076189b
|
493
|
for (i = 0; i < len; i++)
|
Wimpie |
1:7218c076189b
|
494
|
{
|
Wimpie |
1:7218c076189b
|
495
|
crc = dscrc_table[crc ^ addr[i] ];
|
Wimpie |
1:7218c076189b
|
496
|
}
|
Wimpie |
1:7218c076189b
|
497
|
|
Wimpie |
1:7218c076189b
|
498
|
return crc;
|
Wimpie |
1:7218c076189b
|
499
|
}
|
Wimpie |
1:7218c076189b
|
500
|
#else
|
Wimpie |
1:7218c076189b
|
501
|
//
|
Wimpie |
1:7218c076189b
|
502
|
// Compute a Dallas Semiconductor 8 bit CRC directly.
|
Wimpie |
1:7218c076189b
|
503
|
//
|
Wimpie |
1:7218c076189b
|
504
|
BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
|
Wimpie |
1:7218c076189b
|
505
|
{
|
Wimpie |
1:7218c076189b
|
506
|
BYTE i, j;
|
Wimpie |
1:7218c076189b
|
507
|
BYTE crc = 0;
|
Wimpie |
1:7218c076189b
|
508
|
|
Wimpie |
1:7218c076189b
|
509
|
for (i = 0; i < len; i++)
|
Wimpie |
1:7218c076189b
|
510
|
{
|
Wimpie |
1:7218c076189b
|
511
|
BYTE inbyte = addr[i];
|
Wimpie |
1:7218c076189b
|
512
|
for (j = 0; j < 8; j++)
|
Wimpie |
1:7218c076189b
|
513
|
{
|
Wimpie |
1:7218c076189b
|
514
|
BYTE mix = (crc ^ inbyte) & 0x01;
|
Wimpie |
1:7218c076189b
|
515
|
crc >>= 1;
|
Wimpie |
1:7218c076189b
|
516
|
if (mix) crc ^= 0x8C;
|
Wimpie |
1:7218c076189b
|
517
|
inbyte >>= 1;
|
Wimpie |
1:7218c076189b
|
518
|
}
|
Wimpie |
1:7218c076189b
|
519
|
}
|
Wimpie |
1:7218c076189b
|
520
|
|
Wimpie |
1:7218c076189b
|
521
|
return crc;
|
Wimpie |
1:7218c076189b
|
522
|
}
|
Wimpie |
1:7218c076189b
|
523
|
#endif
|
Wimpie |
1:7218c076189b
|
524
|
|
Wimpie |
1:7218c076189b
|
525
|
static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
|
Wimpie |
1:7218c076189b
|
526
|
|
Wimpie |
1:7218c076189b
|
527
|
//
|
Wimpie |
1:7218c076189b
|
528
|
// Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of
|
Wimpie |
1:7218c076189b
|
529
|
// these, but here it is.
|
Wimpie |
1:7218c076189b
|
530
|
//
|
Wimpie |
1:7218c076189b
|
531
|
unsigned short OneWireCRC::crc16(unsigned short* data, unsigned short len)
|
Wimpie |
1:7218c076189b
|
532
|
{
|
Wimpie |
1:7218c076189b
|
533
|
unsigned short i;
|
Wimpie |
1:7218c076189b
|
534
|
unsigned short crc = 0;
|
Wimpie |
1:7218c076189b
|
535
|
|
Wimpie |
1:7218c076189b
|
536
|
for ( i = 0; i < len; i++)
|
Wimpie |
1:7218c076189b
|
537
|
{
|
Wimpie |
1:7218c076189b
|
538
|
unsigned short cdata = data[len];
|
Wimpie |
1:7218c076189b
|
539
|
|
Wimpie |
1:7218c076189b
|
540
|
cdata = (cdata ^ (crc & 0xff)) & 0xff;
|
Wimpie |
1:7218c076189b
|
541
|
crc >>= 8;
|
Wimpie |
1:7218c076189b
|
542
|
|
Wimpie |
1:7218c076189b
|
543
|
if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001;
|
Wimpie |
1:7218c076189b
|
544
|
|
Wimpie |
1:7218c076189b
|
545
|
cdata <<= 6;
|
Wimpie |
1:7218c076189b
|
546
|
crc ^= cdata;
|
Wimpie |
1:7218c076189b
|
547
|
cdata <<= 1;
|
Wimpie |
1:7218c076189b
|
548
|
crc ^= cdata;
|
Wimpie |
1:7218c076189b
|
549
|
}
|
Wimpie |
1:7218c076189b
|
550
|
|
Wimpie |
1:7218c076189b
|
551
|
return crc;
|
Wimpie |
1:7218c076189b
|
552
|
}
|
Wimpie |
1:7218c076189b
|
553
|
|