Program to read the temperature from multiple DS18B20 sensors on the same pin. The original library/code came from Petras Saduikis (see http://mbed.org/users/snatch59/programs/OneWireCRC/gpdz56), but I've modified it to remember the address of multiple sensors all connected to the same data pin. My sample program displays the temperature of each device in turn. If you want to see more of what's going on behind the scenes turn on the debug by setting DebugTrace pc(OFF, TO_SERIAL); to ON (instead of OFF) in the couple of places it's used - it will log the device addresses as they are found etc. The addresses are set in the devices at the factory - I don't think they can be changed, the search always seems to find them in the same order, but this won't be anything to do with the way you've plugged them in. I've had a play with up to 7 sensors (the code has a limit of 10 hardwired in it, but this would be easy to change)

Dependencies:   mbed

Committer:
tonymudd
Date:
Sun Jul 17 15:56:49 2011 +0000
Revision:
0:fb8b6da96a8b

        

Who changed what in which revision?

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