Subversion Repositories idreammicro-arduino

Rev

Details | Last modification | View Log | RSS feed

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