Auto search for All DS18B20 sensors on data bus

Dependencies:   mbed

Committer:
umairaftab
Date:
Sun Apr 13 10:06:52 2014 +0000
Revision:
0:a2a81f538133
Multiple Sensors Functionality Added to Peter Sudensikis Library

Who changed what in which revision?

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