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