Umair Aftab
/
DS18B20MultipleSensors
Auto search for All DS18B20 sensors on data bus
Embed:
(wiki syntax)
Show/hide line numbers
OneWireCRC.cpp
00001 /* 00002 * OneWireCRC. This is a port to mbed of Jim Studt's Adruino One Wire 00003 * library. Please see additional copyrights below this one, including 00004 * references to other copyrights. 00005 * 00006 * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> 00007 * 00008 * This file is part of OneWireCRC. 00009 * 00010 * OneWireCRC is free software: you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation, either version 3 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * OneWireCRC is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with OneWireCRC. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 /* 00024 Copyright (c) 2007, Jim Studt 00025 00026 Updated to work with arduino-0008 and to include skip() as of 00027 2007/07/06. --RJL20 00028 00029 Modified to calculate the 8-bit CRC directly, avoiding the need for 00030 the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 00031 -- Tom Pollard, Jan 23, 2008 00032 00033 Permission is hereby granted, free of charge, to any person obtaining 00034 a copy of this software and associated documentation files (the 00035 "Software"), to deal in the Software without restriction, including 00036 without limitation the rights to use, copy, modify, merge, publish, 00037 distribute, sublicense, and/or sell copies of the Software, and to 00038 permit persons to whom the Software is furnished to do so, subject to 00039 the following conditions: 00040 00041 The above copyright notice and this permission notice shall be 00042 included in all copies or substantial portions of the Software. 00043 00044 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00045 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00046 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00047 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00048 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00049 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00050 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00051 00052 Much of the code was inspired by Derek Yerger's code, though I don't 00053 think much of that remains. In any event that was.. 00054 (copyleft) 2006 by Derek Yerger - Free to distribute freely. 00055 00056 The CRC code was excerpted and inspired by the Dallas Semiconductor 00057 sample code bearing this copyright. 00058 //--------------------------------------------------------------------------- 00059 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. 00060 // 00061 // Permission is hereby granted, free of charge, to any person obtaining a 00062 // copy of this software and associated documentation files (the "Software"), 00063 // to deal in the Software without restriction, including without limitation 00064 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 00065 // and/or sell copies of the Software, and to permit persons to whom the 00066 // Software is furnished to do so, subject to the following conditions: 00067 // 00068 // The above copyright notice and this permission notice shall be included 00069 // in all copies or substantial portions of the Software. 00070 // 00071 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00072 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00073 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00074 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES 00075 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00076 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00077 // OTHER DEALINGS IN THE SOFTWARE. 00078 // 00079 // Except as contained in this notice, the name of Dallas Semiconductor 00080 // shall not be used except as stated in the Dallas Semiconductor 00081 // Branding Policy. 00082 //-------------------------------------------------------------------------- 00083 */ 00084 00085 #include "OneWireCRC.h" 00086 #include "OneWireDefs.h" 00087 00088 // recommended data sheet timings in micro seconds 00089 const int standardT[] = {6, 64, 60, 10, 9, 55, 0, 480, 70, 410}; 00090 const int overdriveT[] = {1.5, 7.5, 7.5, 2.5, 0.75, 7, 2.5, 70, 8.5, 40}; 00091 00092 OneWireCRC::OneWireCRC(PinName oneWire, eSpeed speed) : oneWirePort(oneWire) 00093 { 00094 if (STANDARD == speed) timing = standardT; 00095 else timing = overdriveT; // overdrive 00096 00097 resetSearch(); // reset address search state 00098 } 00099 00100 // Generate a 1-wire reset, return 1 if no presence detect was found, 00101 // return 0 otherwise. 00102 // (NOTE: does not handle alarm presence from DS2404/DS1994) 00103 int OneWireCRC::reset() 00104 { 00105 00106 BYTE result = 0; // sample presence pulse result 00107 00108 wait_us(timing[6]); 00109 oneWirePort.output(); 00110 oneWirePort = 0; 00111 wait_us(timing[7]); 00112 oneWirePort.input(); 00113 wait_us(timing[8]); 00114 result = !(oneWirePort & 0x01); 00115 wait_us(timing[9]); 00116 00117 return result; 00118 } 00119 00120 // 00121 // Write a bit. Port and bit is used to cut lookup time and provide 00122 // more certain timing. 00123 // 00124 void OneWireCRC::writeBit(int bit) 00125 { 00126 bit = bit & 0x01; 00127 00128 if (bit) 00129 { 00130 // Write '1' bit 00131 oneWirePort.output(); 00132 oneWirePort = 0; 00133 wait_us(timing[0]); 00134 oneWirePort.input(); 00135 wait_us(timing[1]); 00136 } 00137 else 00138 { 00139 // Write '0' bit 00140 oneWirePort.output(); 00141 oneWirePort = 0; 00142 wait_us(timing[2]); 00143 oneWirePort.input(); 00144 wait_us(timing[3]); 00145 } 00146 } 00147 00148 // 00149 // Read a bit. Port and bit is used to cut lookup time and provide 00150 // more certain timing. 00151 // 00152 int OneWireCRC::readBit() 00153 { 00154 BYTE result; 00155 00156 oneWirePort.output(); 00157 oneWirePort = 0; 00158 wait_us(timing[0]); 00159 oneWirePort.input(); 00160 wait_us(timing[4]); 00161 result = oneWirePort & 0x01; 00162 wait_us(timing[5]); 00163 00164 return result; 00165 } 00166 00167 // 00168 // Write a byte. The writing code uses the active drivers to raise the 00169 // pin high, if you need power after the write (e.g. DS18S20 in 00170 // parasite power mode) then set 'power' to 1, otherwise the pin will 00171 // go tri-state at the end of the write to avoid heating in a short or 00172 // other mishap. 00173 // 00174 void OneWireCRC::writeByte(int data) 00175 { 00176 // Loop to write each bit in the byte, LS-bit first 00177 for (int loop = 0; loop < 8; loop++) 00178 { 00179 writeBit(data & 0x01); 00180 00181 // shift the data byte for the next bit 00182 data >>= 1; 00183 } 00184 } 00185 00186 // 00187 // Read a byte 00188 // 00189 int OneWireCRC::readByte() 00190 { 00191 int result = 0; 00192 00193 for (int loop = 0; loop < 8; loop++) 00194 { 00195 // shift the result to get it ready for the next bit 00196 result >>= 1; 00197 00198 // if result is one, then set MS bit 00199 if (readBit()) result |= 0x80; 00200 } 00201 00202 return result; 00203 } 00204 00205 int OneWireCRC::touchByte(int data) 00206 { 00207 int result = 0; 00208 00209 for (int loop = 0; loop < 8; loop++) 00210 { 00211 // shift the result to get it ready for the next bit 00212 result >>= 1; 00213 00214 // If sending a '1' then read a bit else write a '0' 00215 if (data & 0x01) 00216 { 00217 if (readBit()) result |= 0x80; 00218 } 00219 else writeBit(0); 00220 00221 // shift the data byte for the next bit 00222 data >>= 1; 00223 } 00224 00225 return result; 00226 } 00227 00228 void OneWireCRC::block(BYTE* data, int data_len) 00229 { 00230 for (int loop = 0; loop < data_len; loop++) 00231 { 00232 data[loop] = touchByte(data[loop]); 00233 } 00234 } 00235 00236 int OneWireCRC::overdriveSkip(BYTE* data, int data_len) 00237 { 00238 // set the speed to 'standard' 00239 timing = standardT; 00240 00241 // reset all devices 00242 if (reset()) return 0; // if no devices found 00243 00244 // overdrive skip command 00245 writeByte(OVERDRIVE_SKIP); 00246 00247 // set the speed to 'overdrive' 00248 timing = overdriveT; 00249 00250 // do a 1-Wire reset in 'overdrive' and return presence result 00251 return reset(); 00252 } 00253 00254 // 00255 // Do a ROM select 00256 // 00257 void OneWireCRC::matchROM(BYTE rom[8]) 00258 { 00259 writeByte(MATCH_ROM); // Choose ROM 00260 00261 for(int i = 0; i < 8; i++) writeByte(rom[i]); 00262 } 00263 00264 // 00265 // Do a ROM skip 00266 // 00267 void OneWireCRC::skipROM() 00268 { 00269 writeByte(SKIP_ROM); // Skip ROM 00270 } 00271 00272 // 00273 // You need to use this function to start a search again from the beginning. 00274 // You do not need to do it for the first search, though you could. 00275 // 00276 void OneWireCRC::resetSearch() 00277 { 00278 searchJunction = -1; 00279 searchExhausted = false; 00280 for (int i = 0; i < 8; i++) 00281 { 00282 address[i] = 0; 00283 } 00284 } 00285 00286 // 00287 // Perform a search. If this function returns a '1' then it has 00288 // enumerated the next device and you may retrieve the ROM from the 00289 // OneWire::address variable. If there are no devices, no further 00290 // devices, or something horrible happens in the middle of the 00291 // enumeration then a 0 is returned. If a new device is found then 00292 // its address is copied to newAddr. Use OneWire::reset_search() to 00293 // start over. 00294 // 00295 BYTE OneWireCRC::search(BYTE* newAddr) 00296 { 00297 BYTE i; 00298 int lastJunction = -1; 00299 BYTE done = 1; 00300 00301 if (searchExhausted) return 0; 00302 00303 if (!reset()) return 0; 00304 00305 writeByte(SEARCH_ROM); 00306 00307 for(i = 0; i < 64; i++) 00308 { 00309 BYTE a = readBit( ); 00310 BYTE nota = readBit( ); 00311 BYTE ibyte = i/8; 00312 BYTE ibit = 1 << (i & 7); 00313 00314 // I don't think this should happen, this means nothing responded, but maybe if 00315 // something vanishes during the search it will come up. 00316 if (a && nota) return 0; 00317 00318 if (!a && !nota) 00319 { 00320 if (i == searchJunction) 00321 { 00322 // this is our time to decide differently, we went zero last time, go one. 00323 a = 1; 00324 searchJunction = lastJunction; 00325 } 00326 else if (i < searchJunction) 00327 { 00328 // take whatever we took last time, look in address 00329 if (address[ibyte] & ibit) a = 1; 00330 else 00331 { 00332 // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s 00333 a = 0; 00334 done = 0; 00335 lastJunction = i; 00336 } 00337 } 00338 else 00339 { 00340 // we are blazing new tree, take the 0 00341 a = 0; 00342 searchJunction = i; 00343 done = 0; 00344 } 00345 lastJunction = i; 00346 } 00347 00348 if (a) address[ibyte] |= ibit; 00349 else address[ibyte] &= ~ibit; 00350 00351 writeBit(a); 00352 } 00353 00354 if (done) searchExhausted = true; 00355 00356 for (i = 0; i < 8; i++) newAddr[i] = address[i]; 00357 00358 return 1; 00359 } 00360 00361 // The 1-Wire CRC scheme is described in Maxim Application Note 27: 00362 // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" 00363 // 00364 00365 #if ONEWIRE_CRC8_TABLE 00366 // This table comes from Dallas sample code where it is freely reusable, 00367 // though Copyright (C) 2000 Dallas Semiconductor Corporation 00368 static BYTE dscrc_table[] = 00369 { 00370 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 00371 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 00372 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 00373 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 00374 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 00375 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 00376 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 00377 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 00378 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 00379 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 00380 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 00381 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 00382 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 00383 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 00384 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 00385 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; 00386 00387 // 00388 // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM 00389 // and the registers. (note: this might better be done without the 00390 // table, it would probably be smaller and certainly fast enough 00391 // compared to all those delayMicrosecond() calls. But I got 00392 // confused, so I use this table from the examples.) 00393 // 00394 BYTE OneWireCRC::crc8(BYTE* addr, BYTE len) 00395 { 00396 BYTE i; 00397 BYTE crc = 0; 00398 00399 for (i = 0; i < len; i++) 00400 { 00401 crc = dscrc_table[crc ^ addr[i] ]; 00402 } 00403 00404 return crc; 00405 } 00406 #else 00407 // 00408 // Compute a Dallas Semiconductor 8 bit CRC directly. 00409 // 00410 BYTE OneWireCRC::crc8(BYTE* addr, BYTE len) 00411 { 00412 BYTE i, j; 00413 BYTE crc = 0; 00414 00415 for (i = 0; i < len; i++) 00416 { 00417 BYTE inbyte = addr[i]; 00418 for (j = 0; j < 8; j++) 00419 { 00420 BYTE mix = (crc ^ inbyte) & 0x01; 00421 crc >>= 1; 00422 if (mix) crc ^= 0x8C; 00423 inbyte >>= 1; 00424 } 00425 } 00426 00427 return crc; 00428 } 00429 #endif 00430 00431 static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; 00432 00433 // 00434 // Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of 00435 // these, but here it is. 00436 // 00437 unsigned short OneWireCRC::crc16(unsigned short* data, unsigned short len) 00438 { 00439 unsigned short i; 00440 unsigned short crc = 0; 00441 00442 for ( i = 0; i < len; i++) 00443 { 00444 unsigned short cdata = data[len]; 00445 00446 cdata = (cdata ^ (crc & 0xff)) & 0xff; 00447 crc >>= 8; 00448 00449 if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001; 00450 00451 cdata <<= 6; 00452 crc ^= cdata; 00453 cdata <<= 1; 00454 crc ^= cdata; 00455 } 00456 00457 return crc; 00458 } 00459
Generated on Tue Jul 12 2022 15:16:06 by 1.7.2