Dependents:   1W-EEPROM

Committer:
Wimpie
Date:
Tue Jan 17 08:30:45 2012 +0000
Revision:
2:193926923cb0
Parent:
1:7218c076189b
readbyte readword

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 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