Revo onewire library, changes to work on FRDM-K22

Fork of OneWire by Zoltan Hudak

Committer:
mooreaa
Date:
Sat Sep 09 09:10:49 2017 +0000
Revision:
6:28e60d774095
Parent:
5:45f3eb39b00c
Child:
7:a42114ac702f
initial not working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:acf75feb0947 1 /*
hudakz 0:acf75feb0947 2 Copyright (c) 2007, Jim Studt (original old version - many contributors since)
hudakz 0:acf75feb0947 3
hudakz 0:acf75feb0947 4 The latest version of this library may be found at:
hudakz 0:acf75feb0947 5 http://www.pjrc.com/teensy/td_libs_OneWire.html
hudakz 0:acf75feb0947 6
hudakz 0:acf75feb0947 7 OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since
hudakz 0:acf75feb0947 8 January 2010. At the time, it was in need of many bug fixes, but had
hudakz 0:acf75feb0947 9 been abandoned the original author (Jim Studt). None of the known
hudakz 0:acf75feb0947 10 contributors were interested in maintaining OneWire. Paul typically
hudakz 0:acf75feb0947 11 works on OneWire every 6 to 12 months. Patches usually wait that
hudakz 0:acf75feb0947 12 long. If anyone is interested in more actively maintaining OneWire,
hudakz 0:acf75feb0947 13 please contact Paul.
hudakz 0:acf75feb0947 14
hudakz 0:acf75feb0947 15 Version 2.2:
hudakz 0:acf75feb0947 16 Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com
hudakz 0:acf75feb0947 17 Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030
hudakz 0:acf75feb0947 18 Fix DS18B20 example negative temperature
hudakz 0:acf75feb0947 19 Fix DS18B20 example's low res modes, Ken Butcher
hudakz 0:acf75feb0947 20 Improve reset timing, Mark Tillotson
hudakz 0:acf75feb0947 21 Add const qualifiers, Bertrik Sikken
hudakz 0:acf75feb0947 22 Add initial value input to crc16, Bertrik Sikken
hudakz 0:acf75feb0947 23 Add target_search() function, Scott Roberts
hudakz 0:acf75feb0947 24
hudakz 0:acf75feb0947 25 Version 2.1:
hudakz 0:acf75feb0947 26 Arduino 1.0 compatibility, Paul Stoffregen
hudakz 0:acf75feb0947 27 Improve temperature example, Paul Stoffregen
hudakz 0:acf75feb0947 28 DS250x_PROM example, Guillermo Lovato
hudakz 0:acf75feb0947 29 PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com
hudakz 0:acf75feb0947 30 Improvements from Glenn Trewitt:
hudakz 0:acf75feb0947 31 - crc16() now works
hudakz 0:acf75feb0947 32 - check_crc16() does all of calculation/checking work.
hudakz 0:acf75feb0947 33 - Added read_bytes() and write_bytes(), to reduce tedious loops.
hudakz 0:acf75feb0947 34 - Added ds2408 example.
hudakz 0:acf75feb0947 35 Delete very old, out-of-date readme file (info is here)
hudakz 0:acf75feb0947 36
hudakz 0:acf75feb0947 37 Version 2.0: Modifications by Paul Stoffregen, January 2010:
hudakz 0:acf75feb0947 38 http://www.pjrc.com/teensy/td_libs_OneWire.html
hudakz 0:acf75feb0947 39 Search fix from Robin James
hudakz 0:acf75feb0947 40 http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
hudakz 0:acf75feb0947 41 Use direct optimized I/O in all cases
hudakz 0:acf75feb0947 42 Disable interrupts during timing critical sections
hudakz 0:acf75feb0947 43 (this solves many random communication errors)
hudakz 0:acf75feb0947 44 Disable interrupts during read-modify-write I/O
hudakz 0:acf75feb0947 45 Reduce RAM consumption by eliminating unnecessary
hudakz 0:acf75feb0947 46 variables and trimming many to 8 bits
hudakz 0:acf75feb0947 47 Optimize both crc8 - table version moved to flash
hudakz 0:acf75feb0947 48
hudakz 0:acf75feb0947 49 Modified to work with larger numbers of devices - avoids loop.
hudakz 0:acf75feb0947 50 Tested in Arduino 11 alpha with 12 sensors.
hudakz 0:acf75feb0947 51 26 Sept 2008 -- Robin James
hudakz 0:acf75feb0947 52 http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
hudakz 0:acf75feb0947 53
hudakz 0:acf75feb0947 54 Updated to work with arduino-0008 and to include skip() as of
hudakz 0:acf75feb0947 55 2007/07/06. --RJL20
hudakz 0:acf75feb0947 56
hudakz 0:acf75feb0947 57 Modified to calculate the 8-bit CRC directly, avoiding the need for
hudakz 0:acf75feb0947 58 the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
hudakz 0:acf75feb0947 59 -- Tom Pollard, Jan 23, 2008
hudakz 0:acf75feb0947 60
hudakz 0:acf75feb0947 61 Jim Studt's original library was modified by Josh Larios.
hudakz 0:acf75feb0947 62
hudakz 0:acf75feb0947 63 Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008
hudakz 0:acf75feb0947 64
hudakz 0:acf75feb0947 65 Permission is hereby granted, free of charge, to any person obtaining
hudakz 0:acf75feb0947 66 a copy of this software and associated documentation files (the
hudakz 0:acf75feb0947 67 "Software"), to deal in the Software without restriction, including
hudakz 0:acf75feb0947 68 without limitation the rights to use, copy, modify, merge, publish,
hudakz 0:acf75feb0947 69 distribute, sublicense, and/or sell copies of the Software, and to
hudakz 0:acf75feb0947 70 permit persons to whom the Software is furnished to do so, subject to
hudakz 0:acf75feb0947 71 the following conditions:
hudakz 0:acf75feb0947 72
hudakz 0:acf75feb0947 73 The above copyright notice and this permission notice shall be
hudakz 0:acf75feb0947 74 included in all copies or substantial portions of the Software.
hudakz 0:acf75feb0947 75
hudakz 0:acf75feb0947 76 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
hudakz 0:acf75feb0947 77 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
hudakz 0:acf75feb0947 78 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
hudakz 0:acf75feb0947 79 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
hudakz 0:acf75feb0947 80 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
hudakz 0:acf75feb0947 81 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
hudakz 0:acf75feb0947 82 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
hudakz 0:acf75feb0947 83
hudakz 0:acf75feb0947 84 Much of the code was inspired by Derek Yerger's code, though I don't
hudakz 0:acf75feb0947 85 think much of that remains. In any event that was..
hudakz 0:acf75feb0947 86 (copyleft) 2006 by Derek Yerger - Free to distribute freely.
hudakz 0:acf75feb0947 87
hudakz 0:acf75feb0947 88 The CRC code was excerpted and inspired by the Dallas Semiconductor
hudakz 0:acf75feb0947 89 sample code bearing this copyright.
hudakz 0:acf75feb0947 90 //---------------------------------------------------------------------------
hudakz 0:acf75feb0947 91 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
hudakz 0:acf75feb0947 92 //
hudakz 0:acf75feb0947 93 // Permission is hereby granted, free of charge, to any person obtaining a
hudakz 0:acf75feb0947 94 // copy of this software and associated documentation files (the "Software"),
hudakz 0:acf75feb0947 95 // to deal in the Software without restriction, including without limitation
hudakz 0:acf75feb0947 96 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
hudakz 0:acf75feb0947 97 // and/or sell copies of the Software, and to permit persons to whom the
hudakz 0:acf75feb0947 98 // Software is furnished to do so, subject to the following conditions:
hudakz 0:acf75feb0947 99 //
hudakz 0:acf75feb0947 100 // The above copyright notice and this permission notice shall be included
hudakz 0:acf75feb0947 101 // in all copies or substantial portions of the Software.
hudakz 0:acf75feb0947 102 //
hudakz 0:acf75feb0947 103 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
hudakz 0:acf75feb0947 104 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
hudakz 0:acf75feb0947 105 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
hudakz 0:acf75feb0947 106 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
hudakz 0:acf75feb0947 107 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
hudakz 0:acf75feb0947 108 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
hudakz 0:acf75feb0947 109 // OTHER DEALINGS IN THE SOFTWARE.
hudakz 0:acf75feb0947 110 //
hudakz 0:acf75feb0947 111 // Except as contained in this notice, the name of Dallas Semiconductor
hudakz 0:acf75feb0947 112 // shall not be used except as stated in the Dallas Semiconductor
hudakz 0:acf75feb0947 113 // Branding Policy.
hudakz 0:acf75feb0947 114 //--------------------------------------------------------------------------
hudakz 0:acf75feb0947 115 */
hudakz 0:acf75feb0947 116
hudakz 0:acf75feb0947 117 #include "OneWire.h"
hudakz 0:acf75feb0947 118
hudakz 0:acf75feb0947 119 OneWire::OneWire(PinName pin):
hudakz 0:acf75feb0947 120 wire(pin)
hudakz 0:acf75feb0947 121 {
hudakz 0:acf75feb0947 122 #if ONEWIRE_SEARCH
hudakz 0:acf75feb0947 123 reset_search();
hudakz 0:acf75feb0947 124 #endif
hudakz 0:acf75feb0947 125 }
hudakz 0:acf75feb0947 126
hudakz 0:acf75feb0947 127
hudakz 0:acf75feb0947 128 // Perform the onewire reset function. We will wait up to 250uS for
hudakz 0:acf75feb0947 129 // the bus to come high, if it doesn't then it is broken or shorted
hudakz 0:acf75feb0947 130 // and we return a 0;
hudakz 0:acf75feb0947 131 //
mooreaa 6:28e60d774095 132 // Returns ONEWIRE_OK if a device asserted a presence pulse, ONEWIRE_ERROR otherwise.
hudakz 0:acf75feb0947 133 //
mooreaa 6:28e60d774095 134
mooreaa 6:28e60d774095 135
mooreaa 6:28e60d774095 136 uint8_t OneWire::init_sequence()
hudakz 0:acf75feb0947 137 {
mooreaa 6:28e60d774095 138 uint16_t retries = 20000;
mooreaa 6:28e60d774095 139
mooreaa 6:28e60d774095 140 /*if( reset(false) == ONEWIRE_ERROR )
mooreaa 6:28e60d774095 141 return ONEWIRE_ERROR;*/
mooreaa 6:28e60d774095 142
mooreaa 6:28e60d774095 143 reset();
mooreaa 6:28e60d774095 144
mooreaa 6:28e60d774095 145 //wire.input(); should be input coming out of reset
mooreaa 6:28e60d774095 146 wait_us(80);
mooreaa 6:28e60d774095 147
mooreaa 6:28e60d774095 148 /* uint8_t result = wire.read_bit();
mooreaa 6:28e60d774095 149
mooreaa 6:28e60d774095 150 if ( result == 0 )
mooreaa 6:28e60d774095 151 {
mooreaa 6:28e60d774095 152 while( result == 0)
mooreaa 6:28e60d774095 153 {
mooreaa 6:28e60d774095 154 result = wire.read_bit();
mooreaa 6:28e60d774095 155
mooreaa 6:28e60d774095 156 if (--retries == 0) {
mooreaa 6:28e60d774095 157 return ONEWIRE_NO_RESPONSE;
mooreaa 6:28e60d774095 158 }
mooreaa 6:28e60d774095 159 }
mooreaa 6:28e60d774095 160
mooreaa 6:28e60d774095 161 return ONEWIRE_OK;
mooreaa 6:28e60d774095 162 }
mooreaa 6:28e60d774095 163
mooreaa 6:28e60d774095 164 return ONEWIRE_NO_RESPONSE;*/
mooreaa 6:28e60d774095 165
mooreaa 6:28e60d774095 166
mooreaa 6:28e60d774095 167 return ONEWIRE_OK;
mooreaa 6:28e60d774095 168 }
mooreaa 6:28e60d774095 169
mooreaa 6:28e60d774095 170 uint8_t OneWire::reset( bool force/* = true*/ )
mooreaa 6:28e60d774095 171 {
hudakz 0:acf75feb0947 172 uint8_t retries = 125;
hudakz 0:acf75feb0947 173
mooreaa 6:28e60d774095 174 /*wire.input();
hudakz 0:acf75feb0947 175 // wait until the wire is high... just in case
hudakz 0:acf75feb0947 176 do {
hudakz 0:acf75feb0947 177 if (--retries == 0) {
mooreaa 6:28e60d774095 178 if( force )
mooreaa 6:28e60d774095 179 break;
mooreaa 6:28e60d774095 180 else
mooreaa 6:28e60d774095 181 return ONEWIRE_ERROR;
hudakz 0:acf75feb0947 182 }
hudakz 0:acf75feb0947 183 wait_us(2);
mooreaa 6:28e60d774095 184 } while (wire.read() != 1);*/
hudakz 0:acf75feb0947 185
hudakz 0:acf75feb0947 186 wire.output();
hudakz 0:acf75feb0947 187 wire = 0;
mooreaa 6:28e60d774095 188 wait_us(500);
hudakz 0:acf75feb0947 189 wire.input();
mooreaa 6:28e60d774095 190
hudakz 0:acf75feb0947 191 wait_us(70);
mooreaa 6:28e60d774095 192 uint8_t err = wire; //just do the reset, use init_seq function to do more
mooreaa 6:28e60d774095 193
mooreaa 6:28e60d774095 194 wait_us(240);
mooreaa 6:28e60d774095 195 if ( wire == 0 ) { // short circuit
mooreaa 6:28e60d774095 196 printf("OneWire::reset SHORT_CIRCUIT\r\n");
mooreaa 6:28e60d774095 197 return ONEWIRE_ERROR_SHORT_CIRCUIT;
mooreaa 6:28e60d774095 198 }
mooreaa 6:28e60d774095 199
mooreaa 6:28e60d774095 200 printf("OneWire::reset OK\r\n");
mooreaa 6:28e60d774095 201 return ONEWIRE_OK;
hudakz 0:acf75feb0947 202 }
hudakz 0:acf75feb0947 203
hudakz 0:acf75feb0947 204 //
hudakz 0:acf75feb0947 205 // Write a bit. Port and bit is used to cut lookup time and provide
hudakz 0:acf75feb0947 206 // more certain timing.
hudakz 0:acf75feb0947 207 //
hudakz 0:acf75feb0947 208 void OneWire::write_bit(uint8_t v)
hudakz 0:acf75feb0947 209 {
mooreaa 6:28e60d774095 210 wire.output();
mooreaa 6:28e60d774095 211
hudakz 0:acf75feb0947 212 if (v & 1) {
hudakz 0:acf75feb0947 213 wire = 0; // drive output low
hudakz 0:acf75feb0947 214 wait_us(10);
hudakz 0:acf75feb0947 215 wire = 1; // drive output high
hudakz 0:acf75feb0947 216 wait_us(55);
hudakz 0:acf75feb0947 217 } else {
hudakz 0:acf75feb0947 218 wire = 0; // drive output low
hudakz 0:acf75feb0947 219 wait_us(65);
hudakz 0:acf75feb0947 220 wire = 1; // drive output high
hudakz 0:acf75feb0947 221 wait_us(5);
hudakz 0:acf75feb0947 222 }
hudakz 0:acf75feb0947 223 }
hudakz 0:acf75feb0947 224
hudakz 0:acf75feb0947 225 //
hudakz 0:acf75feb0947 226 // Read a bit. Port and bit is used to cut lookup time and provide
hudakz 0:acf75feb0947 227 // more certain timing.
hudakz 0:acf75feb0947 228 //
hudakz 0:acf75feb0947 229 uint8_t OneWire::read_bit(void)
hudakz 0:acf75feb0947 230 {
hudakz 0:acf75feb0947 231 uint8_t r;
hudakz 0:acf75feb0947 232
hudakz 0:acf75feb0947 233 wire.output();
hudakz 0:acf75feb0947 234 wire = 0;
mooreaa 6:28e60d774095 235 wait_us(2); //modified to meet ray's values
hudakz 0:acf75feb0947 236 wire.input();
mooreaa 6:28e60d774095 237 wait_us(14);
mooreaa 6:28e60d774095 238 r = wire;
mooreaa 6:28e60d774095 239 wait_us(45);
hudakz 0:acf75feb0947 240 return r;
hudakz 0:acf75feb0947 241 }
hudakz 0:acf75feb0947 242
hudakz 0:acf75feb0947 243 //
hudakz 0:acf75feb0947 244 // Write a byte. The writing code uses the active drivers to raise the
hudakz 0:acf75feb0947 245 // pin high, if you need power after the write (e.g. DS18S20 in
hudakz 0:acf75feb0947 246 // parasite power mode) then set 'power' to 1, otherwise the pin will
hudakz 0:acf75feb0947 247 // go tri-state at the end of the write to avoid heating in a short or
hudakz 0:acf75feb0947 248 // other mishap.
hudakz 0:acf75feb0947 249 //
hudakz 0:acf75feb0947 250 void OneWire::write(uint8_t v, uint8_t power /* = 0 */) {
hudakz 0:acf75feb0947 251 uint8_t bitMask;
mooreaa 6:28e60d774095 252
mooreaa 6:28e60d774095 253 printf("OneWire::write => %#x\r\n", v);
hudakz 0:acf75feb0947 254
hudakz 0:acf75feb0947 255 for (bitMask = 0x01; bitMask; bitMask <<= 1) {
mooreaa 6:28e60d774095 256 OneWire::write_bit( (bitMask & v)?1:0);
hudakz 0:acf75feb0947 257 }
hudakz 0:acf75feb0947 258 if ( !power) {
hudakz 0:acf75feb0947 259 wire.input();
hudakz 0:acf75feb0947 260 }
hudakz 0:acf75feb0947 261 }
hudakz 0:acf75feb0947 262
hudakz 0:acf75feb0947 263 void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) {
mooreaa 6:28e60d774095 264
mooreaa 6:28e60d774095 265 for (uint16_t i = 0 ; i < count ; i++)
mooreaa 6:28e60d774095 266 {
mooreaa 6:28e60d774095 267 write(buf[i]);
mooreaa 6:28e60d774095 268 }
mooreaa 6:28e60d774095 269
mooreaa 6:28e60d774095 270 if (!power) {
hudakz 0:acf75feb0947 271 wire.input();
mooreaa 6:28e60d774095 272 }
hudakz 0:acf75feb0947 273 }
hudakz 0:acf75feb0947 274
hudakz 0:acf75feb0947 275 //
hudakz 0:acf75feb0947 276 // Read a byte
hudakz 0:acf75feb0947 277 //
hudakz 0:acf75feb0947 278 uint8_t OneWire::read() {
hudakz 0:acf75feb0947 279 uint8_t bitMask;
hudakz 0:acf75feb0947 280 uint8_t r = 0;
hudakz 0:acf75feb0947 281
hudakz 0:acf75feb0947 282 for (bitMask = 0x01; bitMask; bitMask <<= 1) {
hudakz 0:acf75feb0947 283 if ( OneWire::read_bit()) r |= bitMask;
hudakz 0:acf75feb0947 284 }
hudakz 0:acf75feb0947 285 return r;
hudakz 0:acf75feb0947 286 }
hudakz 0:acf75feb0947 287
hudakz 0:acf75feb0947 288 void OneWire::read_bytes(uint8_t *buf, uint16_t count) {
hudakz 0:acf75feb0947 289 for (uint16_t i = 0 ; i < count ; i++)
hudakz 0:acf75feb0947 290 buf[i] = read();
hudakz 0:acf75feb0947 291 }
hudakz 0:acf75feb0947 292
hudakz 0:acf75feb0947 293 //
hudakz 0:acf75feb0947 294 // Do a ROM select
hudakz 0:acf75feb0947 295 //
hudakz 0:acf75feb0947 296 void OneWire::select(const uint8_t rom[8])
hudakz 0:acf75feb0947 297 {
hudakz 0:acf75feb0947 298 uint8_t i;
hudakz 0:acf75feb0947 299
hudakz 0:acf75feb0947 300 write(0x55); // Choose ROM
hudakz 0:acf75feb0947 301
hudakz 0:acf75feb0947 302 for (i = 0; i < 8; i++) write(rom[i]);
hudakz 0:acf75feb0947 303 }
hudakz 0:acf75feb0947 304
hudakz 0:acf75feb0947 305 //
hudakz 0:acf75feb0947 306 // Do a ROM skip
hudakz 0:acf75feb0947 307 //
hudakz 0:acf75feb0947 308 void OneWire::skip()
hudakz 0:acf75feb0947 309 {
hudakz 0:acf75feb0947 310 write(0xCC); // Skip ROM
hudakz 0:acf75feb0947 311 }
hudakz 0:acf75feb0947 312
hudakz 0:acf75feb0947 313 void OneWire::depower()
hudakz 0:acf75feb0947 314 {
hudakz 0:acf75feb0947 315 wire.input();
hudakz 0:acf75feb0947 316 }
hudakz 0:acf75feb0947 317
hudakz 0:acf75feb0947 318 #if ONEWIRE_SEARCH
hudakz 0:acf75feb0947 319
hudakz 0:acf75feb0947 320 //
hudakz 0:acf75feb0947 321 // You need to use this function to start a search again from the beginning.
hudakz 0:acf75feb0947 322 // You do not need to do it for the first search, though you could.
hudakz 0:acf75feb0947 323 //
hudakz 0:acf75feb0947 324 void OneWire::reset_search()
hudakz 0:acf75feb0947 325 {
hudakz 0:acf75feb0947 326 // reset the search state
hudakz 0:acf75feb0947 327 LastDiscrepancy = 0;
hudakz 0:acf75feb0947 328 LastDeviceFlag = false;
hudakz 0:acf75feb0947 329 LastFamilyDiscrepancy = 0;
hudakz 0:acf75feb0947 330 for(int i = 7; ; i--) {
hudakz 0:acf75feb0947 331 ROM_NO[i] = 0;
hudakz 0:acf75feb0947 332 if ( i == 0) break;
hudakz 0:acf75feb0947 333 }
hudakz 0:acf75feb0947 334 }
hudakz 0:acf75feb0947 335
hudakz 0:acf75feb0947 336 // Setup the search to find the device type 'family_code' on the next call
hudakz 0:acf75feb0947 337 // to search(*newAddr) if it is present.
hudakz 0:acf75feb0947 338 //
hudakz 0:acf75feb0947 339 void OneWire::target_search(uint8_t family_code)
hudakz 0:acf75feb0947 340 {
hudakz 0:acf75feb0947 341 // set the search state to find SearchFamily type devices
hudakz 0:acf75feb0947 342 ROM_NO[0] = family_code;
hudakz 0:acf75feb0947 343 for (uint8_t i = 1; i < 8; i++)
hudakz 0:acf75feb0947 344 ROM_NO[i] = 0;
hudakz 0:acf75feb0947 345 LastDiscrepancy = 64;
hudakz 0:acf75feb0947 346 LastFamilyDiscrepancy = 0;
hudakz 0:acf75feb0947 347 LastDeviceFlag = false;
hudakz 0:acf75feb0947 348 }
hudakz 0:acf75feb0947 349
hudakz 0:acf75feb0947 350 //
hudakz 0:acf75feb0947 351 // Perform a search. If this function returns a '1' then it has
hudakz 0:acf75feb0947 352 // enumerated the next device and you may retrieve the ROM from the
hudakz 0:acf75feb0947 353 // OneWire::address variable. If there are no devices, no further
hudakz 0:acf75feb0947 354 // devices, or something horrible happens in the middle of the
hudakz 0:acf75feb0947 355 // enumeration then a 0 is returned. If a new device is found then
hudakz 0:acf75feb0947 356 // its address is copied to newAddr. Use OneWire::reset_search() to
hudakz 0:acf75feb0947 357 // start over.
hudakz 0:acf75feb0947 358 //
hudakz 0:acf75feb0947 359 // --- Replaced by the one from the Dallas Semiconductor web site ---
hudakz 0:acf75feb0947 360 //--------------------------------------------------------------------------
hudakz 0:acf75feb0947 361 // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
hudakz 0:acf75feb0947 362 // search state.
hudakz 0:acf75feb0947 363 // Return true : device found, ROM number in ROM_NO buffer
hudakz 0:acf75feb0947 364 // false : device not found, end of search
hudakz 0:acf75feb0947 365 //
hudakz 0:acf75feb0947 366 uint8_t OneWire::search(uint8_t *newAddr)
hudakz 0:acf75feb0947 367 {
hudakz 0:acf75feb0947 368 uint8_t id_bit_number;
hudakz 0:acf75feb0947 369 uint8_t last_zero, rom_byte_number, search_result;
hudakz 0:acf75feb0947 370 uint8_t id_bit, cmp_id_bit;
hudakz 0:acf75feb0947 371
hudakz 0:acf75feb0947 372 unsigned char rom_byte_mask, search_direction;
hudakz 0:acf75feb0947 373
hudakz 0:acf75feb0947 374 // initialize for search
hudakz 0:acf75feb0947 375 id_bit_number = 1;
hudakz 0:acf75feb0947 376 last_zero = 0;
hudakz 0:acf75feb0947 377 rom_byte_number = 0;
hudakz 0:acf75feb0947 378 rom_byte_mask = 1;
hudakz 0:acf75feb0947 379 search_result = 0;
hudakz 0:acf75feb0947 380
hudakz 0:acf75feb0947 381 // if the last call was not the last one
hudakz 0:acf75feb0947 382 if (!LastDeviceFlag)
hudakz 0:acf75feb0947 383 {
hudakz 0:acf75feb0947 384 // 1-Wire reset
hudakz 0:acf75feb0947 385 if (!reset())
hudakz 0:acf75feb0947 386 {
hudakz 0:acf75feb0947 387 // reset the search
hudakz 0:acf75feb0947 388 LastDiscrepancy = 0;
hudakz 0:acf75feb0947 389 LastDeviceFlag = false;
hudakz 0:acf75feb0947 390 LastFamilyDiscrepancy = 0;
hudakz 0:acf75feb0947 391 return false;
hudakz 0:acf75feb0947 392 }
hudakz 0:acf75feb0947 393
hudakz 0:acf75feb0947 394 // issue the search command
hudakz 0:acf75feb0947 395 write(0xF0);
hudakz 0:acf75feb0947 396
hudakz 0:acf75feb0947 397 // loop to do the search
hudakz 0:acf75feb0947 398 do
hudakz 0:acf75feb0947 399 {
hudakz 0:acf75feb0947 400 // read a bit and its complement
hudakz 0:acf75feb0947 401 id_bit = read_bit();
hudakz 0:acf75feb0947 402 cmp_id_bit = read_bit();
hudakz 0:acf75feb0947 403
hudakz 0:acf75feb0947 404 // check for no devices on 1-wire
hudakz 0:acf75feb0947 405 if ((id_bit == 1) && (cmp_id_bit == 1))
hudakz 0:acf75feb0947 406 break;
hudakz 0:acf75feb0947 407 else
hudakz 0:acf75feb0947 408 {
hudakz 0:acf75feb0947 409 // all devices coupled have 0 or 1
hudakz 0:acf75feb0947 410 if (id_bit != cmp_id_bit)
hudakz 0:acf75feb0947 411 search_direction = id_bit; // bit write value for search
hudakz 0:acf75feb0947 412 else
hudakz 0:acf75feb0947 413 {
hudakz 0:acf75feb0947 414 // if this discrepancy if before the Last Discrepancy
hudakz 0:acf75feb0947 415 // on a previous next then pick the same as last time
hudakz 0:acf75feb0947 416 if (id_bit_number < LastDiscrepancy)
hudakz 0:acf75feb0947 417 search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
hudakz 0:acf75feb0947 418 else
hudakz 0:acf75feb0947 419 // if equal to last pick 1, if not then pick 0
hudakz 0:acf75feb0947 420 search_direction = (id_bit_number == LastDiscrepancy);
hudakz 0:acf75feb0947 421
hudakz 0:acf75feb0947 422 // if 0 was picked then record its position in LastZero
hudakz 0:acf75feb0947 423 if (search_direction == 0)
hudakz 0:acf75feb0947 424 {
hudakz 0:acf75feb0947 425 last_zero = id_bit_number;
hudakz 0:acf75feb0947 426
hudakz 0:acf75feb0947 427 // check for Last discrepancy in family
hudakz 0:acf75feb0947 428 if (last_zero < 9)
hudakz 0:acf75feb0947 429 LastFamilyDiscrepancy = last_zero;
hudakz 0:acf75feb0947 430 }
hudakz 0:acf75feb0947 431 }
hudakz 0:acf75feb0947 432
hudakz 0:acf75feb0947 433 // set or clear the bit in the ROM byte rom_byte_number
hudakz 0:acf75feb0947 434 // with mask rom_byte_mask
hudakz 0:acf75feb0947 435 if (search_direction == 1)
hudakz 0:acf75feb0947 436 ROM_NO[rom_byte_number] |= rom_byte_mask;
hudakz 0:acf75feb0947 437 else
hudakz 0:acf75feb0947 438 ROM_NO[rom_byte_number] &= ~rom_byte_mask;
hudakz 0:acf75feb0947 439
hudakz 0:acf75feb0947 440 // serial number search direction write bit
hudakz 0:acf75feb0947 441 write_bit(search_direction);
hudakz 0:acf75feb0947 442
hudakz 0:acf75feb0947 443 // increment the byte counter id_bit_number
hudakz 0:acf75feb0947 444 // and shift the mask rom_byte_mask
hudakz 0:acf75feb0947 445 id_bit_number++;
hudakz 0:acf75feb0947 446 rom_byte_mask <<= 1;
hudakz 0:acf75feb0947 447
hudakz 0:acf75feb0947 448 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
hudakz 0:acf75feb0947 449 if (rom_byte_mask == 0)
hudakz 0:acf75feb0947 450 {
hudakz 0:acf75feb0947 451 rom_byte_number++;
hudakz 0:acf75feb0947 452 rom_byte_mask = 1;
hudakz 0:acf75feb0947 453 }
hudakz 0:acf75feb0947 454 }
hudakz 0:acf75feb0947 455 }
hudakz 0:acf75feb0947 456 while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
hudakz 0:acf75feb0947 457
hudakz 0:acf75feb0947 458 // if the search was successful then
hudakz 0:acf75feb0947 459 if (!(id_bit_number < 65))
hudakz 0:acf75feb0947 460 {
hudakz 0:acf75feb0947 461 // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
hudakz 0:acf75feb0947 462 LastDiscrepancy = last_zero;
hudakz 0:acf75feb0947 463
hudakz 0:acf75feb0947 464 // check for last device
hudakz 0:acf75feb0947 465 if (LastDiscrepancy == 0)
hudakz 0:acf75feb0947 466 LastDeviceFlag = true;
hudakz 0:acf75feb0947 467
hudakz 0:acf75feb0947 468 search_result = true;
hudakz 0:acf75feb0947 469 }
hudakz 0:acf75feb0947 470 }
hudakz 0:acf75feb0947 471
hudakz 0:acf75feb0947 472 // if no device found then reset counters so next 'search' will be like a first
hudakz 0:acf75feb0947 473 if (!search_result || !ROM_NO[0])
hudakz 0:acf75feb0947 474 {
hudakz 0:acf75feb0947 475 LastDiscrepancy = 0;
hudakz 0:acf75feb0947 476 LastDeviceFlag = false;
hudakz 0:acf75feb0947 477 LastFamilyDiscrepancy = 0;
hudakz 0:acf75feb0947 478 search_result = false;
hudakz 0:acf75feb0947 479 }
hudakz 0:acf75feb0947 480 for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
hudakz 0:acf75feb0947 481 return search_result;
hudakz 0:acf75feb0947 482 }
hudakz 0:acf75feb0947 483
hudakz 0:acf75feb0947 484 #endif
hudakz 0:acf75feb0947 485
hudakz 0:acf75feb0947 486 #if ONEWIRE_CRC
hudakz 0:acf75feb0947 487 // The 1-Wire CRC scheme is described in Maxim Application Note 27:
hudakz 0:acf75feb0947 488 // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
hudakz 0:acf75feb0947 489 // Compute a Dallas Semiconductor 8 bit CRC directly.
hudakz 0:acf75feb0947 490 //
hudakz 0:acf75feb0947 491 uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
hudakz 0:acf75feb0947 492 {
hudakz 0:acf75feb0947 493 uint8_t crc = 0;
hudakz 0:acf75feb0947 494
hudakz 0:acf75feb0947 495 while (len--) {
hudakz 0:acf75feb0947 496 uint8_t inbyte = *addr++;
hudakz 0:acf75feb0947 497 for (uint8_t i = 8; i; i--) {
hudakz 0:acf75feb0947 498 uint8_t mix = (crc ^ inbyte) & 0x01;
hudakz 0:acf75feb0947 499 crc >>= 1;
hudakz 0:acf75feb0947 500 if (mix) crc ^= 0x8C;
hudakz 0:acf75feb0947 501 inbyte >>= 1;
hudakz 0:acf75feb0947 502 }
hudakz 0:acf75feb0947 503 }
hudakz 0:acf75feb0947 504 return crc;
hudakz 0:acf75feb0947 505 }
hudakz 0:acf75feb0947 506 #endif