Dependents:   1W-EEPROM

Committer:
Wimpie
Date:
Sun Apr 17 17:26:52 2011 +0000
Revision:
1:7218c076189b
Child:
2:193926923cb0
improved 1W search function

Who changed what in which revision?

UserRevisionLine numberNew 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 1:7218c076189b 105 #include "OneWireDefs.h"
Wimpie 1:7218c076189b 106
Wimpie 1:7218c076189b 107 // recommended data sheet timings in micro seconds
Wimpie 1:7218c076189b 108 const int standardT[] = {6, 64, 60, 10, 9, 55, 0, 480, 70, 410};
Wimpie 1:7218c076189b 109 const int overdriveT[] = {1.5, 7.5, 7.5, 2.5, 0.75, 7, 2.5, 70, 8.5, 40};
Wimpie 1:7218c076189b 110
Wimpie 1:7218c076189b 111 OneWireCRC::OneWireCRC(PinName oneWire, eSpeed speed) : oneWirePort(oneWire)
Wimpie 1:7218c076189b 112 {
Wimpie 1:7218c076189b 113 if (STANDARD == speed) timing = standardT;
Wimpie 1:7218c076189b 114 else timing = overdriveT; // overdrive
Wimpie 1:7218c076189b 115
Wimpie 1:7218c076189b 116 resetSearch(); // reset address search state
Wimpie 1:7218c076189b 117 }
Wimpie 1:7218c076189b 118
Wimpie 1:7218c076189b 119 // Generate a 1-wire reset, return 1 if no presence detect was found,
Wimpie 1:7218c076189b 120 // return 0 otherwise.
Wimpie 1:7218c076189b 121 // (NOTE: does not handle alarm presence from DS2404/DS1994)
Wimpie 1:7218c076189b 122 int OneWireCRC::reset()
Wimpie 1:7218c076189b 123 {
Wimpie 1:7218c076189b 124
Wimpie 1:7218c076189b 125 BYTE result = 0; // sample presence pulse result
Wimpie 1:7218c076189b 126
Wimpie 1:7218c076189b 127 wait_us(timing[6]);
Wimpie 1:7218c076189b 128 oneWirePort.output();
Wimpie 1:7218c076189b 129 oneWirePort = 0;
Wimpie 1:7218c076189b 130 wait_us(timing[7]);
Wimpie 1:7218c076189b 131 oneWirePort.input();
Wimpie 1:7218c076189b 132 wait_us(timing[8]);
Wimpie 1:7218c076189b 133 result = !(oneWirePort & 0x01);
Wimpie 1:7218c076189b 134 wait_us(timing[9]);
Wimpie 1:7218c076189b 135
Wimpie 1:7218c076189b 136 return result;
Wimpie 1:7218c076189b 137 }
Wimpie 1:7218c076189b 138
Wimpie 1:7218c076189b 139 //
Wimpie 1:7218c076189b 140 // Write a bit. Port and bit is used to cut lookup time and provide
Wimpie 1:7218c076189b 141 // more certain timing.
Wimpie 1:7218c076189b 142 //
Wimpie 1:7218c076189b 143 void OneWireCRC::writeBit(int bit)
Wimpie 1:7218c076189b 144 {
Wimpie 1:7218c076189b 145 bit = bit & 0x01;
Wimpie 1:7218c076189b 146
Wimpie 1:7218c076189b 147 if (bit)
Wimpie 1:7218c076189b 148 {
Wimpie 1:7218c076189b 149 // Write '1' bit
Wimpie 1:7218c076189b 150 oneWirePort.output();
Wimpie 1:7218c076189b 151 oneWirePort = 0;
Wimpie 1:7218c076189b 152 wait_us(timing[0]);
Wimpie 1:7218c076189b 153 oneWirePort.input();
Wimpie 1:7218c076189b 154 wait_us(timing[1]);
Wimpie 1:7218c076189b 155 }
Wimpie 1:7218c076189b 156 else
Wimpie 1:7218c076189b 157 {
Wimpie 1:7218c076189b 158 // Write '0' bit
Wimpie 1:7218c076189b 159 oneWirePort.output();
Wimpie 1:7218c076189b 160 oneWirePort = 0;
Wimpie 1:7218c076189b 161 wait_us(timing[2]);
Wimpie 1:7218c076189b 162 oneWirePort.input();
Wimpie 1:7218c076189b 163 wait_us(timing[3]);
Wimpie 1:7218c076189b 164 }
Wimpie 1:7218c076189b 165 }
Wimpie 1:7218c076189b 166
Wimpie 1:7218c076189b 167 //
Wimpie 1:7218c076189b 168 // Read a bit. Port and bit is used to cut lookup time and provide
Wimpie 1:7218c076189b 169 // more certain timing.
Wimpie 1:7218c076189b 170 //
Wimpie 1:7218c076189b 171 int OneWireCRC::readBit()
Wimpie 1:7218c076189b 172 {
Wimpie 1:7218c076189b 173 BYTE result;
Wimpie 1:7218c076189b 174
Wimpie 1:7218c076189b 175 oneWirePort.output();
Wimpie 1:7218c076189b 176 oneWirePort = 0;
Wimpie 1:7218c076189b 177 wait_us(timing[0]);
Wimpie 1:7218c076189b 178 oneWirePort.input();
Wimpie 1:7218c076189b 179 wait_us(timing[4]);
Wimpie 1:7218c076189b 180 result = oneWirePort & 0x01;
Wimpie 1:7218c076189b 181 wait_us(timing[5]);
Wimpie 1:7218c076189b 182
Wimpie 1:7218c076189b 183 return result;
Wimpie 1:7218c076189b 184 }
Wimpie 1:7218c076189b 185
Wimpie 1:7218c076189b 186 //
Wimpie 1:7218c076189b 187 // Write a byte. The writing code uses the active drivers to raise the
Wimpie 1:7218c076189b 188 // pin high, if you need power after the write (e.g. DS18S20 in
Wimpie 1:7218c076189b 189 // parasite power mode) then set 'power' to 1, otherwise the pin will
Wimpie 1:7218c076189b 190 // go tri-state at the end of the write to avoid heating in a short or
Wimpie 1:7218c076189b 191 // other mishap.
Wimpie 1:7218c076189b 192 //
Wimpie 1:7218c076189b 193 void OneWireCRC::writeByte(int data)
Wimpie 1:7218c076189b 194 {
Wimpie 1:7218c076189b 195 // Loop to write each bit in the byte, LS-bit first
Wimpie 1:7218c076189b 196 for (int loop = 0; loop < 8; loop++)
Wimpie 1:7218c076189b 197 {
Wimpie 1:7218c076189b 198 writeBit(data & 0x01);
Wimpie 1:7218c076189b 199
Wimpie 1:7218c076189b 200 // shift the data byte for the next bit
Wimpie 1:7218c076189b 201 data >>= 1;
Wimpie 1:7218c076189b 202 }
Wimpie 1:7218c076189b 203 }
Wimpie 1:7218c076189b 204
Wimpie 1:7218c076189b 205 //
Wimpie 1:7218c076189b 206 // Read a byte
Wimpie 1:7218c076189b 207 //
Wimpie 1:7218c076189b 208 int OneWireCRC::readByte()
Wimpie 1:7218c076189b 209 {
Wimpie 1:7218c076189b 210 int result = 0;
Wimpie 1:7218c076189b 211
Wimpie 1:7218c076189b 212 for (int loop = 0; loop < 8; loop++)
Wimpie 1:7218c076189b 213 {
Wimpie 1:7218c076189b 214 // shift the result to get it ready for the next bit
Wimpie 1:7218c076189b 215 result >>= 1;
Wimpie 1:7218c076189b 216
Wimpie 1:7218c076189b 217 // if result is one, then set MS bit
Wimpie 1:7218c076189b 218 if (readBit()) result |= 0x80;
Wimpie 1:7218c076189b 219 }
Wimpie 1:7218c076189b 220
Wimpie 1:7218c076189b 221 return result;
Wimpie 1:7218c076189b 222 }
Wimpie 1:7218c076189b 223
Wimpie 1:7218c076189b 224 int OneWireCRC::touchByte(int data)
Wimpie 1:7218c076189b 225 {
Wimpie 1:7218c076189b 226 int result = 0;
Wimpie 1:7218c076189b 227
Wimpie 1:7218c076189b 228 for (int loop = 0; loop < 8; loop++)
Wimpie 1:7218c076189b 229 {
Wimpie 1:7218c076189b 230 // shift the result to get it ready for the next bit
Wimpie 1:7218c076189b 231 result >>= 1;
Wimpie 1:7218c076189b 232
Wimpie 1:7218c076189b 233 // If sending a '1' then read a bit else write a '0'
Wimpie 1:7218c076189b 234 if (data & 0x01)
Wimpie 1:7218c076189b 235 {
Wimpie 1:7218c076189b 236 if (readBit()) result |= 0x80;
Wimpie 1:7218c076189b 237 }
Wimpie 1:7218c076189b 238 else writeBit(0);
Wimpie 1:7218c076189b 239
Wimpie 1:7218c076189b 240 // shift the data byte for the next bit
Wimpie 1:7218c076189b 241 data >>= 1;
Wimpie 1:7218c076189b 242 }
Wimpie 1:7218c076189b 243
Wimpie 1:7218c076189b 244 return result;
Wimpie 1:7218c076189b 245 }
Wimpie 1:7218c076189b 246
Wimpie 1:7218c076189b 247 void OneWireCRC::block(BYTE* data, int data_len)
Wimpie 1:7218c076189b 248 {
Wimpie 1:7218c076189b 249 for (int loop = 0; loop < data_len; loop++)
Wimpie 1:7218c076189b 250 {
Wimpie 1:7218c076189b 251 data[loop] = touchByte(data[loop]);
Wimpie 1:7218c076189b 252 }
Wimpie 1:7218c076189b 253 }
Wimpie 1:7218c076189b 254
Wimpie 1:7218c076189b 255 int OneWireCRC::overdriveSkip(BYTE* data, int data_len)
Wimpie 1:7218c076189b 256 {
Wimpie 1:7218c076189b 257 // set the speed to 'standard'
Wimpie 1:7218c076189b 258 timing = standardT;
Wimpie 1:7218c076189b 259
Wimpie 1:7218c076189b 260 // reset all devices
Wimpie 1:7218c076189b 261 if (reset()) return 0; // if no devices found
Wimpie 1:7218c076189b 262
Wimpie 1:7218c076189b 263 // overdrive skip command
Wimpie 1:7218c076189b 264 writeByte(OVERDRIVE_SKIP);
Wimpie 1:7218c076189b 265
Wimpie 1:7218c076189b 266 // set the speed to 'overdrive'
Wimpie 1:7218c076189b 267 timing = overdriveT;
Wimpie 1:7218c076189b 268
Wimpie 1:7218c076189b 269 // do a 1-Wire reset in 'overdrive' and return presence result
Wimpie 1:7218c076189b 270 return reset();
Wimpie 1:7218c076189b 271 }
Wimpie 1:7218c076189b 272
Wimpie 1:7218c076189b 273 //
Wimpie 1:7218c076189b 274 // Do a ROM select
Wimpie 1:7218c076189b 275 //
Wimpie 1:7218c076189b 276 void OneWireCRC::matchROM(BYTE rom[8])
Wimpie 1:7218c076189b 277 {
Wimpie 1:7218c076189b 278 writeByte(MATCH_ROM); // Choose ROM
Wimpie 1:7218c076189b 279
Wimpie 1:7218c076189b 280 for(int i = 0; i < 8; i++) writeByte(rom[i]);
Wimpie 1:7218c076189b 281 }
Wimpie 1:7218c076189b 282
Wimpie 1:7218c076189b 283 //
Wimpie 1:7218c076189b 284 // Do a ROM skip
Wimpie 1:7218c076189b 285 //
Wimpie 1:7218c076189b 286 void OneWireCRC::skipROM()
Wimpie 1:7218c076189b 287 {
Wimpie 1:7218c076189b 288 writeByte(SKIP_ROM); // Skip ROM
Wimpie 1:7218c076189b 289 }
Wimpie 1:7218c076189b 290
Wimpie 1:7218c076189b 291 //
Wimpie 1:7218c076189b 292 // You need to use this function to start a search again from the beginning.
Wimpie 1:7218c076189b 293 // You do not need to do it for the first search, though you could.
Wimpie 1:7218c076189b 294 //
Wimpie 1:7218c076189b 295 void OneWireCRC::resetSearch()
Wimpie 1:7218c076189b 296 {
Wimpie 1:7218c076189b 297 /* searchJunction = -1;
Wimpie 1:7218c076189b 298 searchExhausted = false;
Wimpie 1:7218c076189b 299 for (int i = 0; i < 8; i++)
Wimpie 1:7218c076189b 300 {
Wimpie 1:7218c076189b 301 _address[i] = 0;
Wimpie 1:7218c076189b 302 }*/
Wimpie 1:7218c076189b 303
Wimpie 1:7218c076189b 304 // reset the search state
Wimpie 1:7218c076189b 305 LastDiscrepancy = 0;
Wimpie 1:7218c076189b 306 LastDeviceFlag = 0;
Wimpie 1:7218c076189b 307 LastFamilyDiscrepancy = 0;
Wimpie 1:7218c076189b 308 for(int i = 7; ; i--)
Wimpie 1:7218c076189b 309 {
Wimpie 1:7218c076189b 310 ROM_NO[i] = 0;
Wimpie 1:7218c076189b 311 if ( i == 0) break;
Wimpie 1:7218c076189b 312 }
Wimpie 1:7218c076189b 313 }
Wimpie 1:7218c076189b 314 // Changed in version 1.1
Wimpie 1:7218c076189b 315 //
Wimpie 1:7218c076189b 316 // Perform a search. If this function returns a '1' then it has
Wimpie 1:7218c076189b 317 // enumerated the next device and you may retrieve the ROM from the
Wimpie 1:7218c076189b 318 // OneWire::address variable. If there are no devices, no further
Wimpie 1:7218c076189b 319 // devices, or something horrible happens in the middle of the
Wimpie 1:7218c076189b 320 // enumeration then a 0 is returned. If a new device is found then
Wimpie 1:7218c076189b 321 // its address is copied to newAddr. Use OneWire::reset_search() to
Wimpie 1:7218c076189b 322 // start over.
Wimpie 1:7218c076189b 323 //
Wimpie 1:7218c076189b 324 // --- Replaced by the one from the Dallas Semiconductor web site ---
Wimpie 1:7218c076189b 325 //--------------------------------------------------------------------------
Wimpie 1:7218c076189b 326 // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
Wimpie 1:7218c076189b 327 // search state.
Wimpie 1:7218c076189b 328 // Return TRUE : device found, ROM number in ROM_NO buffer
Wimpie 1:7218c076189b 329 // FALSE : device not found, end of search
Wimpie 1:7218c076189b 330 //
Wimpie 1:7218c076189b 331 uint8_t OneWireCRC::search(uint8_t *newAddr)
Wimpie 1:7218c076189b 332 {
Wimpie 1:7218c076189b 333 uint8_t id_bit_number;
Wimpie 1:7218c076189b 334 uint8_t last_zero, rom_byte_number, search_result;
Wimpie 1:7218c076189b 335 uint8_t id_bit, cmp_id_bit;
Wimpie 1:7218c076189b 336
Wimpie 1:7218c076189b 337 unsigned char rom_byte_mask, search_direction;
Wimpie 1:7218c076189b 338
Wimpie 1:7218c076189b 339 // initialize for search
Wimpie 1:7218c076189b 340 id_bit_number = 1;
Wimpie 1:7218c076189b 341 last_zero = 0;
Wimpie 1:7218c076189b 342 rom_byte_number = 0;
Wimpie 1:7218c076189b 343 rom_byte_mask = 1;
Wimpie 1:7218c076189b 344 search_result = 0;
Wimpie 1:7218c076189b 345
Wimpie 1:7218c076189b 346 // if the last call was not the last one
Wimpie 1:7218c076189b 347 if (!LastDeviceFlag)
Wimpie 1:7218c076189b 348 {
Wimpie 1:7218c076189b 349 // 1-Wire reset
Wimpie 1:7218c076189b 350 if (!reset())
Wimpie 1:7218c076189b 351 {
Wimpie 1:7218c076189b 352 // reset the search
Wimpie 1:7218c076189b 353 LastDiscrepancy = 0;
Wimpie 1:7218c076189b 354 LastDeviceFlag = 0;
Wimpie 1:7218c076189b 355 LastFamilyDiscrepancy = 0;
Wimpie 1:7218c076189b 356 return 0;
Wimpie 1:7218c076189b 357 }
Wimpie 1:7218c076189b 358
Wimpie 1:7218c076189b 359 // issue the search command
Wimpie 1:7218c076189b 360 writeByte(0xF0);
Wimpie 1:7218c076189b 361
Wimpie 1:7218c076189b 362 // loop to do the search
Wimpie 1:7218c076189b 363 do
Wimpie 1:7218c076189b 364 {
Wimpie 1:7218c076189b 365 // read a bit and its complement
Wimpie 1:7218c076189b 366 id_bit = readBit();
Wimpie 1:7218c076189b 367 cmp_id_bit = readBit();
Wimpie 1:7218c076189b 368
Wimpie 1:7218c076189b 369 // check for no devices on 1-wire
Wimpie 1:7218c076189b 370 if ((id_bit == 1) && (cmp_id_bit == 1))
Wimpie 1:7218c076189b 371 break;
Wimpie 1:7218c076189b 372 else
Wimpie 1:7218c076189b 373 {
Wimpie 1:7218c076189b 374 // all devices coupled have 0 or 1
Wimpie 1:7218c076189b 375 if (id_bit != cmp_id_bit)
Wimpie 1:7218c076189b 376 search_direction = id_bit; // bit write value for search
Wimpie 1:7218c076189b 377 else
Wimpie 1:7218c076189b 378 {
Wimpie 1:7218c076189b 379 // if this discrepancy if before the Last Discrepancy
Wimpie 1:7218c076189b 380 // on a previous next then pick the same as last time
Wimpie 1:7218c076189b 381 if (id_bit_number < LastDiscrepancy)
Wimpie 1:7218c076189b 382 search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
Wimpie 1:7218c076189b 383 else
Wimpie 1:7218c076189b 384 // if equal to last pick 1, if not then pick 0
Wimpie 1:7218c076189b 385 search_direction = (id_bit_number == LastDiscrepancy);
Wimpie 1:7218c076189b 386
Wimpie 1:7218c076189b 387 // if 0 was picked then record its position in LastZero
Wimpie 1:7218c076189b 388 if (search_direction == 0)
Wimpie 1:7218c076189b 389 {
Wimpie 1:7218c076189b 390 last_zero = id_bit_number;
Wimpie 1:7218c076189b 391
Wimpie 1:7218c076189b 392 // check for Last discrepancy in family
Wimpie 1:7218c076189b 393 if (last_zero < 9)
Wimpie 1:7218c076189b 394 LastFamilyDiscrepancy = last_zero;
Wimpie 1:7218c076189b 395 }
Wimpie 1:7218c076189b 396 }
Wimpie 1:7218c076189b 397
Wimpie 1:7218c076189b 398 // set or clear the bit in the ROM byte rom_byte_number
Wimpie 1:7218c076189b 399 // with mask rom_byte_mask
Wimpie 1:7218c076189b 400 if (search_direction == 1)
Wimpie 1:7218c076189b 401 ROM_NO[rom_byte_number] |= rom_byte_mask;
Wimpie 1:7218c076189b 402 else
Wimpie 1:7218c076189b 403 ROM_NO[rom_byte_number] &= ~rom_byte_mask;
Wimpie 1:7218c076189b 404
Wimpie 1:7218c076189b 405 // serial number search direction write bit
Wimpie 1:7218c076189b 406 writeBit(search_direction);
Wimpie 1:7218c076189b 407
Wimpie 1:7218c076189b 408 // increment the byte counter id_bit_number
Wimpie 1:7218c076189b 409 // and shift the mask rom_byte_mask
Wimpie 1:7218c076189b 410 id_bit_number++;
Wimpie 1:7218c076189b 411 rom_byte_mask <<= 1;
Wimpie 1:7218c076189b 412
Wimpie 1:7218c076189b 413 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
Wimpie 1:7218c076189b 414 if (rom_byte_mask == 0)
Wimpie 1:7218c076189b 415 {
Wimpie 1:7218c076189b 416 rom_byte_number++;
Wimpie 1:7218c076189b 417 rom_byte_mask = 1;
Wimpie 1:7218c076189b 418 }
Wimpie 1:7218c076189b 419 }
Wimpie 1:7218c076189b 420 }
Wimpie 1:7218c076189b 421 while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
Wimpie 1:7218c076189b 422
Wimpie 1:7218c076189b 423 // if the search was successful then
Wimpie 1:7218c076189b 424 if (!(id_bit_number < 65))
Wimpie 1:7218c076189b 425 {
Wimpie 1:7218c076189b 426 // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
Wimpie 1:7218c076189b 427 LastDiscrepancy = last_zero;
Wimpie 1:7218c076189b 428
Wimpie 1:7218c076189b 429 // check for last device
Wimpie 1:7218c076189b 430 if (LastDiscrepancy == 0)
Wimpie 1:7218c076189b 431 LastDeviceFlag = 1;
Wimpie 1:7218c076189b 432
Wimpie 1:7218c076189b 433 search_result = 1;
Wimpie 1:7218c076189b 434 }
Wimpie 1:7218c076189b 435 }
Wimpie 1:7218c076189b 436
Wimpie 1:7218c076189b 437 // if no device found then reset counters so next 'search' will be like a first
Wimpie 1:7218c076189b 438 if (!search_result || !ROM_NO[0])
Wimpie 1:7218c076189b 439 {
Wimpie 1:7218c076189b 440 LastDiscrepancy = 0;
Wimpie 1:7218c076189b 441 LastDeviceFlag = 0;
Wimpie 1:7218c076189b 442 LastFamilyDiscrepancy = 0;
Wimpie 1:7218c076189b 443 search_result = 0;
Wimpie 1:7218c076189b 444 }
Wimpie 1:7218c076189b 445 else
Wimpie 1:7218c076189b 446 for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
Wimpie 1:7218c076189b 447
Wimpie 1:7218c076189b 448 return search_result;
Wimpie 1:7218c076189b 449 }
Wimpie 1:7218c076189b 450
Wimpie 1:7218c076189b 451 // The 1-Wire CRC scheme is described in Maxim Application Note 27:
Wimpie 1:7218c076189b 452 // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
Wimpie 1:7218c076189b 453 //
Wimpie 1:7218c076189b 454
Wimpie 1:7218c076189b 455 #if ONEWIRE_CRC8_TABLE
Wimpie 1:7218c076189b 456 // This table comes from Dallas sample code where it is freely reusable,
Wimpie 1:7218c076189b 457 // though Copyright (C) 2000 Dallas Semiconductor Corporation
Wimpie 1:7218c076189b 458 static BYTE dscrc_table[] =
Wimpie 1:7218c076189b 459 {
Wimpie 1:7218c076189b 460 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
Wimpie 1:7218c076189b 461 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
Wimpie 1:7218c076189b 462 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
Wimpie 1:7218c076189b 463 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
Wimpie 1:7218c076189b 464 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
Wimpie 1:7218c076189b 465 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
Wimpie 1:7218c076189b 466 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
Wimpie 1:7218c076189b 467 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
Wimpie 1:7218c076189b 468 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
Wimpie 1:7218c076189b 469 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
Wimpie 1:7218c076189b 470 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
Wimpie 1:7218c076189b 471 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
Wimpie 1:7218c076189b 472 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
Wimpie 1:7218c076189b 473 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
Wimpie 1:7218c076189b 474 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
Wimpie 1:7218c076189b 475 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
Wimpie 1:7218c076189b 476
Wimpie 1:7218c076189b 477 //
Wimpie 1:7218c076189b 478 // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
Wimpie 1:7218c076189b 479 // and the registers. (note: this might better be done without the
Wimpie 1:7218c076189b 480 // table, it would probably be smaller and certainly fast enough
Wimpie 1:7218c076189b 481 // compared to all those delayMicrosecond() calls. But I got
Wimpie 1:7218c076189b 482 // confused, so I use this table from the examples.)
Wimpie 1:7218c076189b 483 //
Wimpie 1:7218c076189b 484 BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
Wimpie 1:7218c076189b 485 {
Wimpie 1:7218c076189b 486 BYTE i;
Wimpie 1:7218c076189b 487 BYTE crc = 0;
Wimpie 1:7218c076189b 488
Wimpie 1:7218c076189b 489 for (i = 0; i < len; i++)
Wimpie 1:7218c076189b 490 {
Wimpie 1:7218c076189b 491 crc = dscrc_table[crc ^ addr[i] ];
Wimpie 1:7218c076189b 492 }
Wimpie 1:7218c076189b 493
Wimpie 1:7218c076189b 494 return crc;
Wimpie 1:7218c076189b 495 }
Wimpie 1:7218c076189b 496 #else
Wimpie 1:7218c076189b 497 //
Wimpie 1:7218c076189b 498 // Compute a Dallas Semiconductor 8 bit CRC directly.
Wimpie 1:7218c076189b 499 //
Wimpie 1:7218c076189b 500 BYTE OneWireCRC::crc8(BYTE* addr, BYTE len)
Wimpie 1:7218c076189b 501 {
Wimpie 1:7218c076189b 502 BYTE i, j;
Wimpie 1:7218c076189b 503 BYTE crc = 0;
Wimpie 1:7218c076189b 504
Wimpie 1:7218c076189b 505 for (i = 0; i < len; i++)
Wimpie 1:7218c076189b 506 {
Wimpie 1:7218c076189b 507 BYTE inbyte = addr[i];
Wimpie 1:7218c076189b 508 for (j = 0; j < 8; j++)
Wimpie 1:7218c076189b 509 {
Wimpie 1:7218c076189b 510 BYTE mix = (crc ^ inbyte) & 0x01;
Wimpie 1:7218c076189b 511 crc >>= 1;
Wimpie 1:7218c076189b 512 if (mix) crc ^= 0x8C;
Wimpie 1:7218c076189b 513 inbyte >>= 1;
Wimpie 1:7218c076189b 514 }
Wimpie 1:7218c076189b 515 }
Wimpie 1:7218c076189b 516
Wimpie 1:7218c076189b 517 return crc;
Wimpie 1:7218c076189b 518 }
Wimpie 1:7218c076189b 519 #endif
Wimpie 1:7218c076189b 520
Wimpie 1:7218c076189b 521 static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
Wimpie 1:7218c076189b 522
Wimpie 1:7218c076189b 523 //
Wimpie 1:7218c076189b 524 // Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of
Wimpie 1:7218c076189b 525 // these, but here it is.
Wimpie 1:7218c076189b 526 //
Wimpie 1:7218c076189b 527 unsigned short OneWireCRC::crc16(unsigned short* data, unsigned short len)
Wimpie 1:7218c076189b 528 {
Wimpie 1:7218c076189b 529 unsigned short i;
Wimpie 1:7218c076189b 530 unsigned short crc = 0;
Wimpie 1:7218c076189b 531
Wimpie 1:7218c076189b 532 for ( i = 0; i < len; i++)
Wimpie 1:7218c076189b 533 {
Wimpie 1:7218c076189b 534 unsigned short cdata = data[len];
Wimpie 1:7218c076189b 535
Wimpie 1:7218c076189b 536 cdata = (cdata ^ (crc & 0xff)) & 0xff;
Wimpie 1:7218c076189b 537 crc >>= 8;
Wimpie 1:7218c076189b 538
Wimpie 1:7218c076189b 539 if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001;
Wimpie 1:7218c076189b 540
Wimpie 1:7218c076189b 541 cdata <<= 6;
Wimpie 1:7218c076189b 542 crc ^= cdata;
Wimpie 1:7218c076189b 543 cdata <<= 1;
Wimpie 1:7218c076189b 544 crc ^= cdata;
Wimpie 1:7218c076189b 545 }
Wimpie 1:7218c076189b 546
Wimpie 1:7218c076189b 547 return crc;
Wimpie 1:7218c076189b 548 }
Wimpie 1:7218c076189b 549