comparison service/arduinoNode/arduino-libraries/OneWire/OneWire.cpp @ 970:4f5825a9fc47

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